Create dynamic labels for geom_smooth lines

2019-07-08 10:24发布

I have a changing df and I am grouping different values c. With ggplot2 I plot them with the following code to get a scatterplott with multiple linear regression lines (geom_smooth)

ggplot(aes(x = a, y = b, group = c)) + 
  geom_point(shape = 1, aes(color = c), alpha = alpha) +
  geom_smooth(method = "lm", aes(group = c, color = c), se = F)

Now I want to display on each geom_smooth line in the plot a label with the value of the group c. This has to be dynamic, because I can not write new code when my df changes.


Example: my df looks like this

  a     b     c
----------------
 1.6    24   100
-1.4    43   50
 1      28   100
 4.3    11   50
-3.45   5.2  50

So in this case I would get 3 geom_smooth lines in the plot with different colors.

Now I simply want to add a text label to the plot with "100" next to the geom_smooth with the group c = 100 and a text label with "50"to the line for the group c = 50, and so on... as new groups get introduced in the df, new geom_smooth lines are plotted and need to be labeled.


the whole code for the plot:

 ggplot(aes(x = a, y = b, group = c), data = df, na.rm = TRUE) + 
  geom_point(aes(color = GG, size = factor(c)), alpha=0.3) +
  scale_x_continuous(limits = c(-200,2300))+
  scale_y_continuous(limits = c(-1.8,1.5))+
  geom_hline(yintercept=0, size=0.4, color="black") +
  scale_color_distiller(palette="YlGnBu", na.value="white") +
  geom_smooth(method = "lm", aes(group = factor(GG), color = GG), se = F) +
  geom_label_repel(data = labelInfo, aes(x= max, y = predAtMax, label = label, color = label))

标签: r plot ggplot2
1条回答
时光不老,我们不散
2楼-- · 2019-07-08 11:10

You can probably do it if you pick the location you want the lines labelled. Below, I set them to label at the far right end of each line, and used ggrepel to avoid overlapping labels:

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

set.seed(12345)

df <- 
  data.frame(
    a = rnorm(100,2,0.5)
    , b = rnorm(100, 20, 5)
    , c = factor(sample(c(50,100,150), 100, TRUE))
  )

labelInfo <-
  split(df, df$c) %>%
  lapply(function(x){
    data.frame(
      predAtMax = lm(b~a, data=x) %>%
        predict(newdata = data.frame(a = max(x$a)))
      , max = max(x$a)
    )}) %>%
  bind_rows

labelInfo$label = levels(df$c)

ggplot(
  df
  , aes(x = a, y = b, color = c)
  ) + 
  geom_point(shape = 1) +
  geom_smooth(method = "lm", se = F) +
  geom_label_repel(data = labelInfo
                   , aes(x= max
                         , y = predAtMax
                         , label = label
                         , color = label))
查看更多
登录 后发表回答