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

发布于 2024-12-09 21:49:46 字数 360 浏览 2 评论 0原文

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

有更简单的方法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

鼻尖触碰 2024-12-16 21:49:46

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

在此处输入图像描述


如果您坚持使用基本图形,请使用,如下所示:

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

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

初熏 2024-12-16 21:49:46

对于@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])
    }
  }
})

For @joran and other lattice fans...

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

Unfortunately I don't know of a slick way of doing it, so it's basically wrapping the base solution into a panel function. The above works correctly when using a | to split by groups, for example, y~x|a, with an a variable as here:

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
)

To use group= as well, you'd need the following:

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])
    }
  }
})
无语# 2024-12-16 21:49:46

仅使用基础库的单行:(

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

灵感来自 Andrie 对段的使用,请参阅他的帖子和那里的讨论)

有趣的是,它可以缩短为:

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

One-liner using just the base libraries:

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

(inspired by Andrie's usage of segments, see hist post and the discussion there)

Interestingly, it could be shortened to this:

segments(head(x, -1), head(y, -1), x[-1], y[-1], rep(c("red", "black"), c(49, 10)))
横笛休吹塞上声 2024-12-16 21:49:46

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

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

其中 colorlist 是颜色或颜色名称或其他内容的向量,并且您可以选择符合您需求的算法。安德烈的第一个情节可以用
来完成
colorlist=c('红色','黑色')

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

If you want to set the color based on the y-values rather than the x-values, use plotrix::clplot . It's a fantastic, wonderful, superduper function. Disclaimer: I wrote it :-) . clplot() thus highlights regions of your data where y takes on specified ranges of values.
As a side note: you can expand on Chase's comment as:

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

where colorlist is a vector of colors or colornames or whatever, and you pick an algorithm that matches your needs. The first of Andrie's plots could be done with
colorlist=c('red','black')
and
plot(x,y,t='p', col=colorlist[1+(abs(x-55)<=5)])

要走就滚别墨迹 2024-12-16 21:49:46

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

与 Andrie 讨论后进行编辑,并受到 他的帖子:你可以使用 segments() 来执行一次通话即可完成,请参阅那里的讨论。

In base library, I don't think so (however, I cannot speak for ggplot etc.). Looking at the lines function and trying to supply col as a vector...: it doesn't work. I would do it the same way as you.

EDIT after discussion with Andrie and inspired by his post: you can use segments() to do it in one call, see the discussion there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文