R ggplot heatmap avec plusieurs lignes ayant des légendes distinctes sur le même graphique
J'essaie de créer une carte thermique en utilisant ggplot2 qui contient 3 types de variables où chacune a besoin de sa propre légende/échelle indépendante.
Je suis capable de les tracer tous dans une carte thermique (photo ci-dessous), mais j'ai du mal à les séparer pour avoir leur propre légende. Mes trois catégories sont la ligne "Score", "samp1" et le reste des données. J'aimerais que chacun d'eux ait ses propres légendes indépendantes avec ses gammes respectives.
Mon seul ajout serait que le score de ligne ait un jeu de couleurs vert, jaune, rouge (bas, moyen, élevé), si cela est possible à inclure dans cette question.

C'est le code que j'utilise pour créer ce graphique
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
J'ai utilisé des facettes pour séparer les données par échantillon et par les 3 catégories que j'ai décrites ci-dessus. J'espérais utiliser ce regroupement pour créer également leurs propres légendes, mais je ne suis pas sûr que cela soit possible.
Cliquez ici pour télécharger les données (pré-fondues).
Merci en avance.
Réponses
Cela pourrait être réalisé via le ggnewscale
package comme ceci:
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()
)
Je suggérerais la prochaine approche. Divisez les données par groupes, puis créez un graphique séparé pour chaque groupe avec une fonction. Enfin, utilisez purrr
et patchwork
pour joindre tous les tracés avec les différentes légendes. Ici le code :
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')
Le résultat:

Vous pouvez explorer plus en détail patchwork
et comment joindre plusieurs parcelles.
Il est certes possible de faire 3 tracés et de les coller ensemble, mais étant donné que les facettes sont de formes différentes, ce n'est pas l'idéal. Vous pouvez utiliser le ggnewscale
package selon Stefan, ce qui est plus facile maintenant qu'il est sur CRAN, mais si vous voulez le faire dans un seul ggplot sans add-ons, c'est possible . Il vous suffit de tracer un geom_point
composé de grands carrés pleins. Cela vous permet d'utiliser une échelle de couleurs ainsi qu'une échelle de remplissage.
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"))
