In this report, I start with a simple bar plot that uses basic settings and a small amount of customization. Then I show how to improve it using better design principles and ggplot2 tools.
This plot shows the monthly sales performance across different product categories from April to June. The goal is to compare how each product performed over time.
Data
library(ggplot2)library(dplyr)set.seed(123)sales_data <-data.frame(Category =rep(c("Books", "Computers", "Toys", "Clothing", "Groceries", "Beauty"), each =3),Month =rep(c("April", "May", "June"), times =6),Sales =sample(200:1000, 18, replace =TRUE))head(sales_data)
Category Month Sales
1 Books April 614
2 Books May 662
3 Books June 378
4 Computers April 725
5 Computers May 394
6 Computers June 317
The Ugly Plot
library(ggplot2)ggplot(sales_data, aes(x = Category, y = Sales, group = Month)) +geom_bar(stat ="identity", position ="dodge", fill ="gray70") +labs(x ="Product Category",y ="Sales (NT$)") +theme_classic() +theme(legend.position ="none")
The Beautiful Plot
sales_data$Month <-factor(sales_data$Month, levels =c("April", "May", "June"))ggplot(sales_data, aes(x = Category, y = Sales, fill = Month)) +geom_bar(stat ="identity", position ="dodge") +labs(title ="Monthly Sales by Product Category",subtitle ="Data for April–June",x ="Product Category",y ="Sales (NT$)",fill ="Month" ) +theme_minimal(base_size =14) +theme(axis.text.x =element_text(angle =30, hjust =1),plot.title =element_text(face ="bold", hjust =0.5),plot.subtitle =element_text(hjust =0.5) ) +scale_fill_brewer(palette ="Set2")
What’s improved?
Added colors to distinguish each month.
Added a proper legend.
Added the descriptive title and subtitle.
Better theme and font sizes.
Improved axis text rotation to avoid text overlapping.