R中(x,y,z)的2D图的选项有点多。然而,解决这些选择是一个挑战,特别是在所有三个都是连续的情况下。
为了澄清问题(并且可能有助于解释为什么我可能会被contour
或image
绊倒),这里有一个可能的分类方案:
如果我遗漏了一些情况,请告诉我。我感兴趣的案例是#5。关于人际关系的一些注释:
heatmap
,image
以及ggplot
中的功能轻松支持案例#2。plot
支持,但使用颜色渐变留给用户。cut
转换为#4(然后是#2),但这是不优雅和四四方方的。十六进制分箱可能更好,但这似乎不容易取决于z的值是否存在陡峭的梯度。我决定使用十六进制分箱,但非常欢迎其他聚合功能,特别是如果它们可以使用z值。我怎么能做#5?下面是生成鞍座的代码,尽管spread
的值会改变z值的扩展,这会在绘制渐变时产生差异。
N = 1000
spread = 0.6 # Vals: 0.6, 3.0
set.seed(0)
rot = matrix(rnorm(4), ncol = 2)
mat0 = matrix(rnorm(2 * N), ncol = 2)
mat1 = mat0 %*% rot
zMean = mat0[,2]^2 - mat0[,1]^2
z = rnorm(N, mean = zMean, sd = spread * median(abs(zMean)))
我想做一些像hexbin
这样的事情,但我已经用ggplot
对此进行了攻击并且没有取得多大进展。如果我可以将任意聚合函数应用于区域中的z值,那就更好了。 (这种功能的形式可能类似于plot(mat1, colorGradient = f(z), aggregation = "bin", bins = 50)
。)
如何在ggplot或其他包中执行此操作?我很高兴将这个问题作为社区维基问题(或者其他用户可以通过编辑足够多次)。如果是这样,请为每个帖子提供一个答案,以便我们可以专注于ggplot
,levelplot
,lattice
,contourplot
(或image
)和其他选项,如果存在的话。
更新1:volcano example是案例#3的一个很好的例子:数据有规律地间隔(可以是纬度/经度),每次观察一个z值。地形图具有(纬度,经度,海拔高度),因此每个位置具有一个值。假设一个人在很多天内获得了许多随机放置的传感器的天气(例如降雨,风速,太阳光):这更像是#5而不是#3 - 我们可能有lat&很长,但z值可以相当大,即使是相同或附近的(x,y)值。
更新2:到目前为止,DWin,Kohske和John Colby的答案都非常出色。我的实际数据集是一个较大集合的小样本,但在200K点它产生有趣的结果。在(x,y)平面上,它在一些区域具有非常高的密度(因此,在那些区域中会出现过度绘图)并且在其他区域中密度低得多或完全不存在。根据John fields
提出的建议,我需要对Tps
的数据进行二次抽样以便计算出来(我将调查是否可以在不进行二次抽样的情况下进行),但结果非常有趣。尝试rms
/ Hmisc
(DWin的建议),全部200K积分似乎运作良好。 Kohske的建议相当不错,并且,在绘图之前将数据转换为网格,输入数据点的数量没有问题。它还为我提供了更大的灵活性,可以确定如何聚合区域中的z值。我还不确定我是否会使用均值,中位数或其他聚合。
我还打算用其他方法尝试Kohske的mutate
+ ddply
的好例子 - 它是如何在给定区域内计算不同统计数据的一个很好的例子。
更新3:虽然没有明显的赢家,但不同的方法是截然不同的,有几种方法是显着的。我选择约翰科尔比作为第一个答案。我想我会在进一步的工作中使用它或DWin的方法。
答案 0 :(得分:5)
我对这类问题的fields
软件包运气很好。以下是使用Tps
表示薄板样条线的示例:
编辑:组合图并添加标准错误
require(fields)
dev.new(width=6, height=6)
set.panel(2,2)
# Plot x,y
plot(mat1)
# Model z = f(x,y) with splines
fit = Tps(mat1, z)
pred = predict.surface(fit)
# Plot fit
image(pred)
surface(pred)
# Plot standard error of fit
xg = make.surface.grid(list(pred$x, pred$y))
pred.se = predict.se(fit, xg)
surface(as.surface(xg, pred.se))
答案 1 :(得分:3)
我通常使用rms / Hmisc包组合。这是使用交叉三次样条项的线性回归分析(函数ols
),其绘制的输出非常类似于提供的字段示例:
dfrm <- data.frame(z=z, xcor = mat1[,1], ycor=mat1[,2])
require(rms) # will automatically load Hmisc which needs to have been installed
lininterp <- ols(z ~ rcs(xcor,3)*rcs(ycor,3), data=dfrm)
ddI <- datadist(dfrm)
options(datadist="ddI")
bplot(Predict(lininterp, xcor, ycor)) # Plot not shown
perim <- with(dfrm, perimeter(xcor, ycor))
bplot(Predict(lininterp, xcor, ycor), perim=perim)
# Plot attached after converting to .png
您还可以在我对此问题的回答的第二部分中看到一种不依赖于三维表面回归估计的方法:Using color as the 3rd dimension
绘图范例是格子,您还可以获得等高线图以及这个漂亮的水平图。如果您希望预测值位于某个点,那么您可以使用应用于fit-object的Predict
函数来获取该值。
答案 2 :(得分:3)
panel.2dsmoother
包中有latticeExtra
个功能:
library(lattice)
library(latticeExtra)
df <- data.frame(mat1, z)
names(df)[c(1,2)] <- c('x', 'y')
levelplot(z ~ x * y, data = df, panel = panel.2dsmoother, contour=TRUE)
根据其help page,平滑模型(近似)构造为方法(形式,数据=列表(x = x,y = y,z = z),{args})[... ]这应该适用于任何采用公式参数的模型函数,并且具有预测方法参数“。
答案 3 :(得分:2)
问题可以分为两部分。第一个是聚合数据,第二个是可视化数据。
正如@John所示, fields
包可以同时执行这些操作。
在ggplot2
中,如果汇总只是数据的计数,则stat_bin2d
可用。
无论如何,如果你想要你自己的聚合函数,也许这样的东西会有所帮助:
df <- data.frame(x = mat1[,1], y = mat1[,2], z = z)
Nx <- 10 # nubmer of bins for x
Ny <- 4 # number of bins for y
# create a data.
df2 <- mutate(ddply(df, .(x = cut(x, Nx), y = cut(y, Ny)), summarise,
Mean = mean(z),
Var = var(z)),
xmin = as.numeric( sub("\\((.+),.*", "\\1", x)),
xmax = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", x)),
ymin = as.numeric( sub("\\((.+),.*", "\\1", y)),
ymax = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", y)),
xint = as.numeric(x),
yint = as.numeric(y))
# then, visualize
ggplot(df2, aes(xint, yint, xmin = xmin, ymin = ymin, xmax = xmax, ymax = ymax, fill = Mean)) +
geom_tile(stat = "identity")
ggplot(df2, aes(xint, yint, xmin = xmin, ymin = ymin, xmax = xmax, ymax = ymax, fill = Var)) +
geom_tile(stat = "identity")