R 中的热图 returns 空白图

Heatmap in R returns blank plot

我正在尝试使用以下代码创建热图。

library(ggplot2)
RO_diff1_10 <- c(0.003197056,  0.031952193 , 0.317694767,  0.631357229 , 1.548588179,  3.000675013 , 5.635730267 ,11.710554504, 17.424381041, 14.318469977,8.099506073 , 4.264751628,  1.761246406  ,0.890215117,  0.595636681 , 0.447541540,  0.298905526 , 0.179605462,  0.089901266,0.044975304,0.017996047)

RO_diff1_100 <- c(0.008513677,0.085095597  ,0.846852831,  1.684645430  ,4.144564377,  8.071515418, 15.314786741, 32.831856543, 51.552068405 ,64.110304328, 49.007935109, 32.837083396, 16.467462320 , 8.991137813 , 6.183440560 , 4.711966796 , 3.192501503 , 1.940794781  ,0.980101675 , 0.4925131, 0.197600907)

vectorC_WT <- c( 1.0e-03, 1.0e-02, 1.0e-01, 2.0e-01, 5.0e-01, 1.0e+00, 2.0e+00, 5.0e+00, 1.0e+01, 5.0e+01, 1.0e+02, 2.0e+02, 5.0e+02, 1.0e+03, 1.5e+03, 2.0e+03, 3.0e+03, 5.0e+03, 1.0e+04, 2.0e+04, 5.0e+04)


df11 <- as.data.frame(cbind(x=vectorC_WT, y=10, RO_diff = RO_diff1_10))
df12 <- as.data.frame(cbind(x=vectorC_WT, y=100, RO_diff = RO_diff1_100))

dfheat <- rbind(df11,df12)

ggplot(data=dfheat, aes(x, y, fill=RO_diff)) +
  geom_tile() + 
  scale_fill_viridis()+
  scale_x_log10(breaks = c(0.001,0.01,0.1,1,10,100,1000,10000), limits=c(0.001,20000))+
  scale_y_log10(limits=c(10,100))                

问题是 returns 我的图表是空白的。对于为什么会发生这种情况有什么建议吗?

你得到空白图的原因是因为你的 xy 仍然是数字,也就是说它们仍然是连续的。一般来说,热图对分类数据有意义,也就是说 xy 都是因子。因此,如果您将 xy 值转换为 factor,您将能够绘制热图。 但是, log 对因素没有意义,因此您的最后一行会引发错误。因此,绘制日志值的解决方法是将 xy 值转换为日志,然后转换为因子,然后您可以绘制热图。

library(ggplot2)
library(viridis)
RO_diff1_10 <- c(0.003197056,  0.031952193 , 0.317694767,  0.631357229 , 1.548588179,  3.000675013 , 5.635730267 ,11.710554504, 17.424381041, 14.318469977,8.099506073 , 4.264751628,  1.761246406  ,0.890215117,  0.595636681 , 0.447541540,  0.298905526 , 0.179605462,  0.089901266,0.044975304,0.017996047)

RO_diff1_100 <- c(0.008513677,0.085095597  ,0.846852831,  1.684645430  ,4.144564377,  8.071515418, 15.314786741, 32.831856543, 51.552068405 ,64.110304328, 49.007935109, 32.837083396, 16.467462320 , 8.991137813 , 6.183440560 , 4.711966796 , 3.192501503 , 1.940794781  ,0.980101675 , 0.4925131, 0.197600907)

vectorC_WT <- c( 1.0e-03, 1.0e-02, 1.0e-01, 2.0e-01, 5.0e-01, 1.0e+00, 2.0e+00, 5.0e+00, 1.0e+01, 5.0e+01, 1.0e+02, 2.0e+02, 5.0e+02, 1.0e+03, 1.5e+03, 2.0e+03, 3.0e+03, 5.0e+03, 1.0e+04, 2.0e+04, 5.0e+04)


dfheat <- data.frame(
  x= rep(round(log10(vectorC_WT),2),2), 
  y = c(
    rep(10, length(vectorC_WT)),
    rep(100, length(vectorC_WT))
    ),
  RO_diff= log10(c(RO_diff1_10, RO_diff1_100))
)

ggplot(data=dfheat, aes(as.factor(x), as.factor(y), fill=RO_diff)) +
  geom_tile() +  
  scale_fill_viridis() + 
  labs(x='x', y= 'y')

以上代码,生成如下图表。

@monte 建议的答案可以为您提供热图,但不能完全回答您的问题,即 为什么您没有看到任何数据? 您是看到绘图和比例,所以您实际上没有看到的是 geom_tile() 的结果。原因很简单,您将轴限制设置得太小,它会剪掉数据。

scale_*_log10()limits= 的参数表现得非常像 ylim()xlim(),后者 results in removal of any data outside of that range in your plot。这可能没有意义,因为毕竟 dfheat 中的 y 值是 10 和 100...所以如果限制是 10 到 100,它应该显示出来,对吗?好吧,是的,不是。是的,它可以显示存在于 y=10 和 y=100 的点...但是 geom_tile() 不能那样工作。对于 geom_tile(),x 和 y 美学表示具有 width=height= 尺寸的矩形的中心。这意味着 y=100 处的点的最大值会略大于 100,而 y=10 处的最小值会略低于 10。此外,在对数尺度上,数字往往有点夸大, (为了查看它们)。如果您将 geom_point() 添加到您的绘图中,我们可以清楚地显示这一点:

ggplot(data=dfheat, aes(x, y, fill=RO_diff)) +
  geom_tile() +
  geom_point() +
  scale_fill_viridis()+
  scale_x_log10(breaks = c(0.001,0.01,0.1,1,10,100,1000,10000), limits=c(0.001,20000))+
  scale_y_log10(limits=c(10,100))

因此,这些点在限制范围内,因为它们是点,但图块超出了您的 y 轴限制。如果您增加限制范围,我们可以让它们显示出来,但请记住,现在是对数刻度,因此您必须调整得比您想象的更大(1 个对数单位通常是安全的):

ggplot(data=dfheat, aes(x, y, fill=RO_diff)) +
  geom_tile() +
  geom_point() +
  scale_fill_viridis()+
  scale_x_log10(breaks = c(0.001,0.01,0.1,1,10,100,1000,10000), limits=c(0.001,20000))+
  scale_y_log10(limits=c(1,1000))

现在注意到什么了吗?出于同样的原因,x 轴两端的那些点也没有显示它们的图块。修复方法也是一样的:扩展一个日志单元。我还将使用 width=height= 来获得 geom_tile() 以使图块看起来更“热图”,并使用 alpha= 指示我们重叠图块的位置:

ggplot(data=dfheat, aes(x, y, fill=RO_diff)) +
  geom_tile(width=0.2, height=1, alpha=0.8) +
  geom_point() +
  scale_fill_viridis()+
  scale_x_log10(breaks = c(0.001,0.01,0.1,1,10,100,1000,10000), limits=c(0.0001,100000))+
  scale_y_log10(limits=c(1,1000))

如果您想更进一步,我建议您尝试使用 geom_tile()width= 参数来尝试让它们相遇。基本上,您需要将其设置在 aes(width=...some log10 transformation...) 中才能使其生效。我玩了一点,但没有找到完美的东西。