ggplot syntax confusion

Aloha. I find that ggplot syntax is not consistent when used in a function versus interactively invoked. Maybe someone can comment on this quirk?

This syntax works inside a function:
p1 = ggplot(data, aes(x, y)) + geom_point()
invisible(print(p1))

This syntax does not work inside a function:
p1 = ggplot(data, aes(x, y))
p1 + geom_point()
invisible(print(p1))

The second syntax does work when interactively invoked. Why the difference, please?

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars, aes(mpg,hp)) + geom_point()

# these are equivalent
p1 / print(p1) / invisible(print(p1))


p <- function(x) {
  o = ggplot(x, aes(mpg,hp)) + geom_point()
  o / print(o) / invisible(print(o))
}

p(mtcars)

Created on 2023-05-22 with reprex v2.0.2

Thanks for the reply but the issue is not the print part. It's that

p1 + geom_point()

does not print any data on the p1 background when used this way in a function in a package I'm building. It does work when I execute the code interactively. However, it does work when geom_point is tacked on to the ggplot statement directly ( ggplot() + geom_point() ). I assume it has something to do with aes() but I can't find out what or why.

Without a a reprex (see the FAQ), it's hard to see what's going on in your function.

library(ggplot2)

p <- ggplot(mtcars, aes(mpg,hp)) 

add_points <- function(x) {
  x + geom_point()
}

add_points(p)

I know. I'll work on coming up with something but the environment is a bit complex so I think it somehow is data dependent. I haven't come up with a good example and the trivial tests I've tried all work as you've exhibited above.

It doesn't have to be complete data, or even real data—just enough to illustrate the problem.

Understand. l'll see if I can get something reproducible but minimal.

However, it seems like the p1 + geom_point() is not executing when it is on a line by itself. I know this makes no sense but that's what it seems like.

It is executed, but it's not saved.
you should use:
p1 = p1 + geom_point() to overwrite p1, so it can be recalled in the next step. You could also save it as p2 and then use print(p2).

With

p2 <- p1 + geom_point()

there’s no need for print()

With a f() that creates a ggplot object, must take care to capture it

p3 <- f(…)

hmm, okay that's true.
Still the invisible(print(p1)) statement in the next line overwrites the correct plot with the unfinished one as long as p1 doesn't include the added geom_point().