优雅的方式为线图的特定部分选择颜色?

时间:2011-10-12 17:57:22

标签: r plot line-plot

对于 n 坐标 x,y 的列表,是否有一种方法可以绘制特定颜色上不同点之间的直线?

到目前为止我实现的解决方案不是使用 plot 函数,而是 lines 选择我想要颜色的范围。这是一个例子:

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')

有更简单的方法吗?

5 个答案:

答案 0 :(得分:7)

是的,这样做的一种方法是使用ggplot

ggplot要求您的数据采用data.frame格式。在此data.frame中,我添加了一列col,表示您想要的颜色。然后使用ggplotgeom_linescale_colour_identity构建绘图,因为col变量已经是颜色:

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

更一般地说,每个线段可以是不同的颜色。在下一个例子中,我将颜色映射到x值,给出了一个平滑地将颜色从蓝色变为红色的图表:

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


如果您坚持使用基本图形,请按以下方式使用segments

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

答案 1 :(得分:4)

对于@joran和其他格子迷...

xyplot(y~x, data=df, panel=function(x,y,subscripts, groups, ...) {
  for(k in seq_len(length(subscripts)-1)) {
    i <- subscripts[k]
    j <- subscripts[k+1]
    panel.segments(df$x[i], df$y[i], df$x[j], df$y[j], col=df$col[i])
  }
})

不幸的是,我不知道这样做的光滑方式,所以它基本上将基础解决方案包装到面板功能中。使用|按组拆分时,上述方法正常,例如y~x|a,其中a变量如下所示:

df <- data.frame(
  x = 1:100,
  y = rnorm(100,1,100),
  col = c(rep("red", 50), rep("black", 10), rep("red", 40)),
  a = 1:2
)

要使用group=,您还需要以下内容:

xyplot(y~x, group=a, data=df, panel=function(x,y,subscripts, groups, ...) {
  if(missing(groups)) { groups <- rep(1, length(subscripts)) }
  grps <- split(subscripts, groups)
  for(grp in grps) {
    for(k in seq_len(length(grp)-1)) {
      i <- grp[k]
      j <- grp[k+1]
      panel.segments(df$x[i], df$y[i], df$x[j], df$y[j], col=df$col[i])
    }
  }
})

答案 2 :(得分:3)

单行使用基础库:

segments(head(x, -1), head(y, -1), x[-1], y[-1], rep(c("red", "black", "red"), c(49, 10, 40)))

(受Andrie's usage of segments启发,请参阅文章帖子及其中的讨论)

有趣的是,它可以缩短到这一点:

segments(head(x, -1), head(y, -1), x[-1], y[-1], rep(c("red", "black"), c(49, 10)))

答案 3 :(得分:2)

如果要根据y值而不是x值设置颜色,请使用plotrix::clplot。这是一个梦幻般的,精彩的超级功能。免责声明:我写了:-)。 clplot()因此突出显示数据的区域,其中y采用指定的值范围。 作为旁注:您可以将Chase的评论扩展为:

plot(x,y,t='p', col=colorlist[some_function_of_x]) 

其中colorlist是颜色或颜色名称或其他任何颜色的向量,您可以选择符合您需求的算法。 Andrie的第一个阴谋可以用左右完成     colorlist=c('red','black')

    plot(x,y,t='p', col=colorlist[1+(abs(x-55)<=5)])

答案 4 :(得分:0)

在基础库中,我不这么认为(但是,我不能代表ggplot等)。查看lines函数并尝试将col作为向量提供......:它不起作用。我会像你一样做。

与Andrie讨论后编辑并受到his post的启发:您可以使用segments()在一次通话中完成此操作,请参阅此处的讨论。