Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continuous and Dashed Lines using ggplot

Tags:

r

ggplot2

I have a set of coordinates

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

Whenever there is an increase in the y-ordinate, I would like to join the coordinates by a continuous line. Whenever there is a decrease in the y-ordinate, I would like to join the coordinates by a dashed line. In the example above,

1.) the coordinates (0, 2) and (1, 3) are joined by a straight line,

2.) the coordinates (1, 3) and (1, 2) are joined by a dashed line, and

3.) the coordinates (1, 3) and (2, 4) are joined by a straight line.

Is it possible to do this using ggplot in R? So far, I could only have a continuous line joining the coordinates. (If this possibly makes anything easier, I only have a decrease in the y-ordinate when there is no change in the x-ordinate.)

Thank You for your help!

like image 981
A-A Avatar asked Jul 24 '11 19:07

A-A


2 Answers

try this,

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"))
like image 159
baptiste Avatar answered Oct 08 '22 05:10

baptiste


(Edited to remove some potentially misleading statements...)

Thanks for asking this question! At first I thought that would be pretty horrible, but then I remembered a little trick about how you can store a bunch of ggplot components in a list, and it turns out to not be so bad:

#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

Which resulted in this:

enter image description here

As noted in the comments, though, this solution is going to be quite inefficient...

like image 40
joran Avatar answered Oct 08 '22 04:10

joran