18

Is there somehow a trick to get the font within 'geom_label_repel' alpha=1 but the background maybe alpha=.2?

My problem is, that I have sometimes very dense plots. If I use just text, the text is not readable anymore. If I use label without transparency, the label is perfectly readable but I can not see behind the label. If I choose transparency for the label, then again, the font is no longer readable since it is also transparent and there is not enough contrast against the background.

What I would really love is a white shadow around the font :-)

Here is a minimal example do demonstrate the problem.

library(ggplot2)
library(ggrepel)
library(stringi)

set.seed(1)
df <- data.frame(x=rnorm(10000),
                 y=rnorm(10000),
                 label=NA)
df$label[1:26] <- stringi::stri_rand_strings(26,8)

ggplot(df, aes(x, y)) +
  geom_point(alpha=.3) +
  geom_label_repel(aes(label=label),
                   label.size = NA, 
                   alpha = 0.6, 
                   label.padding=.1, 
                   na.rm=TRUE) +
  theme_bw()

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94
drmariod
  • 11,106
  • 16
  • 64
  • 110

4 Answers4

16

Plot two labels, the second with no fill at all. Set the seed to make sure they perfectly overlap. (Using geom_text_repel doesn't seem to work as the repelling works slightly different.)

ggplot(df, aes(x, y)) +
  geom_point(alpha=.3) +
  geom_label_repel(aes(label=label),
                   label.size = NA, 
                   alpha = 0.6, 
                   label.padding=.1, 
                   na.rm=TRUE,
                   seed = 1234) +
  geom_label_repel(aes(label=label),
                   label.size = NA, 
                   alpha = 1, 
                   label.padding=.1, 
                   na.rm=TRUE,
                   fill = NA,
                   seed = 1234) +
  theme_bw()

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94
  • 2
    ahhhhh, the `seed` is a great idea... Thanks, in that way it works like expected. – drmariod Feb 01 '18 at 13:28
  • 1
    I have tried it on pie chart (with additional argument 'position = position_stack(vjust = 0.5)') and it not worked - it added labels in diffrent places – AAAA Jun 10 '18 at 17:22
  • same for me, eventhough the seed was the same, the labels were not 100% overlapping. – Olympia May 02 '22 at 08:41
16
ggplot(df, aes(x, y)) +
  geom_point(alpha=.3) +
  geom_label_repel(aes(label=label),
                       label.size = NA,  
                       label.padding=.1, 
                       na.rm=TRUE,
                       fill = alpha(c("white"),0.5))

This worked for me. You can set alpha with a color. Since the fill setting is only the background the text is unaffected. The advantage of this to overlaying the text is you can still use the "repel" to keep text from overlapping and not have to worry about getting two layers lining up properly

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • 1
    Nice and easy solution. Not sure if this didn't worked before or I just forgot to test it! Thanks! – drmariod May 15 '20 at 08:19
  • I get the following error: ! Aesthetics must be either length 1 or the same as the data (50) ✖ Fix the following mappings: `fill` – Olympia Jan 05 '23 at 10:55
  • No need to include the fill among the aesthetics of the plot. You can close the `aes` brackets and add the `fill` command. – Cosmin Saveanu Mar 02 '23 at 12:44
5

Maybe something like the following one:

library(ggplot2)
library(ggrepel)
library(stringi)

set.seed(1)
df <- data.frame(x=rnorm(10000),
                 y=rnorm(10000),
                 label=NA)
df$label[1:26] <- stringi::stri_rand_strings(26,8)

ggplot(df, aes(x, y)) +
    geom_point(alpha=.3) +
    geom_label_repel(aes(label=label),
                     label.size = NA, 
                     alpha = 0.75, 
                     fontface = 'bold', color = 'black',
                     box.padding = 0.80, point.padding = 0.5,
                     na.rm=TRUE) +
    theme_bw()

which gives: enter image description here

Scipione Sarlo
  • 1,470
  • 1
  • 17
  • 31
  • I haven't thought about moving the labels further out, also the bold font is easier to read! But am I right, that there is no functionality for having the font in `alpha=1` but the box in `alpha=.6`? – drmariod Feb 01 '18 at 09:16
  • ggplot(df, aes(x, y)) + geom_point(alpha=.25) + geom_label_repel(aes(label=label), label.size = NA, alpha = 1, fontface = 'bold', color = 'black', box.padding = 0.80, point.padding = 0.5, na.rm=TRUE) + theme_bw() – Scipione Sarlo Feb 01 '18 at 11:24
  • Is it what you're looking for? – Scipione Sarlo Feb 01 '18 at 13:44
  • 1
    No, it's not, the background of the labels is not transparent... I want to have the font solid but the background transparent... So this double layer approach by @Axeman is exactly what I was looking for. Just couldn't got the labels overlapping. – drmariod Feb 01 '18 at 13:47
1

Adding on to @spiketheaardvark, if you're getting an error such as

Error in check_aesthetics(): ! Aesthetics must be either length 1 or the same as the data (8): fill

Then remove the c() from within the alpha

Turning

fill = alpha(c("white"),0.5)

into

fill = alpha("white", 0.5)

The error is caused by the c() calling both solid and transparent white, without it is just calls the transparent white

ttalVlatt
  • 138
  • 6