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?
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.
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.
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.
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)
sizeit(p2, 2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With