0

I have a line chart built using ggplot2. It looks following: Pic. 1

Lines are close to each other and data labels are overlapping. It is not convenient. It would be better if light red labels were below the line and green labels where there is room for them. Something of the sort:

Pic. 2

This post is helpful. However, I do not know in advance for which line it would be better to put labels above and for which it would be better to keep them below. Therefore I am looking for a generic solution.

ggrepel does a great job in organizing labels. But cannot figure out how to make it work in my case. I tried different parameters. Here is one of the simplest variants (not the best looking):

Pic. 3

Questions:

  1. Is there any way to make in R the chart look like on the 2nd picture?

  2. I think ggrepel computes the best label position taking into account the size of the chart. If I export the chart to PowerPoint, for example, the size of the PowerPoint chart might be different from the size used to get optimal data label positions. Is there any way to pass the size of the chart to ggrepel?

Here is a code I used to generate data and charts:

library(ggplot2)
library(ggrepel)

set.seed(1)
x = rep(1:20, 3)
y = c(runif(20, 10, 11),
      runif(20, 11, 12),
      runif(20, 12, 13))
z = rep(c("a", "b", "c"), each = 20)
df = data.frame(x = x, y = y, z = z)

ggplot(data = df, aes(x = x, y = y, group = z, color = z)) +
  geom_line() +
  geom_text(aes(label = round(y, 1)), nudge_y = 1) +
  ylim(c(0, 20))

ggplot(data = df, aes(x = x, y = y, group = z, color = z)) +
  geom_line() +
  geom_text_repel(aes(label = round(y, 1)), nudge_y = 1) +
  ylim(c(0, 20))
Serhii
  • 362
  • 4
  • 15
  • 3
    One thing you could do is just set the y limit so that it only shows between 10-13, which would give more room for the labels. You could also set the breaks to be smaller too, then just not use labels – AndrewGB Dec 04 '21 at 21:11

1 Answers1

0

Changing the theme to theme_bw() and removing gridlines from {ggExtra}'s removeGridX() gets the plot closer your second image. I also increased the size of the lines, limited the axes, and changed geom_text_repel to geom_label_repel to improve readability.

library(ggplot2)
library(ggrepel)
library(ggExtra)

set.seed(1)
x = rep(1:20, 3)
y = c(runif(20, 10, 11),
      runif(20, 11, 12),
      runif(20, 12, 13))
z = rep(c("a", "b", "c"), each = 20)
df = data.frame(x = x, y = y, z = z)

ggplot(data = df, aes(x = x, y = y, group = z, color = z)) +
  theme_bw() + removeGridX() +
  geom_line(size = 2) +
  geom_label_repel(aes(label = round(y, 1)), 
                  nudge_y = 0.5, 
                  point.size = NA, 
                  segment.color = NA,
                  min.segment.length = 0.1,
                  key_glyph = draw_key_path) +
  scale_x_continuous(breaks=seq(0,20,by=1))  +
  scale_y_continuous(breaks = seq(0, 14, 2), limits = c(0, 14))

enter image description here

jrcalabrese
  • 2,184
  • 3
  • 10
  • 30