Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserving aspect ratio in R's grid graphics

Tags:

plot

r

r-grid

To draw a "crossed" rectangle of height 2 times larger than its width using the low-level graphics package facilities I call:

xlim <- c(0, 500)
ylim <- c(0, 1000)
plot.new()
plot.window(xlim, ylim, asp=1)
rect(xlim[1], ylim[1], xlim[2], ylim[2])
lines(c(xlim[1], xlim[2]), c(ylim[1], ylim[2]))
lines(c(xlim[1], xlim[2]), c(ylim[2], ylim[1]))

The figure has a nice feature: the aspect ratio is preserved so that if I change the size of the plot window, I get the same height-to-width proportions.

How can I obtain an equivalent result with grid graphics?

like image 943
cenka Avatar asked May 01 '14 08:05

cenka


2 Answers

You should create a viewport that uses Square Normalised Parent Coordinates, see ?unit:

"snpc": (...) This is useful for making things which are a proportion of the viewport, but have to be square (or have a fixed aspect ratio).

Here is the code:

library('grid')
xlim <- c(0, 500)
ylim <- c(0, 1000)
grid.newpage() # like plot.new()
pushViewport(viewport( # like plot.window()
        x=0.5, y=0.5, # a centered viewport
        width=unit(min(1,diff(xlim)/diff(ylim)), "snpc"), # aspect ratio preserved
        height=unit(min(1,diff(ylim)/diff(xlim)), "snpc"),
        xscale=xlim, # cf. xlim
        yscale=ylim  # cf. ylim
))
# some drawings:
grid.rect(xlim[1], ylim[1], xlim[2], ylim[2], just=c(0, 0), default.units="native")
grid.lines(xlim, ylim, default.units="native")
grid.lines(xlim, rev(ylim), default.units="native")

The default.units argument in e.g. grid.rect forces the plotting functions to use the native (xscale/yscale) viewport coordinates. just=c(0, 0) indicates that xlim[1], ylim[1] denote the bottom-left node of the rectangle.

like image 123
gagolews Avatar answered Sep 29 '22 12:09

gagolews


In ggplot2 (which is grid based) you can fix the aspect ratio using coord_fixed():

library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + coord_fixed(ratio = 0.5)

This will fix the ratio, and the ratio will be constant even when changing the size of the graphics window.

I'm not sure if this is helpful, as you asked for a low-level grid based solution. But I thought it might be useful none the less.

like image 40
Paul Hiemstra Avatar answered Sep 29 '22 11:09

Paul Hiemstra