It appears you don’t have a PDF plugin for this browser. No biggie… you can click here to download the PDF file.

Download the PDF of the presentation

The R Script associated with this page is available here. Download this file and open it (or copy-paste into a new script) with RStudio so you can follow along.


In this module, we’ll primarily use the mtcars data object. The data was extracted from the 1974 Motor Trend US magazine, and comprises fuel consumption and 10 aspects of automobile design and performance for 32 automobiles (1973–74 models).

A data frame with 32 observations on 11 variables.

Column name Description
mpg Miles/(US) gallon
cyl Number of cylinders
disp Displacement (
hp Gross horsepower
drat Rear axle ratio
wt Weight (lb/1000)
qsec 1/4 mile time
vs V/S
am Transmission (0 = automatic, 1 = manual)
gear Number of forward gears
carb Number of carburetors


Here’s what the data look like:

mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Base graphics

Base plot()

R has a set of ‘base graphics’ that can do many plotting tasks (scatterplots, line plots, histograms, etc.)


Or you can use the more common formula notation:


And you can customize with various parameters:

  ylab="Miles per gallon (mpg)",
  xlab="Weight (1000 pounds)",
  main="Fuel Efficiency vs. Weight",

Or switch to a line plot:

  ylab="Miles per gallon (mpg)",
  xlab="Weight (1000 pounds)",
  main="Fuel Efficiency vs. Weight",

See ?plot for details.


Check out the help for basic histograms.


Plot a histogram of the fuel efficiencies in the mtcars dataset.



The grammar of graphics: consistent aesthetics, multidimensional conditioning, and step-by-step plot building.

  1. Data: The raw data
  2. geom_: The geometric shapes representing data
  3. aes(): Aesthetics of the geometric and statistical objects (color, size, shape, and position)
  4. scale_: Maps between the data and the aesthetic dimensions
+ geometry,
+ aesthetic mappings like position, color and size
+ scaling of ranges of the data to ranges of the aesthetics

Additional settings

  1. stat_: Statistical summaries of the data that can be plotted, such as quantiles, fitted curves (loess, linear models), etc.
  2. coord_: Transformation for mapping data coordinates into the plane of the data rectangle
  3. facet_: Arrangement of data into grid of plots
  4. theme: Visual defaults (background, grids, axes, typeface, colors, etc.)

For example, a simple scatterplot: alt text

Add variable colors and sizes: alt text

Simple scatterplot

First, create a blank ggplot object with the data and x-y geometry set up.

p <- ggplot(mtcars, aes(x=wt, y=mpg))
## data: mpg, cyl, disp, hp, drat, wt, qsec, vs, am, gear, carb
##   [32x11]
## mapping:  x = wt, y = mpg
## faceting: <ggproto object: Class FacetNull, Facet>
##     compute_layout: function
##     draw_back: function
##     draw_front: function
##     draw_labels: function
##     draw_panels: function
##     finish_data: function
##     init_scales: function
##     map: function
##     map_data: function
##     params: list
##     render_back: function
##     render_front: function
##     render_panels: function
##     setup_data: function
##     setup_params: function
##     shrink: TRUE
##     train: function
##     train_positions: function
##     train_scales: function
##     vars: function
##     super:  <ggproto object: Class FacetNull, Facet>

p + geom_point()

Or you can do both at the same time:

ggplot(mtcars, aes(x=wt, y=mpg)) + 

Aesthetic map: color by # of cylinders

p + 
  geom_point(aes(colour = factor(cyl)))

Set shape using # of cylinders

p + 
  geom_point(aes(shape = factor(cyl)))

Adjust size by qsec

p + 
  geom_point(aes(size = qsec))

Color by cylinders and size by qsec

p + 
  geom_point(aes(colour = factor(cyl),size = qsec))

Multiple aesthetics

p + 
  geom_point(aes(colour = factor(cyl),size = qsec,shape=factor(gear)))

Add a linear model

p + geom_point() + 

Add a LOESS smooth

p + geom_point() + 

Change scale color

p + geom_point(aes(colour = cyl)) + 
  scale_colour_gradient(low = "blue")

Change scale shapes

p + geom_point(aes(shape = factor(cyl))) + 
  scale_shape(solid = FALSE)

Set aesthetics to fixed value

ggplot(mtcars, aes(wt, mpg)) + 
  geom_point(colour = "red", size = 3)

Transparancy: alpha=0.2

d <- ggplot(diamonds, aes(carat, price))
d + geom_point(alpha = 0.2)

Varying alpha useful for large data sets

Transparancy: alpha=0.1

d + 
  geom_point(alpha = 0.1)

Transparancy: alpha=0.01

d + 
  geom_point(alpha = 0.01)

Building ggplots

alt text

Other Plot types

alt text

Edit plot p to include:

  1. points
  2. A smooth (‘loess’) curve
  3. a “rug” to the plot
p <- ggplot(mtcars, aes(x=wt, y=mpg))

alt text

alt text

alt text

Discrete X, Continuous Y

p <- ggplot(mtcars, aes(factor(cyl), mpg))
p + geom_point()

Discrete X, Continuous Y + geom_jitter()

p + 

Discrete X, Continuous Y + geom_violin()

p + 

Discrete X, Continuous Y + geom_violin()

p + 
  geom_violin() + geom_jitter(position = position_jitter(width = .1))

alt text

Three Variables

alt text

Will return to this when we start working with raster maps.


Visualize a data transformation

alt text

  • Each stat creates additional variables with a common syntax
  • Often two ways: stat_bin(geom="bar") OR geom_bar(stat="bin")

alt text

2D kernel density estimation

Old Faithful Geyser Data on duration and waiting times.

m <- ggplot(geyser, aes(x = duration, y = waiting))

alt text photo: Greg Willis

See ?geyser for details.

m + 

m + 
  geom_point() +  stat_density2d(geom="contour")

Check ?geom_density2d() for details

m + 
  geom_point() +  stat_density2d(geom="contour") +
  xlim(0.5, 6) + ylim(40, 110)

Update limits to show full contours. Check ?geom_density2d() for details

m + stat_density2d(aes(fill = ..level..), geom="polygon") + 

Check ?geom_density2d() for details

alt text

Your turn

Edit plot m to include:

  • The point data (with red points) on top
  • A binhex plot of the Old Faithful data

Experiment with the number of bins to find one that works.

See ?stat_binhex for details.

m <- ggplot(geyser, aes(x = duration, y = waiting))
m + stat_binhex(bins=10) + 

Specifying Scales

alt text

Discrete color: default

  geom_bar( aes(fill = fl)); b

Discrete color: greys

b + scale_fill_grey( start = 0.2, end = 0.8, 
                   na.value = "red")

Continuous color: defaults

a <- ggplot(mpg, aes(x=hwy,y=cty,col=displ)) + 
  geom_point(); a

Continuous color: gradient

a +  scale_color_gradient( low = "red", 
                          high = "yellow")

Continuous color: gradient2

a + scale_color_gradient2(low = "red", high = "blue", 
                       mid = "white", midpoint = 4)

Continuous color: gradientn

a + scale_color_gradientn(
  colours = rainbow(10))

Discrete color: brewer

b + 
  scale_fill_brewer( palette = "Blues")

ColorBrewer: Diverging

alt text

ColorBrewer: Filtered

alt text

Your turn

Edit the contour plot of the geyser data:

  1. Reduce the size of the points
  2. Use a sequential brewer palette (select from
  3. Add informative x and y labels
m <- ggplot(geyser, aes(x = duration, y = waiting)) +
  stat_density2d(aes(fill = ..level..), geom="polygon") + 

Note: scale_fill_distiller() rather than scale_fill_brewer() for continuous data

m + stat_density2d(aes(fill = ..level..), geom="polygon") + 
      xlim(0.5, 6) + ylim(40, 110)+
  xlab("Eruption Duration (minutes)")+
  ylab("Waiting time (minutes)")

Or use geom=tile for a raster representation.

m + stat_density2d(aes(fill = ..density..), geom="tile",contour=F) + 
      xlim(0.5, 6) + ylim(40, 110)+
  xlab("Eruption Duration (minutes)")+
  ylab("Waiting time (minutes)")

Axis scaling

Create noisy exponential data

n <- 100
dat <- data.frame(
    xval = (1:n+rnorm(n,sd=5))/20,
    yval = 10^((1:n+rnorm(n,sd=5))/20)

Make scatter plot with regular (linear) axis scaling

sp <- ggplot(dat, aes(xval, yval)) + geom_point()

Example from R Cookbook

log10 scaling of the y axis (with visually-equal spacing)

sp + scale_y_log10()

Coordinate Systems

alt text


alt text

Stacked bars

ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar()

Dodged bars

ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar(position="dodge")


Use facets to divide graphic into small multiples based on a categorical variable.

facet_wrap() for one variable:

ggplot(mpg, aes(x = cty, y = hwy, color = factor(cyl))) +

facet_grid(): two variables

ggplot(mpg, aes(x = cty, y = hwy, color = factor(cyl))) +

Small multiples (via facets) are very useful for visualization of timeseries (and especially timeseries of spatial data.)


Set default display parameters (colors, font sizes, etc.) for different purposes (for example print vs. presentation) using themes.

GGplot Themes

alt text

Quickly change plot appearance with themes.

More options in the ggthemes package.


Or build your own!

Theme examples: default

p=ggplot(mpg, aes(x = cty, y = hwy, color = factor(cyl))) +
  geom_jitter() +
    x = "City mileage/gallon",
    y = "Highway mileage/gallon",
    color = "Cylinders"

Theme examples: default


Theme examples: Solarized

p + theme_solarized()

Theme examples: Solarized Dark

p +  theme_solarized(light=FALSE)

Theme examples: Excel

p + theme_excel() 

Theme examples: The Economist

p + theme_economist()

Theme examples: XKCD

XKCD: A webcomic of romance, sarcasm, math, and language.

alt text Note: the following code will only work if you have the xkcd font installed. See xkcd::vignette("xkcd-intro") for details.


ggplot(mtcars, aes(mpg, wt)) + 
     geom_point() +
     xkcdaxis(xrange=c(10,35), yrange=c(0,7))+
      ylab("Weight")+xlab("Miles per Gallon")+


Saving using the GUI

alt text

Saving using ggsave()

Save a ggplot with sensible defaults:

ggsave(filename, plot = last_plot(), scale = 1, width, height)

Saving using devices

Save any plot with maximum flexibility:

pdf(filename, width, height)  # open device
ggplot()                      # draw the plot(s)                     # close the device


  • pdf
  • jpeg
  • png
  • tif

and more…

Your turn

  1. Save the p plot from above using png() and
  2. Switch to the solarized theme with light=FALSE
  3. Adjust fontsize with base_size in the theme + theme_solarized(base_size=24)

Save a plot: Example 1

p +  theme_solarized(light=FALSE)

alt text

Save a plot: Example 2

p +  theme_solarized(light=FALSE, base_size=24)

alt text

GGPLOT2 Documentation

Perhaps R’s best documented package:

alt text