=======================================================================================

1 Preface

When done right, graphs can be appealing, informative, and of considerable value to an academic article. Unfortunately, researchers generally suck at making good graphs. We surmise that this is because researchers do not completely master their graphing software, and they are either too lazy or too busy to remedy the situation. Consequently, the produced graph is often a severe distortion of the ideal Platonian graph that the researcher had in mind initially.

This compendium facilitates the creation of good graphs by presenting a set of concrete examples, ranging from the trivial to the advanced. The graphs can all be reproduced and adjusted by copy-pasting code into the R console. A note for R fans: the majority of our plots have been created in base R, but you will encounter some examples in ggplot.

Almost every example in this compendium is driven by the same philosophy: A good graph is a simple graph, in the Einsteinian sense that a graph should be made as simple as possible, but not simpler.

We close with a request and a piece of advice. The request: if you create a clean graph in R that you believe is a candidate for inclusion in this compendium, please do not hesitate to contact us at EJ.Wagenmakers@gmail.com or quentingronau@web.de. Your contribution will be acknowledged explicitly, alongside the code you provided. The advice: when you create a clean graph in R, put it on Flickr (public license) before you sign away your copyright to a publisher. For an example, see Figure 1 from this paper.

This work has profited greatly from interactions with our colleagues, many of whom have contributed graphs of their own.

2 Introduction

Producing clean graphs can be a challenging task. First you have to consider what is the best way in which to convey the information: a line graph, a histogram, a multi-panel plot; such conceptual dilemma’s are not dealt with in this compendium, and instead we recommend the reader to the chapters on creating graphs in the excellent book by Briscoe (1996). Second, you have to use computer software to translate the conceptual graph to a publication-ready figure. This is the phase where this compendium may be useful, because it brings together R code for producing a set of clean, publication-ready figures. Hopefully this will make it easy to copy-paste and adjust the code to suit your own needs.

In our experience, many graphs can be dramatically improved by adhering to the following guidlines: (1) invest sufficient time and effort in the process; (2) omit needless graphical elements, that is, make every element count; (3) judge the relative impact of the graphical elements and ensure that they are in balance; (4) use large font sizes for all text; (5) deviate from the R default settings – with a little effort, you can do a lot better.

This compendium does not discuss figure headings. However, we will say that it is clearly desirable to have the main message of a figure be understood without being forced to read the main text. If possible, start your figure heading by stating what the figure is meant to demonstrate (i.e., its interpretation). For example, do not state “Popularity as a function of president height”; instead, state “Taller presidents are more popular”.

Finally, a note on color. Many graphs look better in color, but there are two complications. First, some academic journals do not publish manuscripts in color, at least not without charging a hefty price. Second, many readers and reviewers do not have a color printer. Below, some graphs have color, whereas others only use grey-scales. Of course this is one of the easiest things to adjust.

Based on this compendium, learning to create good graphs in R will be 80% copy-paste and 20% tinkering. Let’s go plot ourselves some graphs!

3 Correlations

Whenever a researcher reports a correlation, it is imperative to plot the data. Anscombe’s quartet (plotted below) is a famous demonstration of this fact.

3.1 The Electoral Advantage of Being Tall

This plot shows the relation between the height ratio of US presidents and the percentage of the popular vote. Note the large circles for the data, the thick line for the linear relation, and the large font size for the axis labels. Also, note that the line does not touch the y-axis (a subtlety that requires deviating from the default).

Show R-Code


4 Histograms

Histograms are relatively straightforward to create and to interpret. In fact, some people may even find them boring. Luckily, it is easy to increase the reader’s interest level by adding information to the plot. Below we illustrate various ways by which this may be accomplished.

4.1 Including “rug” Tick Marks

When in doubt, add tick marks that showcase the individual data points. This is particularly useful when the number of data points is small. The code below is courtesy of Helen Steingroever. Note that the rug tick marks are jittered.

Show R-Code


4.2 Including a Density Estimator

In R, it is easy to include a nonparametric density estimator. This requires that freq = FALSE in the histogram comment. Courtesy of Helen Steingroever.

Show R-Code


4.3 Including Numbers on Top

This example shows how to display the bar heights, using the function l_ply. Courtesy of Helen Steingroever and Quentin Gronau.

Show R-Code


5 Line Plots

The line plot is one of the most standard plots. Nevertheless, many researchers fail to realize that line plots deserve love and attention too.

5.1 Regular Line Plot

This graph plots error bars with a user-defined function. More to the point, the lines are thick, and they do not overlap with the symbols (type = "c"). Note that the legend is not needed; the legend text could simply have been positioned near the associated graphical elements.

Show R-Code


5.2 Box Plot

Similar to the above, this plot shows the distribuion of the data with a user-defined boxplot function.

Show R-Code


5.3 Violin Plot

By now this plot should look familiar. The distribution of the data is now indicated with a violin plot instead of a box plot. Courtesy of Henrik Singmann, who tweaked the results from the vioplot package. Warning: this a a lot of code.

Show R-Code


5.4 Combined Line and Bar Plot

In many psychological experiments, there are two dependent variables for each participant: mean response time (RT) and mean proportion of errors. This plot shows them both – RTs are on the left y-axis, and errors are on the right y-axis.

Show R-Code


6 Bar Plots

Like their histogram cousin, bar plots are intrinsically boring.

6.1 Including Error Bars

The title says it all. Note that the error bars are added with the l_ply function. Courtesy of Helen Steingroever and Quentin Gronau.

Show R-Code


7 Densities

Densities are ubiquitous, particularly for those who have a predeliction for Bayesian inference. As for the histogram and the bar plot, it is generally a good idea to add more information to the bare-bones plot.

7.1 Standard

This is a relatively standard plot. Note the thickness of the lines and the font size for the axis labels.

Show R-Code


7.2 With a Histogram on Top

This plot adds a histogram to the density plot, but without needlessly displaying the vertical histogram lines as well. In addition, the code defines the extent to which the lines are transparent, so that both the density and the histogram remain visible, and one does not completely block the other from view.

Show R-Code


7.3 Including Text

This plot adds text to the plot. Although this is generally trivial, this particular example contains a mathematical symbol that is tricky to display properly (unless, of course, you know how it works).

Show R-Code


7.4 Another Example

This is another example, featuring a nice Greek letter. Seriously, what is important here is that the labels are positioned next to the associated graphical element. This approach is more direct than creating a legend, when the reader has to decode the legend first, keep the symbols in working memory, and then turn attention to the graph itself. Bottom line: only use legends when you have to. Even then, you may find that the legend box almost never fulfills a useful function, and can safely be omitted.

Show R-Code


7.5 Highlighting Specific Areas

It is cool to be able to highlight specific parts of a density by some color coding scheme. In this example, Ravi Selker shows how that can be done (hint: it’s the polygon function).

Show R-Code


7.6 More Highlighting of Specific Areas

Mijke Rhemtulla also likes to highlight specific parts of a density. This is the first plot in a series, taken from one of Mijke’s stats courses.

Show R-Code


7.7 Still More Highlighting

Part 2…

Show R-Code


7.8 Density Ratios

Part 3…

Show R-Code


7.9 Many Density Ratios

Part 4… The take-home message from the last set of plots: use polygon, annotate the plot, and use large font sizes and thick graphical elements.

Show R-Code


7.10 Stacked Densities

Michael Lee attended me to a “stacked densities plot” [http://nxn.se/post/97650612370/high-contrast-stacked-distribution-plots]. Quentin Gronau did the work and shows how multiple densities can be displayed at the same time, while still being discriminable. Note the use of the trans3d function.

Show R-Code


8 Functions

It can be very informative to plot a function. This is relatively straightforward once you stick to the basic principles (thick lines, annotate the plot, large font sizes).

8.1 Plotting a Function

What did we say? Thick lines, annotate the plot, large font sizes!

Show R-Code


9 Time Series

What’s not to love about time series? In constrast to some of the previous plots, time series are virtually always interesting, almost mesmerizing. The bar plot compares to a time series as, well, a refrigerator compares to Marilin Monroe. The reason, of course, is that time series are highly informative: they usually contain many observations; moreover, they show how particular variables change over time (it is a time series, after all). Enough of the talking – let’s turn to some examples.

9.1 A Diffusion Process

Instead of giving a lecture about diffusion processes, I’ll point out that the lines are transparent. We’ve encountered this before but it was Guy Hawkins who showed me how to do this in R.

Show R-Code


9.2 A Sequence of Choices

Helen Steingroever returns to us once again, this time with a choice profile for the Iowa gambling task. The plot conveys a lot of information: for one participant, the plot indicates the sequence of 100 choices among four choice alternatives, and whether or not each choice resulted in a win or a loss.

Show R-Code


9.3 The Electoral Advantage of Being Tall Revisited

This plot shows the development of the Bayes factor (y-axis) as the data accumulate (x-axis). This procedure may give frequentists a heart attack but, in Bayes world, that’s just how we roll. What we like about the graph are the annotations on the right side of the plot, and the subtle horizontal lines that indicate Jeffreys’ criteria on the evidence. It took some time to figure out how to display the word “Evidence” in its current direction. To make this plot we “borrowed” code from Ruud Wetzels and Benjamin Scheibehenne.

Show R-Code


9.4 A Sequential Test on \(\large{\pi}\)

And again the Bayesians flaunt their disdain for the sillyness of sampling plans. The plot below shows the development of the Bayes factor (y-axis) with the number of digits from \(\pi\). As the digits accumulate, so does the evidence in favor of the null hypothesis (yes frequentists, you read that right – evidence in favor of the null hypothesis).

The plot shows the maximum evidence (in red), the actual evidence (for two different priors), and the area that we can expect the Bayes factor be in \(95\%\) of the cases, should the null hypothesis hold. This is dirty frequentist reasoning of course, but the plot does show how it is possible to reject a null hypothesis even when the data provide a lot of support in its favor (i.e., the Jeffreys-Lindley paradox). Courtesy of Quentin Gronau.

Show R-Code


10 Multiple Panels

To suitably impress the readership, any academic needs to be able to create a multi-panel graph. Below is a set of examples. When creating a multi-panel plot, the main challenge is to select the right number of panels (yes, you can have too many) so that the text and the symbols remain readible.

10.1 Two panel plot

This is one of my favorite plots, highlighting the difference between discrete probability mass and continous probability density. Credit goes to Michael Lee for conceptualizing the graph (it is presented in box 3.2 of our book) and to Quentin Gronau for the execution in R. Note the use of ablineclip for lines of distinct length and uniroot for finding the x-value that corresponds to five times the density of another x-value.

Show R-Code


10.2 Buffon’s Needle

The only way to understand the title (and the plot) is to visit the Wikipedia entry on Buffon’s needle. Anyway, this is another two-panel plot, showing two posterior distributions for estimating \(\pi\) using an experiment that involved tossing a needle (ad nauseam).

Show R-Code


10.3 Anscombe’s Quartet

Sometimes a graph is worth a thousand words. Anscombe’s quartet famously drives home the idea that you should always plot your data. This code is based on the Anscombe plot in R. We personally don’t like lapply and similar complications – it may do the trick but when you have to describe the code as “magic” this signals a communication problem. Anyway, the point of the example is graphical display of course. As always, note the thick lines, the large symbols, and the large font size.

Show R-Code


10.4 Four Quite Different Panels

Each panel of this plot shows something very different: histogram, density, point plot, and function. We like the annotations too.

Show R-Code


10.5 Nine-Panel Posterior Predictives

Ravi Selker enters the stage to present a nine-panel plot of posterior predictives. Note the use of textGrob and arrangeGrob. Nice work.

Show R-Code


11 Graphs from JASP

Our lab at the University of Amsterdam has developed JASP, a free and open-source program for statistical analysis. In many ways, JASP is SPSS done right: minimalist output with progressive disclosure, dynamic updating of results, Bayesian analysis options, and, of course, clean graphs. Below is a series of JASP graphs.

11.1 Correlation Matrix

This multi-panel plot combines several elements that should now be familiar: correlation plots, histograms with density estimators, and, on the lower diagonal, the associated statistics.

Show R-Code


11.2 Prior and Posterior

This is one of our favorite JASP graphs. Note the balance between the graphical elements. When it comes to inference about the equality of two means (which is the JASP analysis that yields this plot), this graph provides: (1) the prior distribution of effect size; (2) the posterior distribution of effect size; (3) the 95% credible interval; (4) the posterior median;(5) the Bayes factor; (6) a Savage-Dickey visualization of the Bayes factor by means of the height ratio for the grey dots shown at an effect size of zero; (7) a pizza plot visualization of the Bayes factor. That’s a lot of information, but the graph is still relatively clean.

Show R-Code


11.3 Robustness Check

This JASP graph shows the results of a Bayes factor robustness check. Note the second y-axis, the balance of the graphical elements, and the font size.

Show R-Code


11.4 Evidential Flow

This graph shows the evidential flow, the fluctuations in the Bayes factor (y-axis) as the data accumulate (x-axis).

Show R-Code


11.5 Evidential Flow with Robustness Check

The graph adds a robustness check by displying the evidential flow for different prior choices.

Show R-Code


12 Miscellaneous

Several cool plots do not fall neatly into the above categories.

12.1 Funnel Plot

This is a funnel plot, and it is courtesy of Mark Nieuwenstein. The code depends on the meta and metafor R packages.

Show R-Code


12.2 Network Graph

Sacha Epskamp uses his qgraph package and shows how to display a network with nodes and connections.

Show R-Code


12.3 Questionnaire Graph

Sacha Epskamp shows how to present the many outcomes from a questionnaire in a single graph.

Show R-Code


12.4 Heatmap with Contour Lines

This heatmap with contour lines displays the joint posterior for two variables.

Show R-Code


12.5 Nonparametric Bayes

This plot shows the results of a nonparametric Bayesian Dirichlet process mixture model analysis. The left panel displays the distribution of “active” groups during the MCMC iterations, the right panel visualizes which observations were assigned to the same group (lighter colors indicate higher probabilities of being in the same group).

Show R-Code


12.6 Confidence Band Plot

Courtesy of Liz Page-Gould, this plot shows how to plot a confidence band around a line.

Show R-Code


12.7 Many Intervals in One Plot

Courtesy of Felix Schönbrodt and Maarten Marsman, this plot shows credible intervals for each of 42 experiments in the Social Psychology special issue. Each experiment tried to replicate an important result in the field of social psychology.

Show R-Code


12.8 Many Bayes Factors in One Plot

Courtesy of Felix Schönbrodt and Maarten Marsman, this plot is similar to the one above but now presents the Bayes factor instead of the credible interval.

Show R-Code


12.9 Prior and Posterior Distributions with Frills

This plot aims to explain the conclusions that can be drawn from a prior and a posterior distribution (background story: If Bob’s IQ is higher than 70 he will be executed). In a teaching setting it works best when the different elements (A-G) are visually introduced one at a time.

Show R-Code


12.10 Heatmap Updating

The top row shows a sequence of heatmaps that describe a joint distribution; the bottom row shows the associated predictions. After every observation (the red cross), the heatmap is updated. As information flows in, from left to right, the heatmap becomes more concentrated and the predictions become more specific.

Show R-Code


12.11 Meta-Analytic Forest Plot

This graph contains a lot of information: study number, raw summary data, mean effect size, 95% confidence intervals, and a meta-analytic estimate. Importantly, the broad picture can be obtained from a brief look at the intervals, whereas the numbers allow a more detailed analysis.

Show R-Code


12.12 Many Bayes Factors with Zoom

This two-panel plot presents replication Bayes factors (Verhagen & Wagenmakers, 2014) for the experiments in the “pipeline project” (Schweinsberg et al., in press). The problem that this graph seeks to overcome is that some Bayes factors are very large, extending the scale on the x-axis and making it impossible to discern what happens in the interesting region where the evidence is less compelling. Therefore, the bottom panel zooms in on the area of interest. This fact is evident from the grey area that spreads out from the top panel to the lower panel.

Show R-Code


12.13 Reproducibility Project: The Correlation Graph

Courtesy of Fred Hasselman, this graph is a slightly edited version of the one that was prominently displayed in a groundbreaking publication (Open Science Collaboration, 2015). The associated information on the Open Science Framework is here. You may compare versions – what has changed?

Show R-Code


12.14 Reproducibility Project: The Layered-Violin Graph

Courtesy of Fred Hasselman, this is a slightly edited version of a plot for the Reproducibility Project. The graph shows violin plots for p-values (left panel) and effect-sizes (right panel). Note that the violin plot is divided into four areas.

Show R-Code


13 References

Briscoe, M. H. (1996). Preparing scientific illustrations. Springer.

Open Science Collaboration (2015). Estimating the reproducibility of psychological science. Science, 349, 943.

Schweinsberg, M., Madan, N., Vianello, M., Sommer, S. A., Jordan, J., Tierney, W., Awtrey, E., Zhu, L., Diermeier, D., Heinze, J., Srinivasan, M., Tannenbaum, D., Bivolaru, E., Dana, J., Davis-Stober, C. P., Du Plessis, C. Gronau, Q. F., Hafenbrack, A. C., Liao, E. Y., Ly, A., Marsman, M., Murase, T., Qureshi, I., Schaerer, M., Thornley, N., Tworek, C. M., Wagenmakers, E-J., Wong, L., Anderson, T., Bauman, C. W., Bedwell, W. L., Brescoll, V., Canavan, A., Chandler, J. J., Cheries, E., Cheryan, S., Cheung, F., Cimpian, A., Clark, M., Cordon, D., Cushman, F., Ditto, P. H., Donahue, T., Frick, S. E., Gamez-Djokic, M., Hofstein Grady, R., Graham, J., Gu, J., Hahn, A., Hanson, B. E., Hartwich, N. J., Hein, K., Inbar, Y., Jiang, L., Kellogg, T., Kennedy, D. M., Legate, N., Luoma, T. P., Maibeucher, H., Meindl, P., Miles, J., Mislin, A., Molden, D. C., Motyl, M., Newman, G., Ngo, H. H., Packham, H., Ramsay, P. S., Ray, J. L., Sackett, A. M., Sellier, A-L., Sokolova, T., Sowden, W., Storage, D., Sun, X., Van Bavel, J. J., Washburn, A. N., Wei, C., Wetter, E., Wilson, C., Darroux, S-C., & Uhlmann, E. L. (in press). The pipeline project: Pre-publication independent replications of a single laboratory’s research pipeline. Journal of Experimental Social Psychology.

Verhagen, A. J., & Wagenmakers, E.-J. (2014). Bayesian tests to quantify the result of a replication attempt. Journal of Experimental Psychology: General, 143, 1457-1475.