R ggplot热图,其中多行在同一图形上具有单独的图例

问题描述

我正在尝试使用ggplot2制作一个热图,其中包含3种类型的变量,每个变量都需要各自独立的图例/比例。

我能够将它们全部绘制在一个热图中(如下图所示),但是我很难将它们分开以拥有自己的图例。我的三个类别是“得分”,“ samp1”行和其余数据。我希望它们中的每一个都有各自独立的图例以及各自的范围。

我唯一的补充是,如果可能的话,该行分数具有绿色,黄色,红色(低,中,高)配色方案。

an image of what I have so far

这是我用来创建该图的代码

library(ggplot2)
test_data <- read.csv("test_table.csv",row.names = 1)

ggplot(test_data,aes(x=sample,y=id,fill = value)) + 
  geom_raster() + 
  theme(axis.text.x = element_text(angle = 90,vjust = 0.5,hjust=1),# lables vertical
        strip.text.y = element_blank()) +  #remove facet bar on y 
  scale_fill_gradient(low = "darkblue",high = "lightblue") +
  ggtitle("test table") +
  facet_grid(rows = vars(test_data$category),cols = vars(test_data$group),scales = "free",space="free_y") #facets to add gaps 

我已使用构面按样本和上述3类来分离数据。我也希望使用此分组来创建自己的图例,但不确定是否可行。

点击here以下载数据(已预先熔化)。

谢谢。

解决方法

这可以通过ggnewscale包来实现,例如:

library(ggplot2)
library(dplyr)
library(ggnewscale)

ggplot() +
  geom_raster(data = filter(test_data,category == "1 score"),aes(x = sample,y = id,fill = value)) +
  scale_fill_gradient2(low = "green",mid = "yellow",high = "red",midpoint = 4,name = "Score") +
  new_scale_fill() +
  geom_raster(data = filter(test_data,category == "2 samp1"),fill = value)) +
  scale_fill_gradient(low = "darkblue",high = "lightblue",name = "Sample1") +
  new_scale_fill() +
  geom_raster(data = filter(test_data,category == "3 samp2"),name = "Sample2") +
  ggtitle("test table") +
  facet_grid(
    rows = vars(category),cols = vars(group),scales = "free",space = "free_y"
  ) +
  theme(
    axis.text.x = element_text(angle = 90,vjust = 0.5,hjust = 1),strip.text.y = element_blank()
  )

,

我建议采用下一种方法。按组划分数据,然后使用函数为每个组构建单独的图。最后,使用purrrpatchwork将具有不同图例的所有地块合并在一起。这里的代码:

library(purrr)
library(ggplot2)
library(patchwork)
#Load data
test_data <- read.csv("test_table.csv",row.names = 1)
#Split into list
List <- split(test_data,test_data$group)
#Function for plots
myfun <- function(x)
{
  G <- ggplot(x,aes(x=sample,y=id,fill = value)) + 
    geom_raster() + 
    theme(axis.text.x = element_text(angle = 90,hjust=1),# lables vertical
          strip.text.y = element_blank()) +  #remove facet bar on y 
    scale_fill_gradient(low = "darkblue",high = "lightblue") +
    facet_grid(rows = vars(x$category),cols = vars(x$group),space="free_y")
  return(G)
}
#Apply
List2 <- lapply(List,myfun)
#Plot
reduce(List2,`+`)+plot_annotation(title = 'My plot')

输出:

enter image description here

您可以进一步了解patchwork以及如何加入多个地块。

,

当然可以制作3个图并将它们粘在一起,但是考虑到刻面是不同的形状,这不是理想的。您可以按照Stefan的方式使用ggnewscale软件包,现在在CRAN上更容易,但是如果您想在单个ggplot中完成它而没有附加组件,则 是可能的。您只需要绘制一个由大实心正方形组成的geom_point。这样您就可以使用色标和填充标尺。

ggplot(test_data,fill = value)) + 
  geom_raster() + 
  geom_point(aes(alpha = id,colour = value),size = 12,shape = 15) +
  theme(axis.text.x = element_text(angle = 90,strip.text.y = element_blank()) + 
  scale_fill_gradient(low = "darkblue",high = "lightblue") +
  ggtitle("test table") +
  facet_grid(rows = vars(test_data$category),cols = vars(test_data$group),space = "free_y") +
  scale_alpha_manual(values = c(rep(0,19),1,0),guide = guide_none()) +
  scale_color_gradientn(colours = c("red","orange","gold","yellow"))

enter image description here