ggplot2实现按月份分组绘制箱线图的语法与参数设置
问题核心原因
散点图属于逐观测映射的非聚合图层,不需要明确分组就能正常渲染;但箱线图是聚合类图层,必须提前指定观测的分组规则才能正确计算分位数统计量。
你的COLDATE字段是精确到天的连续型日期变量,ggplot不会自动将其按自然月切分聚合,直接绘制时要么每个独立日期生成一个极小的箱线,要么全量数据合并为一个箱线,无法得到按月分组的效果。
实现方案
方案1:提前加工月份分组字段(推荐,逻辑最稳定)
先在原始数据集中生成一个映射到当月第一天的日期列,作为统一的分组和x轴映射依据,使用lubridate包的floor_date()函数实现,不会破坏原日期字段的格式:
library(lubridate) library(ggplot2) # 新增月份维度列,同一月的所有记录该字段值均为当月1号的日期 Results$collect_month <- floor_date(Results$COLDATE, unit = "month")
之后直接传入ggplot绘图即可,原有坐标轴、主题设置无需修改:
ggplot(Results, aes(x = collect_month, y = `PB(ug/L)`, group = collect_month)) + coord_trans(y = "log10") + geom_boxplot(alpha = 0.5) + xlab("Collection Date") + scale_x_date(date_breaks = "1 month", date_labels = "%b %Y") + theme(axis.text.x=element_text(angle=60, hjust=1))
注意:不要用
cut(COLDATE, breaks = "month")生成月份分组,该函数返回因子类型而非标准日期格式,会导致scale_x_date()日期坐标轴渲染报错。
方案2:不修改原数据集,在映射内直接计算分组
如果不想改动原始数据,可以直接在aes()的group参数内完成分组计算,效果和方案1完全一致:
ggplot(Results, aes( x = COLDATE, y = `PB(ug/L)`, group = floor_date(COLDATE, unit = "month") )) + coord_trans(y = "log10") + geom_boxplot(alpha = 0.5) + xlab("Collection Date") + scale_x_date(date_breaks = "1 month", date_labels = "%b %Y") + theme(axis.text.x=element_text(angle=60, hjust=1))
aes()中group参数的语法规则 - group参数接收与数据集观测行数等长的分组向量,ggplot会将向量中取值相同的观测归为同一组,供箱线图、折线图、聚合柱状图等图层做统计计算。
- 禁止给group传入单个字符串、数值类的标量值,否则会将全部观测归为同一个组,无法生成分组效果。
- 当x轴映射为离散/分类变量时,ggplot会默认以x的取值作为分组依据,此时可省略group参数;如果x轴映射为连续型变量(比如精确到天的日期),必须手动指定group参数明确分组规则,否则聚合图层无法正常渲染。
内容的提问来源于stack exchange,提问作者Paul Wild
相关产品推荐
相关产品推荐

