如何使用3个向量绘制等高线图/热力图?

7

这里是一个玩具版本的问题:

x = runif(10);
y = runif(10);
z = (x+y)*(x-y);

我希望能够生成一个z与(x+y)和(x-y)的热图。问题在于z是一个向量,并且并未在所有y和x的组合中定义。请注意,我不想要一个为这些缺失值生成z的答案,这在实际问题的版本中是不可能的。这只是一个最小化的版本来处理。我能找到的所有解决方案,例如filled.contour,都需要一个指定在独立变量的网格上的z矩阵,而不仅仅是一组没有结构的(x,y,z)数据点。
4个回答

7

您需要的是akima包。它可以使用interp进行二元插值。它可以生成缺失组合的z值,但如果您想要排除这些值,您也可以这样做。如果您不需要生成z值,则可以绘制一个z ~ x*y的三维散点图。

x = runif(10);
y = runif(10);
z = (x+y)*(x-y);

library(akima)
dens <- interp(x+y, x-y, z, 
               xo=seq(min(x+y), max(x+y), length=100),
               yo=seq(min(x-y), max(x-y), length=100),
               duplicate="median")

filled.contour(dens, xlab="x+y", ylab="x-y", main="z",
               color.palette = heat.colors)

enter image description here

如果您坚决不想插值,在@Frank提供的ggplot选项基础上,还有许多美学元素可以用来通过第三个维度对点进行对比。

library(ggplot2)
dat <- data.frame(x1=x+y, x2=x-y, z=z)

## Scaling points by z dimension using size, color, and shading
ggplot(dat, aes(x1, x2, size=z, alpha=z, color=z)) +
  geom_point() +
  scale_color_gradient(low="red", high="yellow") +
  theme_bw()

enter image description here


5
这里有一个在ggplot2中的可能性,与使用插值计算不同的是,当z的值为“missing”时,我不会生成它们的值。
set.seed(54321)
x = runif(10)
y = runif(10)
z = (x+y)*(x-y)

ggplot(df, aes(x+y, x-y, fill=z)) +
  scale_fill_gradient(low = "blue", high = "red") + geom_tile()

输入图像描述

您可以使用 roundcut 来强制/操纵瓦片的大小和整体外观:

ggplot(df, aes(round(x+y,1),round(x-y,1), fill=z)
  scale_fill_gradient(low = "blue", high = "red") + 
  geom_tile()
# OR
ggplot(df, aes(cut(x+y, 15), cut(x-y, 15), fill=z))
  scale_fill_gradient(low = "blue", high = "red") + 
  geom_tile() + 
  theme(axis.text.x=element_blank(), axis.text.y=element_blank())

enter image description hereenter image description here


1
那些最后的 ggplots 真的很棒。 - Rorschach

3
也许实现类似于所需输出的最简单方法是使用lattice包:
set.seed(12358)
x <- runif(10)
y <- runif(10)
z <-(x+y)*(x-y)
x1<-x+y
y1<-x-y
library(lattice)
df<-data.frame(x=x1,y=y1,z=z)
levelplot(z~x1*y1,df,cuts=9,col.regions=grey.colors(10)[10:1])

enter image description here

但是,不可否认的是,这并不美观。可能更好的表示数据的方式是使用交互式 3D散点图,可以使用rgl包生成,如下所示。对于此图表,我使用了温斯顿·张(Winston Chang)的“R图形手册”中的一个函数来绘制垂直蓝线:

library(rgl)
plot3d(x1,y1,z, size=1,type="s")
interleave <- function(v1,v2) as.vector(rbind(v1,v2))
segments3d(interleave(x1,x1), interleave(y1,y1), interleave(z,0),alpha=0.4,col="blue")
planes3d(a=0,b=0,c=1,d=0,alpha=0.1)

插入图像描述

由于原帖作者非常明确地表示不需要插值,因此我不会提供简单的方法来显示这种连续的热力图,尽管我认为对于这种类型的数据集,插值通常是有意义的。

实际上,我有些难以理解将一个本质上是二维的热力图应用于一个无结构的一组不相关的点集。


3

这是一个带基础图形的变体:

x = runif(10);
y = runif(10);
z = (x+y)*(x-y);

n = 5
zz = cut(z, n)
cols <- heat.colors(n)
plot(x, y, col=cols[zz], cex=4, pch=20)
legend('topright', legend=levels(zz), pch=20, col=cols, pt.cex=3)

需要注意的是,如果要对zz进行任何操作,则应确保在cut参数中设置labels=FALSE。否则,许多函数将把zz视为字符类型。除此之外,这是一个非常好的选项! - WetlabStudent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接