I have a dataset that consists of a numerical variable (height, y-axis). Each data point is replicated for an individual (1,2,3) in each treatment (A,B,C,D). Here is a terrible figure that I am looking to replace:

enter image description here

What other creative ways could I show this data? I have been playing around with facets in ggplot2, but couldn't get a layout I like. I am open to any suggestions. I would also like to add some error bars in there at some point, as the data here are means. Help make my data sexy!

Here is the data:

help_3D <- structure(list("one"=c(10,9,8,7), "two"=c(8,7,6,5),   "three"=c(8.9,8.7,8.5,8.4), treatment=c("A", "B", "C", "D")), .Name = c("one", "two", "three", "treatment"), row.names=c(NA, 15L),  class="data.frame")
  • 2
    $\begingroup$ Why not a grouped bar chart? $\endgroup$ – Trisoloriansunscreen Nov 17 '15 at 11:50
  • 1
    $\begingroup$ A grouped bar chart can easily be imagined by looking at my dot chart (answer below) and mentally superimposing bars. $\endgroup$ – Nick Cox Nov 17 '15 at 14:47
  • $\begingroup$ Error bars are applicable when you have made inferences. Your chart, on the other hand, consists of individual data points, i.e., raw data. $\endgroup$ – rolando2 Nov 18 '15 at 1:08
  • $\begingroup$ rolando2- you're absolutely right. The data here are means, so error bars would be appropriate here. Edited to include your comment. Thank you $\endgroup$ – user2325155 Nov 18 '15 at 6:08
  • 1
    $\begingroup$ I suggest that we stick with the original version of the question which implied plain data points. If you want advice on plotting error bars too, then do please ask a new question and post information allowing intervals to be plotted. The detail on the points being means came too late for the first people to build that into their answers. (Declaration of interest implied.) $\endgroup$ – Nick Cox Nov 18 '15 at 9:42

One candidate is the dot chart ably and energetically promoted by W.S. Cleveland. Here's a Stata implementation:

enter image description here

Key points include

  1. There is no absolute reason for lines to start at zero. Here it seems natural; in other cases it can seem superfluous.

  2. Solid markers here draw attention to magnitudes. Whenever points might occlude or obscure each other, open markers may be better.

  3. It's arbitrary which one categorical control nests inside another. Here treatments A B C D occur on the inside, which was found to show a simpler pattern. Another design has all treatments on the same line.

For other ideas and examples, see

Graph for relationship between two ordinal variables

Chart for visualizing multi-dimensional data

How to add a third variable to a bar plot?

Is there a better way than side-by-side barplots to compare binned data from different series

How to best visualize differences in many proportions across three groups?

In this case, there is a small functional difference between this display and similar bar charts, whether vertical or horizontal. The advantages of dot charts are more striking when each line contains two or more "dots" (more generally, markers or point symbols). Some of these threads above are especially pertinent here.

Note: Implemented in Stata with code

graph dot (asis) y, over(treatment) over(x) scheme(s1color) linetype(line) lines(lc(gs12) lw(vthin))

EDIT: Regardless of whether these are real data, a further possibility is just to shuffle the individuals 1, 2, 3. Unless you tell us otherwise, their identifiers are arbitrary; in terms of their response patterns 3 might be better placed between 1 and 2.


Looks like a grouped bar chart, as Tal mentioned. You can easily plot this with the sjPlot-package. See some examples here.

sjPlot makes it easy to produce ggplot figures - however, it requires the "raw" data, where the count (y-pos) is computed within the function. An example:


sjp.grpfrq(efc$e42dep, efc$c172code)

which gives following figure:

enter image description here

You can easily change the plot type to dot plots or similar:

sjp.grpfrq(efc$e42dep, efc$c172code, 
           geom.colors = "Set1", type = "dots", 
           coord.flip = T, showValueLabels = F)

enter image description here

In the upper cases, each group has some observations, and the count for each group is computed before plotting. However, in your case, you don't want to map y to the count of values, but to the value itself. In this case, you may have to create your own plot, which could be done like this:

help_3D <- structure(list("one"=c(10,9,8,7), "two"=c(8,7,6,5),   "three"=c(8.9,8.7,8.5,8.4), treatment=c("A", "B", "C", "D")), .Name = c("one", "two", "three", "treatment"), row.names=c(NA, 4L),  class="data.frame")

library(sjPlot) # just for the theme
sjp.setTheme("scatter") # just for the theme
help_3d_long <- tidyr::gather(help_3D, "grp", "ypos", 1:3)
ggplot(help_3d_long, aes(x = treatment, y = ypos, colour = grp)) + 
  geom_point(position = position_jitter(.2)) +

enter image description here

Finally, to add error bars, you need to have the standard error in your data set. The following plot adds error bars, but uses position_dodge instead of position_jitter, to have control of the position of both dots and error bars:

help_3D <- structure(list("one"=c(10,9,8,7), "two"=c(8,7,6,5),
                          treatment=c("A", "B", "C", "D")),
                     .Name = c("one", "two", "three", "treatment"), 
                     row.names=c(NA, 4L),  class="data.frame")

library(sjPlot) # just for theme
sjp.setTheme("scatter") # just for theme
help_3d_long <- tidyr::gather(help_3D, "grp","ypos", 1:3)
help_3d_long$se <- runif(n = 4, min = 0.2, max = .8)
ggplot(help_3d_long, aes(x = treatment, y = ypos, colour = grp)) +   
  geom_point(position = position_dodge(.2)) +   
  geom_errorbar(aes(ymin = ypos - se, ymax = ypos + se, colour = grp), 
                width = 0,
                position = position_dodge(.2)) +

enter image description here

You also might want to look at either gghtemr or ggthemes to find some "sexy" themes, as you requested. ;-)

  • $\begingroup$ Without detailed reasoning or application to the data posted, this adds nothing to Tal's comment or to the answer from @alexsb. The comment on that answer applies too. Further, answers based on links can lose value drastically if the link disappears, as seems much more likely for your link (to one person's site?). (NB: as the author of the first answer I have precisely no objection to good alternative answers. I want to see developed alternatives to dot charts, and specifically reasons why people prefer bar charts, if it's more than whim or personal taste.) $\endgroup$ – Nick Cox Nov 18 '15 at 8:59
  • $\begingroup$ I was answering from my smartphone, so I kept it short. The links are referring to my personal site where I host the vignettes of my packages. Also, I was not proposing to use bar charts, I just wanted to point to an easy-to-use R-implementation of creating ggplot-figures. In the examples I linked to is also shown how to change the plot type to dot plots. I edited my answer, so it's not dependent on references to other sites. $\endgroup$ – Daniel Nov 18 '15 at 15:50
  • 1
    $\begingroup$ Thanks; there is a strict interpretation of this question that sticks to the data posted and a broad interpretation guided more by the title, and my own view is that both are defensible. Your revised post improves very much on your first version (+1), but I'd encourage further expansion on what works best and why in what circumstances. $\endgroup$ – Nick Cox Nov 18 '15 at 15:55
  • $\begingroup$ according to counts, the easy way would be using sjPlot, according to means, I would use an own solution. I expanded my answer to a third example including error bars. $\endgroup$ – Daniel Nov 18 '15 at 16:07
  • $\begingroup$ Ok, I guess you meant which Chart type works best? I'd argue always use as much dimensions as necessary to describe the data. When comparing means, dot plots should be the choice. Bar charts if the Zero-value has a specific meaning. $\endgroup$ – Daniel Nov 18 '15 at 16:40

There are many possibilities. If you want to stick with a bar chart, you can layer or group them, as shown at (c) and (d) in this picture:

bar alternatives

Source: http://www.nature.com/nmeth/journal/v11/n2/full/nmeth.2807.html

  • 2
    $\begingroup$ So, how would you show the data posted? The pie chart (a) and the stacked, segmented or divided bar chart (b) are arguably quite wrong for the dataset. That leaves the other bar charts (c) and (d). $\endgroup$ – Nick Cox Nov 18 '15 at 0:20
  • 1
    $\begingroup$ Thanks for the reference to the paper in Nature. Unfortunately that is too telegraphic to be authoritative. For example, it is asserted that "Stacked bar charts ... are the best choice if we are primarily interested in comparing the overall quantities across items but also want to illustrate the contribution of each category to the totals." Why? Always? It continues to distress me that many scientists don't know the detailed, well-argued, excellent books of William S. Cleveland from 20 years ago (which date not at all). Start with stat.purdue.edu/~wsc $\endgroup$ – Nick Cox Nov 18 '15 at 11:58
  • $\begingroup$ @NickCox - yes, I'd go for c or d, depending on the task. Note that this is a commentary article and not meant to be a primary source. I do know the authors well and they know what they are talking about. Stacked bar charts are the best choice for comparing overall quantities because their height encodes the overall quantities. It's much harder to compare the parts of the stacked bar charts though, so if that's the task, go for aligned bar charts. You refer to the work by Cleveland & McGill, I presume, and this is very much in line with their work: goo.gl/v7oYjd $\endgroup$ – alexsb Nov 19 '15 at 2:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.