Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-row x-axis labels in ggplot line chart

Tags:

r

ggplot2

Edit: This question has been marked as duplicated, but the responses here have been tried and did not work because the case in question is a line chart, not a bar chart. Applying those methods produces a chart with 5 lines, 1 for each year - not useful. Did anyone who voted to mark as duplicate actually try those approaches on the sample dataset supplied with this question? If so please post as an answer.

Original Question:

There's a feature in Excel pivot charts which allows multilevel categorical axes.I'm trying to find a way to do the same thing with ggplot (or any other plotting package in R).

Consider the following dataset:

set.seed(1) df=data.frame(year=rep(2009:2013,each=4),               quarter=rep(c("Q1","Q2","Q3","Q4"),5),               sales=40:59+rnorm(20,sd=5)) 

If this is imported to an Excel pivot table, it is straightforward to create the following chart:

Note how the x-axis has two levels, one for quarter and one for the grouping variable, year. Are multilevel axes possible with ggplot?

NB: There is a hack with facets that produces something similar, but this is not what I'm looking for.

library(ggplot2) ggplot(df) +   geom_line(aes(x=quarter,y=sales,group=year))+   facet_grid(.~year,scales="free") 

like image 813
jlhoward Avatar asked Dec 13 '13 16:12

jlhoward


1 Answers

New labels are added using annotate(geom = "text",. Turn off clipping of x axis labels with clip = "off" in coord_cartesian.

Use theme to add extra margins (plot.margin) and remove (element_blank()) x axis text (axis.title.x, axis.text.x) and vertical grid lines (panel.grid.x).

library(ggplot2)  ggplot(data = df, aes(x = interaction(year, quarter, lex.order = TRUE),                        y = sales, group = 1)) +   geom_line(colour = "blue") +   annotate(geom = "text", x = seq_len(nrow(df)), y = 34, label = df$quarter, size = 4) +   annotate(geom = "text", x = 2.5 + 4 * (0:4), y = 32, label = unique(df$year), size = 6) +   coord_cartesian(ylim = c(35, 65), expand = FALSE, clip = "off") +   theme_bw() +   theme(plot.margin = unit(c(1, 1, 4, 1), "lines"),         axis.title.x = element_blank(),         axis.text.x = element_blank(),         panel.grid.major.x = element_blank(),         panel.grid.minor.x = element_blank()) 

enter image description here


See also the nice answer by @eipi10 here: Axis labels on two lines with nested x variables (year below months)

like image 176
Henrik Avatar answered Sep 19 '22 08:09

Henrik