Multi-level axis labels in R, ggplot2 axis labels in multiple rows, multi-row R plot axis labels, axis labels in multiple lines in R

Multi-level axis labels in R plot using ggplot2

Here is an example of how to create multi-level axis labels in an R plot using ggplot2. You can separate them into 2 levels on a plot x-axis or more. It depends on the situation.

 

I will visualize part of the AirPassengers dataset.

plot(AirPassengers)

R AirPassengers dataset plot

Here is a sample of the last 36 months with month names and quarters.

require(lubridate)

df <- data.frame(Year = as.numeric(trunc(time(AirPassengers))), 
                 Month = month.abb[cycle(AirPassengers)], 
                 AirPassengers = as.numeric(AirPassengers))

df$Month <- factor(df$Month, levels=unique(df$Month))

df$Quarter <- quarters(make_date(df$Year, df$Month, ))

df <- tail(df, n = 36)

head(df)

#   Year Month AirPassengers Quarter
# 109 1958   Jan           340      Q1
# 110 1958   Feb           318      Q1
# 111 1958   Mar           362      Q1
# 112 1958   Apr           348      Q2
# 113 1958   May           363      Q2
# 114 1958   Jun           435      Q2

To create a plot axis with labels in two levels, I will add two calculations in separate columns. Each of the columns contains the first appearance of the year or quarter. That is what will be on the axis.

require(dplyr)

df <- df %>%
  mutate(
    Q = ifelse(lag(Quarter) != Quarter |
                 is.na(lag(Quarter)), Quarter, ""),
    Y = ifelse(lag(Year) != Year |
                 is.na(lag(Year)), Year, "")
  )

head(df)

#   Year Month AirPassengers Quarter  Q    Y
# 109 1958   Jan           340      Q1 Q1 1958
# 110 1958   Feb           318      Q1        
# 111 1958   Mar           362      Q1        
# 112 1958   Apr           348      Q2 Q2     
# 113 1958   May           363      Q2        
# 114 1958   Jun           435      Q2

The main principle of the solution is that you can use custom x-axis labels that are separated with newline characters. You can use the same approach to split the ggplot2 title into multiple rows.

 

Multi-level axis labels in R

There are multiple ways to create multi-level axis labels in the R plot. In this case, the goal is achieved by using scale_x_discrete with custom labels that are separated by a new line character.

require(ggplot2)

ggplot(df, aes(
  x = interaction(Month, Year),
  y = AirPassengers,
  group = 1
)) +
  geom_line(color = "cadetblue") +
  ylim(0, NA) +
  scale_x_discrete(labels = paste(df$Q , df$Y, sep = "\n")) +
  labs(x = "", y = "") +
  theme_minimal()

ggplot2 with two level axis labels, R plot axis labels in 2 rows

Let’s say you want to put the year in a different position. For example, in the middle of the month series. Here is how it’s done, by detection position in the middle.

dfY <- df %>% 
  select(Month, Year) %>%
  group_by(Year) %>%  
  filter(row_number() == ceiling(n() / 2)) %>% 
  mutate(Y2 = Year)

df <- left_join(df, dfY)

df$Y2 <- ifelse(is.na(df$Y2), "", as.character(df$Y2))

head(df)


#  Year Month AirPassengers Quarter  Q    Y   Y2
# 1 1958   Jan           340      Q1 Q1 1958     
# 2 1958   Feb           318      Q1             
# 3 1958   Mar           362      Q1             
# 4 1958   Apr           348      Q2 Q2          
# 5 1958   May           363      Q2             
# 6 1958   Jun           435      Q2         1958

Here is how it looks as a result.

ggplot(df, aes(
  x = interaction(Month, Year),
  y = AirPassengers,
  group = 1
)) +
  geom_line(color = "cadetblue") +
  ylim(0, NA) +
  scale_x_discrete(labels = paste(df$Q , df$Y2, sep = "\n")) +
  labs(x = "", y = "") +
  theme_minimal() +
  theme(axis.title = element_blank())

multi level axis labels in R plot, multi level axis labels in ggplot2, axis labels in separate rows, axis labels in multiple lines in R

If the space allows, you can show x-axis labels on three levels. Here is a little tweak for using multiple colors for labels. If the year is an odd number, it will appear in one color, otherwise in a different one.

df$AxisColor <- ifelse(df$Year %% 2 == 0, "gray50", "gray")

head(df)

#  Year Month AirPassengers Quarter  Q    Y   Y2 AxisColor
# 1 1958   Jan           340      Q1 Q1 1958         gray50
# 2 1958   Feb           318      Q1                 gray50
# 3 1958   Mar           362      Q1                 gray50
# 4 1958   Apr           348      Q2 Q2              gray50
# 5 1958   May           363      Q2                 gray50
# 6 1958   Jun           435      Q2         1958    gray50

As a result, it looks like this.

ggplot(df, aes(
  x = interaction(Month, Year),
  y = AirPassengers,
  group = 1
)) +
  geom_line(color = "cadetblue", linewidth = 1) +
  ylim(0, NA) +
  geom_vline(
    xintercept = seq(1, length(df$Month), by = 3),
    color = "lightgray",
    linewidth = 0.75,
    linetype = 3) +
  scale_x_discrete(labels = paste(df$Month, df$Q , df$Y2, sep = "\n")) +
  labs(x = "", y = "") +
  theme_minimal()+
  theme(axis.text.y = element_text(color = "gray50"),
        axis.text.x = element_text(color = df$AxisColor),
        axis.line.x = element_line(linewidth = 0.5, color = "lightgray"),
        axis.ticks.x = element_line(linewidth = 0.5, color = df$AxisColor),
        panel.grid = element_blank(),
        axis.title = element_blank())

Multi-level axis labels in R, ggplot2 axis labels in multiple rows, multi-row R plot axis labels, axis labels in multiple lines in R

Please look at other visualizations in this blog made using R. For example, gradient line chartglowing line chart, and gradient word cloud.


Posted

in

, ,

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *