-3

I have a plot with points on a polar coordinate system. Each point has an associated label, which should be shown around the plot at the given angle. This can be achieved either using axis.text or geom_text; I have used geom_text here. Unfortunately, the text labels overlap. Using position = position_jitter() apparently only allows jittering by height, but not by width (i.e., does not solve the issue). MWE:

df <- data.frame("angle" = runif(50, 0, 359),
                 "projection" = runif(50, 0, 1),
                 "labels" = paste0("label_", 1:50))

ggplot(data = df, aes(x = angle, y = projection, label = labels)) +
  geom_point() +
  coord_polar() + 
  theme_minimal() +
  geom_text(aes(x=angle, y=1.1,
                label=labels),
            size = 3)

enter image description here

I would like to jitter the labels such that they do not overlap, but stay outside the plotting area. I have also tried to use the angle argument to conditionally angle the labels to make more space, but couldn't figure out the right formula to make the angles work.


Edit: Here is another way to create the plot, using scale_x_continuous to create the labels as axis.text.x. This does, however, again lead to overlapping labels.

ggplot(data = df, aes(x = angle, y = projection, label = labels)) +
  geom_point() +
  coord_polar() +
  scale_x_continuous(limits = c(0, 360), expand = c(0, 0), breaks = df$angle, labels=df$labels) +
  theme_minimal() + 
  theme(panel.grid = element_blank())
simoncolumbus
  • 526
  • 1
  • 8
  • 23
  • How about this? https://stackoverflow.com/questions/40542685/how-to-jitter-remove-overlap-for-geom-text-labels – Edo Aug 13 '20 at 10:01
  • The first answer does not work---it uses position_jitter with a width argument, which does not work on polar coordinates. – simoncolumbus Aug 13 '20 at 12:21

1 Answers1

3

ggrepel will work well in this context.

library(ggplot2)
library(ggrepel)
df <- data.frame("angle" = runif(50, 0, 359),
                 "projection" = runif(50, 0, 1),
                 "labels" = paste0("label_", 1:50))


ggplot(data = df, aes(x = angle, y = projection, label = labels)) +
    geom_point() +
    coord_polar() + 
    theme_minimal() +
    geom_text_repel(size = 3)

enter image description here

csgroen
  • 2,511
  • 11
  • 28
  • ggrepel is neat (and an improvement of position_jitter()), but I was hoping to keep the labels on the 'rim' of the plot. – simoncolumbus Aug 13 '20 at 12:44
  • You could just do as you did for your example plot and set `geom_text_repel(aes(y = 1.1), size = 3)`. But then confusing which label belongs to which point. – csgroen Aug 14 '20 at 08:06