【问题标题】:Elegant way to select the color for a particular segment of a line plot?为线图的特定部分选择颜色的优雅方式?
【发布时间】:2011-12-06 08:39:01
【问题描述】:

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

有没有更简单的方法?

【问题讨论】:

    标签: r plot line-plot


    【解决方案1】:

    是的,一种方法是使用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()
    

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

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


    如果你坚持使用基础图形,那么使用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])
    }
    

    【讨论】:

    • 什么,没有lattice 解决方案? ;)
    • 关于使用 for 循环的分段解决方案,这与 OP 多次调用 lines 相同。你可以使用更优雅的方式:with(df, segments(head(x, -1), head(y, -1), x[-1], y[-1], rep(c("red", "blue", "green"), c(50, 10, 40)))).
    • @joran:我知道你是在开玩笑,但 lattice 似乎在这里受到了冷遇。看我的回答。
    • 感谢@Andrie,渐变示例对我的工作也很有用。
    【解决方案2】:

    对于@joran 和其他 lattice 粉丝...

    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|aa 变量如下所示:

    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])
        }
      }
    })
    

    【讨论】:

      【解决方案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)))
      

      【讨论】:

        【解决方案4】:

        如果您想根据 y 值而不是 x 值设置颜色,请使用 plotrix::clplot 。这是一个奇妙的、美妙的、超级的功能。免责声明:我写的:-)。因此 clplot() 会突出显示 y 取指定值范围的数据区域。 附带说明:您可以将 Chase 的评论扩展为:

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

        其中 colorlist 是颜色或颜色名称或其他任何内容的向量,您可以选择符合您需求的算法。安德烈的第一个情节可以用
        colorlist=c('red','black')
        完成 和
        plot(x,y,t='p', col=colorlist[1+(abs(x-55)&lt;=5)])

        【讨论】:

          【解决方案5】:

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

          在与 Andrie 讨论后编辑并受到 his post 的启发:您可以使用 segments() 一次性完成,请参阅那里的讨论。

          【讨论】:

          • 虽然有趣的是,p 类型的图确实以这种方式工作。考虑:plot(x,y, type = "p", col = ifelse(x &lt; 10, "pink", "green")).
          • 基础图形:help(plotrix::color.scale.lines)
          • @DWin:我不是在调用 base(你必须为此加载 plotrix 包......)
          • 我在我的答案中添加了一个基本的 R 解决方案:只需使用 segments 而不是行
          • @Andrie,是的,但是您使用 for 循环 - 也可以使用线条。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-19
          • 2016-11-01
          • 1970-01-01
          • 2020-02-07
          • 2010-10-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多