Bring labels to the front and leaders to the back using geom_label_repel in R

Viewed 416

new here and semi-new to R so hoping I can frame this question correctly.

I have data that looks like this (full dataset at the end):

Peak     Length    Height    Class   Label
Peak 16  16.542   1128.60   Class 2  Peak 16
Peak 10  16.592   74909.84  Class 4  Peak 10
Peak 6   16.930   21747.10  Class 2  Peak 6
Peak 9   17.177   98380.79  Class 2  Peak 9
Peak 20  17.235   168036.36 Class 4  Peak 20
Peak 11  17.264   85770.79  Class 5  Peak 11

I am making a plot with labels using geom_label_repel, the code as follows:

library(ggplot)
library(ggrepel)

ggplot(data = df, aes(x = Length, y = Height, color = Class)) +
  geom_col()+
  geom_label_repel(aes(label = Label),
                   fill = "white",
                   color = "black",
                   nudge_x = 0.2,
                   force= 2,
                   segment.alpha = 0.5)

The resulting plot is fine but I'm trying to figure out a way to make sure that the peak labels end up in front of any leader lines.

enter image description here

Maybe you can see that the "Peak 17" label is overlain with the leader line from "Peak 3." I've used nudge_x, nudge_y and force to move labels around, but my full dataset has many more peaks and labels, so I always end up with leaders over the labels.

Any help would be appreciated and glad I found this site!

Full data:

df <- structure(list(Peak = structure(c(8L, 2L, 18L, 21L, 13L, 3L, 
1L, 4L, 14L, 6L, 17L, 16L, 12L, 5L, 7L, 10L, 9L, 15L, 20L, 5L, 
11L, 19L), .Label = c("Peak 1", "Peak 10", "Peak 11", "Peak 12", 
"Peak 13", "Peak 14", "Peak 15", "Peak 16", "Peak 17", "Peak 18", 
"Peak 19", "Peak 2", "Peak 20", "Peak 21", "Peak 3", "Peak 4", 
"Peak 5", "Peak 6", "Peak 7", "Peak 8", "Peak 9"), class = "factor"), 
Length = c(16.542, 16.592, 16.93, 17.177, 17.235, 17.264, 
12.065, 12.33, 12.478, 13.844, 13.848, 14.565, 14.836, 14.903, 
15.425, 15.789, 16.542, 16.592, 16.93, 17.177, 17.235, 17.264
), Height = c(1128.6, 74909.84, 21747.1, 98380.79, 168036.36, 
85770.79, 77156.06, 204716.44, 146063.31, 126574.23, 387495.94, 
407584.38, 103778.66, 134615.45, 166271.98, 35626.38, 8076.28, 
14417.26, 6311.36, 1578.34, 408.42, 2920.28), Class = structure(c(2L, 
4L, 2L, 2L, 4L, 5L, 1L, 3L, 5L, 5L, 2L, 2L, 1L, 5L, 3L, 5L, 
5L, 1L, 3L, 5L, 3L, 3L), .Label = c("Class 1", "Class 2", 
"Class 3", "Class 4", "Class 5"), class = "factor"), Label = structure(c(8L, 
2L, 18L, 21L, 13L, 3L, 1L, 4L, 14L, 6L, 17L, 16L, 12L, 5L, 
7L, 10L, 9L, 15L, 20L, 5L, 11L, 19L), .Label = c("Peak 1", 
"Peak 10", "Peak 11", "Peak 12", "Peak 13", "Peak 14", "Peak 15", 
"Peak 16", "Peak 17", "Peak 18", "Peak 19", "Peak 2", "Peak 20", 
"Peak 21", "Peak 3", "Peak 4", "Peak 5", "Peak 6", "Peak 7", 
"Peak 8", "Peak 9"), class = "factor")), class = "data.frame", row.names = c(NA, 
-22L))
1 Answers

See if this works for you?

ggplot(data = df,
       aes(x = Length, y = Height, label = Label)) +

  # segment layer (alpha = 1 for segment & 0 for label)
  geom_label_repel(nudge_x = 0.2, force = 2, 
                   segment.alpha = 1, alpha = 0,
                   seed = 555) +

  # barchart layer sandwiched in between
  geom_col(aes(color = Class)) +

  # label layer (alpha = 0 for segment & 1 for label, same seed as before)
  geom_label_repel(nudge_x = 0.2, force = 2, 
                   segment.alpha = 0, alpha = 1,
                   seed = 555)

plot

Related