19.4 The plot() method

19.4.1 ggplot structure

The user-facing code and internal code is also separated by when they are evaluated. The user-facing code like geom_smooth() is evaluated immediately to give you a ggplot object, but the internal code is only evaluated when a ggplot object is printed or plotted, via print() and plot().

The following code simply creates a ggplot object from user-facing code, and DOES NOT print or plot the ggplot (yet).

p <- ggplot(mpg, aes(displ, hwy, color = drv)) + 
  geom_point(position = position_jitter(seed = 2022)) +
  geom_smooth(method = "lm", formula = y ~ x) + 
  facet_wrap(vars(year)) + 
  ggtitle("A plot for expository purposes")

The ggplot object is actually just a list under the hood:

class(p)
[1] "gg"     "ggplot"
typeof(p)
[1] "list"

19.4.2 Display

Evaluating the ggplot is what gives you the actual points, rectangles, text, etc. that make up the figure (and you can also do so explicitly with print()/plot())

p

# print(p)
# plot(p)

These are two separate processes, but we often think of them as one monolithic process:

defining_benchmark <- bench::mark(
  # Evaluates user-facing code to define ggplot,
  # but does not call plot/print method
  p <- ggplot(mpg, aes(displ, hwy, color = drv)) + 
    geom_point(position = position_jitter(seed = 2022)) +
    geom_smooth(method = "lm", formula = y ~ x) + 
    facet_wrap(vars(year)) + 
    ggtitle("A plot for expository purposes")
)

plotting_benchmark <- bench::mark(
  # Plots the ggplot
  plot(p)
)
bind_rows(
  defining_benchmark[,2:5],
  plotting_benchmark[,2:5]
)
# A tibble: 2 × 4
       min   median `itr/sec` mem_alloc
  <bch:tm> <bch:tm>     <dbl> <bch:byt>
1   3.05ms    3.2ms    303.     30.34KB
2 238.43ms  238.4ms      4.19    3.58MB