ggplot2:添加辅助 x 标签(年份低于月份)

2023-12-07

我的问题与:带有嵌套 x 变量的两行轴标签(年份低于月份)

但是,我的数据看起来有点不同。

library(dplyr)

set.seed(122)
df <- as_tibble(rlnorm(1260, meanlog = 0.06, sdlog = 0.20))

df$month <- rep(c("Jan", "Feb", "Mär", "Apr", "Mai", "Jun", 
      "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"), 5, each=21)

df$year <- rep(c("Year 1", "Year 2", "Year 3", "Year 4", "Year 5" ), 1, each=252)

我希望我的折线图看起来像这样,但如果可能的话没有垂直线:

enter image description here


我可以想到两种方法来做到这一点,每种方法都有其优点和缺点:

数据准备:

library(dplyr)
library(tibble)
library(lubridate)
library(scales)
library(ggplot2)

set.seed(122)
df <- as_tibble(rlnorm(1260, meanlog = 0.06, sdlog = 0.20))
df$month <- rep(month.abb, 5, each=21)
df$year <- rep(c("Year 1", "Year 2", "Year 3", "Year 4", "Year 5"), 1, each=252)

# We first create a "real" date variable with year, month and day. I've chosen to add 
# "201" in from of your year, but it really doesn't matter in our case.
df <- df %>%
  group_by(year, month) %>%
  mutate(Date = as.Date(paste0("201", sub("^.+(\\d+)$", "\\1", year),
                               "-", month, "-", row_number()),
                        format = "%Y-%b-%d"))

# Since OP's daily values don't make up full months of data, 
# we need this step to show missing data correctly. 
df <- expand.grid(Date = seq.Date(from = min(df$Date), to = max(df$Date), by = "days")) %>% 
  mutate(year = paste("Year", sub("^\\d{3}(\\d)", "\\1", format(Date, "%Y"))),
         month = format(Date, "%b")) %>%
  left_join(df)

请注意,我已经使用了month.abb替换 OP 提供的月份,因为看起来他们使用的是非英语语言环境。

1. Use facet_grid:

ggplot(df, aes(x = Date, y = value, group = year)) +
  geom_line() +
  facet_grid(. ~ year, scale = "free_x") +
  scale_x_date(labels = date_format("%b"), expand = c(0, 0)) +
  theme(panel.spacing.x = unit(0, "lines")) +
  ylim(c(0, 2.5))

enter image description here

我用过expand in scale_x_date防止 ggplot 在每个面的两端添加空格panel.spacing.x以减少刻面之间的间距。这两者的组合给我们一种错觉,即面板已连接,但实际上并非如此(即使没有缺失值,每个面的末尾也不会连接到下一个面的开头)

2. Use geom_rect + geom_text:

# Create labels
label_range <- df %>%
  group_by(year) %>%
  summarize(xmin = min(Date),
            xmax = max(Date),
            ymin = -0.5,
            ymax = ymin + 0.15)

ggplot(df) +
  geom_line(aes(x = Date, y = value)) +
  geom_rect(data = label_range, fill = "lightcoral", color = "#f2f2f2",
            aes(xmin = xmin, xmax = xmax, 
                ymin = ymin, ymax = ymax,
                group = year)) +
  geom_text(data = label_range,
            aes(x = xmin + 365/2, y = ymin + 0.1,
                group = year, label = year)) +
  coord_cartesian(ylim = c(0, 2.5), clip = "off") +
  scale_x_date(labels = date_format("%b"), 
               date_breaks = "1 month",
               expand = c(0.01, 0.01)) +
  theme_bw() +
  theme(plot.margin = unit(c(1,1,3,1), "lines"))

enter image description here

第二种方法比较繁琐,但我们的数据将被视为一个连续的系列。

  1. Create label_range确定每个的四个角的坐标geom_rect.

  2. 使用这个数据集,我使用以下方法绘制了“构面框”geom_rect和他们的标签使用geom_text分组依据year.

  3. 我们希望矩形位于 x 轴下方,所以我使用了coord_cartesian将绘图设置为特定缩放,这可以防止当我们将其设置在绘图之外时,矩形被剪掉。

  4. plot.margin在 x 轴下方为构面标签添加一些空格

  5. 注意之间的差距Dec and Jan。它们是由缺失值引起的,这与之间的差距不同Dec and Jan在第一种方法中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ggplot2:添加辅助 x 标签(年份低于月份) 的相关文章

随机推荐