Recoloring Legend Text Background in ggplot2

Viewed 128

Using this code:

ggplot(mtcars, aes(x=mtcars$mpg, y = mtcars$wt, color = as.factor(mtcars$cyl))) + geom_point()

I get a nice plot that looks like this:

enter image description here

For my purposes, I would like the legend to look something like this:

enter image description here

In words, I would like the background of the legend text for the color legend to match the label's respective color. Is there any simple way to do this?

EDIT: In my current code, I'm using ggtext with scale_color_hue(labels = colorLabels) where colorLabels looks like this <span style='color:red'>MyLabel</span> to have the text itself colored, but I don't like it so much and I want to see how I feel with the colors swapped. Switching color:red with background-color:red just removes the text color, doesn't actually color the background.

1 Answers

Here's a dirty hack, as ggplot does not provide an API to change the background of the labels.

Disclaimer: This methods assumes a certain structure of the underlying grobs which may not be guaranteed. Thus, use with care.

library(ggplot2)
library(grid)
library(gtable)


ToothGrowth$dose <- as.factor(ToothGrowth$dose)

p <- ggplot(ToothGrowth, aes(x=dose, y=len, fill=dose)) + 
  geom_boxplot()

## 1. Store ggplot object as grob
g <- ggplotGrob(p)

## 2. Find and retrieve the guidebox and guides
guide <- g$grobs[[which(g$layout$name == "guide-box")]]
guides <- guide$grobs[[which(guide$layout$name == "guides")]]

## 3. Get the fill colors of the guide
## N.B. This works in this toy example because the key has a fill property, 
## this may be different for other geoms
cols <- vapply(guides$grobs[grep("^key.+[^b][^g]$", guides$layout$name)],
               function(gt) gt$gp$fill, character(1))

## 4. Get the positions of the labels
pos <- guides$layout[grep("^label", guides$layout$name), 
                     c("t", "l", "b", "r", "z")]

## 5. Add colored rects below the labels
## N.B. These span the width of labels
## some more work would be needed to make them bigger and/or center the labels
for (i in seq_along(cols)) {
  guides <- gtable_add_grob(guides,
                            rectGrob(gp = gpar(fill = cols[i])),
                            pos[i, "t"],
                            pos[i, "l"],
                            pos[i, "b"],
                            pos[i, "r"],
                            pos[i, "z"] - 1,
                            name = paste0("key-bg-", i))
}

## 6. Write back the guides to the original object
guide$grobs[[which(guide$layout$name == "guides")]] <- guides
g$grobs[[which(g$layout$name == "guide-box")]] <- guide

## 7. Draw the graph
grid.draw(g)

Colored Keys

Related