R 制作热图、水平/等高线图和六边形装箱的方法

R 制作热图、水平/等高线图和六边形装箱的方法,r,plot,ggplot2,R,Plot,Ggplot2,R中(x,y,z)的2D绘图选项有点多。然而,解决这些选择是一个挑战,尤其是在这三种选择都是连续的情况下 为了澄清问题(并可能有助于解释为什么我可能会被轮廓或图像绊倒),以下是一个可能的分类方案: 情况1:未提供z值,但它是基于(x,y)中的值的条件密度。(注意:这本质上是将z的计算归结为一个单独的函数——密度估计。某些东西仍然需要使用该计算的输出,因此允许任意计算就好了。) 案例2:(x,y)对是唯一的,且间隔规则。这意味着每个(x,y)值只提供一个z值 案例3:(x,y)对是唯一的,但是连

R中(x,y,z)的2D绘图选项有点多。然而,解决这些选择是一个挑战,尤其是在这三种选择都是连续的情况下

为了澄清问题(并可能有助于解释为什么我可能会被
轮廓
图像
绊倒),以下是一个可能的分类方案:

  • 情况1:未提供z值,但它是基于(x,y)中的值的条件密度。(注意:这本质上是将z的计算归结为一个单独的函数——密度估计。某些东西仍然需要使用该计算的输出,因此允许任意计算就好了。)
  • 案例2:(x,y)对是唯一的,且间隔规则。这意味着每个(x,y)值只提供一个z值
  • 案例3:(x,y)对是唯一的,但是连续的。着色或着色仍然仅由一个唯一的z值决定
  • 情况4:(x,y)对不是唯一的,而是有规则的间隔。着色或着色由z值上的聚合函数确定
  • 案例5:(x,y)对不是唯一的,而是连续的。着色/着色必须由z值上的聚合函数确定
如果我漏了一些案子,请告诉我。我感兴趣的案例是#5。关于关系的一些注释:

  • 案例1似乎已经得到了很好的支持
  • 案例2很容易得到
    热图
    图像
    ggplot
    中函数的支持
  • 基本
    绘图
    支持案例3,但颜色渐变的使用由用户决定
  • 通过使用拆分和应用功能,案例4可以变成案例2。我以前做过
  • 通过使用
    cut
    ,可以将第5格转换为第4格(然后再转换为第2格),但这既不雅观又不方正。十六进制装箱可能更好,尽管这似乎不容易取决于z值是否有陡峭的梯度。我愿意接受十六进制binning,但是替代的聚合函数非常受欢迎,特别是如果它们可以利用z值的话
我该怎么办?下面是生成鞍座的代码,尽管
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值应用任意聚合函数,那就更好了。(这种函数的形式可能类似于
绘图(mat1,colorGradient=f(z),aggregation=“bin”,bins=50)

如何在ggplot或其他软件包中执行此操作?我很乐意把这个问题变成一个社区维基问题(或者其他用户可以,只要编辑足够的次数)。如果是这样的话,请在每篇文章中给出一个答案,这样我们就可以关注,比如说,
ggplot
levelplot
lattice
contourplot
(或
image
),以及其他选项,如果它们存在的话


更新1:是案例3的一个很好的例子:数据有规则的间隔(可以是lat/long),每个观测值有一个z值。地形图具有(纬度、经度、海拔),因此每个位置有一个值。假设一个人正在为许多随机放置的传感器获取多天的天气(例如降雨、风速、阳光):这更类似于#5而不是#3-我们可能有lat和long,但z值的范围可能很大,即使是相同或相近的(x,y)值

更新2:到目前为止,德温、科斯基和约翰·科尔比的答案都非常好。我的实际数据集是较大数据集的一个小样本,但在200K点时,它会产生有趣的结果。在(x,y)平面上,它在某些区域具有非常高的密度(因此,这些区域会发生过涂),而在其他区域具有更低的密度或完全缺失。根据John通过
字段
提出的建议,我需要对
Tps
的数据进行二次抽样(我将调查我是否可以不进行二次抽样),但结果非常有趣。尝试
rms
/
Hmisc
(DWin的建议),整个20万分似乎效果不错。Kohske的建议很好,而且,由于数据在绘图之前转换为网格,因此输入数据点的数量没有问题。它还为我提供了更大的灵活性来确定如何聚合区域中的z值。我还不确定我是否会使用均值、中位数或其他聚合

我还打算用其他方法来尝试Kohske的
mutate
+
ddply
,这是如何在给定区域上计算不同统计数据的一个很好的例子



更新3:不同的方法是不同的,有几个是显著的,尽管没有明确的赢家。我选择约翰·科尔比的答案作为第一个答案。我想我会在以后的工作中使用这个方法或DWin的方法。

对于这类问题,我很幸运地使用了
字段
包。以下是使用薄板花键的
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))

这个问题可能可以分为两部分。第一个是聚合数据,第二个是可视化数据

字段
包,如@John所示,可以一次性完成这些任务。 在
ggplot2
中,若聚合只是数据计数,则可以使用
stat\u 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")

df我通常使用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
dfrmi
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)