You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggplot中将年份作为副轴显示在月份主X轴下方?

解决ggplot X轴年份分组标注问题

问题分析

原代码中sec_axis的用法有误,sec_axis的设计目的是创建基于主轴转换的副轴(如单位转换),无法实现“每个年份仅显示一次,对应其所有月份”的分组标注需求。以下是正确的实现方案:


步骤1:清理数据

先移除含缺失值的行,避免绘图异常:

df_clean <- df[!is.na(df$media), ]

步骤2:计算年份在X轴的中间位置

用dplyr计算每个年份对应的X轴中点,确保年份标签居中显示:

library(dplyr)

year_positions <- df_clean %>%
  group_by(year) %>%
  summarize(x_mid = mean(as.numeric(cycle_rounded))) %>%
  mutate(x_mid = as.POSIXct(x_mid, origin = "1970-01-01", tz = "UTC"))

步骤3:绘制图表并添加年份标注

通过annotate在主X轴(月份)下方添加年份标签,替代错误的sec_axis用法:

library(ggplot2)

ggplot(df_clean, aes(x = cycle_rounded, y = media)) +
  # 绘制误差带
  geom_ribbon(aes(ymin = media - desvio, ymax = media + desvio), 
              alpha = .2, fill = "red") +
  # 绘制折线和点
  geom_line(col = "grey10", linewidth = .5) +
  geom_point(col = "grey10", size = 1) +
  # 主X轴显示月份
  scale_x_datetime(date_labels = "%m", breaks = "1 month") +
  # 添加年份标签到X轴下方
  annotate("text", x = year_positions$x_mid, 
           y = min(df_clean$media, na.rm = TRUE) - 0.8,
           label = year_positions$year, size = 4, color = "black") +
  # 可选:添加年份分隔线,增强视觉区分
  annotate("segment", x = as.POSIXct("2020-10-01", tz = "UTC"), 
           xend = as.POSIXct("2020-11-30", tz = "UTC"),
           y = min(df_clean$media, na.rm = TRUE) - 0.4, 
           yend = min(df_clean$media, na.rm = TRUE) - 0.4,
           color = "black") +
  annotate("segment", x = as.POSIXct("2020-12-01", tz = "UTC"), 
           xend = as.POSIXct("2021-12-31", tz = "UTC"),
           y = min(df_clean$media, na.rm = TRUE) - 0.4, 
           yend = min(df_clean$media, na.rm = TRUE) - 0.4,
           color = "black") +
  annotate("segment", x = as.POSIXct("2022-01-01", tz = "UTC"), 
           xend = as.POSIXct("2022-04-30", tz = "UTC"),
           y = min(df_clean$media, na.rm = TRUE) - 0.4, 
           yend = min(df_clean$media, na.rm = TRUE) - 0.4,
           color = "black") +
  # 设置标签
  labs(x = "data", y = "temperatura") +
  # 调整主题,确保年份标签不被裁剪
  theme_classic() +
  theme(
    axis.text.x = element_text(size = 12, angle = 45, vjust = 1, hjust = 1, color = "black"),
    axis.text.y = element_text(size = 12, color = "black"),
    axis.title.x = element_text(size = 14, color = "black", margin = margin(t = 20)),
    axis.title.y = element_text(size = 14, color = "black"),
    plot.margin = margin(b = 20, t = 10, l = 10, r = 10)
  )

关键说明

  • 放弃错误的sec_axis用法,改用annotate直接添加分组标签,更贴合“年份对应月份范围”的需求。
  • 通过调整theme中的边距参数,避免年份标签被图表边界裁剪。
  • 可选的分隔线可根据需求移除,仅保留年份标签即可。

内容的提问来源于stack exchange,提问作者Wilson Souza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:27:52