tidyverse / tidyverse/ggplot2

ggplots are rendered three times on the RStudio graphics device at two different sizes

Open
#3,385 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

performance
Dominant language
R
Stars
7k
Forks
2.1k
Avg merge
59m
Merged PRs (30d)
2

Description

This is something @thomasp85 noticed at Tidy Dev Day when he was helping Edzer and I with lazy raster rendering. He noticed the makeContext method for my custom grob was getting called three times when displaying the plot interactively (using profvis). Two of the three draw calls assume a lower screen resolution. Clicking "Zoom" for any grob results in two additional render calls instead of the expected one (for all grobs), and gtables (but not ggplots) are always rendered twice (even in R Notebooks). I imagine the code to fix this isn't in ggplot2, but I have no idea where that code is.

For context, this all comes out of trying to get (possibly huge) rasters to render in a reasonable amount of time in an interactive session for r-spatial/stars#21. This is the reprex I used to test this below:

library(ggplot2)
library(grid)

log_file <- "log.txt"
unlink(log_file)
makeContext.lazyGrob <- function(x) {
  size <- dev.size(units = "px")
  write(sprintf("Drawing %s at %sx%s", x$test, size[1], size[2]), log_file, append = TRUE)
  x
}

GeomPoint2 <- ggproto(
  "GeomPoint2", GeomPoint,
  draw_panel = function(self, data, panel_params, coord, na.rm = FALSE) {
    layer_grob <- ggproto_parent(GeomPoint, self)$draw_panel(data, panel_params, coord)
    gTree(test = "ggplot", children = gList(layer_grob), cl = "lazyGrob")
  }
)

geom_point2 <- function() {
  layer(geom = GeomPoint2, stat = "identity", position = "identity")
}

# log grid drawing
grid.newpage()
grid.draw(gTree(test = "grid", cl = "lazyGrob"))

# log gtable drawing
grid.newpage()
grid.draw(
  gtable::gtable_row(
    "test", 
    grobs = list(gTree(test = "gtable", cl = "lazyGrob")), 
    widths = unit(1, "npc")
  )
)

# log ggplot drawing
ggplot(mpg, aes(cty, hwy)) +
  geom_point2()

# view the log
cat(paste(readLines(log_file), collapse = "\n"))
#> Drawing grid at 504x360
#> Drawing gtable at 504x360
#> Drawing gtable at 504x360
#> Drawing ggplot at 504x360

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the supplied R reprex and inspecting the logged makeContext.lazyGrob calls from grid.draw, the ggplot display, and the Zoom action. Trace the rendering path through the RStudio graphics device, profvis, and grid entry points; done means the extra renders and differing sizes are explained and the calls match the expected behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
data-visualization, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.