R ggplot mapa de calor con múltiples filas que tienen leyendas separadas en el mismo gráfico
Estoy tratando de hacer un mapa de calor usando ggplot2 que contiene 3 tipos de variables donde cada una necesita su propia leyenda/escala independiente.
Puedo trazarlos a todos en un mapa de calor (en la imagen a continuación), pero tengo problemas para separarlos para tener su propia leyenda. Mis tres categorías son la fila "Puntuación", "muestra1" y el resto de los datos. Me gustaría que cada uno de estos tuviera sus propias leyendas independientes con sus respectivos rangos.
Mi única adición sería que la puntuación de la fila tenga un esquema de color verde, amarillo, rojo (bajo, medio, alto), si es posible incluirlo en esta pregunta.

Este es el código que estoy usando para crear ese gráfico.
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
He usado facetas para separar los datos por muestra y por las 3 categorías que describí anteriormente. Tenía la esperanza de usar esta agrupación para crear sus propias leyendas también, pero no estoy seguro de si esto es posible.
Haga clic aquí para descargar los datos (pre-fundidos).
Gracias de antemano.
Respuestas
Esto podría lograrse a través del ggnewscale
paquete así:
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()
)
Sugeriría el siguiente enfoque. Divida los datos por grupos y luego construya una gráfica separada para cada grupo con una función. Finalmente usa purrr
y patchwork
para unir todas las parcelas con las diferentes leyendas. Aquí el código:
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')
La salida:

Puede explorar más sobre patchwork
y cómo unir múltiples parcelas.
Ciertamente es posible hacer 3 tramas y unirlas, pero dado que las facetas tienen formas diferentes, esto no es lo ideal. Puede usar el ggnewscale
paquete según Stefan, que es más fácil ahora que está en CRAN, pero si desea hacerlo en un solo ggplot sin complementos, es posible. Solo necesita trazar una geom_point
que esté hecha de grandes cuadrados sólidos. Esto le permite usar una escala de color así como una escala de relleno.
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"))
