Search code examples
rplotline-plot

Elegant way to select the color for a particular segment of a line plot?


For a list of n pairs of coordinates x,y is there a way of plotting the line between different points on a specific color?

The solution I've implemented so far is not to use the plot function but lines selecting the range for which I want the color. Here an example:

x <- 1:100
y <- rnorm(100,1,100)
plot(x,y ,type='n')
lines(x[1:50],y[1:50], col='red')
lines(x[50:60],y[50:60], col='black')
lines(x[60:100],y[60:100], col='red')

Is there an easier way of doing this?


Solution

  • Yes, one way of doing this is to use ggplot.

    ggplot requires your data to be in data.frame format. In this data.frame I add a column col that indicates your desired colour. The plot is then constructed with ggplot, geom_line, and scale_colour_identity since the col variable is already a colour:

    library(ggplot2)
    
    df <- data.frame(
      x = 1:100,
      y = rnorm(100,1,100),
      col = c(rep("red", 50), rep("black", 10), rep("red", 40))
    )
    
    ggplot(df, aes(x=x, y=y)) + 
      geom_line(aes(colour=col, group=1)) + 
      scale_colour_identity()
    

    enter image description here

    More generally, each line segment can be a different colour. In the next example I map colour to the x value, giving a plot that smoothly changes colour from blue to red:

    df <- data.frame(
      x = 1:100,
      y = rnorm(100,1,100)
    )
    
    ggplot(df, aes(x=x, y=y)) + geom_line(aes(colour=x))
    

    enter image description here


    And if you insist on using base graphics, then use segments as follows:

    df <- data.frame(
      x = 1:100,
      y = rnorm(100,1,100),
      col = c(rep("red", 50), rep("black", 10), rep("red", 40))
    )
    
    plot(df$x, df$y, type="n")
    for(i in 1:(length(df$x)-1)){
      segments(df$x[i], df$y[i], df$x[i+1], df$y[i+1], col=df$col[i])
    }
    

    enter image description here