为 ggplot 创建注释函数所需的方法

Ben*_*Ben 3 r function ggplot2

我正在创建一个带有多个注释的绘图,因此我编写了一个函数来简化该过程。下面的 ggplot() 显示了annotate()一个“Szarkowski”的费力命令。由于我要添加多个段和文本,因此我创建了该af函数(也如下所示)。但是,在使用该函数时,我抛出“无法将 ggproto 对象添加在一起”错误。

如何正确创建我的注释函数?

数据

df<-structure(list(
  Department = structure(c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L), .Label = c("Architecture & Design", "Architecture & Design - Image Archive", 
    "Drawings & Prints", "Film", "Fluxus Collection", "Media and Performance", "Painting & Sculpture", "Photography"), class = "factor"), 
  Year = c(1970, 1967, 1960, 1960, 1960, 1960, 1970, 1970, 1970, 1970, 1970), 
  Gender2 = c("Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female"), 
  Nationality2 = c(" American ", " American ", " American ", " American ", " American ", " American ", " American ", " American ", 
                               " American ", " American ", " American "), 
  YearDate = structure(c(20491200, -74203200, -295041600, -295041600, -295041600, -295041600, 20491200, 20491200, 20491200, 20491200, 20491200), class = c("POSIXct", "POSIXt"), tzone = ""), 
  American = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("American", "Not American"), class = "factor")), row.names = 5600:5610, class = "data.frame")
Run Code Online (Sandbox Code Playgroud)

这是我的注释函数:

af<-function(s_yr,e_yr,y_pos,lab){
  annotate(geom="point",x=as.POSIXct( as.Date(paste0(s_yr,"-01-01"))), y=y_pos,color='black',size=1)+
  annotate(geom="point",x=as.POSIXct( as.Date(paste0(e_yr,"-01-01"))), y=y_pos,color='black',size=1)+
  annotate(geom="segment",
       x=as.POSIXct( as.Date(paste0(s_yr,"-01-01"))), 
       xend=as.POSIXct( as.Date(paste0(e_yr,"-01-01"))),
       y=y_pos,yend=y_pos,color='black',size=1)+
  annotate(geom="text",x=as.POSIXct( as.Date(s_yr("-01-01"))), y=y_pos+20,color='black',size=3,label=lab)    }
Run Code Online (Sandbox Code Playgroud)

这是我的 ggplot() 命令,注释函数被注释掉

df %>%
ggplot(aes(YearDate,fill=Gender2))+geom_bar()+
  scale_fill_calc()+
  xlab("Date")+ylab("Count")+
  #Szarkowski annotation -- this hard coding works fine
  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")+
  # cannot add `ggproto` objects together
  # af(1970,1990,777,"FakeLabel") +   # this line throws an error; how to fix `af` function?
  theme_minimal()
Run Code Online (Sandbox Code Playgroud)

teu*_*and 5

回复:评论

这就是我的意思。+从函数中删除所有es af(),并将所有注释放入列表中。将组件放入列表中不仅适用于注释,而且可以方便地为多个绘图回收任意数量的绘图组件。这是由于该ggplot2:::ggplot_add.list()方法隐式地+将所有列表元素添加到绘图中。

library(ggplot2)

df<-structure(list(
  Department = structure(c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L), .Label = c("Architecture & Design", "Architecture & Design - Image Archive", 
    "Drawings & Prints", "Film", "Fluxus Collection", "Media and Performance", "Painting & Sculpture", "Photography"), class = "factor"), 
  Year = c(1970, 1967, 1960, 1960, 1960, 1960, 1970, 1970, 1970, 1970, 1970), 
  Gender2 = c("Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female", "Female"), 
  Nationality2 = c(" American ", " American ", " American ", " American ", " American ", " American ", " American ", " American ", 
                               " American ", " American ", " American "), 
  YearDate = structure(c(20491200, -74203200, -295041600, -295041600, -295041600, -295041600, 20491200, 20491200, 20491200, 20491200, 20491200), class = c("POSIXct", "POSIXt"), tzone = ""), 
  American = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("American", "Not American"), class = "factor")), row.names = 5600:5610, class = "data.frame")

af<-function(s_yr,e_yr,y_pos,lab) {
  list(annotate(geom="point",
                x=as.POSIXct( as.Date(paste0(s_yr,"-01-01"))), 
                y=y_pos,color='black',size=1),
       annotate(geom="point",
                x=as.POSIXct( as.Date(paste0(e_yr,"-01-01"))), 
                y=y_pos,color='black',size=1),
       annotate(geom="segment",
                x=as.POSIXct( as.Date(paste0(s_yr,"-01-01"))), 
                xend=as.POSIXct( as.Date(paste0(e_yr,"-01-01"))),
                y=y_pos,yend=y_pos,color='black',size=1),
       annotate(geom="text",x=as.POSIXct( as.Date(paste0(s_yr, "-01-01"))), 
                y=y_pos+20,color='black',size=3,label=lab)   
  )
}

ggplot(df, aes(YearDate,fill=Gender2))+geom_bar()+
  # scale_fill_calc()+
  xlab("Date")+ylab("Count")+
  #Szarkowski annotation -- this hard coding works fine
  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")+
  # cannot add `ggproto` objects together
  af(1970,1990,777,"FakeLabel") +
  theme_minimal()
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v1.0.0)创建于 2021-08-26