Reputation: 1154
I am creating a plot with multiple annotations, so I wrote a function to simplify that process. The ggplot() below shows the laborious annotate()
commands for one "Szarkowski". Since I'm going to add multiple segments and text, I created the af
function (also shown below). However, I throw a "cannot add ggproto objects together" error when using the function.
How do I create my annotation function properly?
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){
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) }
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()
Upvotes: 3
Views: 255
Reputation: 38063
RE: comments
Here is what I mean exactly. Remove all the +
es from the af()
function and instead put all the annotations in a list. Putting components in a list does not only work for annotations, but can be convenient for recycling any number of plot components for multiple plots. This is due to the ggplot2:::ggplot_add.list()
method that implicitly +
es all the list elements to the plot.
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()
Created on 2021-08-26 by the reprex package (v1.0.0)
Upvotes: 5