| 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.
ggthemes and Tableau palettesscale_fill_tableau() and scale_color_tableau() are inspired by Tableau’s color palette.| Mapped feature | Matching scale |
|---|---|
fill: interiors |
scale_fill_tableau() |
color: points or lines |
scale_color_tableau() |
fill and choosing a palettefill = drv maps groups to colors. scale_fill_tableau() chooses the color palette.show.legend = FALSE hides the legend (color key).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 |
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%).Same 139,504 flight records from 2013 in every panel. Colors identify AA, DL, and UA.
Use: totals and breakdown.
Watch out: segments may lack a shared baseline.
Use: subgroup counts.
Watch out: many bars can crowd the chart.
Use: within-group proportions.
Watch out: totals are hidden.
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.| Airport | American records | Selected-airline total | American share |
|---|---|---|---|
| JFK | 13,783 | 39,018 | 35.3% |
| LGA | 15,459 | 46,570 | 33.2% |
| 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() |