Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A different direction from the one @Andrie took. I found it more intuitive to use <code>geom_ribbon</code> (which I'm sure is just a wrapper for <code>geom_polygon</code> at some level).</p> <p>You didn't specify very well what to do with chunks of length one. Technically, the "polygon" for such a chunk would just be a vertical line segment. What seemed more intuitive to me was to have those chunks extend slightly in either direction, to "meet in the middle".</p> <pre><code>#Construct similar data x=c(1,2,7,3,4,8,9,5,6,7,11,13,15,8,9,10,11,12,13,15) y=c(2:10,9,8,7,6,8,10,11,12,13,14,1) date=strptime(20010101:20010120,'%Y%m%d') z=data.frame(date,x,y) z$diff=z$y-z$x z$min=pmin(x,y) z$max=pmax(x,y) #Assign a unique integer to each chunk tmp &lt;- rle(z$diff &gt; 0) z$series &lt;- rep(1:length(tmp$lengths),times = tmp$lengths) #Grab just the useful columns z1 &lt;- z[,c(1,4:7)] #This is the ugly part. # Loop through data and add a row # at the transitions for (i in 2:nrow(z1)){ if (z1$series[i] != z1$series[i-1]){ newRow &lt;- colwise(mean)(z1[c(i,i-1),]) newRow1 &lt;- newRow2 &lt;- newRow newRow1$series &lt;- z1$series[i-1]; newRow2$series &lt;- z1$series[i] newRow1$diff &lt;- z1$diff[i-1]; newRow2$diff &lt;- z1$diff[i] z1 &lt;- rbind(z1,newRow1,newRow2) } } #Put everything back in order z1 &lt;- arrange(z1,date) #Create a factor to build the legend with z1$diff &lt;- sign(z1$diff) z1$grp &lt;- factor(ifelse(z1$diff &gt; 0,"Greater Than","Less Than")) #The only clever bit ;) ribbons &lt;- dlply(z1,.(series),.fun = function(x){geom_ribbon(data = x,aes(ymin = min,ymax = max,fill = grp))}) p &lt;- ggplot(z1,aes(x = date, ymin = min,ymax = max,fill = grp)) + ribbons + labs(x = NULL,y = NULL,fill = "Legend") </code></pre> <p><img src="https://i.stack.imgur.com/6GmhV.png" alt="enter image description here"></p> <p>This obviously has some weaknesses:</p> <ol> <li>Assumes that averaging the <code>x</code> and <code>y</code> values is sensible. Worked with POSIXct, but probably won't with pure dates!</li> <li>If you don't want the chunks to "split the difference" at the boundaries of chunks longer than one day, you'll have to do some fiddling in the <code>for</code> loop to look ahead and see how long each chunk is.</li> </ol> <p>I haven't cleaned this up at all, so I'm sure improvements are possible...</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload