创建一个格状的薄板样条响应曲面。

5

我试图绘制一堆与两个连续变量和一个离散变量相关的测量的薄板样条响应曲面。到目前为止,我一直根据离散变量对数据进行子集生成成对的图,但我认为应该有一种方法来创建一些简洁的分块状图。似乎可以通过在ggplot2中以geom_tilegeom_contour分面热图来完成这一点,但我卡在了:

(1) 如何重新组织数据(或解释预测表面数据)以与ggplot2绘图?

(2) 使用基础图形创建分块状热图的语法?或

(3) 使用rsm图形来完成这一点(rsm可以处理高阶曲面,因此我可以在某种程度上强制事情,但绘图没有完全分块)。

以下是我到目前为止所做的示例:

library(fields)
library(ggplot2)

sumframe<-structure(list(Morph = c("LW", "LW", "LW", "LW", "LW", "LW", 
"LW", "LW", "LW", "LW", "LW", "LW", "LW", "SW", "SW", "SW", "SW", 
"SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW"), xvalue = c(4, 
8, 9, 9.75, 13, 14, 16.25, 17.25, 18, 23, 27, 28, 28.75, 4, 8, 
9, 9.75, 13, 14, 16.25, 17.25, 18, 23, 27, 28, 28.75), yvalue = c(17, 
34, 12, 21.75, 29, 7, 36.25, 14.25, 24, 19, 36, 14, 23.75, 17, 
34, 12, 21.75, 29, 7, 36.25, 14.25, 24, 19, 36, 14, 23.75), zvalue = c(126.852666666667, 
182.843333333333, 147.883333333333, 214.686666666667, 234.511333333333, 
198.345333333333, 280.9275, 246.425, 245.165, 247.611764705882, 
266.068, 276.744, 283.325, 167.889, 229.044, 218.447777777778, 
207.393, 278.278, 203.167, 250.495, 329.54, 282.463, 299.825, 
286.942, 372.103, 307.068)), .Names = c("Morph", "xvalue", "yvalue", 
"zvalue"), row.names = c(NA, -26L), class = "data.frame")

sumframeLW<-subset(sumframe, Morph=="LW")
sumframeSW<-subset(sumframe, Morph="SW")

split.screen(c(1,2))
screen(n=1)
surf.teLW<-Tps(cbind(sumframeLW$xvalue, sumframeLW$yvalue), sumframeLW$zvalue, lambda=0.01)
summary(surf.teLW)
surf.te.outLW<-predict.surface(surf.teLW)
image(surf.te.outLW, col=tim.colors(128), xlim=c(0,38), ylim=c(0,38), zlim=c(100,400), lwd=5, las=1, font.lab=2, cex.lab=1.3, mgp=c(2.7,0.5,0), font.axis=1, lab=c(5,5,6), xlab=expression("X value"), ylab=expression("Y value"),main="LW plot")
contour(surf.te.outLW, lwd=2, labcex=1, add=T)
points(sumframeLW$xvalue, sumframeLW$yvalue, pch=21)
abline(a=0, b=1, lty=1, lwd=1.5)
abline(a=0, b=1.35, lty=2)

screen(n=2)
surf.teSW<-Tps(cbind(sumframeSW$xvalue, sumframeSW$yvalue), sumframeSW$zvalue, lambda=0.01)
summary(surf.teSW)
surf.te.outSW<-predict.surface(surf.teSW)
image(surf.te.outSW, col=tim.colors(128), xlim=c(0,38), ylim=c(0,38), zlim=c(100,400), lwd=5, las=1, font.lab=2, cex.lab=1.3, mgp=c(2.7,0.5,0), font.axis=1, lab=c(5,5,6), xlab=expression("X value"), ylab=expression("Y value"),main="SW plot")
contour(surf.te.outSW, lwd=2, labcex=1, add=T)
points(sumframeSW$xvalue, sumframeSW$yvalue, pch=21)
abline(a=0, b=1, lty=1, lwd=1.5)
abline(a=0, b=1.35, lty=2)

close.screen(all.screens=TRUE)

我认为pkg:rgl是这项工作的一个很好的环境。 - IRTFM
2个回答

3

正如评论中所提到的,melt()可以用于重塑Tps()输出,然后可以稍微重新格式化一下(以删除NA),重新组合成一个数据框,并绘制出图表。这里使用ggplot2levelplot进行绘图:

library(reshape)
library(lattice)

LWsurfm<-melt(surf.te.outLW)
LWsurfm<-rename(LWsurfm, c("value"="z", "Var1"="x", "Var2"="y"))
LWsurfms<-na.omit(LWsurfm)
SWsurfms[,"Morph"]<-c("SW")

SWsurfm<-melt(surf.te.outSW)
SWsurfm<-rename(SWsurfm, c("value"="z", "X1"="x", "X2"="y"))
SWsurfms<-na.omit(SWsurfm)
LWsurfms[,"Morph"]<-c("LW")

LWSWsurf<-rbind(LWsurfms, SWsurfms)

LWSWp<-ggplot(LWSWsurf, aes(x,y,z=z))+facet_wrap(~Morph)
LWSWp<-LWSWp+geom_tile(aes(fill=z))+stat_contour()
LWSWp

ggplot2 图片

或者: levelplot(z~x*y|Morph, data=LWSWsurf, contour=TRUE)

lattice levelplot 图片


这段内容涉及到IT技术,建议您查找相关资料进行了解。

请注意,x轴和y轴不再正确。然而,可能有一种简单的方法可以根据原始坐标轴重新校准它们,并意识到它们已在0到80之间重新缩放。 - rebeccmeister

2
require(rgl)
open3d()
plot3d
surface3d(surf.te.outSW$x, surf.te.outSW$y, surf.te.outSW$z, col="red")
surface3d(surf.te.outLW$x, surf.te.outLW$y, surf.te.outLW$z, col="blue")
decorate3d()
      rgl.snapshot("OutRGL.png")

输入图像描述

另一种版本,我将x和y值乘以10倍,并旋转以“查看”间隙。如果这是您的选择,您可能需要查看?scaleMatrix

输入图像描述


这在同一图中进行直接比较时非常有用,可以更好地了解相对形状;我会查看该软件包。打印出版物级别的图像的粗略约定是彩色、平面图像,因此我仍然需要二维答案。 - rebeccmeister
1
那么我的建议是使用lattice::contourplotlattice::levelplot - IRTFM
有没有关于如何将Tps()输出(列表)翻译为适合使用contourplotlevelplot绘图的任何提示/想法?正如您在此处所指出的那样,它看起来很好:methods-for-doing-heatmaps。我在考虑如果我可以重新组织这两组输出并附加离散变量,我可能能够回答自己的问题。生成的z值是一个带有NA的80x80矩阵,这似乎会产生错误。 - rebeccmeister
我毫不费力地得到了单个图。将数据放入一个80 x 80 x 2数组中,以使用处理分组的数组方法,在坐标轴无法自动完成的情况下,这引发了一些问题。我想分别绘制然后使用grid.arrange可能对我来说是“简单方法”。 - IRTFM
看起来reshape2中的melt()函数可以完成这个任务,使用na.omit清理结果数据几乎是自动化的。我应该很快能够提供一个ggplot2版本。 - rebeccmeister
干得好。我没想到需要去除NA。通常R绘图函数只会留下NA空白点。 - IRTFM

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