[R] Conditional coloring of area between curves

William Dunlap wdunlap at tibco.com
Fri Jun 7 17:51:20 CEST 2013


> that's exactly what I was looking for!

That code has some problems if your time series do not cross at the time
points.  E.g., Duncan's code with some diagnostic plotting is:

  f0 <- function (site1, site2, x = time(site1), check = FALSE) 
  {
      stopifnot(length(x) == length(site1), length(x) == length(site2),  all(diff(x) > 0))
      if (check) {
          oldMfrow <- par(mfrow = c(2, 1))
          on.exit(par(oldMfrow))
          matplot(x, cbind(site1, site2), type = "b")
      }
      smaller <- pmin(site1, site2)
      plot(x, site1, ylim = range(c(site1, site2)), type = "n")
      polygon(c(x, rev(x)), c(smaller, rev(site1)), col = "red")
      polygon(c(x, rev(x)), c(smaller, rev(site2)), col = "blue")
  }
  # See how it messes the crossings in
  f0(c(0, 1, -1, 0), c(1, 0, -2, 1), check=TRUE)

The following is a quick and dirty way of adding all the crossing
points to the original data sets so the plot is right.
  addCrossingPoints <- function (y1, y2, x) 
  {
      stopifnot(length(y1)==length(x), length(y2)==length(x), all(diff(x)>0))
      # isCrossingSegment[i]==TRUE means that y1 and y2 cross between
      #    x[i] and x[i+1]  (strictly, not at x[i] or x[i+1]).
      i <- seq_len(length(y1) - 1)
      isCrossingSegment <- ((y1[i] < y2[i]) & (y1[i+1] > y2[i+1])) |
                           ((y1[i] > y2[i]) & (y1[i+1] < y2[i+1]))
      if (any(isCrossingSegment)) {
          i <- which(isCrossingSegment)
          dx <- x[i+1] - x[i]
          m1 <- (y1[i+1] - y1[i]) / dx
          m2 <- (y2[i+1] - y2[i]) / dx
          newDX <- (y1[i] - y2[i]) / (m2 - m1)
          newY <- y1[i] + newDX * m1 
          o <- order( x <- c(x, x[i] + newDX))
          x <- x[o]
          y1 <- c(y1, newY)[o]
          y2 <- c(y2, newY)[o]
      }
      list(y1=y1, y2=y2, x=x)
  }
  # Combine it with Duncan's code to get a better looking plot
  f1 <- function(site1, site2, x=time(site1), check = FALSE) {
      tmp <- addCrossingPoints(site1, site2, x)
      f0(tmp$y1, tmp$y2, tmp$x, check=check)
  }
  f1(c(0, 1, -1, 0), c(1, 0, -2, 1), check=TRUE)


Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Roland Pape
> Sent: Friday, June 07, 2013 2:51 AM
> To: Duncan Murdoch
> Cc: r-help at r-project.org
> Subject: Re: [R] Conditional coloring of area between curves
> 
> Hi Duncan,
> 
> that's exactly what I was looking for! The series have common times, so that's no
> problem. Thanks a lot!
> 
> Roland
> ________________________________________
> Von: Duncan Murdoch [murdoch.duncan at gmail.com]
> Gesendet: Donnerstag, 6. Juni 2013 18:45
> An: Roland Pape
> Cc: r-help at r-project.org
> Betreff: Re: [R] Conditional coloring of area between curves
> 
> On 06/06/2013 10:41 AM, Roland Pape wrote:
> > Dear list,
> >
> > I have two time series of temperatures from different sites plotted in the same diagram
> and would like to color the area between the curves differently, dependent on whether
> site 1 is cooler than site 2 (colored let's say in blue) or warmer (red). While polygone()
> works fine to color the enclosed area in general, I'm struggling with this conditional
> coloring. Any help is greatly appreciated!
> 
> Suppose the series are named "site1" and "site2", and they have common
> times in a variable "times".  Then the following should do what you want:
> 
> smaller <- pmin(site1, site2)
> plot(x, site1, ylim = range(c(site1, site2)), type="n")
> polygon(c(x, rev(x)), c(smaller, rev(site1)), col="red")
> polygon(c(x, rev(x)), c(smaller, rev(site2)), col="blue")
> 
> If the times for the two series are different it's a little harder;
> first you need to give them common times, and that will depend on how
> you decide to evaluate the values between observations. Probably linear
> interpolation (using approx()) is fine, but it's up to you.
> 
> Duncan Murdoch
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list