Элегантный способ выбрать цвет для определенного сегмента линейного сюжета? - PullRequest
4 голосов
/ 12 октября 2011

Для списка 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 ]

7 голосов
/ 12 октября 2011

Да, один из способов сделать это - использовать ggplot.

ggplot требует, чтобы ваши данные были в формате data.frame.В этом data.frame я добавляю столбец col, который указывает желаемый цвет.Затем график строится с использованием ggplot, geom_line и scale_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

4 голосов
/ 13 октября 2011

Для @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])
    }
  }
})
3 голосов
/ 14 октября 2011

Однострочное использование только базовых библиотек:

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

(вдохновлено использованием Андреем сегментов , см. Исторический пост и обсуждение там)

Интересно, это может быть сокращено до этого:

segments(head(x, -1), head(y, -1), x[-1], y[-1], rep(c("red", "black"), c(49, 10)))
2 голосов
/ 12 октября 2011

Если вы хотите установить цвет на основе значений y, а не значений x, используйте plotrix::clplot.Это фантастическая, замечательная, суперская функция.Отказ от ответственности: я написал это :-).Таким образом, clplot () выделяет области ваших данных, где y принимает заданные диапазоны значений.В качестве примечания: вы можете расширить комментарий Чейза следующим образом:

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)<=5)])

0 голосов
/ 12 октября 2011

В базовой библиотеке я так не думаю (однако я не могу говорить за ggplot и т. Д.). Глядя на функцию lines и пытаясь представить col как вектор ...: это не работает. Я бы сделал это так же, как вы.

РЕДАКТИРОВАТЬ после обсуждения с Андри и вдохновленный его постом : вы можете использовать segments(), чтобы сделать это за один звонок, см. Обсуждение там.

...