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 我的图表是空白的。对于为什么会发生这种情况有什么建议吗?
你得到空白图的原因是因为你的 x
和 y
仍然是数字,也就是说它们仍然是连续的。一般来说,热图对分类数据有意义,也就是说 x
和 y
都是因子。因此,如果您将 x
和 y
值转换为 factor
,您将能够绘制热图。
但是, log
对因素没有意义,因此您的最后一行会引发错误。因此,绘制日志值的解决方法是将 x
和 y
值转换为日志,然后转换为因子,然后您可以绘制热图。
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...)
中才能使其生效。我玩了一点,但没有找到完美的东西。
我正在尝试使用以下代码创建热图。
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 我的图表是空白的。对于为什么会发生这种情况有什么建议吗?
你得到空白图的原因是因为你的 x
和 y
仍然是数字,也就是说它们仍然是连续的。一般来说,热图对分类数据有意义,也就是说 x
和 y
都是因子。因此,如果您将 x
和 y
值转换为 factor
,您将能够绘制热图。
但是, log
对因素没有意义,因此您的最后一行会引发错误。因此,绘制日志值的解决方法是将 x
和 y
值转换为日志,然后转换为因子,然后您可以绘制热图。
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...)
中才能使其生效。我玩了一点,但没有找到完美的东西。