Faheem Mitha
Faheem Mitha

Reputation: 6326

Why does this R ggplot2 code bring up a blank display device?

While SO is not usually used for help with bugs, this one shows particularly simple and particularly annoying behavior. If you are a ggplot2 user, you can reproduce it in 10 seconds or less.

As this GitHub issue: ggplot_gtable creates blank display says, the following code

library(ggplot2)
stat = qplot(Sepal.Length, Petal.Length, data = iris, color = Species)
ggplot_gtable(ggplot_build(stat))

will produce a blank device. Note that since ggplot2 is a graphics library, some commands can bring up a graphics device to show the relevant plot. Specifically, just running ggplot_build(stat) will bring up a plot. But that doesn't explain this behaviour.

I'm not sure how to debug this (print statements don't really seem appropriate or useful), and the ggplot2 development community seems to be on vacation or something, so if any experienced R user can offer suggestions on how to debug this effectively, I would appreciate it. This is a trivial but incredibly annoying bug. Every time I run code which looks like the snippet, it brings up a blank device which the display switches focus to, and so I have to click it away before I can continue.

It is possible that I'm doing something horribly wrong and am the only person who can reproduce this bug. It is also possible, for some reason I can't imagine, that this is normal behavior. If you think either of these things are true, please let me know.

I'm using ggplot2 0.9.3.1 (latest release) on Debian squeeze.

Upvotes: 3

Views: 3947

Answers (4)

HPF
HPF

Reputation: 195

I am still having this issue with R 3.6.1 in 2019.

My lack of reputation doesn't allow me to comment. So I am writing yet another answer:

Things become a bit tricky if your plot uses non-standard fonts, say

library (ggplot2)
stat = qplot(Sepal.Length, Petal.Length, data = iris, color = Species) + 
  theme(text = element_text (family="DejaVu Sans"))

As was explained in the answer by baptiste, the output device is needed in order to determine some text dimensions. With the non-standard font, however, you need the appropriate output device. If you just use a pdf(file=NULL) as baptiste said, you get the dimensions wrong (and a warning that 'DejaVu Sans' was substituted by another font which is responsible for the false dimensions). In order to resolve this, I had to open an output device that is able to render the non-standard font (with a temporary file, say):

cairo_pdf (tempfile (fileext=".pdf"))
grob = ggplot_gtable (ggplot_build (stat))
dummy = dev.off ()

Hope this information is useful.

Upvotes: 0

user2640757
user2640757

Reputation: 1

Problem seems to be caused by "color = Species". If replaced by "group = Species", then no more blank display device.

Upvotes: -1

IRTFM
IRTFM

Reputation: 263382

I wonder if it is related to this thread from 3 years ago on R-Help with this workaround from @G.Grothendieck (copied material follows)

https://stat.ethz.ch/pipermail/r-help/2010-December/263754.html

library(lattice)
library(zoo)

df <- data.frame(y = matrix(rnorm(24), nrow = 6), x = 1:6)
xyplot(zoo(df[1:4], df$x), type = "p")

plot.object <- xyplot(zoo(df[1:4], df$x), type = "p") 
# problem: a Quartz device is opened (on Mac OS X 10.6)

Grothendieck wrote in response:

This also opens up a window on Windows. It occurs within lattice when lattice issues a trellis.par.get . A workaround would be to open a device directed to null. On Windows this would work. I assume if you use "/dev/null" it would work on your machine.

png("NUL")
plot.object <- ...
dev.off()

Upvotes: 2

baptiste
baptiste

Reputation: 77106

Some grid grobs have units that can only be resolved at drawing time, that is to say once a device window is open. This is the case of text grobs, for instance, as their size can depend (in the most general case) of the cex and fontsize arguments of the parent(s) viewports (which can be nested, etc.)

library(grid)
widthDetails(textGrob("hi"))

The current version of ggplot2 appears to use widthDetails in the code to build the legend grobs (guides_build function). It is conceivable that this could be replaced by grobWidth, unless the grob size is too convoluted.

Upvotes: 5

Related Questions