[R] geom_ribbon removes missing values

Karsten Loesing karsten.loesing at gmx.net
Thu Jun 10 01:37:57 CEST 2010


Hi Paul,

On 6/9/10 1:12 AM, Paul Murrell wrote:
> grid.polygon() can do multiple polygons in a single call, but rather
> than using NA's to separate sub-polygons, it uses an 'id' argument (or
> an 'id.lengths' argument) to identify sub-polygons within the vectors of
> x- and y-values (see the examples in ?grid.polygon).  So a ggplot2 patch
> that makes use of that facility might make more sense.

That's a great idea! And it makes the patch look far less ugly. Thanks
for that!

I still can't get rid of the loop, but I'd guess that going through the
vector once is not a performance killer. If someone has an idea how we
can get a similar vector as the one mentioned in the comment, but
without using a loop, please do tell!

Here's the new patch:


--- ggplot2-orig	2010-06-06 14:02:25.000000000 +0200
+++ ggplot2	2010-06-10 01:22:20.000000000 +0200
@@ -5044,9 +5044,19 @@


   draw <- function(., data, scales, coordinates, na.rm = FALSE, ...) {
-    data <- remove_missing(data, na.rm,
-      c("x","ymin","ymax"), name = "geom_ribbon")
     data <- data[order(data$group, data$x), ]
+
+  # Instead of removing NA values from the data and plotting a single
+  # polygon, we want to "stop" plotting the polygon whenever we're missing
+  # values and "start" a new polygon as soon as we have new values.  We do
+  # this by creating an id vector for polygonGrob that has distinct
+  # polygon numbers for sequences of non-NA values and NA for NA values in
+  # the original data.  Example: c(NA, 2, 2, 2, NA, NA, 7, 7, 7, NA)
+  poly_ids <- 1:length(data$x)
+  poly_ids[is.na(data$ymin) | is.na(data$ymax)] <- NA
+  for (i in 2:length(poly_ids))
+    if (!is.na(poly_ids[i]) & !is.na(poly_ids[i-1]))
+      poly_ids[i] <- poly_ids[i-1]

     tb <- with(data,
       coordinates$munch(data.frame(x=c(x, rev(x)), y=c(ymax,
rev(ymin))), scales)
@@ -5054,12 +5064,12 @@

     with(data, ggname(.$my_name(), gTree(children=gList(
       ggname("fill", polygonGrob(
-        tb$x, tb$y,
+        tb$x, tb$y, id=c(poly_ids, rev(poly_ids)),
         default.units="native",
         gp=gpar(fill=alpha(fill, alpha), col=NA)
       )),
       ggname("outline", polygonGrob(
-        tb$x, tb$y,
+        tb$x, tb$y, id=c(poly_ids, rev(poly_ids)),
         default.units="native",
         gp=gpar(fill=NA, col=colour, lwd=size * .pt, lty=linetype)
       ))


Thanks,
--Karsten



More information about the R-help mailing list