Perplexed by the behavior of xlim / ylim in R

R-3.1.1, Win7x64

Hi, I have data where two variables are measured, so that X runs from 0 to 70, and Y runs from 0 to 100. I want to make a simple graph of the scattering of observations. The scatter plot must be dimensional, so the x axis (from 0 to 70) is .7 the size of the y axis (which starts from 0 to 100).

I am using the following code

plot.new() plot(0, 0, asp = 1, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n") 

I am surprised to see that this gives the graph as follows: enter image description here

Two things are not as I expected: 1) the x axis and y axis are NOT limited by their xlim and ylim values. (Why is this?) And 2) the figure is almost square.

I can manually resize the shape by manually resizing the R window or Rstudio window before using the code, but this is not possible because I have so many numbers to draw, many of which have different sizes xlim and ylim, and these numbers need to be inserted to pre-formatted reports later (which is why they need to fulfill these exact layout requirements). I also tried using

 dev.new(width = 7, height = 10) 

but that didn't help either.

My question is: 1) how can I β€œforce” a figure to limit itself to the exact xlim and ylim ranges passed to the function? and 2) how to create a figure with exact relative dimensions (the x axis is 7 times wider than the length of the y axis)

+5
source share
2 answers

A discussion of asp in plot.window help implies that asp override xlim and ylim (if you look at plot help, it will direct you to plot.window to learn more about asp ):

If asp is the final positive value, then the window is adjusted so that one data block in the x direction is equal to the length up to asp * of one information unit in the y direction.

Note that in this case par("usr") no longer defined, for example par("xaxs") , but rather on asp and the aspect ratio of the device. (See what happens if you interactively resize the graphics device after running the example below!)

The special case asp == 1 creates graphs on which the distances between points are displayed exactly on the screen. Values ​​with asp > 1 can be used to get more accurate maps when using latitude and longitude.

As @ mr.joshuagordon noted, you can use the pdf function (or png or jpeg if you want to output bitmap output), and play with the dimensions to get the desired image format while removing asp from plot so that you can set the xlim and ylim .

Another option is to switch to ggplot2 , which will simplify the adjustment of the axial limits and aspect ratio separately:

 library(ggplot2) # Some fake data dat = data.frame(x=c(2,30,50), y=c(10, 60, 90)) # 1 y-unit = 1 x-unit, so the plot area is not square ggplot(dat, aes(x,y)) + geom_point() + scale_x_continuous(limits=c(0,70)) + scale_y_continuous(limits=c(0,100)) + coord_fixed(ratio=1) # 1 y-unit = 0.7 * 1 x-unit, so the plot is square, but the physical distance # of each x-unit and y-unit are no longer the same ggplot(dat, aes(x,y)) + geom_point() + scale_x_continuous(limits=c(0,70)) + scale_y_continuous(limits=c(0,100)) + coord_fixed(ratio=70/100) 

UPDATE: Here's how to control xlim , ylim and aspect ratio independently in the base graph: instead of asp use the pin graphical parameter to set the physical dimensions of the parcel section. This setting does not affect the nominal values ​​of xlim and ylim , but will change the physical measurement distance of 1 x-unit and 1 y-unit. Here are some examples:

Example 1: We will create two panels on one PDF page, each with a different aspect ratio:

 # Create a 12" x 6" pdf graphics device pdf("test.pdf", width=12, height=6) # Divide graphics device into two regions, each of which will contain a plot par(mfrow=c(1,2)) # Left Panel: 5" x 5" plot area (plot region is square, so 1 y-unit = # 0.7 * 1 x-unit in terms of physical distance in the plot region) par(pin=c(5,5)) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n",main='par(pin=c(5,5)') # Right Panel: 0.7*5" x 5" plot area (so 1 x-unit = 1 y-unit # in terms of physical distance in the plot region) par(pin=c(0.7*5,5)) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n",main='par(pin=c(5,0.7*5)') dev.off() 

Example 2. Show that you receive an error message if you set the pin larger than the size of the graphics device. We will use the default device ( RStudioGD in my case).

 par(pin=c(10, 10)) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n",main='par(pin=c(5,4)') # Get dimensions of the default plot device par("din") # Create a plot that takes up an area just a bit smaller than the device size par(pin=par("din")-0.2) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n",main='par(pin=c(5,4)') # Create a plot that takes up an area just a bit larger than the device size # (we'll get an error this time) par(pin=par("din") + 0.01) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n") > Error in plot.new() : plot region too large 

Example 3: the same error occurs if you exceed the size of your pdf device (or png , etc.):

 # Create a 5" x 5" pdf graphics device pdf("test.pdf", 5,5) # Create a plot that takes up a little bit less than the device size par(pin=c(5,5)-0.2) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n") dev.off() # Create a plot that takes up a little bit more than the device size pdf("test.pdf", 5,5) par(pin=c(5,5)+0.01) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), xlab = "", ylab = "", type = "n") # Gives the following error: Error in plot.new() : plot region too large dev.off() 
+5
source

You can save the chart as pdf and specify its dimensions as follows:

 pdf("SampleGraph.pdf",width=7,height=10) plot(0, 0, xlim = c(0, 70), ylim = c(0, 100), asp=NA, xlab = "", ylab = "", type = "n") # change asp to NA dev.off() # turn off plotting 
+5
source

Source: https://habr.com/ru/post/1201471/


All Articles