如何用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") # 增加分面间距,提升可读性 )
关键修改说明
解决X轴仅显示一月的问题
- 在
scale_x_date中添加date_breaks = "1 month",强制每月生成一个刻度标签 - 可选使用
complete()补全年份缺失的月份,让X轴刻度连续,图表更规整 - 用
expand = c(0,10)调整X轴留白,避免柱子紧贴边缘
- 在
解决分面标题遮挡问题
- 降低
theme_bw的base_size(从15改为12),整体减小元素字号 - 通过
theme(strip.text = element_text(size = 10))单独调整分面年份标题的字号 - 添加
axis.text.x = element_text(angle = 45, hjust = 1)让X轴月份标签倾斜,防止重叠
- 降低
修正虚拟数据语法错误
原虚拟数据代码存在语法问题,修正后版本: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
相关产品推荐
相关产品推荐

