【问题标题】:How to add months on top of daily data on the x-axis in ggplot2?如何在ggplot2的x轴上的每日数据之上添加月份?
【发布时间】:2021-10-11 11:52:14
【问题描述】:

我有一个数据框,其中 Y 的降水量 (cm) 和 X 的天数。

> head(precip)
  Day     mean
1   1 1.784654
2   2 1.850796
3   3 1.850486
4   4 1.858424
5   5 1.884435
6   6 1.907781

直到 366 天(平均值包括闰年)。两列当前都是数字。这是我绘制它的代码:

precip_plots <- ggplot(data = precip, aes_string(x = "Day", y = "mean", group=1)) +
  geom_line(size = 1)+
  theme_bw()+
  labs(title = "Daily precipitation",
      x = "Day",
      y = "Precipitation (cm)")

看起来像

我希望日期在 X 轴上,但在下方(也在 X 轴上)我希望每个月的范围都有月份字母 (JFMAMJJASOND),例如

我已尝试将此添加到 ggplot:

scale_x_discrete(limits = 1:366, labels=Day[1:31] = "J", Day[32:60] = "F", Day[61:91] = "M", 
                   Day[92:121] = "A", Day[122:152] = "M", Day[153:182] = "J", Day[183:213] = "J",
                   Day[214:244] = "A", Day[245:274] = "S", Day[275:305] = "O", Day[306:335] = "N", 
                   Day[336:366] = "D")

但它只是返回一堆“错误:意外'='”和“错误:意外','”。

我在网上和 SO 上到处找,似乎找不到任何有类似问题的人。

【问题讨论】:

标签: r date ggplot2


【解决方案1】:

更新
这是在scale_x_continuous 中使用函数作为labels 参数的一种方法。仅当 breaks 包含所有天以及常规休息时间(100、200 等)时,此方法才有效。由于这会弄乱断线和轴刻度(它们不再对称),我用element_blank() 隐藏了它们,并用geom_vline 插入了自定义断线。

library(tidyverse)

# some toy data similar to the original data
dat <- tibble(Day = 1:366,
              mean = 2+rnorm(366))

# setup breaks
month <- c(31,60,91,121,152,182,213,244,274,305,335,365)
breaks <- seq(100,300,100)
mybreaks <- sort(c(month,breaks))

precip_plots <- ggplot(data = dat,
                       aes_string(x = "Day",
                                  y = "mean",
                                  group = 1)) +
  geom_line(size = 1) +
  scale_x_continuous(
    breaks = mybreaks,
    # custom function using `dplyr::case_when`
    labels = function(x) {
      
      case_when(
        x == 31  ~ "\nJ",
        x == 60  ~ "\nF",
        x == 91 ~ "\nM",
        x == 121 ~ "\nA",
        x == 152 ~ "\nM",
        x == 182 ~ "\nJ",
        x == 213 ~ "\nJ",
        x == 244 ~ "\nA",
        x == 274 ~ "\nS",
        x == 305 ~ "\nO",
        x == 335 ~ "\nN",
        x == 365 ~ "\nD",
        x %% 100 == 0 ~ as.character(x))
      
    }) +
  # creates fake break lines
  geom_vline(xintercept = breaks,
             color = "#d6d6d6",
             size = 0.5) + 
  theme_bw() +
  # hides original break lines and axis ticks
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        axis.ticks.x = element_blank()
  ) +
  labs(title = "Daily precipitation",
       x     = "Day",
       y     = "Precipitation (cm)") 

precip_plots

reprex package (v0.3.0) 于 2021-08-07 创建

【讨论】:

  • 这很好用(虽然我不完全理解所有的代码),但如果行的一侧有边距,我会更喜欢。是否有删除那些默认 ggplot2 边距的代码?或者如何添加默认边距。
  • @HarleyZhang:很好用。您是指实际数据线与 x 和 y 轴之间的绘图区域内的边距吗?在这种情况下,您可以从 scale_x_continuous 函数中删除参数 expand = c(0, 0)。这有帮助吗?我相应地更新了我的答案。
  • 谢谢,一切都很完美。最后一个问题:如何为每个 y 值(降水)添加水平网格线?
  • @HarleyZhang:我更新了我的答案,现在只隐藏了 x 轴上的原始网格线和刻度线。 y 轴现在保持不变,如果需要,可以使用scale_y_continous 进一步自定义。
猜你喜欢
  • 1970-01-01
  • 2020-05-12
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多