0

From this SO answer I've constructed a geom_point() with a geom_line() that connect across NAs.With the code and data below I get something like this:

old

I would however like the color to change midway between -1 and 1, and not at the next node (so to speak). I imagine something like this:

neew

How can I do this in a simple way?

Here's the code I've used so far.

df <- data.frame(
  x = c(-3, -2, -1, 1, 2, 3, -3, -2, -1, 1, 2, 3),
  y = c(2.5, NA, 2, 3, NA, 4, 1.5, 3.5, NA, NA, 2, 1),
  typ = factor(c('Before x', 'Before x', 'Before x', 'After x', 'After x',
                 'After x', 'Before x', 'Before x', 'Before x', 'After x',
                 'After x', 'After x')), 
  grp = c(rep(1, 6), rep(2, 6)) ) # df

df$x2 <- with(df, ifelse(x < 0, x+.5, x-.5))

library(ggplot2)

ggplot(df[!is.na(df$y),], 
       aes(x2, y, group = grp, colour = typ)) + 
  geom_point() + 
  geom_line() + 
  scale_x_continuous(breaks = c(-2.5, -1.5, -.5, 0.5, 1.5, 2.5), 
                     labels = c(-3:-1, 1:3)) +
  scale_fill_brewer(palette="Spectral")
Z.Lin
  • 28,055
  • 6
  • 54
  • 94
Eric Fail
  • 8,191
  • 8
  • 72
  • 128
  • My guess is the best way to do this is to add points for `x2 = 0` to your data set, and then filter them off the `geom_point` call. – Mako212 Oct 24 '17 at 15:31

1 Answers1

1

As Mako212 commented, you can add points at the midway for each group, between the two types:

library(dplyr)

df2 <- df %>% 
  filter(!is.na(y)) %>% 
  select(grp, x2, y, typ)

df2 <- rbind(df2 %>% mutate(pt.alpha = 1),
             df2 %>%
               group_by(grp, typ) %>%
               arrange(x2) %>%
               mutate(isMin = x2 == min(x2),
                      isMax = x2 == max(x2)) %>%
               ungroup() %>%
               filter((typ == "Before x" & isMax) | 
                        (typ == "After x" & isMin)) %>%
               group_by(grp) %>%
               summarize(x2 = mean(x2),
                         y = mean(y)) %>%
               mutate(typ = "After x",
                      pt.alpha = 0))

> df2
   grp   x2    y      typ pt.alpha
1    1 -2.5 2.50 Before x        1
2    1 -0.5 2.00 Before x        1
3    1  0.5 3.00  After x        1
4    1  2.5 4.00  After x        1
5    2 -2.5 1.50 Before x        1
6    2 -1.5 3.50 Before x        1
7    2  1.5 2.00  After x        1
8    2  2.5 1.00  After x        1
9    1  0.0 2.50  After x        0
10   2  0.0 2.75  After x        0

Plot (line size increased to show colour change):

ggplot(df2,
       aes(x2, y,  group = grp, colour = typ)) + 
  geom_point(aes(alpha = pt.alpha), size = 4) + 
  geom_line(size = 2) +
  scale_x_continuous(breaks = seq(-2.5, 2.5, 1), 
                     labels = c(-3:-1, 1:3)) +
  scale_alpha_identity()

plot

I did not specify a palette for line colour, as it's not part of the question, but you may wish to switch scale_fill_XX for scale_colour_XX if you're working with line colours.

Z.Lin
  • 28,055
  • 6
  • 54
  • 94