I would like superimpose two scatter plots in R so that each set of points has its own (different) y-axis (i.e., in positions 2 and 4 on the figure) but the points appear superimposed on the same figure.
Is it possible to do this with plot
?
Edit Example code showing the problem
# example code for SO question
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)
x <- 1:10
# in this plot y2 is plotted on what is clearly an inappropriate scale
plot(y1 ~ x, ylim = c(-1, 150))
points(y2 ~ x, pch = 2)
As its name suggests, twoord.plot()
in the plotrix package plots with two ordinate axes.
library(plotrix)
example(twoord.plot)
One option is to make two plots side by side. ggplot2
provides a nice option for this with facet_wrap()
:
dat <- data.frame(x = c(rnorm(100), rnorm(100, 10, 2))
, y = c(rnorm(100), rlnorm(100, 9, 2))
, index = rep(1:2, each = 100)
)
require(ggplot2)
ggplot(dat, aes(x,y)) +
geom_point() +
facet_wrap(~ index, scales = "free_y")
If you can give up the scales/axis labels, you can rescale the data to (0, 1) interval. This works for example for different 'wiggle' trakcs on chromosomes, when you're generally interested in local correlations between the tracks and they have different scales (coverage in thousands, Fst 0-1).
# rescale numeric vector into (0, 1) interval
# clip everything outside the range
rescale <- function(vec, lims=range(vec), clip=c(0, 1)) {
# find the coeficients of transforming linear equation
# that maps the lims range to (0, 1)
slope <- (1 - 0) / (lims[2] - lims[1])
intercept <- - slope * lims[1]
xformed <- slope * vec + intercept
# do the clipping
xformed[xformed < 0] <- clip[1]
xformed[xformed > 1] <- clip[2]
xformed
}
Then, having a data frame with chrom
, position
, coverage
and fst
columns, you can do something like:
ggplot(d, aes(position)) +
geom_line(aes(y = rescale(fst))) +
geom_line(aes(y = rescale(coverage))) +
facet_wrap(~chrom)
The advantage of this is that you're not limited to two trakcs.
I too suggests, twoord.stackplot()
in the plotrix
package plots with more of two ordinate axes.
data<-read.table(text=
"e0AL fxAL e0CO fxCO e0BR fxBR anos
51.8 5.9 50.6 6.8 51.0 6.2 1955
54.7 5.9 55.2 6.8 53.5 6.2 1960
57.1 6.0 57.9 6.8 55.9 6.2 1965
59.1 5.6 60.1 6.2 57.9 5.4 1970
61.2 5.1 61.8 5.0 59.8 4.7 1975
63.4 4.5 64.0 4.3 61.8 4.3 1980
65.4 3.9 66.9 3.7 63.5 3.8 1985
67.3 3.4 68.0 3.2 65.5 3.1 1990
69.1 3.0 68.7 3.0 67.5 2.6 1995
70.9 2.8 70.3 2.8 69.5 2.5 2000
72.4 2.5 71.7 2.6 71.1 2.3 2005
73.3 2.3 72.9 2.5 72.1 1.9 2010
74.3 2.2 73.8 2.4 73.2 1.8 2015
75.2 2.0 74.6 2.3 74.2 1.7 2020
76.0 2.0 75.4 2.2 75.2 1.6 2025
76.8 1.9 76.2 2.1 76.1 1.6 2030
77.6 1.9 76.9 2.1 77.1 1.6 2035
78.4 1.9 77.6 2.0 77.9 1.7 2040
79.1 1.8 78.3 1.9 78.7 1.7 2045
79.8 1.8 79.0 1.9 79.5 1.7 2050
80.5 1.8 79.7 1.9 80.3 1.7 2055
81.1 1.8 80.3 1.8 80.9 1.8 2060
81.7 1.8 80.9 1.8 81.6 1.8 2065
82.3 1.8 81.4 1.8 82.2 1.8 2070
82.8 1.8 82.0 1.7 82.8 1.8 2075
83.3 1.8 82.5 1.7 83.4 1.9 2080
83.8 1.8 83.0 1.7 83.9 1.9 2085
84.3 1.9 83.5 1.8 84.4 1.9 2090
84.7 1.9 83.9 1.8 84.9 1.9 2095
85.1 1.9 84.3 1.8 85.4 1.9 2100", header=T)
require(plotrix)
twoord.stackplot(lx=data$anos, rx=data$anos,
ldata=cbind(data$e0AL, data$e0BR, data$e0CO),
rdata=cbind(data$fxAL, data$fxBR, data$fxCO),
lcol=c("black","red", "blue"),
rcol=c("black","red", "blue"),
ltype=c("l","o","b"),
rtype=c("l","o","b"),
lylab="Años de Vida", rylab="Hijos x Mujer",
xlab="Tiempo",
main="Mortalidad/Fecundidad:1950–2100",
border="grey80")
legend("bottomright", c(paste("Proy:",
c("A. Latina", "Brasil", "Colombia"))), cex=1,
col=c("black","red", "blue"), lwd=2, bty="n",
lty=c(1,1,2), pch=c(NA,1,1) )
Another alternative which is similar to the accepted answer by @BenBolker is redefining the coordinates of the existing plot when adding a second set of points.
Here is a minimal example.
Data:
x <- 1:10
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)
Plot:
par(mar=c(5,5,5,5)+0.1, las=1)
plot.new()
plot.window(xlim=range(x), ylim=range(y1))
points(x, y1, col="red", pch=19)
axis(1)
axis(2, col.axis="red")
box()
plot.window(xlim=range(x), ylim=range(y2))
points(x, y2, col="limegreen", pch=19)
axis(4, col.axis="limegreen")
Source: Stackoverflow.com