R ggplot тепловая карта с несколькими строками, имеющими отдельные легенды на одном графике
Я пытаюсь создать одну тепловую карту с использованием 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
Я использовал фасеты, чтобы разделить данные по образцам и по трем категориям, которые я описал выше. Я надеялся использовать эту группировку для создания собственных легенд, но не уверен, возможно ли это.
Щелкните здесь, чтобы загрузить данные (предварительно расплавленные).
Заранее спасибо.
Ответы
Этого можно добиться с помощью такого 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()
)
Я бы предложил следующий подход. Разделите данные по группам, а затем постройте отдельный график для каждой группы с функцией. Наконец, используйте 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
узнать о том, как объединить несколько сюжетов.
Конечно, можно сделать 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"))
