Data
The mtcars data frame ships with R and was extracted from the 1974 US Magazine Motor Trend. The data compares fuel consumption and 10 aspects of automobile design and performance for 32 automobiles (1973–74 models).
Basic Bar Graph Syntax
A basic plot skeleton is created by declaring the data, aesthetic mappings. The additional stat argument is set equal to “bin” (the default) to obtain counts of the data observations and “identity” and to plot observed values.
1 2 3 4 5 6 7 8 |
library(ggplot) # Plot skeleton c <- ggplot(mtcars, aes(factor(cyl))) # The argument stat="bin" is the default and is not specified # Plot1: Basic bar chart of car count by cylinder c + geom_bar() |
Bar Graph Aesthetics
Bar chart aesthetics define the x data used, bar width, bar fill color, bar line color, linetype, and size, alpha level (or transparency) and weight.
1 2 3 4 5 6 7 8 9 10 11 |
# Plot2: Change bar width c + geom_bar(width = 0.5) # Plot3: Horizontal bar chart c + geom_bar() + coord_flip() # Plot4: Fixed colors, line size and transparency c + geom_bar(fill = "steelblue", color = "green", size = 1.5, alpha = 0.75) # Plot5: default aes() color formats c + geom_bar(aes(fill = factor(cyl))) |
Bar Graphs of Values vs Counts
So far, all bar graphs depict observation counts, not values. The argument stat = “identity” must appear in geom_bar() to plot values. The following code calculates the mean quarter mile times as a function of the number of cylinders, and depicts the resulting values
1 2 3 4 5 6 7 |
# calc average quater mile times as a function of cylinders library(plyr) avg <- ddply(mtcars, "cyl", summarize, avg.qmile = mean(qsec)) # Plot6: Basic chart of average quarter mile times by cylinder ggplot(avg, aes(x = factor(cyl), y = avg.qmile)) + geom_bar(stat="identity", fill = "black", color = "green", alpha = 0.5) |
Changing the Order of the Bars
Use of the factor() command and the levels argument to control the order of the bars. For example:
1 2 3 |
avg[, "cyl"] <- factor(avg[, "cyl"], levels = c(8, 4, 6)) ggplot(avg, aes(x = factor(cyl), y = avg.qmile)) + geom_bar(stat="identity", fill = "black", color = "green", alpha = 0.5) |
Stacked Bar Charts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Plot7: Stacked bar chart black outline ggplot(mtcars, aes(x = factor(cyl), fill = factor(gear))) + geom_bar(color="black") # Plot8: Stack bar chart manual fill ggplot(mtcars, aes(x = factor(cyl), fill = factor(gear))) + geom_bar(color="green") + scale_fill_manual(values=c("grey35", "grey50", "grey65")) # Plot9: Change the stack order with factor() mtcars$gear <- factor(mtcars$gear, levels = c(5, 4, 3)) ggplot(mtcars, aes(x = factor(cyl), fill = factor(gear))) + geom_bar(color="green") + scale_fill_manual(values=c("grey35", "grey50", "grey65")) # Plot10: Dodged bar short ggplot(mtcars, aes(x = factor(cyl), fill = factor(gear))) + geom_bar(color="black", position=position_dodge()) |
Eliminating Space Between the Bottom of the Bars and the Axis
The white space found at the bottom of the bars can be eliminated using the scale_y_continuous() command with the following argument:
1 2 3 |
ggplot(avg, aes(x = factor(cyl), y = avg.qmile)) + geom_bar(stat="identity", fill = "black", color = "green", alpha = 0.5) + scale_y_continuous(expand = c(0,0)) |
An Example: Fully Loaded
A bar-chart in finished form is depicted below and followed by code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
ggplot(data, aes(x = year, y = MW, fill = factor(Tech_RE20))) + geom_bar(stat = "identity", color = "grey25") + scale_fill_brewer(palette = 17, name = "Generation Type", labels = c("Solar Tower w/Storage", "Solar Trough", "Solar Fresnel", "Solar Fesnel w/Storage", "Solar Fresnel Hybrid Gas", "PV Utility", "PV Commercial", "PV Residential", "Wind Energy")) + scale_y_continuous(limits = c(0, 16000), breaks = seq(0, 16000, by = 2000)) + labs(title = expression(atop(bold("Kuwait 20% RE Target"), atop(italic("Constrained Growth Path"), ""))), x = "Production Year", y = "Installed Capacity (MW)") + theme(plot.title = element_text(size = 25), axis.title.y = element_text(size = 16, vjust = 0.25, face = "bold"), axis.text.y = element_text(size = 13, color = "grey15"), axis.title.x = element_text(size = 16, vjust = -0.25, face = "bold"), axis.text.x = element_text(size = 13, color = "grey15", angle = -90, vjust = 0.5), legend.title = element_text(size = 14), legend.text = element_text(size = 12), # legend.position = c(0.08765,.8575), panel.border = element_rect(fill = NA, colour="grey25") ) |