4

Advancing on the answer given here where the same question was asked for a scatter plot, is it possible to plot a line where the colour is based on the y value?

Example data

x = 1:11
y = abs(6 - x)
plot(1:22,c(y,y), col = ifelse(c(y,y) < 2.5, 2, 3), pch = 16)

Will give scatter

However, trying

plot(1:22,c(y,y), col = ifelse(c(y,y) < 2.5, 2, 3), type = "l")

Gives

bad

or doing lines on y<2.5 which gives

enter image description here

instead of the solution I am after, which is

enter image description here

Is there any easy method to do this? This is only a simple case, and I can't manually add each section to my actual data. Thanks!

Beavis
  • 476
  • 3
  • 13
  • 1
    I recommend using ggplot2, as is used in the answer of this question: https://stackoverflow.com/questions/7744379/elegant-way-to-select-the-color-for-a-particular-segment-of-a-line-plot – P1storius Aug 23 '19 at 10:54
  • Once you have `data.frame` then this will help you: `df <- data.frame(x,y) # Combine your data to data.frame; ggplot(df, aes(x = y, y = y, color = I(ifelse(y < 2.5, "Red", "Green")))) + geom_line(aes(group = 1))` – Saurabh Chauhan Aug 23 '19 at 10:56

2 Answers2

4

Try this

x = 1:11
y = abs(6 - x)
y = c(y,y)
plot(1:22,y, col = ifelse(c(y,y) < 2.5, 2, 3), pch = 16)



for(i in 1:21){
  if(y[i]>1.9&& y[i+1]>1.9){
    linecolour="green"
  } else {
    linecolour="red"
  }
  lines(c((1:22)[i],(1:22)[i+1]),c(y[i],y[i+1]),col=linecolour)
}

enter image description here

Daniel O
  • 4,258
  • 6
  • 20
0

Here is a vectorized solution. It is partly based on the answers to this question with the main difference that the function plotted there is a smooth function, unlike this one. This makes a difference when computing the points to plot and their colors.

fun <- function(x) abs(6 - x)

x <- 1:11
y <- fun(x)
X <- c(x, x + 11)
Y <- c(y, y)
n <- length(X)

color <- ifelse((Y[-n] < 2.5) & (Y[-1] < 2.5), 2, 3)

plot(X, Y, col = color, pch = 16)
segments(x0 = X[-n], y0 = Y[-n], 
         x1 = X[-1], y1 = Y[-1],
         col = color, pch = 16)

enter image description here

To remove the points, start with

plot(X, Y, type = "n")
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66