Assignment Data Visualization

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

1. Comparison - mpg

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.

2. Distribution - diamonds

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.

3. Relationship - diamonds_sample

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).

4. Time Series - economics

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.

5. Improve a Visualization

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:

  1. X-axis labels overlap since they aren’t rotated or flipped.

  2. The data isn’t sorted from highest to lowest.

  3. The color is monotone with no emphasis on the important value.

  4. The title is uninformative and axis labels aren’t clear.

  5. 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:

  1. Data is sorted and turned into a horizontal bar chart so labels are readable without overlapping.

  2. 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.

  3. Title and subtitle are made descriptive, axis labels are clarified, value labels are added on each bar, and a data source caption is included.

  4. Grid lines and the y-scale are cleaned up so number labels aren’t cut off.