| manufacturer | model | year | cty | drv | class |
|---|---|---|---|---|---|
| audi | a4 | 1999 | 18 | f | compact |
| audi | a4 | 1999 | 21 | f | compact |
| audi | a4 | 2008 | 20 | f | compact |
| audi | a4 | 2008 | 21 | f | compact |
Data Visualization I: Distributions and Group Comparisons
October 21, 2026
mpg describes a vehicle| manufacturer | model | year | cty | drv | class |
|---|---|---|---|---|---|
| audi | a4 | 1999 | 18 | f | compact |
| audi | a4 | 1999 | 21 | f | compact |
| audi | a4 | 2008 | 20 | f | compact |
| audi | a4 | 2008 | 21 | f | compact |
mpg comes with ggplot2. It contains data on 234 vehicles from 1999 and 2008.| Column | Meaning | Type for this comparison |
|---|---|---|
cty |
City fuel economy in miles per gallon | Numeric |
drv |
Drive system, coded 4, f, or r |
Categorical |
class |
Vehicle class, such as compact or SUV | Categorical |
ggplot2 is part of the tidyverselibrary(tidyverse) loads ggplot2 along with packages such as dplyr.mpg is available after loading ggplot2. This example needs no CSV import.| Essential component | Its job in our histogram |
|---|---|
Data frame: data = mpg |
Supplies the observations in rows and variables in columns |
Aesthetic mappings: mapping = aes(x = cty) |
Connect variables to visual features, such as position or color |
Geometric object: geom_histogram() |
Chooses how to draw the data. This geom groups values into bins and draws bars |
geom_*()) draw objects such as bars, points, or lines. We choose the geom to match our question.aes() is short for aesthetics. Here, x = cty maps city MPG to horizontal position. The geom_histogram() calculates the vertical counts automatically.data = and mapping = are argument names. R lets us omit these names when we supply the arguments in that order.+ connects the plot’s parts+ at the end of a line when the plotting expression continues on the next line.+ adds a plot component. We can add more layers or settings with another +, such as labs() for labels.At the R console
A + at the R console prompt means R is waiting for the rest of an unfinished command. Do not type that prompt into your code.
aes()fill controls the inside of the bars. color controls their outlines.aes() because they give all bars one appearance. aes(x = cty) maps a data column.labs() provides readable labelslabs() changes displayed text. The column name remains cty.binwidth sets each interval’s width. These bins are 1 MPG or 5 MPG wide.Roughly similar bar heights across bins.
One clear peak (mode).
Two clear peaks separated by a dip.

drv identifies the drive systemValue of drv |
Meaning |
|---|---|
4 |
Four-wheel drive |
f |
Front-wheel drive |
r |
Rear-wheel drive |
cty. The categorical variable drv tells us which group each row belongs to.facet_wrap(~ drv) means “make panels by drive system.” Each row appears in its group’s panel.
Weekly sales. Red–green simulation below.
Original: Store A Store B
Original: Store A Store B
Red and green look similar in this simulation.
Weekly sales, shown without color. Can you identify each store?
Text labels identify each line directly. Separate panels (e.g., facet_wrap()) identify groups with panel labels.
Weekly sales, shown without color. Which line belongs to each store?
Point shapes and line types distinguish groups even when colors look alike.
ggthemes: color scales
scale_*_colorblind() and scale_*_tableau() functions are provided by the ggthemes package.scale_fill_tableau() and scale_color_tableau() are inspired by Tableau’s color palette.| Mapped feature | Tableau functions | Colorblind-friendly functions |
|---|---|---|
fill: interiors |
scale_fill_tableau() |
scale_fill_colorblind() |
color: points or lines |
scale_color_tableau() |
scale_color_colorblind() |
fill and choosing a palettefill = drv maps groups to colors. scale_fill_colorblind() chooses the colorblind-friendly color palette.x and its numeric values on y.geom_boxplot() calculates a separate summary for each drive-system group. fill = drv inside aes() gives each group its own color.| Display | Especially useful for | Main limitation |
|---|---|---|
| Histograms | Peaks, gaps, tails, and distribution shape | Bin width changes visible detail |
| Boxplots | Comparing group medians and spread compactly | Can hide peaks and gaps within groups |
geom_bar() counts categoriesmpg?geom_bar() counts rows automatically. Map class to y for horizontal bars and to fill inside aes() for category colors.| Histogram | Bar chart | |
|---|---|---|
| Variable | Numeric, such as city MPG | Categorical, such as vehicle class |
| Grouping | Numeric intervals called bins | Named categories |
| Order | Follows the numeric scale | Chosen to support the comparison |
count() creates a table of counts| class | n |
|---|---|
| 2seater | 5 |
| compact | 47 |
| midsize | 41 |
| minivan | 11 |
| pickup | 33 |
| subcompact | 35 |
| suv | 62 |
count(class) creates one row per vehicle class.n gives the number of original rows in that class.mpg.geom_col() uses numbers already in a columnclass_counts data.frame from the previous slide: one row per vehicle class, with its count in n.x = n sets each bar’s length. geom_col() uses these supplied values, while geom_bar() counts rows automatically.fct_reorder(class, n) orders the categories using their corresponding counts.| Column | Categories used |
|---|---|
origin |
EWR: Newark JFK: John F. Kennedy LGA: LaGuardia |
carrier |
AA: American DL: Delta UA: United |
count(origin, carrier) counts combinations| origin | carrier | n |
|---|---|---|
| EWR | AA | 3487 |
| EWR | DL | 4342 |
| EWR | UA | 46087 |
| JFK | AA | 13783 |
| JFK | DL | 20701 |
| JFK | UA | 4534 |
| LGA | AA | 15459 |
| LGA | DL | 23067 |
| LGA | UA | 8044 |
n counts its flight records.fill = carrier gives each airline a color. geom_bar() stacks the airline counts within each airport.position = "dodge": grouped countsposition = "dodge" puts the airline bars side by side. All bars start at zero, and their heights are flight-record counts. position = "fill": within-group proportionsfill = carrier assigns colors. position = "fill" rescales each airport’s selected-airline total to 1 (100%).Use: totals and breakdown.
Watch out: unaligned segments.
Use: subgroup counts.
Watch out: crowded bars with many categories.
Use: within-group proportions.
Watch out: hidden totals.
| Question | Mapping | Drawing layer |
|---|---|---|
| How does city MPG vary? | aes(x = cty) |
geom_histogram() |
| How does city MPG differ by drive system? | aes(x = drv, y = cty, fill = drv) |
geom_boxplot() |
| How many vehicles are in each class? | aes(y = class, fill = class) |
geom_bar() |
| How do airline counts differ across airports? | aes(x = origin, fill = carrier) |
geom_bar(position = "dodge") |
| What counts are in our class-count table? | aes(x = n, y = class, fill = class) |
geom_col() |