GithubHelp home page GithubHelp logo

Unexpected blank page in pdf about cowplot HOT 7 CLOSED

wilkelab avatar wilkelab commented on July 30, 2024
Unexpected blank page in pdf

from cowplot.

Comments (7)

JSanzR avatar JSanzR commented on July 30, 2024 17

Doing:
pdf("test.pdf", onefile=FALSE)
seems to get rid of the blank page. See: http://stackoverflow.com/questions/12481267/in-r-how-to-prevent-blank-page-in-pdf-when-using-gridbase-to-embed-subplot-insi)

from cowplot.

clauswilke avatar clauswilke commented on July 30, 2024

Yes, this happens. I'm not sure why. However, fundamentally pdf() is not the supported mechanism to save ggplot2 figures. The supported mechanism is ggsave(). (I'm pretty certain that ultimately, this is a ggplot2 bug, not a cowplot bug.)

from cowplot.

jscamac avatar jscamac commented on July 30, 2024

I don't think this a ggplot bug.

Problematic cowplot example giving a blank page:

library(couplet)
library(ggplot2)
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(~class)
pdf('test.pdf',width=6.69, height=6.69)
plot_grid(p, p, labels=letters[1:2], ncol = 1, label_size = 11, hjust = -1.5)
dev.off()

However, if I replace plot_grid with grid.arrange I don't have the problem,

library(gridExtra)
p <- ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  facet_wrap(~class)
pdf('test.pdf',width=6.69, height=6.69)
grid.arrange(p, p, ncol = 1)
dev.off()

from cowplot.

clauswilke avatar clauswilke commented on July 30, 2024

It is a ggplot2 bug.

This code produces one page of output:

library(ggplot2) # load only ggplot2, not cowplot
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(~class)
pdf('test.pdf',width=6.69, height=6.69)
p
dev.off()

But this produces two:

pdf('test.pdf',width=6.69, height=6.69)
g <- ggplot2::ggplotGrob(p)
p
dev.off()

So calling the function ggplot2::ggplotGrob has the side-effect of creating an extra page in the pdf device, even if the result of that call is assigned to a new object. Cowplot calls ggplot2::ggplotGrob to create the grobs it works with.

from cowplot.

marcus1487 avatar marcus1487 commented on July 30, 2024

I have been struggling with this issue myself within my own hacky version of cowplot for while and have not been satisfied with work arounds I have found. I have usually used the pdf(NULL) solution when calling ggplotGrob in my own scripts. From what I can tell in discussions about this issue within ggplot2 forums it has to do with the definition of line and other plotting values do not have a meaning until a device is opened, so the default device is opened when ggplotGrob is called. I therefore have two comments on this matter.

First, I think that the current correct workaround to use cowplot should be the following:

p <- ggplot(mpg, aes(displ, hwy)) + geom_point() + facet_wrap(~class)
p <- ggplotGrob(p)
ggsave(p, 'test.pdf')
## or
pdf('test.pdf')
p
dev.off()

Also this is not a pdf versus ggsave issue as both of the following produce 2 plots.

p <- ggplot(mpg, aes(displ, hwy)) + geom_point() + facet_wrap(~class)
ggsave('test.pdf', p)
## and 
pdf('test.pdf')
p
dev.off()

Instead it is an issue with any device that can save multiple plots to a single file (e.g. PDF).

Second, even though ggplot needs an open device when a call to ggplotGrob is made, I don't believe anything within cowplot depends on the device opened when ggplotGrob is called. Thus I believe this bug (whether it is in gggplot2 or not) could be resolved in cowplot by wrapping the only ggplotGrob call in cowplot with a null device call. This may be bad form to open a NULL device, but seems like the only solutions as @hadley indicates that there is no plan to fix this issue as noted in tidyverse/ggplot2#809 . I have opened a fork to resolve this issue (https://github.com/marcus1487/cowplot/tree/blankpage) and am happy to open a pull request for this issue unless this will not be integrated as it is seen as bad form to use a NULL device.

from cowplot.

clauswilke avatar clauswilke commented on July 30, 2024

Yes, please set up a pull request. Two requests from my side:

  1. Comment the code, so it is clear why these lines are added.
  2. Verify that this is the only place where we call ggplot2::ggplotGrob().

Thanks!

from cowplot.

marcus1487 avatar marcus1487 commented on July 30, 2024

I have opened the pull request (with comment). The only ggplotGrob call in the R directory scripts is wrapped in a NULL device call within the draw.R script in the pull request. There are many ggplotGrob calls in the vignettes and docs, but I don't think these need to be fixed with this pull request.

P.S. Thanks for saving me from porting all of my hacky code now that cowplot is here! Great work!

from cowplot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.