Given this matrix where on the x-axis are the latent values (1,2,3,4) and on the y-axis three levels for each drug (RAS, BB and AA). Each box of the matrix contains values between 0 and 1, I would like the boxes colored with an increasing colour gradient based on the value shown, with legends different for each drug.
Currently, for each row of each drug, the boxes are colored in the same color (RAS-ivory, BB-darkred, MRA-darkblue ). I would like to create three legends where each legend has a continuous scale of colors (from light to dark) and color the matrix according to its value.
#Dataframe
df <-data.frame(category=rep(c(0,1,2),12),
state=c(rep(1,3),rep(2,3),rep(3,3),rep(4,3)),
value=runif(36),
drug = c(rep("RAS",12),rep("BB",12),rep("AA",12)),
cat_drug = paste(rep(c(0,1,2),12),sep="_",c(rep("RAS",12),rep("BB",12), rep("AA",12))))
#Different color for each drug
color_scale <- c("RAS" = "ivory", "BB" = "darkred", "AA" = "darkblue")
ggplot(Psi, aes(y = cat_drug, x = state, fill = drug, label = round(value, 3))) +
geom_raster() +
geom_text(color = "black") +
scale_fill_manual(values = color_scale, name = "Drug") +
guides(fill = guide_colourbar(title = "Drug")) +
labs(y = "Level of adherence", x = "Latent state") +
theme_bw() +
theme(
axis.text.x = element_text(size = 9, angle = 0, vjust = 0.3),
axis.text.y = element_text(size = 9),
plot.title = element_text(size = 11),
legend.position = "right"
)

One option to have multiple scales and legends for the same aesthetic is to use the
ggnewscalepackage. However, doing so requires some additional effort in that we have to use multiplegeomlayers, i.e. one for each of yourdrugs and of course multiplescales. To avoid copy & paste I split the data bydrug, then usepurrr::imapto loop over the splitted data and add the layers. Unfortunately I ran in some issue withgeom_rasterso I switched togeom_tilewhich also requires to set theheightof the tiles. Finally note that I usescale_fill_distillerand some of the Brewer color palettes.