Author

Steen Flammild Harsted & Søren O´Neill

Published

April 25, 2025



1 Presentation

You can download the course slides for this section here

Getting Started

  • Create a new quarto document and name it “ggplot.qmd”
  • Change the YAML header to style your document output. (see YAML example below)
  • Insert a code chunk and load 2 important libraries
  • Insert a new code chunk- Write source(here("scripts", "01_import.R")) in the chunk
  • Discuss what the code does and run it
  • Write a short headline to each code chunk
---
title: "TITLE"
subtitle: "SUBTITLE"
author: "ME"
date: today
format: 
  html:
    toc: true
    toc-depth: 2
    embed-resources: true
    number-sections: true
    number-depth: 2
    code-fold: true
    code-summary: "Show the code"
    code-tools: true
execute:
  message: false
  warning: false
---
Show the code
# Load libraries
library(tidyverse)  # Data wrangling and plots
library(here)       # File control in project

# Load the cleaned soldiers dataset
source(here("scripts", "01_import.R"))


1.1 Guess the output

Discuss the code below.

You’ll need to guess a little because you haven’t seen all the datasets and functions yet, but use your common sense! See if you can predict what each plot will look like before running the code.

ggplot(mpg, aes(cty, hwy)) + geom_point()

ggplot(diamonds, aes(carat, price)) + geom_point()

ggplot(economics, aes(date, unemploy)) + geom_line()

ggplot(mpg, aes(cty)) + geom_histogram()


1.2 Aesthetic mappings - aes()

Use the mpg dataset.


Explore the columntypes in the mpg dataset

Use one or more of: ?mpg, head(), glimpse() and/or summary() ::: {.cell}

Show the code
mpg |>  head()
mpg |>  glimpse()
mpg |>  summary()  # or library(skimr) and then mpg |> skim()

:::


Experiment with the colour, shape, and size aesthetics.

Use this basic code, and add/change the colour, shape, and size aesthetics. ::: {.cell}

ggplot(mpg, aes(cty, hwy)) + 
  geom_point()

:::

  • What happens when you map continuous variables to one or more of the aesthetics?
  • What about categorical variables?
  • What happens when you use multiple aesthetics in a plot?
Show the code
## Examples

# Categorial
ggplot(mpg, aes(cty, hwy, colour = class)) + 
  geom_point()

# Continuous 
ggplot(mpg, aes(cty, hwy, size = displ)) + 
  geom_point()

# Continuous 
ggplot(mpg, aes(cty, hwy, color = hwy)) +  # Notice hwy is mapped to both y axis and color
  geom_point()

## A continuous variable doesn't work for shape
ggplot(mpg, aes(cty, hwy, shape = displ)) + 
  geom_point()

# Multiple Categorical - a legend for each aesthetic is created
ggplot(mpg, aes(cty, hwy, colour = class, shape = fl)) + 
  geom_point()


What’s gone wrong with this code? Why are the points not blue?

ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy, color = "blue"))
Show the code
# If you want all the points to be colored blue, then color = "blue" must be placed outside the aes() function.
ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy),
             color = "blue")  


1.3 geom_point() and geom_smooth()

Use your soldiers dataset


Explore the relationship between heightcm and weightkg using geom_point() ::: {.cell}

Show the code
soldiers |> 
  ggplot(aes(x = heightcm, y = weightkg))+
  geom_point()

:::


  • Color the points according to BMI ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(x = heightcm, y = weightkg, color = BMI))+
  geom_point()

:::


  • Color the points according to category ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(x = heightcm, y = weightkg, color = category))+
  geom_point()

:::


Explore the relationship between heightcm and weightkg using geom_point() and geom_smooth() ::: {.cell}

Show the code
soldiers |> 
  ggplot(aes(x = heightcm, y = weightkg))+
  geom_point()+
  geom_smooth(method = "lm")

:::


  • color by sex ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(x = heightcm, y = weightkg, color = sex))+
  geom_point()+
  geom_smooth(method = "lm")

:::

 

1.4 facet_wrap()

  • What arguments can you use to control how many rows and columns appear in the output?
  • What does the scales argument in facet_wrap() do? When might you use it?


Explore the relationship between heightcm and weightkg

  • Use geom_point() and geom_smooth()
  • facet by sex
  • color the points by category ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(x = heightcm, y = weightkg))+
  geom_point(aes(color = category))+
  geom_smooth(method = "lm")+
  facet_wrap(~sex)

:::


1.5 geom_bar()


Use geom_bar() to explore how many soldiers of each race there is

Show the code
soldiers |> 
  ggplot(aes(x = race))+
  geom_bar()


Use geom_bar() to explore how many soldiers are at each Installation

Show the code
soldiers |> 
  ggplot(aes(x = Installation))+
  geom_bar()

# OR - Whats the difference?

soldiers |> 
  ggplot(aes(y = Installation))+
  geom_bar()


  • Use the fill aestetic to color the Installation bars according to race ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(y = Installation, fill = race))+
  geom_bar()

:::

 

  • Change something so that you can visually evaluate if race is equally distributed across the Installations ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(y = Installation, fill = race))+
  geom_bar(position = "fill",   #  All bars have full length/height - this makes it easier to see proportional differences between groups
           color = "black"      #  Adds a black line around each box.
           )

:::


1.6 geom_boxplot()


Use geom_boxplot to explore weightkg across the different Installations

Show the code
soldiers |> 
  ggplot(aes(x = Installation, y = weightkg))+
  geom_boxplot()

# OR

soldiers |> 
  ggplot(aes(y = Installation, x = weightkg))+
  geom_boxplot()


  • Remove the outliers from the boxplot (read the documentation)
  • Add some jittered points to give an impression of the nr of soldiers at each installation
  • Give the jittered points some transparency (decrease alpha) to avoid overplotting ::: {.cell}
Show the code
soldiers |> 
  ggplot(aes(y = Installation, x = weightkg))+
  geom_boxplot(
    outlier.shape = NA)+
  geom_jitter(
    height = 0.2,
    alpha = 0.1)

:::


* Use facet_wrap() to split on sex have the plots placed in one column ::: {.cell}

Show the code
soldiers |> 
  ggplot(aes(y = Installation, x = weightkg))+
  geom_boxplot(
    outlier.shape = NA)+
  geom_jitter(
    height = 0.2,
    alpha = 0.1)+
  facet_wrap(~sex, ncol = 1)

:::



1.7 Explore

  • Download the sets_for_vis_exercise.csv file sets_for_vis_exercise.csv
  • Place the sets_for_vis_exercise.csv file in your raw_data folder.
  • Import the sets_for_vis_exercise.csv and assign it to an object called sets ::: {.cell}
Show the code
sets <- read_csv(here("raw_data", "sets_for_vis_exercise.csv"))

:::

About the data:
The data contains x and y coordinates for 13 sets. For learning purposes we have obscured the names of these sets.
The data comes from the jumpingrivers GitHub repository. Once you have completed the exercise you can read more about the data here.

dplyr recap

For each set calculate:

  • mean of x
  • mean of y
  • standard deviation of x
  • standard deviation of y
  • correlation between x and y
Show the code
sets |> 
  group_by(set) |> 
  summarise(
    mean_x = mean(x), 
    mean_y = mean(y), 
    sd_x = sd(x), 
    sd_y = sd(y), 
    cor_x_y = cor(x,y)
  )

Explore the sets using your new found visualization skills

Show the code
### You have to do this one yourself
### You can do this! 
### Use your visualization skills to unlock the mysteries of the sets!
### We know you can unlock the mysteries of the sets 



1.8 Annotations (title, legends, etc.)


Read the documentation for labs()

What can we control with this function?


Use labs() and recreate this plot

To create a completely blank plot just type ggplot()

Show the code
ggplot()+
  labs(x = "X-axis",
       y = "Y-axis",
       title = "Title",
       subtitle = "Subtitle",
       caption = "Caption")



1.9 Themes

What theme was used for this plot?

  • To recreate the basic plot use: ggplot(mpg, aes(hwy, cty))+ geom_point()
  • Try another theme. Type theme_ and try some of the suggestions. ::: {.cell} ::: {.cell-output-display} ::: :::


Want more?

Use install.packages() to download the ggthemes package. When you have done that add library(ggthemes) to the code chunk where you call your libraries and execute the line.
Watch the gallery


1.10 Saving plots

In your project folder, create a new folder for saving plots and/or tables (e.g. “plots”)


read the documentation for ggsave()

  • What does the arguments I have specified below do?
  • Are they different from the defaults? ::: {.cell}
ggsave(filename = here("[YOUR FOLDER]", "[THE NAME OF YOUR FILE].png"), # .png .pdf .jpg are typical options
       plot = [The name of the ggplot object],                      # 
       dpi = "retina", 
       device = NULL, # Why can we leave this as NULL?
       height = 6, # What unit is this (6 cm?)?
       width = 6 # What unit is this (6 cm?)?
       )

:::


Create a simple plot and save it to your folder using ggsave()

ggplot(mpg, aes(hwy, cty))+
  geom_point()+
  theme_classic()

ggsave(filename = here("plots", "my_plot.png"),
       plot = last_plot(),
       height = 6, 
       width = 6,
       dpi = "retina")


1.11 color and fill scales


Put a different fill scale on this plot

starwars |> 
  ggplot(aes(y = skin_color, fill = sex))+
  geom_bar() 

Show the code
starwars |> 
  ggplot(aes(y = skin_color, fill = sex))+
  geom_bar() +
  scale_fill_brewer(type = "qual", palette = 3)


Put a different color scale on this plot

mtcars |>
  ggplot(aes(x = mpg, y = disp, color = hp)) +
  geom_point(size = 6)

Show the code
mtcars |>
  ggplot(aes(x = mpg, y = disp, color = hp)) +
  geom_point(size = 6) +
  scale_color_continuous(type = "viridis", option = "magma")


Using diamonds, recreate the R code necessary to generate the following graphs.


Using diamonds, recreate the R code necessary to generate the following graph.


Using diamonds, recreate the R code necessary to generate the following graphs.

HINT HINT: Think position=?????

1.12 Overplotting

Fix this plot

  • change alpha
  • change shape ::: {.cell}
diamonds |> 
  filter(x>3 & x<9) |> 
  ggplot(aes(x = x, y = price))+
  geom_point()

:::

Show the code
# alpha and point
diamonds |> 
  filter(x>3 & x<9) |> 
  ggplot(aes(x = x, y = price))+
  geom_point(alpha = 0.2,
             shape = ".") # This shape gives each point the size of a pixel


1.13 Arranging Plots

Load the patchwork package

  • Add library(patchwork) to the code chunk where you call your libraries and execute the line.
  • If patchworkis not installed on your machine. Type install.packages("patchwork") in the console. This line should not be included in the “ggplot.qmd” file.




Run this code and then recreate the plot below

p <- ggplot(diamonds)
pf <- ggplot(diamonds |> filter(carat<3))
p1 <- p + geom_bar(aes(x = cut, fill = clarity), position = "fill") +labs(title = "p1")
p2 <- p + geom_bar(aes(x = cut, fill = clarity)) +labs(title = "p2")
p3 <- pf + geom_histogram(aes(x = carat, fill = clarity), binwidth = 0.1, position = "fill", na.rm = TRUE) +labs(title = "p3")
p4 <- pf + geom_histogram(aes(x = carat, fill = clarity), binwidth = 0.1, position = "dodge", na.rm = TRUE) +labs(title = "p4")
Show the code
(p1|p2/(p3+p4)) + plot_layout(guide = "collect")


Read the documentation for plot_annotation()

  • What does the function overall do?
  • What does the argument tag_levels = 'A' do?


Tag the plots with roman numerals, and suffix the numerals with a “.”

Show the code
(p1|p2/(p3+p4)) + 
  plot_layout(guide = "collect") +
  plot_annotation(tag_levels = "I",
                  tag_suffix = ".")


Add a catchy title

Show the code
(p1|p2/(p3+p4)) +
  plot_layout(guide = "collect") +
  plot_annotation(tag_levels = "I",
                  tag_suffix = ".", 
                  title = "A catchy title")


Remove the small plot titles (p1, p2, p3, p4) from the four plots

  • You need to use the & symbol to do this the smart way
  • You need to use the labs() function
  • You need to set an argument in the labs() function to NULL
Show the code
(p1|p2/(p3+p4)) +
  plot_layout(guide = "collect") +
  plot_annotation(tag_levels = "I",
                  tag_suffix = ".", 
                  title = "A catchy title") &
  labs(title = NULL)


Apply the theme_void() and the viridis magma fill scale

Show the code
(p1|p2/(p3+p4)) +
  plot_layout(guide = "collect") +
  plot_annotation(tag_levels = "I",
                  tag_suffix = ".",
                  title = "A catchy title") & 
  theme_void() &
  scale_fill_viridis_d(option = "magma")


Save the plot to your plot folder

Show the code
ggsave(filename = here("plots", "my_patchwork_plot.png"),
       plot = last_plot(),
       dpi = "retina")