Re: [R] levelplot and unequal cell sizes
On 4/26/07, Deepayan Sarkar <[EMAIL PROTECTED]> wrote: > On 4/25/07, Waichler, Scott R <[EMAIL PROTECTED]> wrote: > > Hadley and Deepayan, > > > > Thank you for responding. Here is a simple example of what I'm talking > > about. It is a grid that is 5 cells wide by 2 cells tall. The width of > > the cells in the x-direction is variable; the cells at either end have > > width = 4 units, and the three cells in the middle have width = 2 units. > > My objective is to have the color contour boundaries fall on the cell > > boundaries instead of equidistant between cell nodes. In the plot, I > > want the cyan/blue and orange/gray boundaries to be located at the red > > cell boundary lines. Also, the colored regions should extend to the > > ends of the domain (x = 0, 14). > > > > > > library(lattice) > > > > x.node <- rep(c(2, 5, 7, 9, 12), 2) > > y.node <- c(rep(0.5, 5), rep(1.5, 5)) > > z <- rep(1:5, 2) > > contour.levels <- seq(0.5, 5.5, by=1) > > x.cell.boundary <- c(0, 4, 6, 8, 10, 14) > > contour.colors <- c("cyan", "blue", "green", "orange", "gray") > > > > print( > > levelplot(z ~ x.node * y.node, > > panel = function(z,...) { > > panel.levelplot(z,...) > > panel.abline(v = x.cell.boundary, col="red") > > }, > > xlim = range(x.cell.boundary), > > at=contour.levels, > > colorkey = list(space="top", width=1, height=0.9, > > at=1:5, > > col=contour.colors, > > labels=list(labels=z, at=z) > > ), > > col.regions=contour.colors, > > region = T, > > contour = F > > ) > > ) > > You are right, panel.levelplot is indeed assuming that the boundaries > are between consecutive midpoints. There is no built in way around > that; there simply isn't enough information available to the panel > function. > > The cleanest solution, in principle, is to write your own panel > function that ends up calling panel.polygon or grid.polygon. > panel.levelplot is a good starting point (the only tricky part is > getting the colors right, almost everything else you can get rid of). > Maybe Hadley will have a simpler solution. Sorry, it's taken me so long to get back to you on this, but I've been travelling and internet access has been spotty. You can do something very similar with ggtile, which already has the width and height arguments build in (but defaults to similar behaviour to lattice). If you don't mind, I'll include this example in the next version of ggplot so others can see how to use it. Hadley __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] levelplot and unequal cell sizes
> my.panel.levelplot <- > function (x, y, z, subscripts, at = pretty(z), > col.regions = regions$col, ..., > w, h) > { > regions <- trellis.par.get("regions") > numcol <- length(at) - 1 > numcol.r <- length(col.regions) > col.regions <- if (numcol.r <= numcol) > rep(col.regions, length = numcol) > else col.regions[floor(1+(1:numcol-1) * (numcol.r-1)/(numcol-1))] > zcol <- findInterval(z, at, rightmost.closed = TRUE) > x <- as.numeric(x[subscripts]) > y <- as.numeric(y[subscripts]) > z <- as.numeric(z[subscripts]) > w <- as.numeric(w[subscripts]) > h <- as.numeric(h[subscripts]) > zcol <- as.numeric(zcol[subscripts]) > print(data.frame(z, x.node, y.node, w.node, h.node, > col.regions[zcol])) > panel.rect(x = x, y = y, width = w, height = h, >col = col.regions[zcol], ...) } > Another note on this panel function to use with levelplot()---the cut() function may be better than findInterval() for applications where you want NA returned for values outside the supplied interval ranges. So intead of using zcol <- findInterval(z, at, rightmost.closed = TRUE) above, I use zcol <- as.integer(cut(z, at, labels=F)) Intervals here are closed on the right, open on the left (b1, bd]. So, for at = (1,2,3) and z = (1,1.01,3,3.01), then zcol = (NA,1,2,NA). I represent NA with "transparent" in the final color contour plot. Scott Waichler __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] levelplot and unequal cell sizes
> You are right, panel.levelplot is indeed assuming that the > boundaries are between consecutive midpoints. There is no > built in way around that; there simply isn't enough > information available to the panel function. > > The cleanest solution, in principle, is to write your own > panel function that ends up calling panel.polygon or grid.polygon. > panel.levelplot is a good starting point (the only tricky > part is getting the colors right, almost everything else you > can get rid of). > Maybe Hadley will have a simpler solution. > > Here's a possible implementation using a panel function: > > > my.panel.levelplot <- > function (x, y, z, subscripts, at = pretty(z), > col.regions = regions$col, ..., > w, h) > { > regions <- trellis.par.get("regions") > numcol <- length(at) - 1 > numcol.r <- length(col.regions) > col.regions <- if (numcol.r <= numcol) > rep(col.regions, length = numcol) > else col.regions[floor(1+(1:numcol-1) * (numcol.r-1)/(numcol-1))] > zcol <- findInterval(z, at, rightmost.closed = TRUE) > x <- as.numeric(x[subscripts]) > y <- as.numeric(y[subscripts]) > z <- as.numeric(z[subscripts]) > w <- as.numeric(w[subscripts]) > h <- as.numeric(h[subscripts]) > zcol <- as.numeric(zcol[subscripts]) > print(data.frame(z, x.node, y.node, w.node, h.node, > col.regions[zcol])) > panel.rect(x = x, y = y, width = w, height = h, >col = col.regions[zcol], ...) } Deepayan, thanks so much for this solution. It's great for my needs and will allow me to keep using my existing lattice "infrastructure." I never would have arrived at using findInterval() and panel.rect() on my own. Users might find my slight modification below for handling NA values useful. It also hides the cell borders: PANEL.LEVELPLOT1 <- function (x, y, z, subscripts, at = pretty(z), col.regions = regions$col, ..., w, h) { regions <- trellis.par.get("regions") numcol <- length(at) - 1 numcol.r <- length(col.regions) col.regions <- if (numcol.r <= numcol) rep(col.regions, length = numcol) else col.regions[floor(1+(1:numcol-1) * (numcol.r-1)/(numcol-1))] zcol <- findInterval(z, at, rightmost.closed = TRUE) x <- as.numeric(x[subscripts]) y <- as.numeric(y[subscripts]) z <- as.numeric(z[subscripts]) w <- as.numeric(w[subscripts]) h <- as.numeric(h[subscripts]) zcol <- as.numeric(zcol[subscripts]) these.colors <- ifelse(!is.na(zcol), col.regions[zcol], "transparent") # my addition :) #print(data.frame(z.vec, x.vec, y.vec, w.vec, h.vec, these.colors)) panel.rect(x = x, y = y, width = w, height = h, col = these.colors, border=NA,...) } # end PANEL.LEVELPLOT1() Regards, Scott Waichler __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] levelplot and unequal cell sizes
On 4/25/07, Waichler, Scott R <[EMAIL PROTECTED]> wrote: > Hadley and Deepayan, > > Thank you for responding. Here is a simple example of what I'm talking > about. It is a grid that is 5 cells wide by 2 cells tall. The width of > the cells in the x-direction is variable; the cells at either end have > width = 4 units, and the three cells in the middle have width = 2 units. > My objective is to have the color contour boundaries fall on the cell > boundaries instead of equidistant between cell nodes. In the plot, I > want the cyan/blue and orange/gray boundaries to be located at the red > cell boundary lines. Also, the colored regions should extend to the > ends of the domain (x = 0, 14). > > > library(lattice) > > x.node <- rep(c(2, 5, 7, 9, 12), 2) > y.node <- c(rep(0.5, 5), rep(1.5, 5)) > z <- rep(1:5, 2) > contour.levels <- seq(0.5, 5.5, by=1) > x.cell.boundary <- c(0, 4, 6, 8, 10, 14) > contour.colors <- c("cyan", "blue", "green", "orange", "gray") > > print( > levelplot(z ~ x.node * y.node, > panel = function(z,...) { > panel.levelplot(z,...) > panel.abline(v = x.cell.boundary, col="red") > }, > xlim = range(x.cell.boundary), > at=contour.levels, > colorkey = list(space="top", width=1, height=0.9, > at=1:5, > col=contour.colors, > labels=list(labels=z, at=z) > ), > col.regions=contour.colors, > region = T, > contour = F > ) > ) You are right, panel.levelplot is indeed assuming that the boundaries are between consecutive midpoints. There is no built in way around that; there simply isn't enough information available to the panel function. The cleanest solution, in principle, is to write your own panel function that ends up calling panel.polygon or grid.polygon. panel.levelplot is a good starting point (the only tricky part is getting the colors right, almost everything else you can get rid of). Maybe Hadley will have a simpler solution. Here's a possible implementation using a panel function: my.panel.levelplot <- function (x, y, z, subscripts, at = pretty(z), col.regions = regions$col, ..., w, h) { regions <- trellis.par.get("regions") numcol <- length(at) - 1 numcol.r <- length(col.regions) col.regions <- if (numcol.r <= numcol) rep(col.regions, length = numcol) else col.regions[floor(1+(1:numcol-1) * (numcol.r-1)/(numcol-1))] zcol <- findInterval(z, at, rightmost.closed = TRUE) x <- as.numeric(x[subscripts]) y <- as.numeric(y[subscripts]) z <- as.numeric(z[subscripts]) w <- as.numeric(w[subscripts]) h <- as.numeric(h[subscripts]) zcol <- as.numeric(zcol[subscripts]) print(data.frame(z, x.node, y.node, w.node, h.node, col.regions[zcol])) panel.rect(x = x, y = y, width = w, height = h, col = col.regions[zcol], ...) } x.node <- rep(c(2, 5, 7, 9, 12), 2) y.node <- c(rep(0.5, 5), rep(1.5, 5)) z <- rep(1:5, 2) contour.levels <- seq(0.5, 5.5, by=1) x.cell.boundary <- c(0, 4, 6, 8, 10, 14) contour.colors <- c("cyan", "blue", "green", "orange", "gray") w.node <- rep(diff(x.cell.boundary), 2) h.node <- rep(1, 10) levelplot(z ~ x.node * y.node, h = h.node, w = w.node, panel = function(...) { my.panel.levelplot(...) panel.abline(v = x.cell.boundary, col="red") }, xlim = range(x.cell.boundary), at=contour.levels, colorkey = list(space="top", width=1, height=0.9, at=contour.levels, col=contour.colors, labels=list(labels=z, at=z)), col.regions=contour.colors) -Deepayan __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] levelplot and unequal cell sizes
Hadley and Deepayan, Thank you for responding. Here is a simple example of what I'm talking about. It is a grid that is 5 cells wide by 2 cells tall. The width of the cells in the x-direction is variable; the cells at either end have width = 4 units, and the three cells in the middle have width = 2 units. My objective is to have the color contour boundaries fall on the cell boundaries instead of equidistant between cell nodes. In the plot, I want the cyan/blue and orange/gray boundaries to be located at the red cell boundary lines. Also, the colored regions should extend to the ends of the domain (x = 0, 14). library(lattice) x.node <- rep(c(2, 5, 7, 9, 12), 2) y.node <- c(rep(0.5, 5), rep(1.5, 5)) z <- rep(1:5, 2) contour.levels <- seq(0.5, 5.5, by=1) x.cell.boundary <- c(0, 4, 6, 8, 10, 14) contour.colors <- c("cyan", "blue", "green", "orange", "gray") print( levelplot(z ~ x.node * y.node, panel = function(z,...) { panel.levelplot(z,...) panel.abline(v = x.cell.boundary, col="red") }, xlim = range(x.cell.boundary), at=contour.levels, colorkey = list(space="top", width=1, height=0.9, at=1:5, col=contour.colors, labels=list(labels=z, at=z) ), col.regions=contour.colors, region = T, contour = F ) ) Any help you can offer is appreciated. Thanks, Scott Waichler Pacific Northwest National Laboratory scott.waichler _at_ pnl.gov http://hydrology.pnl.gov __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] levelplot and unequal cell sizes
On 4/25/07, Waichler, Scott R <[EMAIL PROTECTED]> wrote: > I am using levelplot() from lattice with grids that have unequal cell > sizes. This means that the boundary between two cells is not always > half-way between nodes, as levelplot() assumes. levelplot() is not supposed to make any such assumptions. Can you provide a reproducible example please? -Deepayan > The result is that some > cell sizes are rendered incorrectly, which can be painfully obvious if > using relatively large cells. Is there any work-around? I am using the > conditioning capability of lattice and therefore image() would not be a > good way to go. > > Thanks, > Scott Waichler > Pacific Northwest National Laboratory > scott.waichler _at_ pnl.gov __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] levelplot and unequal cell sizes
On 4/25/07, Waichler, Scott R <[EMAIL PROTECTED]> wrote: > I am using levelplot() from lattice with grids that have unequal cell > sizes. This means that the boundary between two cells is not always > half-way between nodes, as levelplot() assumes. The result is that some > cell sizes are rendered incorrectly, which can be painfully obvious if > using relatively large cells. Is there any work-around? I am using the > conditioning capability of lattice and therefore image() would not be a > good way to go. You might be able to use the tile plot in ggplot, which allows you to specify the size of each tile (it assumes they're all the same size by default). Have a look at ?ggtile, or if you provide more info about your data, I could provide a worked example. Regards, Hadley __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
[R] levelplot and unequal cell sizes
I am using levelplot() from lattice with grids that have unequal cell sizes. This means that the boundary between two cells is not always half-way between nodes, as levelplot() assumes. The result is that some cell sizes are rendered incorrectly, which can be painfully obvious if using relatively large cells. Is there any work-around? I am using the conditioning capability of lattice and therefore image() would not be a good way to go. Thanks, Scott Waichler Pacific Northwest National Laboratory scott.waichler _at_ pnl.gov __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.