Home › Data Visualization Exercises in R: 50 Practice Problems
Data Visualization Exercises in R: 50 Practice Problems
Fifty practice problems on data visualization in R: chart types, customization, themes, multi-plot composition, and publication-ready output. Hidden solutions.
By Selva Prabhakaran · Published May 11, 2026 · Last updated May 11, 2026
library (ggplot2)
library (dplyr)
library (scales)
library (tibble)
library (forcats)
▶ Run
↺ Reset
Section 1. Chart types (12 problems)
Exercise 1.1: Scatter plot
Difficulty: Beginner. mpg vs wt.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point ()
▶ Run
↺ Reset
Exercise 1.2: Bar chart of counts
Difficulty: Beginner.
Show solution
ggplot (diamonds, aes (cut)) + geom_bar ()
▶ Run
↺ Reset
Exercise 1.3: Bar with explicit heights (geom_col)
Difficulty: Intermediate.
Show solution
counts <- diamonds |> count (cut)
ggplot (counts, aes (cut, n)) + geom_col ()
▶ Run
↺ Reset
Exercise 1.4: Histogram
Difficulty: Beginner.
Show solution
ggplot (diamonds, aes (price)) + geom_histogram (bins = 30 )
▶ Run
↺ Reset
Exercise 1.5: Density
Difficulty: Intermediate.
Show solution
ggplot (iris, aes (Sepal.Length, fill = Species)) + geom_density (alpha = 0.5 )
▶ Run
↺ Reset
Exercise 1.6: Box plot per group
Difficulty: Beginner.
Show solution
ggplot (iris, aes (Species, Sepal.Length)) + geom_boxplot ()
▶ Run
↺ Reset
Exercise 1.7: Violin
Difficulty: Intermediate.
Show solution
ggplot (iris, aes (Species, Sepal.Length)) + geom_violin ()
▶ Run
↺ Reset
Exercise 1.8: Line chart
Difficulty: Intermediate.
Show solution
ggplot (economics, aes (date, unemploy)) + geom_line ()
▶ Run
↺ Reset
Exercise 1.9: Area chart
Difficulty: Intermediate.
Show solution
ggplot (economics, aes (date, unemploy)) + geom_area (fill = "steelblue" , alpha = 0.5 )
▶ Run
↺ Reset
Exercise 1.10: Heatmap (geom_tile)
Difficulty: Advanced.
Show solution
df <- expand.grid (x = 1 : 5 , y = 1 : 5 )
df$ z <- runif (nrow (df))
ggplot (df, aes (x, y, fill = z)) + geom_tile ()
▶ Run
↺ Reset
Exercise 1.11: Pie chart (via coord_polar)
Difficulty: Advanced.
Show solution
ggplot (diamonds, aes ("" , fill = cut)) +
geom_bar (width = 1 ) + coord_polar ("y" )
▶ Run
↺ Reset
Exercise 1.12: 2D density
Difficulty: Advanced.
Show solution
ggplot (diamonds, aes (carat, price)) + geom_density_2d ()
▶ Run
↺ Reset
Section 2. Aesthetics & mapping (8 problems)
Exercise 2.1: Color by group
Difficulty: Beginner.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, color = Species)) + geom_point ()
▶ Run
↺ Reset
Exercise 2.2: Size by continuous
Difficulty: Beginner.
Show solution
ggplot (mtcars, aes (wt, mpg, size = hp)) + geom_point ()
▶ Run
↺ Reset
Exercise 2.3: Shape by category
Difficulty: Intermediate.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, shape = Species)) + geom_point (size = 3 )
▶ Run
↺ Reset
Exercise 2.4: Color vs fill on bars
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (cut, fill = clarity)) + geom_bar (color = "black" )
▶ Run
↺ Reset
Exercise 2.5: Alpha for overlap
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (carat, price)) + geom_point (alpha = 0.05 )
▶ Run
↺ Reset
Exercise 2.6: Group line by id
Difficulty: Intermediate.
Show solution
ggplot (ChickWeight, aes (Time, weight, group = Chick)) + geom_line (alpha = 0.4 )
▶ Run
↺ Reset
Exercise 2.7: Multiple aesthetics
Difficulty: Advanced.
Show solution
ggplot (mtcars, aes (wt, mpg, color = factor (cyl), size = hp, shape = factor (am))) +
geom_point (alpha = 0.7 )
▶ Run
↺ Reset
Exercise 2.8: Constant outside aes
Difficulty: Advanced.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point (color = "red" , size = 3 )
▶ Run
↺ Reset
Section 3. Customization (10 problems)
Exercise 3.1: Title + subtitle + caption
Difficulty: Beginner.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
labs (title = "Weight vs MPG" , subtitle = "Motor Trend 1974" , caption = "Source: mtcars" )
▶ Run
↺ Reset
Exercise 3.2: Axis labels
Difficulty: Beginner.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
labs (x = "Weight (1000 lbs)" , y = "Miles per gallon" )
▶ Run
↺ Reset
Exercise 3.3: Format y as currency
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (carat, price)) + geom_point (alpha = 0.05 ) +
scale_y_continuous (labels = dollar_format ())
▶ Run
↺ Reset
Exercise 3.4: Log axis
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (carat, price)) + geom_point (alpha = 0.05 ) +
scale_x_log10 () + scale_y_log10 ()
▶ Run
↺ Reset
Exercise 3.5: Manual color
Difficulty: Intermediate.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, color = Species)) + geom_point () +
scale_color_manual (values = c (setosa = "red" , versicolor = "blue" , virginica = "green" ))
▶ Run
↺ Reset
Exercise 3.6: ColorBrewer
Difficulty: Intermediate.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, color = Species)) + geom_point () +
scale_color_brewer (palette = "Set2" )
▶ Run
↺ Reset
Exercise 3.7: Viridis
Difficulty: Intermediate.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, color = Species)) + geom_point () +
scale_color_viridis_d ()
▶ Run
↺ Reset
Exercise 3.8: Reorder x by frequency
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (forcats:: fct_infreq (cut))) + geom_bar ()
▶ Run
↺ Reset
Exercise 3.9: Coord flip
Difficulty: Beginner.
Show solution
ggplot (diamonds, aes (cut)) + geom_bar () + coord_flip ()
▶ Run
↺ Reset
Exercise 3.10: Zoom without filtering
Difficulty: Advanced.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
coord_cartesian (ylim = c (15 , 30 ))
▶ Run
↺ Reset
Section 4. Themes (8 problems)
Exercise 4.1: theme_minimal
Difficulty: Beginner.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () + theme_minimal ()
▶ Run
↺ Reset
Exercise 4.2: theme_bw
Difficulty: Beginner.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () + theme_bw ()
▶ Run
↺ Reset
Exercise 4.3: Rotate x text
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (clarity)) + geom_bar () +
theme (axis.text.x = element_text (angle = 45 , hjust = 1 ))
▶ Run
↺ Reset
Exercise 4.4: Bottom legend
Difficulty: Beginner.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, color = Species)) + geom_point () +
theme (legend.position = "bottom" )
▶ Run
↺ Reset
Exercise 4.5: Remove legend
Difficulty: Beginner.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length, color = Species)) + geom_point () +
theme (legend.position = "none" )
▶ Run
↺ Reset
Exercise 4.6: Bold centered title
Difficulty: Intermediate.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
labs (title = "Title" ) +
theme (plot.title = element_text (face = "bold" , hjust = 0.5 ))
▶ Run
↺ Reset
Exercise 4.7: Remove minor gridlines
Difficulty: Intermediate.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
theme (panel.grid.minor = element_blank ())
▶ Run
↺ Reset
Exercise 4.8: Custom theme function
Difficulty: Advanced.
Show solution
my_theme <- function () theme_minimal () + theme (plot.title = element_text (face = "bold" ))
ggplot (mtcars, aes (wt, mpg)) + geom_point () + labs (title = "Demo" ) + my_theme ()
▶ Run
↺ Reset
Section 5. Multi-plot & faceting (6 problems)
Exercise 5.1: facet_wrap
Difficulty: Beginner.
Show solution
ggplot (iris, aes (Sepal.Length, Petal.Length)) + geom_point () + facet_wrap (~ Species)
▶ Run
↺ Reset
Exercise 5.2: facet_grid
Difficulty: Intermediate.
Show solution
ggplot (diamonds, aes (carat, price)) + geom_point (alpha = 0.1 ) + facet_grid (cut ~ clarity)
▶ Run
↺ Reset
Exercise 5.3: Free scales
Difficulty: Intermediate.
Show solution
ggplot (mpg, aes (displ, hwy)) + geom_point () + facet_wrap (~ drv, scales = "free_y" )
▶ Run
↺ Reset
Exercise 5.4: patchwork side by side
Difficulty: Intermediate.
Show solution
library (patchwork)
p1 <- ggplot (mtcars, aes (wt, mpg)) + geom_point ()
p2 <- ggplot (mtcars, aes (hp, mpg)) + geom_point ()
p1 | p2
▶ Run
↺ Reset
Exercise 5.5: patchwork two-by-two
Difficulty: Intermediate.
Show solution
library (patchwork)
p1 <- ggplot (mtcars, aes (wt, mpg)) + geom_point ()
p2 <- ggplot (mtcars, aes (hp, mpg)) + geom_point ()
p3 <- ggplot (mtcars, aes (disp, mpg)) + geom_point ()
p4 <- ggplot (mtcars, aes (qsec, mpg)) + geom_point ()
(p1 | p2) / (p3 | p4)
▶ Run
↺ Reset
Exercise 5.6: Custom facet labels
Difficulty: Advanced.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
facet_wrap (~ cyl, labeller = labeller (cyl = c (`4` = "4-cyl" , `6` = "6-cyl" , `8` = "8-cyl" )))
▶ Run
↺ Reset
Section 6. Publication & save (6 problems)
Exercise 6.1: ggsave PNG
Difficulty: Beginner.
Show solution
p <- ggplot (mtcars, aes (wt, mpg)) + geom_point ()
ggsave ("plot.png" , p, width = 6 , height = 4 , dpi = 300 )
▶ Run
↺ Reset
Exercise 6.2: ggsave PDF
Difficulty: Beginner.
Show solution
p <- ggplot (mtcars, aes (wt, mpg)) + geom_point ()
ggsave ("plot.pdf" , p, width = 6 , height = 4 )
▶ Run
↺ Reset
Exercise 6.3: Annotate threshold line
Difficulty: Intermediate.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
geom_hline (yintercept = mean (mtcars$ mpg), linetype = "dashed" , color = "red" )
▶ Run
↺ Reset
Exercise 6.4: Annotate text
Difficulty: Intermediate.
Show solution
ggplot (mtcars, aes (wt, mpg)) + geom_point () +
annotate ("text" , x = 4 , y = 30 , label = "Outlier zone" , color = "red" )
▶ Run
↺ Reset
Exercise 6.5: Highlight region
Difficulty: Advanced.
Show solution
ggplot (mtcars, aes (wt, mpg)) +
annotate ("rect" , xmin = - Inf , xmax = Inf , ymin = 25 , ymax = Inf ,
fill = "lightgreen" , alpha = 0.3 ) +
geom_point ()
▶ Run
↺ Reset
Exercise 6.6: Publication-ready ensemble
Difficulty: Advanced.
Show solution
ggplot (diamonds |> sample_n (2000 ), aes (carat, price, color = cut)) +
geom_point (alpha = 0.6 ) +
scale_y_continuous (labels = dollar_format ()) +
scale_color_brewer (palette = "Set2" ) +
labs (title = "Diamond price vs carat" , subtitle = "Sample of 2000" ,
x = "Carat" , y = "Price" , color = "Cut" ) +
theme_minimal () +
theme (plot.title = element_text (face = "bold" ), legend.position = "bottom" )
▶ Run
↺ Reset
What to do next
ggplot2 -Exercises (shipped), depth on every geom and scale.
EDA-Exercises (shipped), viz inside the analysis loop.