Skip to content

Refactor titleGrob() #5273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 21, 2023
Merged

Refactor titleGrob() #5273

merged 10 commits into from
Apr 21, 2023

Conversation

teunbrand
Copy link
Collaborator

@teunbrand teunbrand commented Apr 17, 2023

This PR aims to fix a performance bottleneck for #5030 as identified in #5030 (comment).

Briefly, it introduces the following changes:

  1. The titleGrob grobs no longer have viewports.
  2. Instead of viewports, the position of the textGrob is adjusted to get the same effect.
  3. The titleGrob() constructor now does the job of what previously was done by title_spec() and add_margins().
  4. The assemble_strip() no longer needs to awkwardly hassle with all these viewports.
  5. A bunch of functions, like title_spec(), add_margins(), margin_width(), margin_height() have become obsolete. I've removed them, but we might expect this to bite us during revdepchecks because they're missing.

Benchmark below shows a ~4 fold reduction in drawing time for 574 titleGrobs.

library(ggplot2)
library(grid)
library(scales)

x <- rescale(as.numeric(economics$date))
y <- rescale(as.numeric(economics$unemploy))
lab <- as.character(economics$pop)

make_grob <- function(fun, x, y, label, margin = margin()) {
  do.call(
    grobTree,
    Map(
      fun,
      x = x, y = y, label = label, hjust = 0.5, vjust = 0.5,
      MoreArgs = list(margin_x = TRUE, margin_y = TRUE, margin = margin)
    )
  )
}

grob_old <- make_grob(
  ggplot2:::titleGrob, x = x, y = y, label = lab, 
  margin = margin(5, 5, 5, 5)
)

devtools::load_all("~/packages/ggplot2/")
#> ℹ Loading ggplot2

grob_new <- make_grob(
  titleGrob, x = x, y = y, label = lab, 
  margin = margin(5, 5, 5, 5)
)

render <- function(grob) {
  file <- tempfile(fileext = ".png")
  ragg::agg_png(file)
  grid.newpage(); grid.draw(grob)
  dev.off()
  unlink(file)
}

bench::mark(
  render(grob_old),
  render(grob_new),
  min_iterations = 10
)
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
#> # A tibble: 2 × 6
#>   expression            min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr>       <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 render(grob_old)    575ms    585ms      1.67    3.67MB     5.02
#> 2 render(grob_new)    126ms    135ms      7.50  132.94KB     5.25

Created on 2023-04-17 with reprex v2.0.2

@teunbrand teunbrand mentioned this pull request Apr 19, 2023
Copy link
Member

@thomasp85 thomasp85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM... Can I get you to run the visual tests on a non-arm64 computer (assuming you are working on a M1 Mac). I've found the chip architecture influences these weird rounding issues and all the large theme tests never matches on my machine

@teunbrand
Copy link
Collaborator Author

teunbrand commented Apr 21, 2023

Can I get you to run the visual tests on a non-arm64 computer

These visual tests were run on a windows machine with an x64-based processor. Bit weird that CPU architecture matters for this rounding.

@teunbrand teunbrand merged commit 90de384 into tidyverse:main Apr 21, 2023
@teunbrand teunbrand deleted the titlegrob_refactor branch April 21, 2023 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants