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
Apparently Analagous 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