Reputation: 53
I'm using geom_raster and geom_text to put a letter on each of the coloured rectangles in my plot. I'd like this letter to appear on top of the color boxes in the legend as well, but cannot figure out how.
I've tried adding show.legend=TRUE
to the geom_text
, but this results in the letter 'a' in each legend key, instead of the desired character.
The desired result looks as follows:
Here is code to reproduce the basic plot:
library(tidyverse)
d <-tribble(
~a, ~b, ~c,
"a", "l", "A",
"a", "r", "F",
"b", "l", "Q",
"b", "r", "R"
)
ggplot(data=d, aes(x=a, y=b, fill=c)) +
geom_raster(na.rm=TRUE) +
geom_text(aes(label=c), size=3, na.rm=TRUE)
And the output:
This might be related to this issue: https://github.com/tidyverse/ggplot2/issues/2004, but perhaps there's a workaround?
Upvotes: 5
Views: 962
Reputation: 29085
You can hack it after turning the ggplot object into a grob:
# store the original ggplot object as p
p <- ggplot(data=d, aes(x=a, y=b, fill=c)) +
geom_raster(na.rm=TRUE) +
geom_text(aes(label=c), size=3, na.rm=TRUE, show.legend = TRUE)
# convert to grob
gp <- ggplotGrob(p)
grid::grid.draw(gp) # can verify the plot here. Should look the same as before.
Now we can examine the hierarchical structure of the grob object to find appropriate slots to change the legend keys. It's possible to do this programmatically as well, but unless your use case involves generating many different charts with different number of legend keys, I find it easier to read off the console output:
gp # this shows the 15th grob in gp corresponds to "guide-box" (i.e. legend)
gp$grobs[15][[1]] # this shows the the first grob of the above corresponds to "guides"
gp$grobs[15][[1]]$grobs[1][[1]]
# this shows the 5th / 8th / 11th / 14th grobs of the above correspond to the text on legend keys
str(gp$grobs[15][[1]]$grobs[1][[1]]$grobs[5][[1]])
# each of the legend key texts is a list, with a slot for "label"
Change the legend keys accordingly:
gp$grobs[15][[1]]$grobs[1][[1]]$grobs[5][[1]]$label <- "A"
gp$grobs[15][[1]]$grobs[1][[1]]$grobs[8][[1]]$label <- "F"
gp$grobs[15][[1]]$grobs[1][[1]]$grobs[11][[1]]$label <- "Q"
gp$grobs[15][[1]]$grobs[1][[1]]$grobs[14][[1]]$label <- "R"
# check the amended plot
grid::grid.draw(gp)
Upvotes: 2
Reputation: 28339
You can use geom_point
instead and specify point shape as letters with scale_shape_manual(values = d$c)
.
# We have to remove legend text and label with theme
ggplot(d, aes(a, b, fill = c, shape = c)) +
geom_raster() +
geom_point(size = 3) +
scale_shape_manual(values = d$c) +
theme(legend.text = element_text(size = 0),
legend.title = element_text(size = 0))
Upvotes: 5