R: display values in levelplot stratified by a gro

2019-05-23 13:57发布

问题:

In this following example, I need to display the values for each of the cells in each of the panels stratified by the grouping variable class:

library("lattice")
x <- seq(pi/4, 5*pi, length.out=5)
y <- seq(pi/4, 5*pi, length.out=5)
r1 <- as.vector(sqrt(outer(x^2, y^2, "+")))
r2 <- as.vector(sqrt(outer(x^2, y^2, "/")))

grid1 <- grid2 <- expand.grid(x=x, y=y)
grid1$z <- cos(r1^2)*exp(-r1/(pi^3))
grid2$z <- cos(r2^2)*exp(-r2/(pi^3))
grid <- rbind(grid1, grid2)
grid$class <- c(rep("addition",length(x)^2), rep("division", length(x)^2))

p <- levelplot(z~x*y | factor(class), grid, 
               panel=function(...) {
                 arg <- list(...)
                 panel.levelplot(...)
                 panel.text(arg$x, arg$y, round(arg$z,1))})
print(p)

However, the cell values are superimposed on each other because the panel option dose not distinguish between the two groups. How can I get the values to display correctly in each group?

回答1:

Slightly behind the scenes, lattice uses an argument called subscripts to subset data for display in different panels. Often, it does so without you needing to be aware of it, but this is not one of those cases.

A look at the source code for panel.levelplotreveals that it handles subscripts on its own. args(panel.levelplot) shows that it's among the function's formal arguments, and the function's body shows how it uses them.

panel.text(), (really just a wrapper for lattice:::ltext.default()), on the other hand, doesn't know about or do anything with subscripts. From within a call to panel.text(x,y,z), the x, y, and z that are seen are the full columns of the data.frame grid, which is why you saw the overplotting that you did.

To plot text for the values that are a part of the current panel, you need to make explicit use of the subscripts argument, like this:

myPanel <- function(x, y, z, ..., subscripts=subscripts) {
    panel.levelplot(x=x, y=y, z=z, ..., subscripts=subscripts)        
    panel.text(x = x[subscripts], 
               y = y[subscripts], 
               labels = round(z[subscripts], 1))
}
p <- levelplot(z~x*y | factor(class), grid, panel = myPanel)
print(p)