修改:此问题已被标记为重复,但回复here已经过尝试但无效,因为相关案例是折线图,而不是条形图。应用这些方法会生成一个包含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轴有两个级别,一个用于四分之一,一个用于分组变量year。 ggplot
可以使用多级轴吗?
注意:有一个黑客的方面会产生类似的东西,但这不是我想要的。
library(ggplot2)
ggplot(df) +
geom_line(aes(x=quarter,y=sales,group=year))+
facet_grid(.~year,scales="free")
答案 0 :(得分:44)
使用annotate(geom = "text",
添加新标签。在clip = "off"
中使用coord_cartesian
关闭x轴标签的裁剪。
使用theme
添加额外的边距(plot.margin
)并移除(element_blank()
)x轴文字(axis.title.x
,axis.text.x
)和垂直网格线( 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())
另请参阅@ eipi10的好答案:Axis labels on two lines with nested x variables (year below months)
答案 1 :(得分:26)
Henrik建议的代码确实起作用并帮助了我很多!我认为该解决方案具有很高的价值。但请注意,代码的第一行存在一个小错误,导致数据的顺序错误。 而不是
... aes(x = interaction(year,quarter), ...
应该是
... aes(x = interaction(quarter,year), ...
生成的图形的数据顺序正确。
P.S。我提出了一个编辑(直到现在才遭到拒绝),并且由于声誉很小,我不能发表评论,我宁愿这样做。
答案 2 :(得分:0)
用户Tung
的回答很好on this thread
library(tidyverse)
library(lubridate)
library(scales)
set.seed(123)
df <- tibble(
date = as.Date(41000:42000, origin = "1899-12-30"),
value = c(rnorm(500, 5), rnorm(501, 10))
)
# create year column for facet
df <- df %>%
mutate(year = as.factor(year(date)))
p <- ggplot(df, aes(date, value)) +
geom_line() +
geom_vline(xintercept = as.numeric(df$date[yday(df$date) == 1]), color = "grey60") +
scale_x_date(date_labels = "%b",
breaks = pretty_breaks(),
expand = c(0, 0)) +
# switch the facet strip label to the bottom
facet_grid(.~ year, space = 'free_x', scales = 'free_x', switch = 'x') +
labs(x = "") +
theme_classic(base_size = 14, base_family = 'mono') +
theme(panel.grid.minor.x = element_blank()) +
# remove facet spacing on x-direction
theme(panel.spacing.x = unit(0,"line")) +
# switch the facet strip label to outside
# remove background color
theme(strip.placement = 'outside',
strip.background.x = element_blank())
p