一组绘画的热力图的R图表

3
我有一个矩阵,其中有x行(即抽样次数),y列(观测次数)。它们代表了y个预测的分布。
现在我想制作一种“热图”来表示这些抽样。也就是说,我想绘制一个“置信区间”(不是真正的置信区间,而只是所有值之间的阴影),但作为“热图”(热图的示例)。这意味着,如果例如对于观测值y = y*,许多抽样值都在1左右,但是对于相同的观测值,还有一个5的抽样,则围绕1的置信区间的面积会更暗(但1到5之间的整个区域仍然被阴影填充)。
完全清楚:例如我喜欢答案中的图形here,但我希望灰色置信区间被彩色强度替换(即某些区域更暗)。
请问如何实现?
提前感谢。

编辑: 根据要求提供: 示例数据. 第一列前20个值的示例(即y [1:20,1]):

[1]  0.032067416 -0.064797792  0.035022338  0.016347263  0.034373065 
0.024793101 -0.002514447  0.091411355 -0.064263536 -0.026808208 [11]  0.125831185 -0.039428744  0.017156454 -0.061574540 -0.074207109 -0.029171227  0.018906181  0.092816957  0.028899699 -0.004535961

发布一些示例数据,也许我们中的某个人会试着处理它。 - Mike Wise
@MikeWise,我现在在原帖中发布了一些示例数据。谢谢 :)! - dreamer
我不太理解你的维度...你给了一个三维示例(具有x、y和颜色维度的热图)和一个二维示例(x和y,其中y恰好具有置信区间)。如果您想要绘制2D矩阵的每个值,则热图将起作用。如果您想要将2D矩阵的每一列总结为(例如)带有置信区间的平均值或中位数,则热图不合适,但是您链接到的第二个图很容易实现。 - Gregor Thomas
我建议至少分享两列数据...一个列会在热图中生成单个方块吗?还是在热图中生成一列方块?或者是一个带置信区间的单个点? - Gregor Thomas
@Gregor 所有列都是相似的,这就是我只发布了一列的原因。为了澄清:所有列实际上都有10000个值。我想要的是在这10000个值的最小值和最大值之间进行着色,但由于有如此多的值,因此这些着色的某些区域应反映出更多的10000个值在该区域周围。希望这样对您更有意义。 - dreamer
2个回答

3
因此,最困难的部分是将您的数据转换为正确的形状,这就是为什么分享真正看起来像您的数据而不仅仅是单一列数据非常好的原因。
假设您的数据是一个由10,000行和10列组成的矩阵。我将只使用均匀分布,这样最终的图表会比较无聊。
n = 10000
k = 10
mat = matrix(runif(n * k), nrow = n)

接下来,我们将使用apply函数为每一列计算分位数,然后转置并将其转换为数据框:

dat = as.data.frame(t(apply(mat, MARGIN = 2, FUN = quantile, probs = seq(.1, 0.9, 0.1))))

添加一个x变量(我们进行转置后,每个x值对应原始数据中的一列)

dat$x = 1:nrow(dat)

我们现在需要将其转换为“长”格式,按照中位数周围某个偏差组的最小值和最大值进行分组,并且当然要摆脱由quantile引入的讨厌的百分号:
library(dplyr)
library(tidyr)
dat_long = gather(dat, "quantile", value = "y", -x) %>%
    mutate(quantile = as.numeric(gsub("%", "", quantile)),
           group = abs(50 - quantile))

dat_ribbon = dat_long %>% filter(quantile < 50) %>%
    mutate(ymin = y) %>%
    select(x, ymin, group) %>%
    left_join(
        dat_long %>% filter(quantile > 50) %>%
        mutate(ymax = y) %>%
        select(x, ymax, group)
    )

dat_median = filter(dat_long, quantile == 50)

最后我们可以绘制图表。我们将为每个“组”绘制一个透明的带状区间,即10%-90%区间,20%-80%区间,... 40%-60%区间,然后在中位数(50%)处绘制单条线。使用透明度,中间部分会更暗,因为它有更多的带状区间重叠在其上方。这不是从最小值到最大值,但如果您将quantile调用中的probs设置为从0到1而不是从.1到.9,则会实现该效果。
library(ggplot2)
ggplot(dat_ribbon, aes(x = x)) +
    geom_ribbon(aes(ymin = ymin, ymax = ymax, group = group), alpha = 0.2) +
    geom_line(aes(y = y), data = dat_median, color = "white")

enter image description here

值得注意的是,这不是传统的热力图。热力图通常意味着您有三个变量,即x、y和z(颜色),其中每个x-y对都有一个z值。在这里,您有两个变量x和y,y取决于x。


当我运行 dat_long = gather(dat, "quantile", value = "y", -x) %>% mutate(quantile = as.numeric(gsub("%", "", quantile)), group = abs(50 - quantile)) 时,我遇到了错误 Error in as.character(x) : cannot coerce type 'closure' to vector of type 'character'。你知道这是什么原因吗? - dreamer
@dreamer 噢,我在之前的尝试中更改了列名,留下了一行代码。删除 names(dat) = ... 这一行,一切都应该正常工作。(答案代码已经进行了编辑。) - Gregor Thomas
谢谢,不过很抱歉我还是收到了相同的信息(当我运行dat_long...语句时)。你有其他建议吗?可能出了什么问题? - dreamer
被删除的代码行修改了“dat”,因此您必须从开头(或从首次定义“dat”的位置)开始。如果在那之后仍然有问题,可能存在一些函数掩盖的情况。我刚刚测试过,在新的R会话中我的代码可以正常运行。 - Gregor Thomas
函数掩码确实引起了问题。现在它可以工作了 :)!非常感谢,你应该得到更多的赞!最后一个问题:是否可以轻松地尝试不同于黑色阴影的颜色(我看到了均线的参数,但其他参数呢)?如果不行也没关系,现在图表看起来真的很好!我非常感谢你的帮助! - dreamer
当然,这是一个“填充”颜色,设置在 geom_ribbon 内。你可以将其设置为 geom_ribbon(..., alpha = 0.2, fill = "dodgerblue4")。感谢您发布最终产品! - Gregor Thomas

1

谢谢,这可能是一个很好的起点(已赞)!会看一下,但希望有更简单的解决方案。 - dreamer
今晚晚些时候我会试一试。 - Mike Wise

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