Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save plot with a given aspect ratio

Tags:

I'm working with the really awesome library ggplot2. I figured out how to set the aspect ratio of a plot by using coord_fixed. Now, I'd like to save the plot to a PDF with a specified width (e.g 10 cm) and let required height get calculated. I did not figure out how to achieve this. Is this even possible?

like image 763
marsl Avatar asked May 07 '13 15:05

marsl


People also ask

How do you set aspect ratio on a plot?

The plot box aspect ratio is the relative lengths of the x-axis, y-axis, and z-axis. By default, the plot box aspect ratio is based on the size of the figure. You can change the aspect ratio using the pbaspect function. Set the ratio as a three-element vector of positive values that represent the relative axis lengths.

How do you save an AR plot?

Plots panel –> Export –> Save as Image or Save as PDF Specify files to save your image using a function such as jpeg(), png(), svg() or pdf(). Additional argument indicating the width and the height of the image can be also used. Create the plot.

What is the aspect ratio of a graph?

The aspect ratio of a data graph is defined as the height-to-width ratio of the graph's size. Most software determine the default aspect ratio using your monitor's display size, which could be anywhere close to 4:3, 5:4, 16:10 or 16:9.


1 Answers

You can use grid functions to calculate the full size of the ggplot grob, but there are (edit: at least) two caveats:

  • an extra device window will open, to do the unit conversion

  • the plot panel size will be 0 by default, as it is meant to be calculated on-the-fly according to the device (viewport) it lives in, not the opposite.

That being said, the following function attempts to open a device that fits the ggplot exactly,

library(ggplot2) library(grid)  sizeit <- function(p, panel.size = 2, default.ar=1){    gb <- ggplot_build(p)   # first check if theme sets an aspect ratio   ar <- gb$plot$coordinates$ratio    # second possibility: aspect ratio is set by the coordinates, which results in    # the use of 'null' units for the gtable layout. let's find out   g <- ggplot_gtable(gb)   nullw <- sapply(g$widths, attr, "unit")   nullh <- sapply(g$heights, attr, "unit")    # ugly hack to extract the aspect ratio from these weird units   if(any(nullw == "null"))     ar <- unlist(g$widths[nullw == "null"]) / unlist(g$heights[nullh == "null"])    if(is.null(ar)) # if the aspect ratio wasn't specified by the plot        ar <- default.ar    # ensure that panel.size is always the larger dimension   if(ar <= 1 ) panel.size <- panel.size / ar    g$fullwidth <- convertWidth(sum(g$widths), "in", valueOnly=TRUE) +      panel.size   g$fullheight <- convertHeight(sum(g$heights), "in", valueOnly=TRUE) +      panel.size / ar    class(g) <- c("sizedgrob", class(g))   g }   print.sizedgrob <- function(x){   # note: dev.new doesn't seem to respect those parameters   # when called from Rstudio; in this case it    # may be replaced by x11 or quartz or ...   dev.new(width=x$fullwidth, height=x$fullheight)   grid.draw(x) }   p1 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + coord_fixed() +   theme(plot.background = element_rect(colour = "red"))  p2 <- p1 + aes(x = mpg, y = wt)  # need for an explicit dummy device open, otherwise it's a bit off # for no apparent reason that I can understand dev.new()   sizeit(p1, 0.1) 

enter image description here

sizeit(p2, 2) 

enter image description here

like image 194
baptiste Avatar answered Jan 18 '23 10:01

baptiste