0

I'm trying to do a line graph and have the last point of each series be labelled by a combination of text and image. I usually use ggrepel package for this and have no problem doing this with text only. My problem is I can't figure out how to add an image in the label.

I thought that a label like Country <img src='https://link.com/to/flag.png' width='20'/> would work and so this is what I've tried to do:

library(dplyr)
library(ggplot2)
library(ggrepel)

# example df
df <- data.frame(
  Country = c(rep("France", 5), rep("United Kingdom", 5)),
  Ratio = rnorm(10),
  Days = c(seq(1, 5, 1), seq(4, 8, 1)),
  abbr = c(rep("FR", 5), rep("GB", 5))) %>% 
  group_by(Country) %>% 
  
  # add "label" only to last point of the graph
  mutate(label = if_else(Days == max(Days), 
                         # combine text and img of country's flag
                         true = paste0(Country, " <img src='https://raw.githubusercontent.com/behdad/region-flags/gh-pages/png/", abbr, ".png' width='20'/>"), 
                         false = NA_character_)
  )
  

# line graph
ggplot(data = df, aes(x = Days, y = Ratio, color = Country)) +
  geom_line(size = 1) +
  theme(legend.position = "none") +
  
  geom_label_repel(aes(label = label),
                   nudge_x = 1,
                   na.rm = T)

But this produces the raw label and not the country's name with its flag, as intended:

enter image description here

This is obviously not the way to go, can anyone please help me?

MonkeyBack
  • 61
  • 6

1 Answers1

0

Try this approach using ggtext function geom_richtext(). You can customize other elements if you wish. Here the code:

library(dplyr)
library(ggplot2)
library(ggrepel)
library(ggtext)
# example df
df <- data.frame(
  Country = c(rep("France", 5), rep("United Kingdom", 5)),
  Ratio = rnorm(10),
  Days = c(seq(1, 5, 1), seq(4, 8, 1)),
  abbr = c(rep("FR", 5), rep("GB", 5))) %>% 
  group_by(Country) %>% 
  
  # add "label" only to last point of the graph
  mutate(label = if_else(Days == max(Days), 
                         # combine text and img of country's flag
                         true = paste0(Country, " <img src='https://raw.githubusercontent.com/behdad/region-flags/gh-pages/png/", abbr, ".png' width='20'/>"), 
                         false = NA_character_)
  )


# line graph
ggplot(data = df, aes(x = Days, y = Ratio, color = Country,label = label)) +
  geom_line(size = 1) +
  theme(legend.position = "none") +
  geom_richtext(na.rm = T,nudge_x = -0.1,nudge_y = -0.1)

Output:

enter image description here

Duck
  • 39,058
  • 13
  • 42
  • 84
  • Thanks @Duck, this works on principle on this example, however my real dataset has more than two series, with most of them ending at similar values. My problem now is that the labels don't repel each other anymore and the graph is not legible. – MonkeyBack Oct 16 '20 at 20:55
  • @MonkeyBack Try testing the ggrepel arguments in the function from `ggtext`. It must be an option such as `checkoverlap=T` that can arrange labels better! – Duck Oct 16 '20 at 20:57
  • I just found [this](https://github.com/slowkow/ggrepel/issues/169) on `ggrepel` GitHub, so it looks like it's not yet possible with `ggrepel`. And I'm guessing that since people are asking for the features of `ggtext` within `ggrepel`, it must be because `ggrepel` features are also not available within `ggtext`... – MonkeyBack Oct 16 '20 at 21:13
  • @MonkeyBack In that case my suggestion would be select some countries to be plotted or create groups and use facets so that they can be separated! – Duck Oct 16 '20 at 21:15