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

如何用ggplot2的facet_wrap()绘制时序数据并修复图表异常

问题描述

我正在用ggplot2绘制时序数据,绘制每年每月新球茎频率时遇到两个问题:

  • X轴仅显示一月的标签
  • 年份分面标题尺寸过大,遮挡柱子,难以看清

数据示例

year     month Number_Daffodils Frequency_New_Bulbs       date n_month
1  2012   January                1                   7 2012-01-01       1
2  2012  February                8                  59 2012-02-01       2
3  2012     April               18                 144 2012-04-01       4
4  2012       May               21                 193 2012-05-01       5

当前代码

# Note that %b represents the abbreviated month which will be plotted as labels on the x-axis.
# Use the column 'date' that contains month of the year as a class of type date

Year_Group_Size <- dat_Ds %>% 
  ggplot(aes(x = date, y = Frequency_New_Bulbs)) +
  geom_bar(stat = "identity", fill = "darkorchid4") +
  facet_wrap(~ year, ncol = 3) +
  labs(title = "Montly Total Estimated Group Size Per Month Per Year",
       subtitle = "Data plotted by year",
       y = "Estimated Group Size",
       x = "Month") + 
  theme_bw(base_size = 15) +
  scale_x_date(date_labels = "%b")

虚拟数据生成代码

tibble(
  Month = sample(month.name, 120, replace = TRUE),
  Year = sample(2012:2024, 120, replace = TRUE),
  Date = Sys.Date(), 120, replace = TRUE,
  Number_Daffodils = sample(1:5, 120, replace = TRUE)
) 

效果对比

  • 当前输出:每个分面的X轴仅显示"Jan"标签,年份标题字号过大,柱子被标题遮挡
  • 期望输出:每个分面X轴显示所有存在数据的月份缩写,年份标题尺寸合适,不遮挡柱子,图表布局紧凑合理

解决方案

针对你的问题,从X轴刻度控制和分面主题样式两方面修改即可,以下是完整修正代码及说明:

修正后完整代码

library(tidyverse)

# 预处理数据:确保日期格式正确,可选补全年份缺失月份
dat_Ds <- dat_Ds %>%
  mutate(date = as.Date(date)) %>%
  # 可选操作:补全年份中缺失的月份,让X轴刻度连续
  complete(year = unique(year), n_month = 1:12, fill = list(Frequency_New_Bulbs = 0)) %>%
  mutate(date = as.Date(paste(year, n_month, "01", sep = "-")))

Year_Group_Size <- dat_Ds %>% 
  ggplot(aes(x = date, y = Frequency_New_Bulbs)) +
  geom_bar(stat = "identity", fill = "darkorchid4") +
  facet_wrap(~ year, ncol = 3) +
  labs(title = "Monthly Total Estimated Group Size Per Month Per Year",
       subtitle = "Data plotted by year",
       y = "Estimated Group Size",
       x = "Month") + 
  theme_bw(base_size = 12) +  # 降低基础字号,避免元素拥挤
  scale_x_date(
    date_labels = "%b",
    date_breaks = "1 month",  # 强制每月生成一个刻度标签
    expand = c(0, 10)  # 调整X轴两端留白,避免柱子贴边
  ) +
  theme(
    strip.text = element_text(size = 10),  # 单独缩小分面的年份标题字号
    axis.text.x = element_text(angle = 45, hjust = 1),  # X轴标签倾斜防重叠
    panel.spacing = unit(1, "lines")  # 增加分面间距,提升可读性
  )

关键修改说明

  1. 解决X轴仅显示一月的问题

    • 在scale_x_date中添加date_breaks = "1 month",强制每月生成一个刻度标签
    • 可选使用complete()补全年份缺失的月份,让X轴刻度连续,图表更规整
    • 用expand = c(0,10)调整X轴留白,避免柱子紧贴边缘
  2. 解决分面标题遮挡问题

    • 降低theme_bw的base_size(从15改为12),整体减小元素字号
    • 通过theme(strip.text = element_text(size = 10))单独调整分面年份标题的字号
    • 添加axis.text.x = element_text(angle = 45, hjust = 1)让X轴月份标签倾斜,防止重叠
  3. 修正虚拟数据语法错误
    原虚拟数据代码存在语法问题,修正后版本:

    tibble(
      Month = sample(month.name, 120, replace = TRUE),
      Year = sample(2012:2024, 120, replace = TRUE),
      Date = sample(seq(as.Date("2012-01-01"), as.Date("2024-12-01"), by="month"), 120, replace=TRUE),
      Number_Daffodils = sample(1:5, 120, replace = TRUE),
      Frequency_New_Bulbs = Number_Daffodils * sample(5:20, 120, replace=TRUE)
    ) %>%
      mutate(n_month = match(Month, month.name))
    

内容的提问来源于stack exchange,提问作者Alice Hobbs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:25:16