The Grammar of Graphics

The “Grammar of Graphics” is a powerful concept that ggplot2 in R is built on. It breaks down the process of data visualization into layers, making it easier to customize and understand how to build effective charts.

The visualization illustrates the essential layers used to create a plot are:

In this session we discuss in detail how to implement these layers for plotting amazing graphis using ggplot2.

1. Data:

The foundation, where you start by defining the dataset. You cannot produce a graph unless you have data that has variables for creating such a graph. For convinience and easy followup, we will use the PlantGrowth dataset which is installed with R. First we need to inspect our data.

head(PlantGrowth, n = 5)
summary(PlantGrowth)
##      weight       group   
##  Min.   :3.590   ctrl:10  
##  1st Qu.:4.550   trt1:10  
##  Median :5.155   trt2:10  
##  Mean   :5.073            
##  3rd Qu.:5.530            
##  Max.   :6.310
names(PlantGrowth)
## [1] "weight" "group"

2. Aesthetics:

Map variables to visual aspects like color, size, and position. Aesthetics define the mapping between your data variables and the visual properties of a plot. Instead of just drawing static shapes, aesthetics translate columns in your dataset into positions, colors, sizes, or shapes that human eyes can interpret.

Different geometric layers (geoms) utilize different aesthetics, but the most frequently used include:

  • Position (x, y): Maps data to the horizontal and vertical axes.

  • Color (color or colour): Changes the outline color of points, lines, and text.

  • Fill (fill): Fills the interior area of bars, polygons, densities, and certain shapes.

  • Size (size or linewidth): Controls point diameters, text size, or the width of lines.

  • Shape (shape): Changes the point marker type (e.g., circle, triangle, square).

  • Alpha (alpha): Controls the transparency level (ranging from 0 for completely invisible to 1 for fully opaque).

  • Linetype (linetype): Modifies line styles (e.g., 1 for solid, 2 for dashed, 3 for dotted).

3. Geometries:

Specify the type of plot you want, such as bar, line, or scatter. These are are the visual layers or marks used to represent your data points on a plot. While the ggplot() function sets up the data and the coordinate space, it does not draw anything by itself. You must add a geometry layer using the + operator to make the data visible.

Geoms are broadly split into two categories based on how they process your data rows:

  • Individual Geoms: Draw a distinct graphical object for each row/observation in your dataset (e.g., a single dot for a scatterplot).

  • Collective Geoms: Group and display multiple data points using a single geometric object (e.g., a boxplot or a trend line).

library(ggplot2)
ggplot(data = PlantGrowth,   # Data
       aes(y = weight)) +   # aesthetics for mapping
  geom_boxplot() 

4. Facets:

Create subplots for different subsets of your data. Faceting creates small multiples by splitting your data into subsets based on one or more categorical variables and displaying them as a matrix of panels. It is one of the most powerful tools in R for avoiding overcrowded charts and uncovering patterns across subgroups.

Here is a comprehensive breakdown of how to use the two primary faceting functions: facet_wrap() and facet_grid().

  • Use facet_wrap() when you want to split your plot by a single variable with many levels.

  • Use facet_grid() when you want to cross-reference two categorical variables forming a structured matrix.

ggplot(data = PlantGrowth,  # Data
       aes(y = weight)) +   # aesthetics for mapping
  geom_boxplot() +          # the type of plot
  facet_wrap(~ group) 

5. Statistics:

Add statistical transformations, like mean lines or trend lines. Statistical transformations calculates new values from raw data to display on graph.

Common Statistical Functions

  • stat_smooth(): Fits a model line (like a trendline or loess smoother) with a confidence interval.

  • stat_summary(): Computes custom summary metrics (mean, median, or error bars) for a variable without needing a separate summary data frame.

  • stat_bin(): Groups continuous data into intervals to build histograms and frequency polygons.

  • stat_identity(): Performs no calculations and plots the raw values directly.

ggplot(data = PlantGrowth,      # Data
       aes(y = weight)) +       # aesthetics for mapping
  geom_boxplot() +              # the type of plot
  facet_wrap(~ group) +
  stat_summary(aes(x = 0),      # statistics to be presented
               fun = mean,
               geom = "point",
               col = "red",
               size = 3)

6. Coordinates:

This is the plot’s coordinate system, such as flipping axes. In ggplot2, coordinate systems are responsible for translating data coordinates (x and y position aesthetics) into visual positions on a 2D plot canvas.

Coordinate systems in ggplot2 are broadly divided into two major categories: linear (Cartesian-based) and non-linear systems.

Linear Coordinate Systems:

  • coord_cartesian(): The default coordinate system in ggplot2. It plots data on a flat, perpendicular x and y plane.

  • coord_flip(): Swaps the horizontal (x) and vertical (y) axes. This is highly useful for rotating vertical bar plots or box plots horizontally

Non-Linear Coordinate Systems:

  • coord_polar(): Converts a Cartesian system into polar coordinates. This function is commonly used to build pie charts, donut charts, or radar charts.

  • coord_sf(): The standard coordinate system for geographic map data using Simple Features (sf objects). It automatically handles map projections, ensuring that spatial data layers align correctly according to their coordinate reference systems (CRS).

7. Theme:

Adjust the overall appearance, like grid lines, font styles, and background. A ggplot2 theme controls all non-data visual elements of a plot, including backgrounds, grid lines, fonts, and legends.

You can change the entire look of a plot instantly by adding a built-in theme function:

  • theme_grey(): The default gray background with white grid lines.

  • theme_bw(): A clean black-and-white theme with high contrast.

  • theme_minimal(): A minimalist style with no background annotations.

  • theme_classic(): A traditional look featuring x and y axis lines and no grid lines.

  • theme_void(): A completely empty canvas with no chart chrome.

ggplot(data = PlantGrowth,      # Data
       aes(y = weight)) +       # aesthetics for mapping
  geom_boxplot() +              # the type of plot
  facet_wrap(~ group) +
  stat_summary(aes(x = 0),      # statistics to be presented
               fun = mean,
               geom = "point",
               col = "red",
               size = 3) +
  #coord_flip() +
  theme_bw()

In the code example shown, each of these layers is combined to produce the boxplot visualization. The process starts with defining the data and aesthetics, then moves through geometries, adding facets to split the data by groups, and even applying statistical transformations to highlight the mean value of each group. Finally, it configures the coordinates and finishes with a clean theme.