Ggplot2 different text colors for each legend label

I'm trying to get the text color of legend labels to match their respective fill / line colors. Ideally, I would like to match the color of the label with the aesthetics, but at this point I would be just as happy to manually specify the colors. Here are some test codes using PlantGrowth's built-in dataset that includes my attempt to manually specify label colors:

ggplot(data=PlantGrowth, aes(x=group, y=weight, fill=group)) +
    geom_boxplot() +
    scale_fill_discrete(guide=guide_legend(label.theme=element_text(angle=0,
                                                                    size=9,
                                                                    color=c("red",
                                                                            "green",
                                                                            "blue"))))

      

When I run this code, the legend labels use the first color I specify (red). Instead, I want each legend label to use a different color. Is this currently possible in ggplot2?

+3


source to share


1 answer


First of all, I tried experimenting with different versions of your current attempt, as well as with help theme(legend.text = element_text(color = c("red","blue","green")))

, but none of the above did so, so I had to switch to gtable

s.

What you want is possible, but requires you to be familiar with packages gtable

and gtable

. It will look very messy because there are many nested lists and the object we ultimately want to change is at the bottom. Just bear with me:



library(ggplot2)
library(gtable)
library(grid)
pGrob <- ggplotGrob(ggplot(data=PlantGrowth, aes(x=group, y=weight, fill=group)) +
  geom_boxplot() +
  scale_fill_discrete(guide=guide_legend(label.theme=element_text(angle=0,
                                                                  size=9))))



gb <- which(grepl("guide-box", pGrob$layout$name))
gb2 <- which(grepl("guides", pGrob$grobs[[gb]]$layout$name))
label_text <- which(grepl("label",pGrob$grobs[[gb]]$grobs[[gb2]]$layout$name))
pGrob$grobs[[gb]]$grobs[[gb2]]$grobs[label_text] <- mapply(FUN = function(x, y) {x$gp$col <- y; return(x)},
                                                           x =   pGrob$grobs[[gb]]$grobs[[gb2]]$grobs[label_text],
                                                           y =   c("red", "green", "blue"), SIMPLIFY = FALSE)

grid.draw(pGrob)

      

enter image description here

The first three lines, which create gb

, gb2

and label_text

, are for dynamically moving to the bottom level that we want to change. Once we have our path for obtaining objects, we can modify them with mapply

and change them col

to the vector you need.

+3


source







All Articles