12

I've been learning ggplot2, and hope to use it for all my R graphing. However, I've yet to find a way to make a contour plot that looks analogous to a conventional contour plot, like what can be obtained using lattice:filled.contour(). For example:

#define data
x<-seq(1,11,1)
y<-seq(1,11,1)
xyz.func<-function(x,y) {-10.4+6.53*x+6.53*y-0.167*x^2-0.167*y^2+0.0500*x*y}

#contour plot using lattice graphics and R Color Brewer
library(lattice) #for filled.contour()
library(RColorBrewer) #for brewer.pal()
z.lattice<-outer(x,y,xyz.func)
filled.contour(x,y,z.lattice,nlevels=6,col=brewer.pal(6,"YlOrRd"))

This gives me a nice contour plot.

enter image description here

Now, let's try the same thing in ggplot2. The best I can come up with, based on everything I've read (particularly Drawing labels on flat section of contour lines in ggplot2) is:

#contour plot using ggplot2
library(ggplot2)
library(reshape2) #for melt()
z.molten<-melt(z.lattice) 
names(z.molten) <- c("x", "y", "z")
v<-ggplot(z.molten, aes(x,y,z=z))+
    geom_tile(aes(fill=z))+
    stat_contour(bins=6,aes(x,y,z=z), color="black", size=0.6)+
    scale_fill_gradientn(colours=brewer.pal(6,"YlOrRd"))
v

This graph has the same basic idea as filled.contour(), but the colored tiles don't conform to the contours very well.

enter image description here

I haven't been successful with changing the sizes of the tiles, either.

Any suggestions on how to make ggplot2's output closer to filled.contour()'s output?

Wissenschaftler
  • 165
  • 1
  • 1
  • 9
  • Thanks, MrFlick, for adding the graphs! – Wissenschaftler Dec 19 '14 at 17:04
  • Thanks for the suggestion, @jlhoward. When I try using geom=polygon with stat_contour() I end up with polygonal contours, but maybe I'm using it incorrectly. For example, `ggplot(z.molten, aes(x,y,z=z))+stat_contour(geom="polygon",bins=6,aes(x,y,z=z))` makes the contours polygonal. – Wissenschaftler Dec 19 '14 at 17:11

1 Answers1

16

The essence of your question, it seems, is how to produce a contour plot in ggplot with discrete filled contours, rather than continuous contours as you would get using the conventional geom_tile(...) approach. Here is one way.

x<-seq(1,11,.03)                    # note finer grid
y<-seq(1,11,.03)
xyz.func<-function(x,y) {-10.4+6.53*x+6.53*y-0.167*x^2-0.167*y^2+0.0500*x*y}
gg <- expand.grid(x=x,y=y)
gg$z <- with(gg,xyz.func(x,y))      # need long format for ggplot
library(ggplot2)
library(RColorBrewer)               #for brewer.pal()
brks <- cut(gg$z,breaks=seq(0,100,len=6))
brks <- gsub(","," - ",brks,fixed=TRUE)
gg$brks <- gsub("\\(|\\]","",brks)  # reformat guide labels
ggplot(gg,aes(x,y)) + 
  geom_tile(aes(fill=brks))+
  scale_fill_manual("Z",values=brewer.pal(6,"YlOrRd"))+
  scale_x_continuous(expand=c(0,0))+
  scale_y_continuous(expand=c(0,0))+
  coord_fixed()

The use of, e.g., scale_x_continuos(...) is just to get rid of the extra space ggplot puts around the axis limits; fine for most things but distracting in contour plots. The use of coord_fixed(...) is just to set the aspect ratio to 1:1. These are optional.

jlhoward
  • 58,004
  • 7
  • 97
  • 140