如何编写ggplot自定义注释函数解决cannot add ggproto objects报错
问题修复方案
核心报错原因
- 自定义函数不能直接用
+拼接多个ggplot层返回:ggplot的+运算符仅支持在ggplot对象和图层/主题等对象之间使用,函数内部直接对多个annotate层执行相加操作,会触发「无法叠加ggproto对象」的错误,正确做法是将所有需要返回的注释层封装到list中返回。 - 函数内部存在语法笔误:文本注释行的
as.Date(s_yr("-01-01"))写法错误,同时可以优化文本位置为时间区间中点,和你硬编码的注释效果对齐。
修复后的自定义注释函数
af <- function(s_yr, e_yr, y_pos, lab) { # 统一转换时间格式避免重复代码 start_x <- as.POSIXct(as.Date(paste0(s_yr, "-01-01"))) end_x <- as.POSIXct(as.Date(paste0(e_yr, "-01-01"))) mid_x <- start_x + (end_x - start_x)/2 # 文本放在区间中间,和硬编码逻辑对齐 # 所有注释层放入list返回 list( annotate(geom = "point", x = start_x, y = y_pos, color = 'black', size = 1), annotate(geom = "point", x = end_x, y = y_pos, color = 'black', size = 1), annotate(geom = "segment", x = start_x, xend = end_x, y = y_pos, yend = y_pos, color = 'black', size = 1), annotate(geom = "text", x = mid_x, y = y_pos + 20, color = 'black', size = 3, label = lab) ) }
正确调用方式
不需要修改原有绘图逻辑,直接取消自定义函数调用行的注释即可,scale_fill_calc来自ggthemes包,运行前需要先加载:
library(tidyverse) library(ggthemes) df %>% ggplot(aes(YearDate, fill = Gender2)) + geom_bar() + scale_fill_calc() + xlab("Date") + ylab("Count") + # 硬编码的Szarkowski注释 annotate(geom="point",x=as.POSIXct( as.Date("1962-01-01")), y=600,color='black',size=1)+ annotate(geom="point",x=as.POSIXct( as.Date("1991-01-01")), y=600,color='black',size=1)+ annotate(geom="segment", x=as.POSIXct( as.Date("1962-01-01")), xend=as.POSIXct( as.Date("1991-01-01")), y=600,yend=600,color='black',size=1)+ annotate(geom="text",x=as.POSIXct( as.Date("1978-01-01")), y=620,color='black',size=3,label="Szarkowski") + # 自定义函数调用,不会再报错 af(1970, 1990, 777, "FakeLabel") + theme_minimal()
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

