R ggplot тепловая карта с несколькими строками, имеющими отдельные легенды на одном графике

Aug 20 2020

Я пытаюсь создать одну тепловую карту с использованием ggplot2, которая содержит 3 типа переменных, для каждой из которых нужна собственная независимая легенда / масштаб.

Я могу изобразить их все на одной тепловой карте (изображенной ниже), но у меня возникают проблемы с их разделением, чтобы иметь собственную легенду. Мои три категории - это строка «Оценка», «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 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, состоящий из больших сплошных квадратов. Это позволяет использовать как цветовую шкалу, так и шкалу заливки.

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