cellmatrix.net

XY-Bar Combination Chart

Recently I've had to create a series of Bar charts that incorporate points that allow additional data labels. I've created these points by building in an XY scatter chart into the Bar chart. The additional data labels are tied to the XY points using a tool such as John Walkenbach's J-Walk Chart Tools or Rob Bovey's XY Chart Labeler.

An example of one of these charts, less data labels, looks like this:

image

The person who requested the chart wanted each XY point to be visible as well as vertically centered within each bar. To do so, I started by setting the gap width to 100%. Next, a calculation creates the Y values of the XY points as illustrated below.

image

The calculation starts with the source data for the bar chart which is contained in the range B4:E8. There are four categories and three series within each category. I've entered those numbers into the yellow highlighted cells D19 and D20. The calculation of the lowest Y point on the XY chart vertical axis is contained in cell D23. The calculation is:

=D20/(D20+1)

Once this calculation is done, the results can be applied to all of the Y values of the XY chart. The XY chart source is contained in the range C11:H15. The results of the calculation above are linked to cell D12. Cell D13 adds the series per category value to the results in C12. The formula in D13 is:

=D12+$D$20

Cell F12 adds the series per category value to the results in C12. The formula in F12 is:

=D12+$D$23

Finally, the maximum value of the secondary axis is simply the number of categories multiplied by the series per category. The formula in cell D24 is:

=D19*D20

The VBA procedure below attempts to quickly build this chart based on the template above. Please note that it references the color palette that I currently use - your colors may be different. At this point the output produces the following:

image

Given time the procedure could be written to complete the formatting. It could also be modified to automatically accept a reasonable number of changing categories and series, use a custom color palette, and allow more efficient range references.

Option Explicit

Sub BuildChart
()

    
Application.ScreenUpdating = False

    Dim XVals
As Range
    Dim Srs1
As String
    Dim Srs2
As String
    Dim Srs3
As String

    Set XVals
= ActiveSheet.Range("B5:B8")
    
Srs1 = ActiveSheet.Range("C4").Value
    Srs2
= ActiveSheet.Range("D4").Value
    Srs3
= ActiveSheet.Range("E4").Value

    Charts
.Add
    ActiveChart
.Location Where:=xlLocationAsObject, Name:="Sheet1"

    
With ActiveChart.SeriesCollection.NewSeries
        
.Name = Srs1
        
.ChartType = xlBarClustered
        
.XValues = XVals
        
.Values = Sheets("Sheet1").Range("C5:C8")
        .
Interior.ColorIndex = 22
        
.Border.LineStyle = xlNone
    End With

    With ActiveChart
.SeriesCollection.NewSeries
        
.Name = Srs2
        
.ChartType = xlBarClustered
        
.XValues = XVals
        
.Values = Sheets("Sheet1").Range("D5:D8")
        .
Interior.ColorIndex = 35
        
.Border.LineStyle = xlNone
    End With

    With ActiveChart
.SeriesCollection.NewSeries
        
.Name = Srs3
        
.ChartType = xlBarClustered
        
.XValues = XVals
        
.Values = Sheets("Sheet1").Range("E5:E8")
        .
Interior.ColorIndex = 24
        
.Border.LineStyle = xlNone
    End With

    With ActiveChart
.SeriesCollection.NewSeries
        
.Name = Srs1 & "_XY"
        
.ChartType = xlXYScatter
        
.XValues = Sheets("Sheet1").Range("C12:C15")
        .
Values = Sheets("Sheet1").Range("D12:D15")
        .
MarkerSize = 3
        
.MarkerStyle = xlDiamond
        
.MarkerBackgroundColorIndex = 3
        
.MarkerForegroundColorIndex = 3
    End With

    With ActiveChart
.SeriesCollection.NewSeries
        
.Name = Srs2 & "_XY"
        
.ChartType = xlXYScatter
        
.XValues = Sheets("Sheet1").Range("E12:E15")
        .
Values = Sheets("Sheet1").Range("F12:F15")
        .
MarkerSize = 3
        
.MarkerStyle = xlDiamond
        
.MarkerBackgroundColorIndex = 10
        
.MarkerForegroundColorIndex = 10
    End With

    With ActiveChart
.SeriesCollection.NewSeries
        
.Name = Srs3 & "_XY"
        
.ChartType = xlXYScatter
        
.XValues = Sheets("Sheet1").Range("G12:G15")
        .
Values = Sheets("Sheet1").Range("H12:H15")
        .
MarkerSize = 3
        
.MarkerStyle = xlDiamond
        
.MarkerBackgroundColorIndex = 5
        
.MarkerForegroundColorIndex = 5
    End With

    ActiveChart
.ChartGroups(1).GapWidth = 100

    ActiveChart
.Axes(xlCategory, xlSecondary).MaximumScale = ActiveSheet.Range("D25").Value
    ActiveChart
.Axes(xlCategory, xlSecondary).MinimumScale = 0
    ActiveChart
.Axes(xlCategory, xlSecondary).MajorUnit = 1

    ActiveChart
.Axes(xlValue).MaximumScale = ActiveSheet.Range("D25").Value
    ActiveChart
.Axes(xlValue).MinimumScale = 0
    ActiveChart
.Axes(xlValue).MajorUnit = 1

    ActiveChart
.Axes(xlValue, xlSecondary).MaximumScale = ActiveSheet.Range("D24").Value
    ActiveChart
.Axes(xlValue, xlSecondary).TickLabels.NumberFormat = "#,##0"

    
ActiveChart.Parent.Height = 189.75
    ActiveChart
.Parent.Width = 319.5

End Sub

Around the Web 2

Below are interesting items from around the web:

It's that time to update the annual and five-year financial forecasting model that I use at work. The model relies heavily on linear regression techniques to perform the forecasts. For reference, Kelly O'Day has an excellent writeup on his Process Trends site titled Trend Analysis with Excel.

In A Belated Review of Excel 2007, Jon Peltier describes his experiences with the latest release. Although I have Excel 2003 and 2007, I tend to do almost all of my work in 2003 more than likely because that's also what we use at work. However, that will probably change soon as the healthcare system that I work for recently purchased licenses for Office 2007 to support the local staff.

In September of 2005, David Gainer wrote in the The Excel Team Blog that Excel 2007 "made huge improvements to our charting engine for great-looking charts in Excel and across Office" and that Microsoft had "reworked the chart UI to make creating and working with charts much simpler and easier". Fast-forward to 2008 . . . I wonder what the general opinion of end-users and developers is now regarding functionality and features?

Microsoft's Office Fluent User Interface Developer Portal contains a series of resources for customizing the Office 2007 ribbon.

This site uses a combination of CSS and HTML tables. One of my favorite references for formatting tables in CSS is Robert Denton's CSS Tables Tutorial. Although the last update to this site was in 2002, adapting the CSS examples to XHTML standards was very easy with the help of the WC3 Validator. TechRepublic also has a nice writeup titled Why CSS Styling is for Tables Too.

Mandarin Design is one of my favorite resources for general website and blog design. The site features a variety of formatting techniques for setting up multiple columns, floating images, etc. Unfortunately the author passed away sometime back so the site is no longer actively updated. However, it is still online which is great for novice users like myself.

Pivot Table Difference Between Columns

When I most need it, I always seem to forget how to compute the difference between two pivot table columns. So, it's about time to put it in writing. Assume the following data:

image

Create a simple pivot table with the years as columns and the areas as rows.

image

Next, eliminate the row totals. To do so, right-click any cell within the pivot table and go to Table Options. Deselect "Grand total for rows" from the format options area of the Table Options dialog box.

At this point it's time to create a calculated item that subtracts the 2008 data from the 2007 data. Right-click on the year (cell B2) and select Show Pivot Table Toolbar. In the Pivot Table toolbar, choose Formulas -> Calculated Item. The following dialog box will appear:

image

Add the formula for the calculated item as shown below:

image

To make all of the accountants happy, we need to make the most recent year appear as the first column of the table. To do so, right-click within the column titles (2008, 2007, or Difference) -> Order. You can then move the any of the columns to the right or left to achieve the desired look.

The end-result looks like this:

image

Percent Change Error Trap

To keep the percent change formula from returning errors and/or extreme values, consider a nested IF statement to trap errors or values that fall outside of a certain range. In the example below, "n/a" refers to "not applicable". Errors have been trapped in lines one through three. In line four, the formula returns "n/a" because the absolute value of the change is greater than 200%. This logic is written into the formula to prevent it from returning exteme values.

image

The formula in G4 is below. It is copied from cell G4 into cells G6, G8, G10, and G12.

=IF(ISERROR((E12-F12)/ABS(F12)),"n/a",IF(ABS((E12-F12)/ABS(F12))>2,"n/a",IF((E12-F12)/ABS(F12)=-1,"n/a",(E12-F12)/ABS(F12))))

Simple Goal Seek Procedure

Unfortunately Excel's goal seeking feature forces you to hand-enter a value into the "To value" field of the input box. You can't directly tie this input to a cell like you can with the "Set cell" and "By changing cell" inputs (see the screenshot below).

image

This can make things difficult especially if you're trying to seek very large values or values that that are carried out to many decimal points.

The following procedure allows you to get around this limitation. First, enter the cell addresses for the variables called Rng1, Rng2, and Rng3. Note that a formula must appear in Rng1 and a value must be entered into Rng3. Next, run the procedure.

Sub GoalSeek()

    
Dim Rng1 As Range
    Dim Rng2
As Range
    Dim Rng3
As Range

    On Error GoTo errHandler
:

    
'Set the value in this cell
    Set Rng1 = ActiveSheet.Range("C4")

    '
Equal to the value in this cell
    
'Note:  This cell must contain a formula
    Set Rng2 = ActiveSheet.Range("C7")

    '
By changing the value in this cell
    Set Rng3
= ActiveSheet.Range("C2")

    If
Rng1.HasFormula = True Then
        
If IsNumeric(Rng3) = True Then
            Rng1
.GoalSeek Goal:=Rng2, ChangingCell:=Rng3
        End
If
    
End If

    Exit
Sub

errHandler
:
    
MsgBox "Procedure failed - please check inputs."

End Sub

Interpretation of Percent Change

Over time I've found that the interpretation of percent change is one of the most simple and misunderstood calculations in finance. As an example, take the following data:

image

The formula in cell C3 is

=(B3-B4)/B4

This is the formula that I've found most people use. The formula works great when you're comparing positive numbers. However, a problem occurs when you bring in the negatives. Looking at cell C11, is it correct to say that the increase from -45 to -35 is -22.2%? If -35 is a larger number than -45, how can the increase be a negative?

If you look at all numbers, positive and negative, as being on a single scale the calculation is easier to see. Now we'll take the same data above and apply a slightly different formula:

image

The formula in cell C3 is

=(B3-B4)/(ABS)B4

When you look at column C, all of the percent increases are positive percentages. Likewise, when you look at column D all of the percent decreases are negative percentages. Positive percentages correspond to moving up the number scale and negative percentages correspond to moving down the number scale.

To conclude, the formula that includes Excel's ABS function is the correct formula. The ABS function insures that the denominator in the formula is always positive which allows the formula to return the correct percentage change. If you use this formula and think of the number scale, you'll never have to worry about the calculation of percent change and / or how to explain it to those that may not understand how to interpret it.

Secondary Axes in Charts Discussion

Recently the topic of primary and secondary axis scales was discussed at the PTS Blog. The discussion starts with a reference to Stephen Few's March 2008 Visual Business Intelligence Newsletter titled Dual-Scaled Axis in Graphs - Are They Ever the Best Solution . Stephen starts his article by concluding that He then goes on to cite a series of examples. Finally, at the end of his article he states that "I certainly cannot conclude, once and for all, that graphs with dual-scaled axes are never useful; only that I cannot think of a situation that warrants them in light of other, better solutions. I invite you to propose viable exceptions, which I will welcome with open arms."

From a healthcare finance perspecitive, it has been my experience that these charts are great tools for those who know how to build them and for those audiences that know how to interpret the underlying data. Below are several comments I have concerning Stephen's article:

Comment #1 - It's not necessarily the chart with two axes that's bad, it's the data behind it. In the newsletter, most of Stephen's graphs illustrate the relationship between revenue and units sold. I would argue that is comparison is flawed from the beginning and, as such, this type of chart should not be used. My reasoning is that, although it seems like the data is should be related, when you drill down into the data you might find out that the correlation is not as close as you might have thought. Depending on the data:

  • What defines a unit?
  • Are the units the same unit each quarter or are there multiple types of units being charted as one?
  • If there are multiple units, how are the changes in volume accounted for within the sales mix?
  • Won't price increases distort the data over time?
  • How does the chart account for decreases in purchasing power over time i.e inflation over time?
  • If the data is measured by quarter and one of the quarters includes a leap year, how do you account for the extra day?

In my opinion, I think an argument can be made that a dual axis chart showing revenue and units sold is probably not the the best use of a dual-axes chart. That being said I do have to admit that I do use this type comparison at a top-level where the components of variance might be considered immaterial. If a dual-axes chart is to be used the audience should be educated on how to interpret the underlying data and how to recognize and address possible flaws before decisions a made.

Comment #2 - If you are going to present a dual-axis chart, the axes need to be proportional. That means doing the math for each axes to make sure it is in fact proportional to the other.

Comment #3 - As Stephen observed, line graphs are the best presentation for this type of chart.

Comment #4 - "I can’t think of a single case when there isn’t a better solution than a graph with a dual-scaled axis." In my line of work, we've found that these graphs are very useful for auditing calculations. For example, you are tasked with building a projection of revenue and discounts for the next year. In a healthcare environment, revenue and discounts both contain the same components of variance i.e. work days, fee increases, volume changes, payer mix changes, and changes in service mix or acuity. The calculations the build all of these components can get very complex. Rather than attemping to proof each calculation that builds the projection, this chart can quickly pick up areas of possible error.

In the example below, it's obvious that there's problem with June calculations because the lines are not in sync for that month.

image

Comparing the growth in same-type volumes (for example Radiology vs. Laboratory volumes) is another example.

To conclude, there may in fact be better charts for displaying certain types of data. But if the audience understands the relationships between the data I think there is a place for these charts. And like the example above shows, there's most definitely a place for these charts when performing audits.

Size and Export Embedded Charts as .GIF Images

To add images of embedded charts to this weblog, I use the VBA procedure below. To run the procedure, first make sure the specifications are correct. You can make changes to the chart height, width, file name, and file path. When all of the inputs are correct, click on (activate) the embedded chart and run the macro.

Sub ExportChart()

    
Dim Cht As ChartObject
    Dim Path
As String
    Dim FileName
As String
    
    Set Cht
= ActiveChart.Parent

    Cht
.Height = 210
    Cht
.Width = 336
    FileName
= "2008032301.gif"
    
Path = "C:\Program Files\"
    
    
ActiveChart.Export Path & FileName

End Sub

Please note that the height and width are not really needed. I've added this code only because I like to make sure all of the charts are exactly the same size.

About

Formulas, Charts, and Models Created with Microsoft Excel.

Read more...

Statistics

  • Total Entries - 81
  • Current Viewers - 2
  • Days Online - 419

Categories

Entries by Day

May 2008
S M T W T F S
27 28 29 30 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Excel Web Logs

Syndicate

Validate

My Resources...

Copyright © 2007 - 2008