동일한 그래프에 별도의 범례가있는 여러 행이있는 R ggplot 히트 맵

Aug 20 2020

각각 고유 한 범례 / 스케일이 필요한 3 가지 유형의 변수를 포함하는 ggplot2를 사용하여 하나의 히트 맵을 만들려고합니다.

하나의 히트 맵 (아래 그림 참조)에 모두 플로팅 할 수 있지만 고유 한 전설을 갖기 위해 분리하는 데 문제가 있습니다. 내 세 가지 범주는 "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

다음 접근 방식을 제안합니다. 데이터를 그룹별로 분할 한 다음 함수를 사용하여 각 그룹에 대해 별도의 그림을 만듭니다. 마지막으로 및를 사용 purrr하여 patchwork모든 플롯을 다른 범례와 결합합니다. 여기에 코드 :

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 개의 플롯을 만들고 함께 붙일 수는 있지만 패싯의 모양이 다르기 때문에 이상적이지 않습니다. 당신은 사용할 수 ggnewscale는 CRAN에 지금 쉽게 스테판에 따라 패키지를,하지만 당신은하지 않고 단일 ggplot에서 작업을 수행하려는 경우 추가 기능이 있습니다 가능합니다. geom_point큰 사각형으로 구성된 a를 플로팅하기 만하면 됩니다. 이를 통해 색상 스케일과 채우기 스케일을 사용할 수 있습니다.

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"))