wrong data frame for stat_contour?

1,322 views
Skip to first unread message

Michael Bach

unread,
Mar 15, 2011, 1:07:07 PM3/15/11
to ggp...@googlegroups.com
Dear ggplot users,

I want to do a contour plot of this example data frame M:

Timestamp, var1, var2, Temperature, var4, var5, var6, PR, AM
2007-06-01 06:45:00,293,293,25.4,1.119,183.5,205.4,70.1023890784983,2.40704239074236
2007-06-01 07:00:00,350,350,28.1,1.41,180.5,254.1,72.6,2.16082559391613
2007-06-01 07:15:00,412,412,30.4,1.687,183.3,309.4,75.0970873786408,1.9643201381691
2007-06-01 07:30:00,419,419,31.7,1.777,189.4,335.9,80.1670644391408,1.80461948890186
2007-06-01 07:45:00,477,477,35.1,2.043,185.6,379.9,79.643605870021,1.67295419550583
2007-06-01 08:00:00,509,509,34.7,2.225,188.5,420.6,82.6326129666012,1.5631640123187
...
snipped
...
2008-05-31 16:00:00,421,421,44.6,1.824,179.5,327.4,77.7672209026128,1.82254818737165
2008-05-31 16:15:00,370,370,43.4,1.572,176.2,276.9,74.8378378378378,1.98613539823816
2008-05-31 16:30:00,322,322,41.7,1.285,177.1,227.7,70.7142857142857,2.18779700497932
2008-05-31 16:45:00,268,268,40.6,1.024,174.6,178.7,66.6791044776119,2.44107007369387

I was following the tutorial on http://had.co.nz/ggplot2/stat_contour.html and adapted it to the following code:

p <- ggplot(M, aes(AM, Temperature, z = PR))
p + stat_contour()

It fails with:

"Error in if (empty(new)) return(data.frame()) : 
  missing value where TRUE/FALSE needed"

Why is this happening? Can you give me a hint on this? I am pretty new to all this...

Thanks in advance,
Michael Bach

Dennis Murphy

unread,
Mar 15, 2011, 6:42:22 PM3/15/11
to Michael Bach, ggp...@googlegroups.com
Hi:

Contour plots are generally produced by constructing a grid in the x-y plane and then mapping values of z to the grid. You're basically asking for a 3D scatterplot, which is not available in ggplot2. Some alternatives are cloud() in lattice, the scatterplot3d package or perhaps rgl.

If you look at the example in geom_contour(), the original volcano object is a matrix. When melted, the row and column indices become the 'x' and 'y', forming a type of grid (similar to expand.grid() ), and the values of the matrix become the z values.
> head(volcano3d)
  X1 X2 value
1  1  1   100
2  2  1   101
3  3  1   102
4  4  1   103
5  5  1   104

I manufactured an example that is similar to what you seem to want to do and replicated your finding:

> dd <- data.frame(x = rnorm(1000), y = rpois(1000, 30), z = rnorm(1000))
> ggplot(dd, aes(x, y, z = z)) + geom_contour()

Error in if (empty(new)) return(data.frame()) :
  missing value where TRUE/FALSE needed

I also tried contourplot() in lattice and ended up with an empty plot. This indicates that your data don't conform to the structure needed for contour plots, but it does work for a 3D scatterplot:

library(lattice)
contourplot(z ~ x * y, data = dd)       # empty
cloud(z ~ x * y, data = dd)                # works

If you want to get a contour plot from ggplot2, it appears you're going to need to manufacture an appropriate rectangular grid. Typically, that means the z-values are predictions from a model with covariates x and y, but not exclusively so - e.g., a spatial lattice also generates the equivalent of a grid.

Hope that clarifies matters somewhat.

Dennis


--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: http://gist.github.com/270442
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

Michael Bach

unread,
Mar 16, 2011, 6:18:52 AM3/16/11
to Dennis Murphy, ggp...@googlegroups.com
Thanks for your message Dennis.

I tried to do a rounding of the last two columns so that the data frame now looks like:

Timestamp, var1, var2, Temperature, var4, var5, var6, PR, AM
2007-06-01 06:45:00,293,24.4,1.193,174.8,209.1,73.877,2.407
2007-06-01 07:00:00,350,27.9,1.504,169,254.4,75.244,2.161
2007-06-01 07:15:00,412,30.8,1.829,164.9,302.4,75.981,1.964
..
snipped
...
2008-05-31 16:15:00,370,46.3,1.728,160.5,278,77.780,1.986
2008-05-31 16:30:00,322,44.5,1.511,154.3,233.7,75.132,2.188
2008-05-31 16:45:00,268,43.1,1.239,151,187.3,72.348,2.441

Now I get a different error message, namely:

Error in storage.mode(z) <- "double" : 
  (list) object cannot be coerced to type 'double'

Again, I am not familiar with debugging R/ggplot2 code, and I cannot see my mistake. It looks like the PR column, i.e. the z variable in my plot, is of type list. This is doubly odd since I now use the following code until I get it to work with ggplot:

library(akima)
data.interp <- interp(M$AM,M$Temperature,M$PR, duplicate="mean")
filled.contour(data.interp, nlevels=10)

@Dennis: As far as I can see, the interp function takes care of the "grid-scaling" you mentioned. Also when I try to use the scaled  `data.interp` for ggplot, I get:

Error: ggplot2 doesn't know how to deal with data of class list

I will try to play around with it a bit. Maybe cast the data.interp as in your example as it seems to have the same format as the volcano dataset.

Best Regards,
Michael Bach

Michael Bach

unread,
Mar 16, 2011, 9:57:33 AM3/16/11
to Michael Bach, ggp...@googlegroups.com
I made some progress, at least I think so.

I managed to get the following data frame via the melt function:

sane3d <- melt(data.interp$z)
names(sane3d) <- c("x","y","z")

Now my data frame looks like this:
      x  y        z
1     1  1       NA
2     2  1       NA
3     3  1       NA
4     4  1       NA
---
snipped
---
1597 37 40       NA
1598 38 40       NA
1599 39 40       NA
1600 40 40       NA

When trying to do the steps indicated in the stat_contour() documentation

v <- ggplot(sane3d, aes(x, y, z = z))
v + stat_contour()

I get

Warning message:
Removed 437 rows containing missing values (stat_contour).

and no plot. I then tried to remove NA entries from the data frame via 

sane3dno <- sane3d[!is.na(sane3d$z),]

So now data frame looks like 
      x  y        z
63   23  2 91.16882
64   24  2 88.00280
65   25  2 84.83677
---
snipped
---
1522  2 39 74.82651
1523  3 39 74.32170
1524  4 39 74.26800

When trying to plot it as above via 

v <- ggplot(sane3d, aes(x, y, z = z))
v + stat_contour()

It finishes without error warning, but also without plot. The elimination of NA's probably messed up the grid. Any ideas on this?

Thanks again!

Michael Bach

Dennis Murphy

unread,
Mar 16, 2011, 11:30:15 AM3/16/11
to Michael Bach, ggp...@googlegroups.com
Hi:

Since there is no reproducible example (hint!), I'll borrow one from example(akima)

library(akima)
example(akima)      # generates an object named akima.spl
> str(akima.spl)
List of 3
 $ x: num [1:100] 0 0.253 0.505 0.758 1.01 ...
 $ y: num [1:100] 0 0.202 0.404 0.606 0.808 ...
 $ z: num [1:100, 1:100] 58.2 NA NA NA NA NA NA NA NA NA ...

If you look carefully, the z element of the list is a 100 x 100 matrix. To convert it to a data frame, here's one approach:

v <- expand.grid(x = akima.spl$x, y = akima.spl$y)     # creates a 10000 x 2 data frame
v$z <- as.vector(akima.spl$z)                                     # unravel the matrix columnwise
str(v)
'data.frame':   10000 obs. of  3 variables:
 $ x: num  0 0.253 0.505 0.758 1.01 ...
 $ y: num  0 0 0 0 0 0 0 0 0 0 ...
 $ z: num  58.2 NA NA NA NA NA NA NA NA NA ...
 <attributes snipped>

ggplot(v, aes(x, y, z = z)) + geom_tile(aes(fill = z)) + geom_contour() +
    scale_fill_gradientn(colours = topo.colors(10))
Warning message:
Removed 375 rows containing missing values (stat_contour).

Perhaps you can adapt this example to your problem...notice that I didn't remove any NAs from the converted list.

HTH,
Dennis

Michael Bach

unread,
Mar 16, 2011, 12:25:57 PM3/16/11
to Dennis Murphy, ggp...@googlegroups.com
Thanks again Dennis for your advice. I appreciate the full example. Reminder for me: include one the next time. I followed your example with my data frame. I managed to get equivalent data structures. However, when I want to plot it with your last line, I get the same thing as mentioned in my last message. Namely: Nothing! Except for a meager:

Warning message:
Removed 463 rows containing missing values (stat_contour). 

ggplot again finishes nicely, also tells me about the NA lines (presumably), but fails to open a plot window...

How can I inspect what is going on here?

Michael Bach

unread,
Mar 17, 2011, 4:41:52 AM3/17/11
to Dennis Murphy, ggp...@googlegroups.com
I am sorry for all this noise. Just wanted to say it works now. Seems I had badly borked up my R session with all the trial and error...

Thanks yet again Dennis!
Reply all
Reply to author
Forward
0 new messages