I'm creating a panel with multiple persp plots, each showing a range of data generated by tweaking predictor variables in a complex regression model. I want my 3D surface to be color coded by my z variable, which I was able to do easily enough. How do I take this color scale and make it cover the range of all z variable values that would be represented by all plots in my panel, so that the color scale between multiple persp plots can be compared?
我正在创建一个面板,其中包含多个persp图,每个图都显示了在复杂回归模型中调整预测变量所生成的数据范围。我想让我的三维曲面用z变量来表示颜色,这很容易做到。我如何使用这个颜色标度并使它覆盖所有z变量值的范围这些z变量值将由面板中的所有图来表示,以便在多个persp图之间进行颜色标度比较?
#colorized z scale, only a smidge modified from http://www.inside-r.org/r-doc/graphics/persp
par(bg = "white")
par(mfrow=c(1,2))
x <- seq(-1.95, 1.95, length = 30)
y <- seq(-1.95, 1.95, length = 35)
z1 <- outer(x, y, function(a, b) a*b^2)
nrz <- nrow(z1)
ncz <- ncol(z1)
# Create a function interpolating colors in the range of specified colors
jet.colors <- colorRampPalette( c("blue", "green") )
# Generate the desired number of colors from this palette
nbcol <- 100
color <- jet.colors(nbcol)
# Compute the z-value at the facet centres
zfacet <- z1[-1, -1] + z1[-1, -ncz] + z1[-nrz, -1] + z1[-nrz, -ncz]
# Recode facet z-values into color indices
facetcol <- cut(zfacet, nbcol)
persp(x, y, z1, zlim=c(-8, 10.5), col = color[facetcol], phi = 30, theta = -30)
#zlim added to encompass combined ranges of z1 and z2
#exact same code, with different values of z
x <- seq(-1.95, 1.95, length = 30)
y <- seq(-1.95, 1.95, length = 35)
z2 <- outer(x, y, function(a, b) a*b^2+3)
nrz <- nrow(z2)
ncz <- ncol(z2)
# Create a function interpolating colors in the range of specified colors
jet.colors <- colorRampPalette( c("blue", "green") )
# Generate the desired number of colors from this palette
nbcol <- 100
color <- jet.colors(nbcol)
# Compute the z-value at the facet centres
zfacet <- z2[-1, -1] + z2[-1, -ncz] + z2[-nrz, -1] + z2[-nrz, -ncz]
# Recode facet z-values into color indices
facetcol <- cut(zfacet, nbcol)
persp(x, y, z2, zlim=c(-8, 10.5), col = color[facetcol], phi = 30, theta = -30)
#zlim added to encompass combined ranges of z1 and z2
#comparing the values, we see that there's different, overlapping scales from z1 and z2
summary(as.vector(z1))
summary(as.vector(z2))
So when you look at the two plots of z2, you see that they're on different scales, sort of. It would be a lot clearer if I could get that color scale to cover the ranges of z1 and z2
所以当你看z2的两个图,你会发现它们在不同的尺度上。如果我能把这个颜色标度覆盖到z1和z2的范围就会清楚得多
1 个解决方案
#1
4
You can concatenate the two vectors (matrices) of z values before cutting, and then refer to the relevant subset of the resulting (cut) vector when specifying colour.
您可以在切割前将z值的两个向量(矩阵)连接起来,然后在指定颜色时引用结果(切割)向量的相关子集。
color <- jet.colors(nbcol)
z1facet <- z1[-1, -1] + z1[-1, -ncz] + z1[-nrz, -1] + z1[-nrz, -ncz]
z2facet <- z2[-1, -1] + z2[-1, -ncz] + z2[-nrz, -1] + z2[-nrz, -ncz]
facetcol <- cut(c(z1facet, z2facet), nbcol)
persp(x, y, z1, zlim=c(-8, 10.5),
col=color[facetcol[seq_along(z1facet)]],
phi=30, theta=-30)
persp(x, y, z2, zlim=c(-8, 10.5),
col=color[facetcol[-seq_along(z1facet)]],
phi=30, theta=-30)
Alternatively, use lattice::wireframe
, which might be simpler particularly when dealing with many surface plots:
或者,使用晶格:线框,这可能更简单,特别是在处理许多表面图时:
library(lattice)
# First, create a named list of the surface matrices.
L <- list(z1=z1, z2=z2)
# Iterate over the elements of L, creating data.frames with row number,
# column number, and cell value, as well as matrix name (i.e. name of
# the element of L).
dat <- do.call(rbind, lapply(seq_along(L), function(i) {
setNames(data.frame(which(!is.na(L[[i]]), arr.ind=TRUE),
c(L[[i]]), names(L)[i]),
c('x', 'y', 'z', 'g'))
}))
# Plot with wireframe, faceting by `g` (the matrix name).
wireframe(z ~ x + y|g, data=dat, drape=TRUE, col.regions=color)
Adjust screen
and distance
as desired to get the look you're after, e.g.:
根据需要调整屏幕和距离,以达到你想要的效果。
wireframe(z ~ x + y|g, data=dat, drape=TRUE, col.regions=color,
screen=list(z=30, x=-60), distance=0.5)
#1
4
You can concatenate the two vectors (matrices) of z values before cutting, and then refer to the relevant subset of the resulting (cut) vector when specifying colour.
您可以在切割前将z值的两个向量(矩阵)连接起来,然后在指定颜色时引用结果(切割)向量的相关子集。
color <- jet.colors(nbcol)
z1facet <- z1[-1, -1] + z1[-1, -ncz] + z1[-nrz, -1] + z1[-nrz, -ncz]
z2facet <- z2[-1, -1] + z2[-1, -ncz] + z2[-nrz, -1] + z2[-nrz, -ncz]
facetcol <- cut(c(z1facet, z2facet), nbcol)
persp(x, y, z1, zlim=c(-8, 10.5),
col=color[facetcol[seq_along(z1facet)]],
phi=30, theta=-30)
persp(x, y, z2, zlim=c(-8, 10.5),
col=color[facetcol[-seq_along(z1facet)]],
phi=30, theta=-30)
Alternatively, use lattice::wireframe
, which might be simpler particularly when dealing with many surface plots:
或者,使用晶格:线框,这可能更简单,特别是在处理许多表面图时:
library(lattice)
# First, create a named list of the surface matrices.
L <- list(z1=z1, z2=z2)
# Iterate over the elements of L, creating data.frames with row number,
# column number, and cell value, as well as matrix name (i.e. name of
# the element of L).
dat <- do.call(rbind, lapply(seq_along(L), function(i) {
setNames(data.frame(which(!is.na(L[[i]]), arr.ind=TRUE),
c(L[[i]]), names(L)[i]),
c('x', 'y', 'z', 'g'))
}))
# Plot with wireframe, faceting by `g` (the matrix name).
wireframe(z ~ x + y|g, data=dat, drape=TRUE, col.regions=color)
Adjust screen
and distance
as desired to get the look you're after, e.g.:
根据需要调整屏幕和距离,以达到你想要的效果。
wireframe(z ~ x + y|g, data=dat, drape=TRUE, col.regions=color,
screen=list(z=30, x=-60), distance=0.5)