Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
552 views
in Technique[技术] by (71.8m points)

r - How to fill in the contour fully using stat_contour

I am looking for ways to fully fill in the contour generated by ggplot2's stat_contour. The current result is like this:

# Generate data
library(ggplot2)
library(reshape2) # for melt
volcano3d <- melt(volcano)
names(volcano3d) <- c("x", "y", "z")

v <- ggplot(volcano3d, aes(x, y, z = z))
v + stat_contour(geom="polygon", aes(fill=..level..)) 

enter image description here

The desired result can be produced by manually modifying the codes as follows.

v + stat_contour(geom="polygon", aes(fill=..level..)) +
  theme(panel.grid=element_blank())+  # delete grid lines
  scale_x_continuous(limits=c(min(volcano3d$x),max(volcano3d$x)), expand=c(0,0))+ # set x limits
  scale_y_continuous(limits=c(min(volcano3d$y),max(volcano3d$y)), expand=c(0,0))+  # set y limits
  theme(panel.background=element_rect(fill="#132B43"))  # color background

enter image description here

My question: is there a way to fully fill the plot without manually specifying the color or using geom_tile()?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @tonytonov has suggested this thread, the transparent areas can be deleted by closing the polygons.

# check x and y grid
minValue<-sapply(volcano3d,min)
maxValue<-sapply(volcano3d,max)
arbitaryValue=min(volcano3d$z-10)

test1<-data.frame(x=minValue[1]-1,y=minValue[2]:maxValue[2],z=arbitaryValue)
test2<-data.frame(x=minValue[1]:maxValue[1],y=minValue[2]-1,z=arbitaryValue)
test3<-data.frame(x=maxValue[1]+1,y=minValue[2]:maxValue[2],z=arbitaryValue)
test4<-data.frame(x=minValue[1]:maxValue[1],y=maxValue[2]+1,z=arbitaryValue)
test<-rbind(test1,test2,test3,test4)

vol<-rbind(volcano3d,test)

w <- ggplot(vol, aes(x, y, z = z))
w + stat_contour(geom="polygon", aes(fill=..level..)) # better

# Doesn't work when trying to get rid of unwanted space
w + stat_contour(geom="polygon", aes(fill=..level..))+
  scale_x_continuous(limits=c(min(volcano3d$x),max(volcano3d$x)), expand=c(0,0))+ # set x limits
  scale_y_continuous(limits=c(min(volcano3d$y),max(volcano3d$y)), expand=c(0,0))  # set y limits

# work here!
w + stat_contour(geom="polygon", aes(fill=..level..))+
coord_cartesian(xlim=c(min(volcano3d$x),max(volcano3d$x)),
                ylim=c(min(volcano3d$y),max(volcano3d$y)))

enter image description here

The problem remained with this tweak is finding methods aside from trial and error to determine the arbitaryValue.

[edit from here]

Just a quick update to show how I am determining the arbitaryValue without having to guess for every datasets.

BINS<-50
BINWIDTH<-(diff(range(volcano3d$z))/BINS) # reference from ggplot2 code
arbitaryValue=min(volcano3d$z)-BINWIDTH*1.5

This seems to work well for the dataset I am working on now. Not sure if applicable with others. Also, note that the fact that I set BINS value here requires that I will have to use bins=BINS in stat_contour.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...