library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 4.0.3 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(scales)
## Warning: package 'scales' was built under R version 4.4.3
##
## Attaching package: 'scales'
##
## The following object is masked from 'package:purrr':
##
## discard
##
## The following object is masked from 'package:readr':
##
## col_factor
mpg_top10 <- mpg %>%
group_by(manufacturer) %>%
summarise(avg_cty = mean(cty)) %>%
arrange(desc(avg_cty)) %>%
slice_head(n = 10)
plot1 <- ggplot(mpg_top10, aes(x = reorder(manufacturer, avg_cty), y = avg_cty)) +
geom_col(fill = "#2C7FB8") +
geom_text(aes(label = round(avg_cty, 1)), hjust = -0.2, size = 3.5) +
coord_flip() +
labs(
title = "Top 10 Manufacturers by Average City MPG",
subtitle = "Based on the mpg dataset",
x = "Manufacturer",
y = "Average City MPG (cty)"
) +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(face = "bold"))
plot1
Manufacturers with the highest city fuel efficiency (cty) are generally small, fuel-efficient car manufacturers (e.g., Honda and Subaru), while manufacturers of larger cars/trucks tend not to appear in the top 10 because their fuel consumption is higher.
plot2 <- ggplot(diamonds, aes(x = cut, y = price, fill = cut)) +
geom_boxplot(outlier.alpha = 0.15, outlier.size = 0.8) +
scale_fill_brewer(palette = "Set2") +
scale_y_continuous(labels = label_dollar()) +
labs(
title = "Distribution of Diamond Prices by Cut Quality",
subtitle = "diamonds dataset",
x = "Cut Quality",
y = "Price (USD)",
fill = "Cut"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold"),
legend.position = "none"
)
plot2
Interestingly, diamonds with “Fair” cut quality (the lowest grade) actually have a relatively high median price and a wide spread (IQR), while “Ideal” (the best quality) tends to have a lower median price. This suggests diamond price is influenced more by other factors, such as carat/weight, than by cut alone because a large diamond with a less-than-perfect cut can still be expensive.
set.seed(123)
diamonds_sample <- diamonds %>% sample_n(1000)
plot3 <- ggplot(diamonds_sample, aes(x = carat, y = price, color = clarity)) +
geom_point(alpha = 0.7, size = 1.8) +
geom_smooth(aes(group = 1), method = "loess", color = "black",
se = FALSE, linewidth = 0.8, linetype = "dashed") +
scale_color_viridis_d(option = "plasma") +
scale_y_continuous(labels = label_dollar()) +
labs(
title = "Relationship between Carat and Diamond Price",
subtitle = "Sample of 1000 diamonds, colored by Clarity",
x = "Carat",
y = "Price (USD)",
color = "Clarity"
) +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(face = "bold"))
plot3
## `geom_smooth()` using formula = 'y ~ x'
There is a strong, positive, non-linear relationship between carat and price: as carat increases, price increases, and the rate of increase grows steeper at larger carat values. The clarity coloring shows that, for a given carat, diamonds with better clarity (e.g. IF, VVS1) tend to sit on the higher-price side compared to lower clarity grades (e.g. I1).
highlight_point <- economics %>% filter(date == as.Date("2008-01-01"))
plot4 <- ggplot(economics, aes(x = date, y = psavert)) +
geom_line(color = "#D95F02", linewidth = 0.7) +
annotate("rect", xmin = as.Date("2007-12-01"), xmax = as.Date("2009-06-01"),
ymin = -Inf, ymax = Inf, alpha = 0.15, fill = "red") +
annotate("text", x = as.Date("2008-09-01"), y = max(economics$psavert) - 1,
label = "Financial Crisis\n2007-2009", size = 3.3, color = "darkred",
fontface = "italic") +
scale_x_date(date_breaks = "5 years", date_labels = "%Y") +
labs(
title = "Trend of Personal Saving Rate (PSAVERT) in the US",
subtitle = "1967 - 2015",
x = "Year",
y = "Personal Saving Rate (%)"
) +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(face = "bold"))
plot4
The personal saving rate declined gradually from the late 1960s through the early 2000s, reaching its lowest point just before the 2008 financial crisis. After the 2007–2009 crisis (the highlighted area), the saving rate spiked sharply as people became more financially cautious amid economic uncertainty.
Problematic Visualization:
plot5_before <- ggplot(mpg_top10, aes(x = manufacturer, y = avg_cty)) +
geom_col(fill = "grey") +
labs(title = "cty by manufacturer")
plot5_before
Problems in the original version:
X-axis labels overlap since they aren’t rotated or flipped.
The data isn’t sorted from highest to lowest.
The color is monotone with no emphasis on the important value.
The title is uninformative and axis labels aren’t clear.
No data values are shown on the bars.
The Improvements
plot5_after <- mpg_top10 %>%
mutate(highlight = avg_cty == max(avg_cty)) %>%
ggplot(aes(x = reorder(manufacturer, avg_cty), y = avg_cty, fill = highlight)) +
geom_col(width = 0.7) +
geom_text(aes(label = round(avg_cty, 1)), hjust = -0.2, size = 3.5) +
coord_flip() +
scale_fill_manual(values = c("TRUE" = "#D95F02", "FALSE" = "#2C7FB8"),
guide = "none") +
scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
labs(
title = "Top 10 Manufacturers by City Fuel Efficiency",
subtitle = "The manufacturer with the highest average cty is marked in orange",
x = NULL,
y = "Average City MPG (cty)",
caption = "Source: mpg dataset"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 13),
plot.subtitle = element_text(color = "grey40", size = 10),
panel.grid.minor = element_blank(),
panel.grid.major.y = element_blank()
)
plot5_after
Improvements made:
Data is sorted and turned into a horizontal bar chart so labels are readable without overlapping.
Color is given meaning which is the manufacturer with the highest value is highlighted in a distinct color, and the legend is removed since it’s redundant.
Title and subtitle are made descriptive, axis labels are clarified, value labels are added on each bar, and a data source caption is included.
Grid lines and the y-scale are cleaned up so number labels aren’t cut off.