# save to pdf format
pdf("my_output.pdf", width = 6, height = 4)
print(my_plot)
dev.off()
# save to svg format
svg("my_output.svg", width = 6, height = 4)
print(my_plot)
dev.off()1 Visualizing data using ggplot2
1.1 Goal
Introduce the package ggplot2, which is part of the tidyverse bundle. Learn how to use ggplot2 to produce publication-quality figures. Discuss the philosophical underpinnings of the “Grammar of Graphics”, showcase the ggplot2 syntax, produce examples of the different types of graphs. Learn how to change colors, legends, scales. Visualize histograms, barplots, scatterplots, etc. Given that today coding is easier than ever, the emphasis will be on the logic of the code, interpretation of the code, and troubleshooting.
1.2 Introduction to the Grammar of Graphics
The most salient feature of scientific graphs should be clarity. Each figure should make crystal-clear a) what is being plotted; b) what are the axes; c) what do colors, shapes, and sizes represent; d) the message the figure wants to convey. Each figure is accompanied by a (sometimes long) caption, where the details can be explained further, but the main message should be clear from glancing at the figure (often, figures are the first thing editors and referees look at).
Many scientific publications contain very poor graphics: labels are missing, scales are unintelligible, there is no explanation of some graphical elements. Moreover, some color graphs are impossible to understand if printed in black and white, or difficult to discern for color-blind people.
Given the effort that you put into your science, you want to ensure that it is well presented and accessible. The investment to master some plotting software will be rewarded by pleasing graphics that convey a clear message.
In this section, we introduce ggplot2, a plotting package for R. This package was developed by Hadley Wickham who contributed many important packages to R (all included in the tidyverse bundle we’re going to use for the remainder of the class). Unlike many other plotting systems, ggplot2 is deeply rooted in a “philosophical” vision. The goal is to conceive a grammar for all graphical representation of data. Leland Wilkinson and collaborators proposed The Grammar of Graphics. It follows the idea of a well-formed sentence that is composed of a subject, a predicate, and an object. The Grammar of Graphics likewise aims at describing a well-formed graph by a grammar that captures a very wide range of statistical and scientific graphics. This might be clearer with an example – take a simple two-dimensional scatterplot. How can we describe it? We have:
Data The data we want to plot.
Mapping What part of the data is associated with a particular visual feature? For example: Which column is associated with the x-axis? Which with the y-axis? Which column corresponds to the shape or the color of the points? In
ggplot2lingo, these are called aesthetic mappings (aes).Geometry Do we want to draw points? Lines? In
ggplot2we speak of geometries (geom).Scale Do we want the sizes and shapes of the points to scale according to some value? Linearly? Logarithmically? Which palette of colors do we want to use?
Coordinate We need to choose a coordinate system (e.g., Cartesian, polar).
Faceting Do we want to produce different panels, partitioning the data according to one (or more) of the variables?
This basic grammar can be extended by adding statistical transformations of the data (e.g., regression, smoothing), multiple layers, adjustment of position (e.g., stack bars instead of plotting them side-by-side), annotations, and so on.
Exactly like in the grammar of a natural language, we can easily change the meaning of a “sentence” by adding or removing parts. Also, it is very easy to completely change the type of geometry if we are moving from say a histogram to a boxplot or a violin plot, as these types of plots are meant to describe one-dimensional distributions. Similarly, we can go from points to lines, changing one “word” in our code. Finally, the look and feel of the graphs is controlled by a theming system, separating the content from the presentation.
1.3 Basic ggplot2
ggplot2 ships with a simplified graphing function, called qplot. In this introduction we are not going to use it, and we concentrate instead on the function ggplot, which gives you complete control over your plotting. We will need to use the package tidyverse, which is already loaded if you are using the Web version of the book. If you want to copy this code into an R script to execute on your local machine, start with this line:
To explore the features of ggplot2, we are going to use a data set detailing the life expectancy, population, and per-capita GDP of several countries per year.
Let’s select Italy (or your favorite country) to have a small table:
Let’s also prepare a table with the data for all countries in Europe for the year 1997:
A particularity of ggplot2 is that it accepts exclusively data organized in tables (a data.frame or a tibble object—more on tibbles later). Thus, all of your data needs to be converted into a data frame format for plotting.
1.4 Building a well-formed graph
For our first plot, we’re going to produce a basic scatterplot showing the evolution of life expectancy in time:
As you can see, nothing is drawn: we need to specify what we would like to associate with the x axis, and what with the y axis, etc. (i.e., we want to set the aesthetic mappings). A scatterplot needs a variable for the x axis, and one for the y axis:
Note that we concatenate pieces of our “sentence” using the + sign! We’ve got the aesthetic mappings figured out, but still no graph… We need to specify a geometry, i.e., the type of graph we want to produce. In this case, for a scatterplot we could use points:
We can easily connect the points with segments:
Now let’s try to visualize the life expectancy in European countries for 1997: we need the three parts of a well-formed graph: data + mapping + geometry.
Because it is very difficult to see the labels, let’s swap the axes:
We can add “adjectives” and “adverbs” to our graph, to make it clearer; for example, we can order the countries by life expectancy, add labels for the axes, and include a main title:
1.5 Scatterplots
Using ggplot2, one can produce very many types of graphs. The package works very well for 2D graphs (or 3D rendered in two dimensions), while it lack capabilities to draw proper 3D graphs, or networks, though some extensions deal with these types of graphs.
The main feature of ggplot2 is that you can tinker with your graph fairly easily, and with a common grammar. You don’t have to settle on a certain presentation of the data until you’re ready, and it is very easy to switch from one type of graph to another.
For example, let’s plot the per capita GDP vs. life expectancy:
Showing that there is a relationship between per capita GDP and life expectancy, with higher GDP generally associated with higher life expectancy.
Let’s see whether this is true for the whole data set:
While the positive relationship between GDP and life expectancy is evident, there is an obvious saturation such that increases in GDP beyond a certain point result in diminishing gains in life expectancy.
1.6 Histograms, density and boxplots
We want to see the distribution of the per capita GDP across the world, for year 1997:
We can control the width of the bins by specifying:
Let’s see whether the histograms differ between continents:
To plot the histogram side by side, use
Similarly, we can approximate the histogram using a density plot, which interpolates the bin height to create a smooth distribution:
To see the graph better, let’s make the coloring semi-transparent:
Showing similar tails but a larger number of middle-income countries in Europe compared to Asia.
A boxplot shows the median (horizontal bar), the inter-quartile range (box size goes from 25th to 75th percentile), as well as the typical range of the data (whiskers). The dots represent “outliers”. To show the full distribution, you can use a violin plot:
Note that when producing “similar” plots (e.g., histogram vs. density, box vs. violin, or any other plot sharing the same aesthetic mappings), changing a single word can change the structure of the graph considerably!
1.7 Scales
We can use scales to determine how the aesthetic mappings are displayed. For example, we could set the x axis to be in logarithmic scale, or we can choose how the colors, shapes and sizes are used. ggplot2 uses two types of scales: continuous scales are used for continuous variables (e.g., real numbers); discrete scales are used for variables that can only take a certain number of values (e.g., colors, shapes, sizes).
For example, let’s highlight the United States in the plot showing GDP vs life expectancy:
A slightly nicer version:
We can change the scale of the x axis by calling:
Similarly, we can change the use of colors, points, etc.
1.8 List of aesthetic mappings
We’ve seen some of the aesthetic mappings. Here’s a list of the main aes:
xwhat to use for x axisywhat to use for y axiscolorthe color of points and linesfillthe color of shapes (e.g., boxes, bars, etc.)sizethe size of points, lines, etc.shapethe shape of pointsalphathe level of transparency of the objectlinetypethe type of line (e.g., solid, dashed, etc.)
1.9 List of geometries
There are very many geometries; here are a few of the most useful ones:
- Lines:
geom_abline(line given slope and intercept);geom_hline,geom_vline(horizontal, vertical line);geom_line(connect observation in scatterplot). - Bars:
geom_bar(bar height is the count/sum);geom_col(bar heigts are provided by the data). - Boxes:
geom_boxplot. - Distributions:
geom_violin(like boxplots, but showing the density of the distribution);geom_density(density of 1D distribution),geom_density2d(density of bivariate distribution);geom_histogram,geom_bin2d(histograms). - Text:
geom_text. - Smoothing function:
geom_smooth(interpolates the points of a scatterplot). - Error bars:
geom_errorbar. - Maps:
geom_map(polygons from a reference map).
1.10 List of scales
There are also very many scales. Here are a few:
xlab,ylab,xlim,ylimcontrol labels and ranges of the axes.scale_alphatransparency of the points/shapes.scale_color(many options) colors of points and lines.scale_fill(many options) colors of boxes, bars and shapes.scale_shapeshape of the points.scale_linetypetype of lines.scale_sizesize of points and lines.scale_x,scale_y(many options) transformations of the axes.
1.11 Themes
Themes allow you to manipulate the look and feel of a graph with just one command. The package ggthemes extends the themes collection of ggplot2 considerably. For example:
1.12 Faceting
In many cases, we would like to produce a multi-panel graph, in which each panel shows the data for a certain combination of parameters. In ggplot2 this is called faceting: the command facet_grid is used when you want to produce a grid of panels, in which all the panels in the same row (or column) have axes-ranges in common; facet_wrap is used when the different panels do not necessarily have axes-ranges in common.
For example:
Let’s add a line showing the best-fit line:
1.13 Setting features
Often, you want to simply set a feature (e.g., the color of the points, or their shape), rather than using it to display information (i.e., mapping some aesthetic). In such cases, simply declare the feature outside the aes:
1.14 Saving graphs
You can either save graphs as done normally in R:
or use the function ggsave
# save current graph
ggsave("my_output.pdf")
# save a graph stored in ggplot object
ggsave(plot = my_plot, filename = "my_output.svg")1.15 Multiple layers
You can overlay different plots. To do so, however, they must share some of the aesthetic mappings. The simplest case is that in which you have only one dataset:
1.16 Discuss with your peers
How would you display the data to highlight:
- Differences in the growth of life expectancy across continents
- Include population size in a display of the relationship between life expectancy and per capita GDP
- Highlight the multimodality of life expectancy (for a given year) within each continent
Discuss these visualizations with your peers, and try your hand at producing the graphs yourself.
1.17 Try on your own data!
Now that you’re familiar with ggplot2, try producing some meaningful plots for your own data.