ggplot2 builds charts in layers. This page covers bar plots specifically — counting categories with geom_bar() and plotting pre-summarised values with geom_col().
Setup
R Code
install.packages("ggplot2") # one-time install library(ggplot2) # load it at the top of every script
geom_bar() — Counting Categories Automatically
R Code
df <- data.frame(grade = c("A","B","A","C","A","B")) ggplot(df, aes(x = grade)) + geom_bar(fill = "steelblue") + labs(title = "Grade Counts", x = "Grade", y = "Count") + theme_minimal()
geom_col() — Plotting Pre-Summarised Values
Use geom_col() instead of geom_bar() when your data already has one row per category with the bar height you want, rather than raw observations to count.
R Code
summary_df <- data.frame(month = c("Jan","Feb","Mar"), sales = c(120,150,90)) ggplot(summary_df, aes(x = month, y = sales)) + geom_col(fill = "darkorange") + labs(title = "Monthly Sales")
Grouped Bars with fill
R Code
df2 <- data.frame( quarter = rep(c("Q1","Q2"), each = 2), gender = rep(c("Male","Female"), times = 2), count = c(20,35,30,25) ) ggplot(df2, aes(x = quarter, y = count, fill = gender)) + geom_col(position = "dodge") + scale_fill_manual(values = c("Male" = "skyblue", "Female" = "pink"))
Advanced: Ordering Bars by Value
🚀 Advanced Example
reorder() inside aes() sorts bars by a value instead of alphabetically - almost always more readable for ranked comparisons.R Code
ggplot(summary_df, aes(x = reorder(month, -sales), y = sales)) + geom_col(fill = "steelblue") + labs(x = "Month", title = "Sales, Highest to Lowest")
Key Points
- geom_bar() counts rows per category automatically; geom_col() plots values you already computed.
- Map a second categorical variable to fill = to compare groups.
- position = "dodge" places grouped bars side-by-side instead of stacking them.
- reorder(category, value) sorts bars by magnitude instead of alphabetically.