【问题标题】:How to overlay two heatmaps via ggplot2 with two different scales_fill_gradient?如何通过 ggplot2 用两个不同的 scale_fill_gradient 覆盖两个热图?
【发布时间】:2019-07-25 20:31:32
【问题描述】:

我有一个包含两个变量的数据,我希望看到一个带有热图的图,每个图都相互叠加,并显示两个不同变量的两个色标。我的代码虽然不正确,但应该清楚地表明我想要实现的目标。

我查看了几个示例,这些示例都没有说明如何为 geom_tile() 执行此操作。 geom_point 会很容易。我提供了一个综合示例来展示我在做什么。我收到错误消息“'填充'的比例已经存在。为'填充'添加另一个比例,它将替换现有的比例。”显然它只接受第二个 scale_fill_gradient,但我想查看与同一热图中的变量对应的颜色渐变。 如果我能找到一种方法来获得这个情节,那就太好了。谢谢!

library(reshape2)
library(ggplot2)

set.seed(2)
m1 = matrix(rnorm(100), nrow=10)
m2 = matrix(rnorm(100), nrow=10)
M1 = melt(m1)
M2 = melt(m2)
names(M1)  = c("Var1", "Var2", "value1")
names(M2)  = c("Var1", "Var2", "value2")
pp1 <- ggplot() +
  geom_tile(data=M1, aes(x=Var1, y=Var2, fill=value1)) +
  scale_fill_gradient(low="white", high="red") +
  geom_tile(data=M2, aes(x=Var1, y=Var2, fill=value2)) +
  scale_fill_gradient(low="blue", high="yellow")
pp1

【问题讨论】:

  • 重叠颜色的问题是给定图块中的结果颜色会有所不同。那将是与两个色标不同的颜色。所以你需要一个双变量颜色图例。
  • 我对实际使用中的两个重叠热图并不熟悉。你有没有做的例子,不管“做得好”还是“做得好”? (我认为,类似于关于在绘图上具有多个 y 轴的讨论,它很容易令人困惑,因此不鼓励,因此不容易支持。)
  • 你可以做 M2$value_1
  • 将图像的通道视为单独的灰度图像。因此,我一定希望将它们视为热图,以查看各个通道的强度但重叠。 @r2evans
  • @PabloRod 我明白你的意思;映射到 alpha 实际上并不能满足我的目的……但谢谢!

标签: r ggplot2


【解决方案1】:

因此,ggnewscale 包中的图例本身没有问题,问题在于选择要显示的实际颜色。因此,让我们用您要显示的实际颜色创建一个新矩阵:

library(ggnewscale)
library(scales)

r <- rescale(M1$value1)
# 1 - rescaled value because yellow should be bottom
g <- 1 - rescale(M2$value2)

# Second scale goes from yellow (low) to blue (high)
# Yellow is 100% blue, 100% green, so blue stays invariant
rgb <- rgb(r, g, 1)

# Make new matrix
M3 <- M1
M3$value1 <- rgb

现在绘图将如下所示:

ggplot(mapping = aes(x = Var1, y = Var2)) +
  # This bit is for making scales
  geom_tile(data=M1, aes(fill = value1)) +
  scale_fill_gradient(low = "white", high = "red") +
  new_scale_fill() +
  geom_tile(data=M2, aes(fill=value2)) +
  scale_fill_gradient(low="yellow", high="blue") +
  new_scale_fill() +
  # This is the actual colours
  geom_tile(data=M3, aes(fill = M3$value1)) +
  scale_fill_identity()

图例并非 100% 准确,因为 ggplot 在“实验室”空间混合颜色,而我们在 rgb 空间混合颜色,但您可以将 scale_fill_gradient() 替换为例如 scale_fill_gradientn(colours = rgb(seq(0, 1, length.out = 100), 0, 0))。另请注意,在此示例中,从技术上讲,白色到红色的比例应该是黑色到红色的比例。

【讨论】:

  • 这很好用。我试图使用 ggplotly(pp2) 使其具有交互性,pp2 被存储为代码中的绘图对象。它提供了一堆警告,然后绘制了一个混乱的图例。我尝试在geom_tile(data = M3,aes(fill = M3 $ value1)之后添加主题(legend.position =“none”),但这也删除了M1和M2的图例。关于如何解决这个问题的任何想法?@teunbrand
  • 对不起,我从未使用过任何与 ggplotly 相关的东西,我不知道如何回溯错误并尝试修复它。
【解决方案2】:

双变量颜色图例。间隔应该是对应的分位数。

library(tidyverse)
library(cowplot)

set.seed(2)
m1 = matrix(rnorm(100), nrow=10)
m2 = matrix(rnorm(100), nrow=10)
M1 = melt(m1)
M2 = melt(m2)
names(M1)  = c("Var1", "Var2", "value1")
names(M2)  = c("Var1", "Var2", "value2")

M1$value_cut <- cut(M1$value1, breaks = 3)
M2$value_cut <- cut(M2$value2, breaks = 3)

M1$value_cut2 <- M2$value_cut
M1$cuts <- paste(M1$value_cut, M1$value_cut2, sep = "-")

levels_comb <- expand.grid(lev1 = levels(M1$value_cut), lev2 = levels(M2$value_cut))
levels_comb$cuts <- paste(levels_comb$lev1, levels_comb$lev2, sep = "-")
levels_comb$filling <- c("#be64ac","#8c62aa","#3b4994","#dfb0d6","#a5add3","#5698b9","#e8e8e8","#ace4e4","#5ac8c8")

data_m <- left_join(M1, levels_comb, by = "cuts")

plot_tile <- ggplot(data_m, aes(x = Var1, y = Var2, fill = filling)) +
  geom_tile() +
  scale_fill_identity() +
  coord_equal() +
  theme_minimal()

legend_tile <- ggplot(levels_comb, aes(x = lev1, y = lev2, fill = filling)) +
  geom_tile() +
  scale_fill_identity() +
  coord_equal() +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggdraw() +
  draw_plot(plot_tile, 0, 0, 1, 1) +
  draw_plot(legend_tile, .75, .4, .3, .3)

【讨论】:

    【解决方案3】:

    我发现geom_col() + facet_grid() 是一种有用的模式,可以帮助您实现将同一区域的多个值可视化在一起的目标。

    您的起始数据有一点设置开销:

    names(M1)  = c("Var1", "Var2", "value")
    names(M2)  = c("Var1", "Var2", "value")
    M1$type <- "M1"
    M2$type <- "M2"
    
    M <- rbind(M1, M2)
    

    但情节是直截了当的。您不再需要填充比例,但我喜欢继续突出显示值的变化。

    ggplot(M) +
      geom_col(aes(type, value, fill = value)) +
      facet_grid(Var2 ~ Var1) +
      scale_fill_gradient(low="blue", high="yellow")
    

    不确定这是否适合您,但至少您可以看到另一种可视化选项。

    【讨论】:

    • 感谢@Nate,这有助于我查看小图像或大图像的一小部分!
    猜你喜欢
    • 2014-07-27
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多