Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Label particular datapoints with text and box (and arrows) in ggplot

Tags:

r

ggplot2

I have a scatterplot and the underlying regression model. I would like to give a nice example on another datapoint (assume not included in the estimation sample), i.e. it's actual versus predicted value. I have everything ready but for the labels (thinking about geom_text or geom_label, nothing working so far):

data(mtcars)

model <- lm(mpg ~ wt, data=mtcars)
mycar <- data.frame(wt=c(2.5))
predict(model, mycar)

model <- lm(Coupon ~ Total, data=df)
mycar <- data.frame(Total=c(79037022, 83100656, 104299800))
predict(model, new.df)

ggplot(mtcars, aes(x=wt, y=mpg)) +
  geom_point() +
  geom_smooth(method="lm", se=FALSE) +
  geom_point(aes(x=2.5,y=23.92395),   # red is the prediction for my car
             color='red',
             size=3, show.legend = TRUE) + 
  geom_point(aes(x=2.5,y=28),         # green is the actual mpg of my car
             color='green',
             size=3) 

enter image description here

I am flexible at the exact implementation:

  • Text may be in same colour as datapoint (without line or arrow)
  • Text in black colour with line or arrow (would require a box background since in real data the datacloud is almost black everywhere)
  • There could be a legend which maps the colour of manual added points to text label (alhtough I fancy the label next to the data points).
  • ...

I am looking for something easy to implement and visually appealing. Thank you

like image 224
Marco Avatar asked Oct 26 '25 05:10

Marco


2 Answers

I recommend the ggrepel package which provide some functionality to avoid overlap with exsting items already drawed on the plot especially when you have multiple labels/text

library(ggplot2)
library(ggrepel)
data(mtcars)

model <- lm(mpg ~ wt, data = mtcars)
mycar <- data.frame(wt = c(2.5))

ggplot() +
  geom_point(data = mtcars, aes(x = wt, y = mpg)) +
  geom_smooth(data = mtcars, aes(x = wt, y = mpg), method = "lm", se = FALSE) +
  geom_point(aes(x = 2.5, y = 23.92395), # red is the prediction for my car
    color = "red",
    size = 3, show.legend = TRUE
  ) +
  geom_point(aes(x = 2.5, y = 28), # green is the actual mpg of my car
    color = "green",
    size = 3
  ) +
  geom_label_repel(aes(x = 2.5, y = 23.92395),
    # using nudge_x & nudge_y to manual adjust the location to avoid
    # label overlay on a data point around 3.5 & 25    
    color = "red", label = "My car prediction", nudge_x = .5, nudge_y = 1.5
  ) +
  geom_label_repel(aes(x = 2.5, y = 28),
    color = "green", label = "My actual car", nudge_x = .5, nudge_y = 1
  )
#> `geom_smooth()` using formula 'y ~ x'

ggplot() +
  geom_point(data = mtcars, aes(x = wt, y = mpg)) +
  geom_smooth(data = mtcars, aes(x = wt, y = mpg), method = "lm", se = FALSE) +
  geom_point(aes(x = 2.5, y = 23.92395), # red is the prediction for my car
    color = "red",
    size = 3, show.legend = TRUE
  ) +
  geom_point(aes(x = 2.5, y = 28), # green is the actual mpg of my car
    color = "green",
    size = 3
  ) +
  geom_text_repel(aes(x = 2.5, y = 23.92395),
    color = "red", label = "My car prediction", nudge_x = .5, nudge_y = 1
  ) +
  geom_text_repel(aes(x = 2.5, y = 28),
    color = "green", label = "My actual car", nudge_x = .5, nudge_y = 1
  )
#> `geom_smooth()` using formula 'y ~ x'

Created on 2021-05-04 by the reprex package (v2.0.0)

like image 183
Sinh Nguyen Avatar answered Oct 28 '25 20:10

Sinh Nguyen


It works with either geom_label or geom_text functions; A couple of examples to allow visual effect to be judged; Mix and match and play with arguments to get the appearance you desire.

library(ggplot2)

ggplot(mtcars, aes(x=wt, y=mpg)) +
  geom_point() +
  geom_smooth(method="lm", se=FALSE) +
  geom_point(aes(x=2.5,y=23.92395),
             color='red',
             size=3, show.legend = TRUE) + 
  geom_label(aes(x=2.5,y=23.92395, label = "My car prediction"), size=3,
             hjust = 0, vjust =  "inward",
             nudge_x = 0.05, nudge_y = 2,
             label.padding = unit(0.5, "lines")) +
  geom_point(aes(x=2.5,y=28),
             color='green',
             size=3) +
  geom_label(aes(x=2.5,y=28, label = "My actual car"), size=3,
             hjust = 0, vjust = "inward",
             nudge_x = 0.05, nudge_y = 2,
             label.padding = unit(0.5, "lines"))
#> `geom_smooth()` using formula 'y ~ x'


ggplot(mtcars, aes(x=wt, y=mpg)) +
  geom_point() +
  geom_smooth(method="lm", se=FALSE) +
  geom_point(aes(x=2.5,y=23.92395),   # red is the prediction for my car
             color='red',
             size=3, show.legend = TRUE) + 
  geom_text(aes(x=2.5,y=23.92395, label = "My car prediction"), size=4, colour = "red", hjust = -0.1, vjust = -0.2, check_overlap = TRUE ) + 
  
  geom_point(aes(x=2.5,y=28),         # green is the actual mpg of my car
             color='green',
             size=3) +
  geom_text(aes(x=2.5,y=28, label = "My actual car"), colour = "green", size=4, hjust = -0.1, vjust = -0.2, check_overlap = TRUE )
#> `geom_smooth()` using formula 'y ~ x'

Created on 2021-05-04 by the reprex package (v2.0.0)

like image 38
Peter Avatar answered Oct 28 '25 19:10

Peter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!