Многострочные метки оси x в линейной диаграмме ggplot
Изменить: Этот вопрос был отмечен как дублированный, но ответы здесь были опробованы и не работали, потому что рассматриваемый случай это линейная диаграмма, а не гистограмма. Применение этих методов дает диаграмму с 5 строками, 1 для каждого года - не полезно. Кто-нибудь, кто проголосовал за то, чтобы отмечать как дубликат, на самом деле попробовал эти подходы к образцу данных, предоставленному этим вопросом? Если это так, напишите как ответ.
Оригинальный вопрос:
Есть функция в сводных диаграммах Excel, которая допускает многоуровневые категориальные оси. Я пытаюсь найти способ сделать то же самое с ggplot
(или любым другим графическим пакетом в R).
Рассмотрим следующий набор данных:
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))
Если это импортировано в сводную таблицу Excel, просто создать следующую диаграмму:
![]()
Обратите внимание, как ось x имеет два уровня: один для четверти и один для переменной группировки, год. Возможны ли многоуровневые оси с помощью ggplot
?
NB: Есть хак с фасетками, которые производят нечто подобное, но это не то, что я ищу.
library(ggplot2)
ggplot(df) +
geom_line(aes(x=quarter,y=sales,group=year))+
facet_grid(.~year,scales="free")
![]()
Ответы
Ответ 1
Мы используем аргументы в theme
для удаления текста по оси x по умолчанию (axis.title.x
/axis.text.x = element_blank()
) и добавляются дополнительные поля (plot.margin
).
Новые метки добавляются с помощью annotate(geom = "text",
. Преобразуя объект plot в grob (ggplot_gtable(ggplot_build(
), обрезание меток оси x может быть отключено.
library(ggplot2)
g1 <- ggplot(data = df, aes(x = interaction(year, quarter, lex.order = TRUE),
y = sales, group = 1)) +
geom_line(colour = "blue") +
coord_cartesian(ylim = c(35, 65), expand = FALSE) +
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) +
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())
# remove clipping of x axis labels
g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid::grid.draw(g2)
![введите описание изображения здесь]()
См. также хороший ответ от @eipi10 здесь: Предотвращать многократное отображение года с временными рядами
Ответ 2
Предлагаемый код Хенрика действительно работает и мне очень помог! Я думаю, что решение имеет большое значение. Но, пожалуйста, имейте в виду, что в первой строке кода есть небольшая ошибка, что приводит к неправильному порядку данных.
Вместо
... aes(x = interaction(year,quarter), ...
он должен быть
... aes(x = interaction(quarter,year), ...
Полученный рисунок имеет данные в правильном порядке.
![enter image description here]()
P.S. Я предложил изменение (которое было отклонено до сих пор), и из-за небольшой нехватки репутации мне не разрешено комментировать, что бы я сделал.