Solved – How to visualize two bar charts with very different scales without looking redundant

barplotdata visualization

More an aesthetics question to do with presentation of statistical data, say you have 2 sets of data,

     speed     weight
a      2.2      500
b      4.7      222
c      7.3      999
d      3.1     1000

So if you plot the speeds and weights on the same bar chart, you will get squishy tiny bars for all the speed values (making them unreadable). The data should be viewed together though, because there is some relationship between speed and weight that you're trying to show.

What I came up with was adjacent bar charts:

enter image description here

But it kind of looks redundant, with the repeated axes there.

Best Answer

In general, if you have two different measurements on each of a set of observations, and you think there may be a relationship between them, I think it's best to visualize them with a scatterplot. I don't know if you use R, but here is some simple code and a sample plot:

speed  = c(2.2, 4.7, 7.3, 3.1)
weight = c(500, 222, 999, 1000)

windows()
  plot(speed, weight)

enter image description here This plot doesn't look very exciting, mainly because you only have 4 data points.

Another way to visualize data is to use a dotplot. This is an especially good way to look at data that represent simple magnitudes, which is what would you have, if you were looking at only one of your variables. Note that this is the same thing a bar chart provides, it's just that dotplots have been shown to be easier for people to extract the information. The question is, can you look at two variables at the same time in such a way that you could perhaps see relationships, but without redundancy?

One way to deal with this general problem is to plot two variables on the same plot (in this case, the same dotplot). This sort of thing is very commonly done with time series data in economics (here's one I found through Googling). The trick is to find a way to get two different scales on the same plot. This can be done by rescaling one of the variables in terms of the other; in addition, you must rescale the axis values of the other variable into the terms of the first. These 'rescalings' must be linear transformations so as not to change the data in a meaningful way. The following is some R code that does this in a way which is incredibly kluge-y, but that I hope will be easy to follow:

sM  = mean(speed);     wM  = mean(weight)
sSD = sd(speed);       wSD = sd(weight)

weightZ     = (weight-wM)   / wSD
convertedW  = (weightZ*sSD) + sM

sTicks      = c(0:8)
sTicksZ     = (sTicks-sM)    / sSD
convertedST = (sTicksZ*wSD)  + wM
convertedST = round(convertedST)

sY = seq(from=1.1, to=4.1, by=1)
wY = seq(from=0.9, to=3.9, by=1)


windows()
  plot(speed, sY, pch=1, col="red", axes=F, xlab="", ylab="", ylim=c(0.5, 4.5), xlim=c(0,8))
  points(convertedW, wY, pch=2, col="blue")
  abline(h=c(1:4), lty="dashed", col="lightgray")

  box()
  axis(side=2, at=c(1:4), labels=c("a","b","c","d"))
  axis(side=3, at=sTicks,                          col="red")
  axis(side=1, at=sTicks, labels=convertedST,      col="blue")

  mtext("Speed",  side=3, line=2.5, cex=1.5, col="red")
  mtext("Weight", side=1, line=2.5, cex=1.5, col="blue")

  legend("bottomright", legend=c("Speed", "Weight"), pch=c(1,2), col=c("red","blue"))

enter image description here
With smaller amounts of data, as you have here, this may be more informative.

Related Question