Andy Bunn
2007-Jun-18 20:34 UTC
[R] Second y-axis in xyplot (lattice) where y1 and y2 have different ranges
Hi all,
I realize this is asking a lot of lattice, but I want to add a second y
axis inside a xyplot and have y1 and y2 have different ranges. Given dat
below, I can add a second y axis by overlaying a new plot with
par(new=T) and label axis 4 with standard graphics. I've seen an example
for doing something similar in xyplot even though Deepayan has indicated
that lattice isn't the right tool for the job.
However, is there a way to gracefully add a second y-axis to a xyplot
where y1 and y2 have different scales as in the example below? I've seen
the experimental tools to focus and modify lattice graphics but do not
know if these are applicable.
I have unreasonable faith that lattice can do anything. Since my
eventual goal is to make use of a grouping variable as with dat2 below,
lattice will be preferable to complex layouts. Thanks, Andy
dat <- data.frame(Year = 1751:2000,
Stuff = rnorm(250),
Samples = floor(seq(5,30,length.out=250)
+rnorm(250,5)),
Grp = rep('SiteOne',250))
par(mar=c(5,4,4,4) + 0.1)
plot(Stuff~Year, data=dat, type='l')
par(new=T)
plot(Samples~Year, data=dat, type="l", axes=F, bty="n",
xlab="", ylab="")
axis(4, at=pretty(range(dat$Samples)))
mtext("Number of Samples", 4, 3)
xyplot(Stuff + Samples ~ Year | Grp, data=dat,
layout = c(1, 1),
panel = panel.superpose.2,
ylab = "Stuff",
legend = list(right list(fun =
grid::textGrob("Samples", rot = 90))),
type = c('l', 'l'))
dat2 <- data.frame(Year = rep(1751:2000,2),
Stuff = rep(rnorm(250),2),
Samples = rep(floor(seq(5,30,length.out=250)+
rnorm(250,5)),2),
Grp = c(rep('SiteOne',250),
rep('SiteTwo',250)))
xyplot(Stuff + Samples ~ Year | Grp, data=dat2,
panel = panel.superpose.2,
ylab = "Stuff",
legend = list(right list(fun =
grid::textGrob("Samples", rot = 90))),
type = c('l', 'l'))
Deepayan Sarkar
2007-Jun-18 22:09 UTC
[R] Second y-axis in xyplot (lattice) where y1 and y2 have different ranges
On 6/18/07, Andy Bunn <Andy.Bunn at wwu.edu> wrote:> Hi all, > > I realize this is asking a lot of lattice, but I want to add a second y > axis inside a xyplot and have y1 and y2 have different ranges. Given dat > below, I can add a second y axis by overlaying a new plot with > par(new=T) and label axis 4 with standard graphics. I've seen an example > for doing something similar in xyplot even though Deepayan has indicated > that lattice isn't the right tool for the job. > > However, is there a way to gracefully add a second y-axis to a xyplot > where y1 and y2 have different scales as in the example below? I've seen > the experimental tools to focus and modify lattice graphics but do not > know if these are applicable.You could use those, but one drawback there is that you don't get the usual benefit of automatic allocation of space. Here is a ``better'' solution (as long as you realize that this is still a hack): [Note: this won't work if scales="free" or "sliced"] [...]> dat2 <- data.frame(Year = rep(1751:2000,2), > Stuff = rep(rnorm(250),2), > Samples = rep(floor(seq(5,30,length.out=250)+ > rnorm(250,5)),2), > Grp = c(rep('SiteOne',250), > rep('SiteTwo',250)))scale.pars <- function(x) { c(mx = min(x), dx = diff(range(x))) } rescale <- function(x, pars = scale.pars(x)) { (x - pars["mx"]) / pars["dx"] } pars.Stuff <- scale.pars(dat2$Stuff) pars.Samples <- scale.pars(dat2$Samples) rng.Stuff <- range(dat2$Stuff) rng.Samples <- range(dat2$Samples) my.yscale.components <- function(lim, ...) { ## template we will modify ans <- yscale.components.default(lim, ...) ## labels for Stuff in original scale Stuff <- yscale.components.default(rng.Stuff, ...) Stuff$left$ticks$at <- rescale(Stuff$left$ticks$at, pars.Stuff) Stuff$left$labels$at <- rescale(Stuff$left$labels$at, pars.Stuff) ## labels for Samples in original scale Samples <- yscale.components.default(rng.Samples, ...) Samples$left$ticks$at <- rescale(Samples$left$ticks$at, pars.Samples) Samples$left$labels$at <- rescale(Samples$left$labels$at, pars.Samples) ## modified 'components' ans$left <- Stuff$left ans$right <- Samples$left ans } xyplot(rescale(Stuff, pars.Stuff) + rescale(Samples, pars.Samples) ~ Year | Grp, data=dat2, panel = panel.superpose.2, ## newlay added: yscale.components = my.yscale.components, scales = list(alternating = 3), ylab = "Stuff", legend = list(right list(fun = grid::textGrob("Samples", rot = 90))), type = c('l', 'l')) -Deepayan
Maybe Matching Threads
- xyplot second y-xis and legend
- (Resolved) How to draw a line in plot when I know the start point(x1, y1) and end point(x2, y2)?
- How to draw a line in plot when I know the start point(x1, y1) and end point(x2, y2)?
- add trend line to each group of data in: xyplot(y1+y2 ~ x | grp...
- plot y1 and y2 on one graph