Search code examples
rplotlattice

lattice plot only lines with positive slope


Is there a easy and efficient way to define a function like panel.xyplot (or rather panel.lines) that connects only two point (x1,y1) and (x2,y2) if x1 <= x2 and y1 <= y2? (Ideally, with all other properties are retained by label.xyplot(...))

I asked the same question a view month ago and the solution is great: lattice, connect points only if the connection has a positive slope

Now it would be fine to have a real panel.xyplot like function so that I can use my own groups. It should work and plot like below, except the crossed lines. I welcome suggestions.

enter image description here


Solution

  • I'm not sure I understand what you're after, but if I do, then I think this should work for any given group:

    library(dplyr)
    
    set.seed(1)
    
    dat <- data.frame(x=1:10,y=sample(1:10))
    dat <- mutate(dat, x0 = x, y0 = y, x1 = lead(x), y1 = lead(y), slope = (x1 - x0)/(y1 - y0))
    
    with(dat, plot(x, y))
    with(dat[1:nrow(dat) - 1,], segments(x0 = x0, y0 = y0, x1 = x1, y1 = y1,
        col = ifelse(slope >= 0, "black", "white"))) # This bit gets makes line-drawing conditional
    

    Here's what I get from that:

    enter image description here

    And here's a version for grouped data that doesn't depend on lattice:

    dat2 <- data.frame(x = rep(seq(10), 10),
                       y = sample(1:10, size = 100, replace = TRUE),
                       indx = rep(seq(10), each = 10))
    
    dat2g <- dat2 %>%
        group_by(indx) %>%
        mutate(., x0 = x, y0 = y, x1 = lead(x), y1 = lead(y), slope = (x1 - x0)/(y1 - y0))
    
    plotit <- function(group) {
        require(dplyr)
        datsub <- filter(dat2g, indx == group)
        with(datsub, plot(x, y, main = group))
        with(datsub[1:nrow(datsub) - 1,], segments(x0 = x0, y0 = y0, x1 = x1, y1 = y1, col = ifelse(slope >= 0, "black", "white")))
    }
    
    par(mfrow=c( floor(sqrt(max(dat2g$indx))), ceiling(sqrt(max(dat2g$indx)))))
    par(mai=c(0.5,0.5,0.5,0.25))
    for (i in 1:length(unique(dat2g$indx))) { plotit(i) }
    

    Here's the plot output from that process. It could use fine-tuning, but I think it's what you're after?

    enter image description here