Adding a custom symbol next to y-axis label

Viewed 179

Is there any way to add a custom symbol alongside a y-axis label in ggplot? I would like to add a small circle next to each racer's name indicating their respective line color a la image below (also recognize Maria's blue is more purple, but that's MS Paint for you).

enter image description here

library(ggplot2)
library(scales)
dat <- data.frame(name = c(rep("bill", 3), rep("maria", 3), rep("claudio", 3)),
                  lap = rep(0:2, 3),
                  pos = c(1, 1, 2, 
                          2, 3, 1,
                          3, 2, 3))

dat %>% 
  ggplot(aes(x = lap, y = pos, color = name)) +
  geom_line() +
  scale_y_reverse(breaks = 1:3,
                  labels = function(x) {
                    dat$name[dat$lap == 0][order(dat$pos[dat$lap == 0])][x]
                    },
                  sec.axis = sec_axis(function(x) x, 
                                      breaks = 1:3, labels = label_ordinal())) +
  scale_x_continuous(breaks = pretty_breaks(3)) +
  theme(legend.position = "none")
1 Answers

This is not an answer to your question but an alternative solving a similar problem. Instead of trying to fiddle around with symbols, you could use the ggtext() package to colour the text itself the same as your lines.

You'd need 3 things:

  • Colour the text in html syntax
  • Provide the coloured text as the labels argument
  • Set the theme element to interpret the text as markdown
library(ggplot2)
library(scales)
library(ggtext)
#> Warning: package 'ggtext' was built under R version 4.0.3

dat <- data.frame(name = c(rep("bill", 3), rep("maria", 3), rep("claudio", 3)),
                  lap = rep(0:2, 3),
                  pos = c(1, 1, 2, 
                          2, 3, 1,
                          3, 2, 3))

colors <- hue_pal()(3)[c(1,3,2)]
labels <- glue::glue("<i style='color:{colors}'>{unique(dat$name)}</i>")

ggplot(dat, aes(x = lap, y = pos, color = name)) +
  geom_line() +
  scale_y_reverse(breaks = 1:3,
                  labels = labels,
                  sec.axis = sec_axis(function(x) x, 
                                      breaks = 1:3, labels = label_ordinal())) +
  scale_x_continuous(breaks = pretty_breaks(3)) +
  theme(legend.position = "none",
        axis.text.y.left = element_markdown())

Created on 2021-01-03 by the reprex package (v0.3.0)

EDIT: If you insist on the circle, you can take the same approach to colour a unicode circle character. Use the code below instead of the previous labels.

labels <- glue::glue("{unique(dat$name)} <i style='color:{colors}'>\u25CF</i>")
Related