0

I have a df "test_data", which contains values of the recent year ("recent"), the year before ("before") and the difference between these two ("delta").

in the given ggplot, the points are coloured according to the value of "delta" with scale_color_gradient2.

Line segments are drawn to link the points with the dashed line.

I was only able to colour all negative deltas in one colour (red) and all positive deltas in one colour (green), which does not reflect delta.

Is there a way to colour the line segments according to delta, like with scale_color_gradient2 for the points?

reproducable code:


library(ggplot2)
library(dplyr)

test_data<-structure(list(recent = c(65.2997185753145, 59.7196309660111,
                                     69.6283618162288, 72.8567667757411, 75.5042106908949, 65.9349599258225, 
                                     63.821946931775, 84.5492780693781, 70.1954593423904, 68.7330477506608, 
                                     74.7016955531504, 71.0329793728603, 90.8076584032142, 72.1556242719194),
                          before = c(68.1971224074475, 53.6815581922758, 67.3141074572482,
                                     70.8701488937935, 73.9713609414785, 63.2296191743796, 56.6943338152896, 
                                     81.7035240884654, 77.3175553964688, 69.7366705789213, 78.2019304405689, 
                                     71.6072916545225, 86.8455685297511, 75.7745946931338),
                          delta = c(-2.89740383213299, 6.03807277373529, 2.31425435898061, 
                                    1.98661788194759, 1.5328497494164, 2.7053407514429, 7.1276131164854, 
                                    2.8457539809127, -7.1220960540784, -1.0036228282605, -3.5002348874185, 
                                    -0.574312281662188, 3.96208987346309, -3.6189704212144)),
                     
                     row.names = c(NA,-14L),
                     class = "data.frame")
               
  
                                                                                                          

test_data<-test_data%>%
  mutate(x1_neg=case_when(delta<0 ~ before),
         y1_neg=case_when(delta<0 ~ recent),
         x2_neg=case_when(delta<0 ~ recent),
         y2_neg=case_when(delta<0 ~ recent))%>%
  mutate(x1_pos=case_when(delta>0 ~ before),
         y1_pos=case_when(delta>0 ~ recent),
         x2_pos=case_when(delta>0 ~ before),
         y2_pos=case_when(delta>0 ~ before))


plt<-ggplot(test_data, aes(x=before,y=recent))+
  geom_abline(slope=1,linetype = "dashed")+
  geom_segment(aes(x = x1_neg, y = y1_neg, xend = x2_neg, yend = y2_neg),
               colour="#E24C3B",
               size=1.3)+
  geom_segment(aes(x = x1_pos, y = y1_pos, xend = x2_pos, yend = y2_pos),
               colour="#ADCA1E",
               size=1.3)+
  geom_point(aes(color=delta),size=3)+
  scale_color_gradient2(high = "#ADCA1E",mid="#6ECFF6",low = "#E24C3B")+
  theme(plot.background = element_rect(fill = "#FFFFFF"),
        panel.background = element_rect(fill = "#FFFFFF"),
        axis.line = element_line(colour = "black"),
        panel.grid = element_line(colour = "#D2D0CF"),
        legend.justification = "bottom")+
  ylab("recent")+
  xlab("before")+
  coord_fixed()

x11(5,5)

plt


resulting plot

2
  • 1
    Map delta on color in geom_segment too? Commented Apr 4, 2023 at 10:11
  • yes you're right! never thought it was that easy. so it works, the result is exactly, what I want, but what I don't understand is how the colours are "synchronized" between the segment, mapped on color, and the points, coloured by scale_colour_gradient2() Commented Apr 4, 2023 at 11:07

1 Answer 1

0

as @stefan mentioned, "delta" can be mapped on color in geom_segment. so if the plot definition is adapted like this, it works:

plt<-ggplot(test_data, aes(x=before,y=recent))+
  geom_abline(slope=1,linetype = "dashed")+
  geom_segment(aes(x = x1_neg, y = y1_neg, xend = x2_neg, yend = y2_neg, colour=delta),
               size=1.3)+
  geom_segment(aes(x = x1_pos, y = y1_pos, xend = x2_pos, yend = y2_pos, colour=delta),
               size=1.3)+
  geom_point(aes(color=delta),size=3)+
  scale_color_gradient2(high = "#ADCA1E",mid="#6ECFF6",low = "#E24C3B")+
  theme(plot.background = element_rect(fill = "#FFFFFF"),
        panel.background = element_rect(fill = "#FFFFFF"),
        axis.line = element_line(colour = "black"),
        panel.grid = element_line(colour = "#D2D0CF"),
        legend.justification = "bottom")+
  ylab("recent")+
  xlab("before")+
  coord_fixed()

x11(5,5)

plt

with coloured segments

Sign up to request clarification or add additional context in comments.

1 Comment

you could make it even easier by using just one geom_segment, i.e. there is no need for _neg and _pos, just do mutate(x1 = before, y1 = recent, x2 = if_else(delta < 0, recent, before), y2 = if_else(delta < 0, recent, before)). For your question concerning the "sync" between the points and the segment. For both you map the same delta on the color aes. Hence both get assigned the same colour via scale_color_gradient2, i.e. the scale is not connected to a geom, it's connected to the aesthetic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.