2011-07-24 2 views
8

У меня есть набор координатНепрерывные и пунктирные линии с использованием ggplot

(x, y) = (0, 2), (1, 3), (1, 2), (2, 4)  (this is a simplified example) 

Всякий раз, когда происходит увеличение в у-ординат, я хотел бы присоединиться координаты сплошной линией. Всякий раз, когда происходит уменьшение оси ординат, я хотел бы присоединиться к координатам пунктирной линией. В приведенном выше примере,

1.) координат (0, 2) и (1, 3) соединены прямой линией,

2.) координаты (1, 3) и (1, 2) соединяются пунктирной линией, и

3.) координаты (1, 3) и (2, 4) соединены прямой линией.

Можно ли это сделать, используя ggplot в R? До сих пор у меня могла быть сплошная линия, соединяющая координаты. (Если это, возможно, делает что-то проще, у меня есть только уменьшение оси ординат при отсутствии изменений в оси ординат.)

Спасибо за помощь!

ответ

7

попробовать это,

dat <- data.frame(x=c(0,1,1,2),y=c(2,3,2,4)) 

## add endpoints (xend, yend), and and id variable 
## tracking the sign of diff(y) 
dat2 <- with(dat, data.frame(x=x[-length(x)], y=y[-length(y)], 
          id= diff(y) > 0,xend=x[-1], yend=y[-1])) 

head(dat2) 
ggplot(dat2) + 
    geom_segment(aes(x=x, y=y, xend=xend, yend=yend, linetype=id)) + 
    scale_linetype_manual(values=c("dashed", "solid")) 
+0

Насколько ясен ответ @ joran, этот ответ намного эффективнее при выполнении задачи. Благодарим вас и за ваш комментарий. –

+0

+1 для diff (y). –

5

(под редакцией удалить некоторые потенциально вводящие в заблуждение заявления ...)

Спасибо за этот вопрос! Сначала я подумал, что было бы довольно ужасно, но потом я вспомнил небольшой трюк о том, как вы можете хранить кучу ggplot компонентов в списке, и это оказывается не так уж плохо:

#Your example data 
dat <- data.frame(x=c(0,1,1,2),y=c(2,3,2,4)) 

#Initialize the list  
pathList <- vector("list",nrow(dat) - 1) 
#Loop over the data and put the appropriate `geom_line` in each slot 
for (i in 2:nrow(dat)){ 
    if (dat$y[i] - dat$y[i-1] >= 0){ 
     pathList[[i-1]] <- geom_line(data = dat[(i-1):i,],aes(x=x,y=y)) 
    } 
    else{ 
     pathList[[i-1]] <- geom_line(data = dat[(i-1):i,],aes(x=x,y=y), 
           linetype="dashed") 
    } 
} 

p <- ggplot(data=dat,aes(x=x,y=y)) + pathList 

Что привело в этом:

enter image description here

Как было отмечено в комментариях, однако, это решение будет весьма неэффективным ...

+0

Большое спасибо за ваше время. Это хорошо работает, и это легко понять. –

+0

Это решение было бы довольно неэффективным с большим количеством сегментов, поскольку оно не использует тот факт, что сетчатая графика имеет векторизованные функции для одновременного рисования нескольких сегментов с различными эстетическими параметрами. – baptiste

+0

@baptiste - Действительно, ваш гораздо приятнее! – joran

Смежные вопросы