R for Bioinformatics

Lesson 9 of 14 · 11 min

Plotting with ggplot2

ggplot2 is the most popular package for making charts in R. A package is a bundle of extra R functions that someone else has written and shared. ggplot2 builds charts from a system called the grammar of graphics, where you describe a plot in layers instead of drawing it by hand, so the same short pattern makes scatter plots, bar charts, and boxplots.

The grammar of graphics

Every ggplot2 chart needs three things. First, data, which is the table of numbers you want to show. Second, aesthetic mappings written inside aes(), which connect columns of your data to visual properties such as the x position, the y position, or the colour. Third, at least one geom layer, which decides the shape that gets drawn, such as points or bars. You join the pieces with a plus sign, and labs() adds a title and axis labels.

r
# install.packages("ggplot2")   # run once to download the package
library(ggplot2)                 # load the package so its functions are available

# A data frame is a table: one row per sample, one column per measurement
expr <- data.frame(
  sample = paste0("S", 1:8),                    # sample IDs S1 through S8
  group  = rep(c("tumor", "normal"), each = 4), # first 4 tumor, next 4 normal
  MYC    = c(15.1, 14.2, 16.0, 13.8, 6.1, 5.4, 7.0, 6.7),  # MYC gene expression
  TP53   = c(8.2, 7.9, 9.1, 8.0, 10.5, 11.2, 9.8, 10.9)    # TP53 gene expression
)

head(expr)   # print the first six rows to check the table looks right
  sample  group  MYC TP53
1     S1  tumor 15.1  8.2
2     S2  tumor 14.2  7.9
3     S3  tumor 16.0  9.1
4     S4  tumor 13.8  8.0
5     S5 normal  6.1 10.5
6     S6 normal  5.4 11.2

Scatter plot with geom_point

r
# ggplot() sets the data and the aes() mappings shared by every layer
# geom_point() draws one dot per row; colour = group gives each group its own colour
ggplot(expr, aes(x = MYC, y = TP53, colour = group)) +
  geom_point(size = 3) +                       # size = 3 makes the dots larger
  labs(
    title = "MYC vs TP53 expression",          # text shown above the chart
    x = "MYC expression",                       # label for the horizontal axis
    y = "TP53 expression"                       # label for the vertical axis
  )

Bar charts

r
# geom_bar() counts the rows in each group, so each bar height = number of samples
ggplot(expr, aes(x = group, fill = group)) +   # fill colours the inside of each bar
  geom_bar()

# geom_col() uses the y value you give it, so use it when you already have the numbers
mean_expr <- data.frame(
  gene       = c("MYC", "TP53", "BRCA1"),      # gene names for the horizontal axis
  expression = c(10.5, 9.6, 6.4)               # the bar height for each gene
)
ggplot(mean_expr, aes(x = gene, y = expression)) +
  geom_col()

Boxplots by group

r
# geom_boxplot() summarises the spread of MYC values within each group:
# the box shows the middle half of the values and the line inside is the median
ggplot(expr, aes(x = group, y = MYC, fill = group)) +
  geom_boxplot() +
  labs(
    title = "MYC expression by group",
    x = "Sample group",
    y = "MYC expression"
  )

Try it yourself: Using the expr data frame, draw a scatter plot of TP53 on the x axis and MYC on the y axis. Put colour = group inside aes() so tumor and normal samples get different colours, add geom_point(size = 3), then use labs() to set the title to "TP53 vs MYC" and label both axes. As a bonus, make a boxplot of TP53 by group to compare its spread between tumor and normal samples.