creating multiple scatter plots with same axes in R
graphics, plot, r, rpy2
Solution
ggplot2 might be have the highest pretty / easy ratio if beginning.
Example with rpy2:
from rpy2.robjects.lib import ggplot2
from rpy2.robjects import r, Formula
iris = r('iris')
p = ggplot2.ggplot(iris) + \
ggplot2.geom_point(ggplot2.aes_string(x="Sepal.Length", y="Sepal.Width")) + \
ggplot2.facet_wrap(Formula('~ Species'), ncol=2, nrow = 2) + \
ggplot2.GBaseObject(r('ggplot2::coord_fixed')()) # aspect ratio
# coord_fixed() missing from the interface,
# therefore the hack. This should be fixed in rpy2-2.3.3
p.plot()
Reading the comments to a previous answer I see that you might mean completely separate plots. With the default plotting system for R, `par(mfrow(c(2,2))` or `par(mfcol(c(2,2)))` would the easiest way to go, and keep aspect ratio, ranges for the axes, and tickmarks consistent through the usual way those are fixed.
The most flexible system to plot in R might be `grid`. It is not as bad as it seems, think of is as a scene graph. With rpy2, ggplot2, and grid:
from rpy2.robjects.vectors import FloatVector
from rpy2.robjects.lib import grid
grid.newpage()
lt = grid.layout(2,2) # 2x2 layout
vp = grid.viewport(layout = lt)
vp.push()
# limits for axes and tickmarks have to be known or computed beforehand
xlims = FloatVector((4, 9))
xbreaks = FloatVector((4,6,8))
ylims = FloatVector((-3, 3))
ybreaks = FloatVector((-2, 0, 2))
# first panel
vp_p = grid.viewport(**{'layout.pos.col':1, 'layout.pos.row': 1})
p = ggplot2.ggplot(iris) + \
ggplot2.geom_point(ggplot2.aes_string(x="Sepal.Length",
y="rnorm(nrow(iris))")) + \
ggplot2.GBaseObject(r('ggplot2::coord_fixed')()) + \
ggplot2.scale_x_continuous(limits = xlims, breaks = xbreaks) + \
ggplot2.scale_y_continuous(limits = ylims, breaks = ybreaks)
p.plot(vp = vp_p)
# third panel
vp_p = grid.viewport(**{'layout.pos.col':2, 'layout.pos.row': 2})
p = ggplot2.ggplot(iris) + \
ggplot2.geom_point(ggplot2.aes_string(x="Sepal.Length",
y="rnorm(nrow(iris))")) + \
ggplot2.GBaseObject(r('ggplot2::coord_fixed')()) + \
ggplot2.scale_x_continuous(limits = xlims, breaks = xbreaks) + \
ggplot2.scale_y_continuous(limits = ylims, breaks = ybreaks)
p.plot(vp = vp_p)
More documentation in the rpy2 documentation about graphics, and after in the ggplot2 and grid documentations.
Problem
I'm trying to plot four scatter plots in 2 x 2 arrangement in R (I'm actually plotting via rpy2). I'd like each to have an aspect ratio of 1 but also be on the same scale, so identical X and Y ticks for all the subplots so that they can be compared. I tried to do this with `par`: ``` par(mfrow=c(2,2)) # scatter 1 plot(x, y, "p", asp=1) # scatter 2 plot(a, b, "p", asp=1) # ... ``` Edit: Here's a direct example of what I have now: ``` > par(mfrow=c(2,2)) > for (n in 1:4) { plot(iris$Petal.Width, rnorm(length(iris$Petal.Width)), "p", asp=1) } ``` which creates the right type of scatter but with different scales. Setting `ylim` and `xlim` to be the same in each call to `plot` above does not fix the problem. You still get very different tick marks and tick numbers on each axis, which makes the scatter unnecessarily difficult to interpret. I want the X and Y axes to be identical. For example, this: ` for (n in 1:4) { plot(iris$Petal.Width, rnorm(length(iris$Petal.Width)), "p", asp=1, xlim=c(-4, 6), ylim=c(-2, 4)) } ` Generates the wrong result: What's the best way to ensure that the same axes are used in all subplots? All I was looking for is a parameter like `axis=same` or something like that to `par(mfrow=...)`, which sounds like the default behavior for `lattice`, to make the axes shared and identical in every subplot. lgautier gave nice code with ggplot, but it requires the axes to be known in advance. I want to clarify that I wanted to avoid iterating through the data in each subplot and computing myself the correct ticks to be plotted. If that has to be known in advance, then the ggplot solution is much more complex than just plotting with `plot` and explicitly agstudy gave a solution with lattice. This looks closest to what I what I want in that you don't have to explicitly precompute the tick positions for each scatter, but as a new user I'm unable to figure out how to make lattice look like an ordinary plot. The closest I've gotten is this: ``` > xyplot(y~x|group, data =dat, type='p', between =list(y=2,x=2), layout=c(2,2), aspect=1, scales =list(y = list(relation='same'), alternating=FALSE)) ``` which yields: How can I make this look like the R base? I don't want these `group` subtitles on the top of each subplot, or ticks hanging unlabeled on the top and right hand side of each scatter, I just want each x and y of the scatter to be labeled. I'm also not looking for a shared label for the X and Y -- each subplot gets its own X and Y labels. And the axis labels have to be the same in each scatter although with the data chosen here it doesn't make sense. Unless there's an easy way to make trellis look like the R base, it sounds like the answer is that there's no way to do what I'm trying to do in R (surprisingly), without precomputing the exact places of each tick in each subplot, which requires iterating through the data in advance.