1

I would like to get a single line passing through given points and having specified colors for values which are within specified intervals. But I can only get multiple lines of the specified colors rather than a single line which would change colors on its subintervals.

The reproducible example is as follows:

require(ggplot2)
require(plotly)

vectX <- c(-5,-4.5,-3.2,-2.1,-0.8,0.1,1.3,2.7,3.6,4.4,5)
vectY <- c(-2.3,1.4,2.7,0.3,-0.4,1.5,3.9,2.4,0.5,-1.2,1.4)

requestedQuantilesZscores <-  c(0.0,0.25,0.5,0.75,1.0)
zScores <- base::scale(vectY, center = TRUE, scale = TRUE)
quantilesZscore <- stats::quantile(zScores, requestedQuantilesZscores, na.rm = TRUE)

theDataFrame <- base::data.frame(theX = vectX, theY = vectY, theZ = zScores)

valuesColor <- c('green','red','blue','yellow','orange')
theDataFrame$conditionalColor <- ifelse(theDataFrame$theZ > quantilesZscore[[4]], valuesColor[[1]] ,
      ifelse(theDataFrame$theZ > quantilesZscore[[3]] & theDataFrame$theZ <= quantilesZscore[[4]], valuesColor[[2]],
        ifelse(theDataFrame$theZ > quantilesZscore[[2]] & theDataFrame$theZ <= quantilesZscore[[3]], valuesColor[[3]],
          ifelse(theDataFrame$theZ <= quantilesZscore[[2]], valuesColor[[4]], valuesColor[[5]]))))

theGGplotLine <- ggplot(theDataFrame) +
  geom_line(aes(x = theX, y = theY, color = conditionalColor)) +
  xlab('X') + ylab('Y') +
  scale_colour_manual(values = valuesColor) +
  theme(legend.position='none')

theGGplotLine

(plotly::ggplotly(theGGplotLine))
Aex
  • 131
  • 1
  • 11
  • If I understand your question (and I'm not certain I do), then what you are looking for is to segment your one line into various colours. That cannot be achieved to my knowledge using `geom_line`, you will need to revert to graphical primitives such as `geom_abline` and friends to plot each piece of your line separately – Kevin Arseneau Oct 09 '17 at 22:50

2 Answers2

2

The answer combines elements of solutions provided by user2738526 for the original question, and also on solution to Question 46146720

It uses geom_segment, and making each segment link up to the next (x, y) value, regardless of color.

The code becomes

require(ggplot2)
require(plotly)
require((dplyr))

vectX <- c(-5,-4.5,-3.2,-2.1,-0.8,0.1,1.3,2.7,3.6,4.4,5)
vectY <- c(-2.3,1.4,2.7,0.3,-0.4,1.5,3.9,2.4,0.5,-1.2,1.4)

requestedQuantilesZscores <-  c(0.0,0.25,0.5,0.75,1.0)
zScores <- base::scale(vectY, center = TRUE, scale = TRUE)
quantilesZscore <- stats::quantile(zScores, requestedQuantilesZscores, na.rm = TRUE)

theDataFrame <- base::data.frame(theX = vectX, theY = vectY, theZ = zScores)

theDataFrame <- theDataFrame %>%
  arrange(theX) %>%
  mutate(theNextX = lead(theX), theNextY = lead(theY))

valuesColor <- c('green','red','blue','magenta','orange')
theDataFrame$conditionalColor <- ifelse(theDataFrame$theZ > quantilesZscore[[4]], valuesColor[[1]] ,
        ifelse(theDataFrame$theZ > quantilesZscore[[3]] & theDataFrame$theZ <= quantilesZscore[[4]], valuesColor[[2]],
               ifelse(theDataFrame$theZ > quantilesZscore[[2]] & theDataFrame$theZ <= quantilesZscore[[3]], valuesColor[[3]],
                      ifelse(theDataFrame$theZ <= quantilesZscore[[2]], valuesColor[[4]], valuesColor[[5]]))))

theGGplotLine <- ggplot(theDataFrame, aes(x = theX, y = theY)) +
  geom_segment(aes(xend = theNextX, yend = theNextY, color = conditionalColor)) +
  xlab('X') + ylab('Y') +
  scale_colour_manual(values = valuesColor) +
  theme_bw() +
  theme(legend.position='none')

theGGplotLine

(plotly::ggplotly(theGGplotLine)) 
Aex
  • 131
  • 1
  • 11
0

If I understand correctly what you want, all you need is to add a different grouping into your ggplot code

theGGplotLine <- ggplot(theDataFrame) +
  geom_line(aes(x = theX, y = theY, color = conditionalColor, group = 1)) +
  xlab('X') + ylab('Y') +
  scale_colour_manual(values = valuesColor) +
  theme(legend.position='none')

This gives one line with all points connected, but the colour is dependent on the conditionalColor column. Grouping like this could also be based on a separate column if necessary

Sarah
  • 3,022
  • 1
  • 19
  • 40
  • 1
    Thank you @user2738526. Your answer provides the expected behavior for the static plot (created with ggplot2), and it will be accepted. The interactive plot (with ggplotly) still have some issues, but your answer put me in the right direction and I was able to also solve it – Aex Oct 10 '17 at 07:57