setempler
setempler

Reputation: 1751

How to use do.call to add elements to a ggplot object?

Objection

I would like to use do.call to combine a list of layers e with a main plot g. My intention is to use annotation_custom(ggplotGrob(x)) objects (where x is an independent ggplot object) to overlay a main plot with.

Simplified problem

This simplified example uses a list e of calls to geom_* functions:

library(ggplot2)
# data
d <- data.frame(a = 1:3, x = 1:3, y = 1:3)
# main plot
g <- ggplot(d, aes(x, y, label = a))
# plot elements
e <- list(geom_point(), geom_text())

Undesired solution

To combine the plot g with all elements in e, I could use single elements (which works) as in:

g + e[[1]] + e[[2]]

But my intention is (for automation reasons) to use do.call.

Problem

Using do.call with + and a list of g and es fails:

do.call(`+`, c(list(g), e))
# Error in .Primitive("+")(list(data = list(a = 1:3, x = 1:3, y = 1:3),  : 
#   unused argument (<environment>)

Question

How can I use do.call, the + method and my list of g and es correctly?

Upvotes: 2

Views: 593

Answers (3)

GGamba
GGamba

Reputation: 13680

This also works:

do.call(`+`, c(list(g), list(e)))

Upvotes: 1

baptiste
baptiste

Reputation: 77116

what's wrong with just g + e ?

Upvotes: 2

LyzandeR
LyzandeR

Reputation: 37889

I don't think you need do.call for this. do.call uses the list you provided to run it as arguments within the function. + only takes 2 arguments though. If you want to chain calls with +, Reduce would do the job with the same call.

Reduce(`+`, c(list(g), e))

Output:

enter image description here

Upvotes: 2

Related Questions