Visualize Penguins with ggplot2

Build layered figures — histograms, scatterplots, and boxplots — all in your browser

Welcome back. Everything on this page runs real R in your browser — same setup as Coding Activity 1. You already plotted with base R’s hist(); today you will build figures in layers with ggplot2.

The first time you click Run Code, your browser downloads R once (a few seconds). After that it is quick.

NoteThe grammar of graphs

Every ggplot2 figure has three essential pieces:

  1. data — the dataset (for example penguins)
  2. aes — aesthetic mappings: which column goes on which axis, or which color
  3. geom — the geometric object: points, boxes, bars, histogram bins

You add layers with +. We will practice all three today.

1. Load the tidyverse

Coding Assignment 2 starts the same way. Run library(tidyverse) to load ggplot2 and friends. A conflicts message afterward is expected, not an error.

NoteHint

From ?library: library(package, ...) attaches a package so its functions become available. Replace package with the name of the collection you need (ggplot2 ships inside the tidyverse bundle).

Try ?library in R for the full help page.

TipSolution
library(tidyverse)

On DataHub and in your graded assignment you will type exactly this.

2. Glimpse the penguins

glimpse() is a tidyverse way to inspect a dataset: rows, columns, and column types. Run it on penguins from the palmerpenguins package so you know which columns to map to axes and colors.

NoteHint

From ?glimpse: glimpse(x) — print a compact summary of a data frame (rows, columns, types).

Example with a built-in dataset:

glimpse(mtcars)

Apply the same function to the dataset named in the exercise prompt.

TipSolution
glimpse(penguins)

You should see 344 rows and 8 columns. species and island are <fct> (categories); measurements like body_mass_g are <dbl> (numbers).

From the glimpse() output:

  1. How many rows are there?
  2. What type is body_mass_g?
  3. Which column tells you which island each penguin was sampled on?

Answers: 344 rows; body_mass_g is <dbl>; island.

3. Histogram with ggplot2

Start a figure with ggplot(), map body_mass_g to the x-axis, and add geom_histogram(). Use the penguins dataset directly — an upgrade from Coding Activity 1’s hist(). Add a title with labs(title = "...").

NoteHint

From ?ggplot: ggplot(data = NULL, mapping = aes(), ...) — then add a layer with +.

From ?geom_histogram: bins one continuous variable.

Example:

ggplot(mtcars, aes(x = mpg)) +
  geom_histogram() +
  labs(title = "Car fuel economy")

Map the x-axis to one continuous column from penguins and add your own title.

TipSolution
ggplot(penguins, aes(x = body_mass_g)) +
  geom_histogram() +
  labs(title = "Penguin body mass")

A histogram shows how one continuous variable is distributed — how many penguins fall in each weight range. ggplot2 may warn about two rows with missing body mass; that is normal.

4. Scatterplot — two continuous variables

Build a scatterplot: flipper length on the x-axis, body mass on the y-axis. Map species to color so each species gets its own hue. Use geom_point().

NoteHint

From ?geom_point: scatterplot of two continuous variables. Map a third variable to color inside aes().

Example:

ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
  geom_point()

Use flipper length and body mass on the axes and map species to color on the penguin data.

TipSolution
ggplot(penguins, aes(
  x = flipper_length_mm,
  y = body_mass_g,
  color = species
)) +
  geom_point()

Scatterplots relate two continuous measurements. Color adds a third variable — here, species — so you can see clusters.

5. Boxplot — compare groups

Coding Assignment 2 builds a boxplot one layer at a time. Here is the core pattern:

  • Put island on the x-axis, body_mass_g on the y-axis
  • Add geom_boxplot() with fill mapped to island
  • Add theme_minimal() and readable labs()
NoteHint

From ?geom_boxplot: compare a numeric variable across groups.

Example pattern:

ggplot(mtcars, aes(
  x = factor(cyl),
  y = mpg,
  fill = factor(cyl)
)) +
  geom_boxplot() +
  theme_minimal() +
  labs(title = "MPG by cylinder count", x = "Cylinders", y = "MPG")

Apply the same layering — boxplot, fill, theme_minimal(), labs() — to islands and body mass.

TipSolution
ggplot(penguins, aes(
  x = island,
  y = body_mass_g,
  fill = island
)) +
  geom_boxplot() +
  theme_minimal() +
  labs(
    title = "Body mass by island",
    x = "Island",
    y = "Body mass (g)"
  )

Boxplots compare a continuous variable across groups. On your graded assignment you will add reorder() to sort groups by elevation after you join that metadata in Coding Activity 3.

6. Recap — ggplot verbs you practiced

Function Role
library(tidyverse) Loads ggplot2 and related packages
glimpse() Quick look at rows, columns, and types
ggplot() + aes() Starts a figure and maps columns to axes, color, or fill
geom_histogram() Distribution of one continuous variable
geom_point() Relationship between two continuous variables
geom_boxplot() Compare a continuous variable across groups
theme_minimal() + labs() Cleans appearance and adds titles/labels

If you can explain each row in your own words, you have covered the figure-building core of Coding Assignment 2.

7. Transfer to Coding Assignment 2

On Canvas you will build figures step by step with hemoglobin measurements and population elevation data:

  1. library(tidyverse) and read your dataset
  2. Build a boxplot one layer at a time with ggplot(), geom_boxplot(), fill, theme_minimal(), and labs()

You practiced the layering here. Coding Activity 3 covers the wrangling steps — filtering, reshaping, and joining — that prepare the table for those plots.

Keep playing

No grading here. Try swapping geoms, mapping a different column to color, or predicting what a plot will look like before you run it.

Try this with a partner. One of you predicts the figure; the other runs the code. Swap roles. Saying your prediction out loud first is one of the fastest ways to learn.