同じグラフ上に別々の凡例を持つ複数の行を持つRggplotヒートマップ

Aug 20 2020

それぞれが独自の独立した凡例/スケールを必要とする3種類の変数を含むggplot2を使用して1つのヒートマップを作成しようとしています。

それらすべてを1つのヒートマップ(下の写真)にプロットすることはできますが、独自の凡例を持つためにそれらを分離するのに問題があります。私の3つのカテゴリは、行「Score」、「samp1」、および残りのデータです。これらのそれぞれに、それぞれの範囲を持つ独自の独立した凡例を持たせたいと思います。

私の唯一の追加は、この質問に含めることができる場合、行スコアに緑、黄、赤(低、中、高)の配色を持たせることです。

これは私がそのグラフを作成するために使用しているコードです

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つのカテゴリごとにデータを分離しました。このグループ化を使用して独自の凡例を作成することも望んでいましたが、これが可能かどうかはわかりません。

クリックしてここにデータをダウンロードする(事前融解)。

前もって感謝します。

回答

3 stefan Aug 20 2020 at 03:03

これは、次の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"), aes(x = sample, y = id, fill = value)) +
  scale_fill_gradient(low = "darkblue", high = "lightblue", name = "Sample1") +
  new_scale_fill() +
  geom_raster(data = filter(test_data, category == "3 samp2"), aes(x = sample, y = id, fill = value)) +
  scale_fill_gradient(low = "darkblue", high = "lightblue", 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()
  )

3 Duck Aug 20 2020 at 03:06

次のアプローチを提案します。データをグループごとに分割し、関数を使用してグループごとに個別のプロットを作成します。最後に、を使用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, vjust = 0.5, 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), scales = "free", space="free_y")
  return(G)
}
#Apply
List2 <- lapply(List,myfun)
#Plot
reduce(List2, `+`)+plot_annotation(title = 'My plot')

出力:

patchwork複数のプロットを結合する方法についてさらに詳しく調べることができます。

1 AllanCameron Aug 20 2020 at 03:24

3つのプロットを作成してそれらを貼り付けることは確かに可能ですが、ファセットの形状が異なるため、これは理想的ではありません。ggnewscaleStefanに従ってパッケージを使用することもできます。これは、CRAN上で簡単になりましたが、アドオンなしで単一のggplotで実行したい場合可能です。geom_point大きな正方形でできているをプロットする必要があります。これにより、塗りつぶしスケールだけでなくカラースケールも使用できます。

ggplot(test_data, aes(x=sample, y=id, fill = value)) + 
  geom_raster() + 
  geom_point(aes(alpha = id, colour = value), size = 12, shape = 15) +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
        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),  scales = "free", space = "free_y") +
  scale_alpha_manual(values = c(rep(0, 19), 1, 0, 0), guide = guide_none()) +
  scale_color_gradientn(colours = c("red", "orange", "gold", "yellow"))