2015-02-12 112 views
8

我寻找各种方法来通过GGPLOT2的stat_contour产生的轮廓完全填满。当前结果是这样的:如何填写轮廓充分利用stat_contour

# 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

期望的结果可以通过手动修改代码如下来生产。

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

我的问题:有没有办法完全填满,而无需手动指定颜色或使用geom_tile()的情节?

+0

相关:http://stackoverflow.com/questions/25788727/filled-contour-vs-ggplot2-stat-contour – tonytonov 2015-02-12 06:52:49

+0

据我所知,你需要扩大你的数据集手动。你的解决方案看起来更简单,所以如果你对它满意,就放手吧。 – tonytonov 2015-02-12 06:55:15

+0

我也看过那篇文章,但geom_tile()使用小矩形,所以它不是我要找的效果。 filled.contour产生了迄今为止最好的结果,但它与多个阴谋的不兼容导致我尝试使用ggplots。我想知道是什么产生了透明区域。 – chengvt 2015-02-12 07:14:25

回答

9

作为@tonytonov曾建议此thread,透明区域可以通过闭合多边形被删除。

# 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

存在的问题仍然与这个调整是从试验和错误一边寻找方法来确定arbitaryValue

[从这里编辑]

只是一个快速更新,以显示我如何确定arbitaryValue而不必猜测每个数据集。

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

这似乎对我现在正在使用的数据集很好。不确定是否适用于其他人。另外请注意,我在此设置BINS值的事实要求我必须在stat_contour中使用bins=BINS

+0

很高兴我能帮到你。很好的解决方案,特别是现在这些看起来很肮脏的文物。感谢发布! – tonytonov 2015-02-12 08:39:41

0

感谢@ chengvt的回答。我有时需要这种技术,所以我做了一个广义的function()

test_f <- function(df) { 
    colname <- names(df) 
    names(df) <- c("x", "y", "z") 
    Range <- as.data.frame(sapply(df, range)) 
    Dim <- as.data.frame(t(sapply(df, function(x) length(unique(x))))) 
    arb_z = Range$z[1] - diff(Range$z)/20 
    df2 <- rbind(df, 
       expand.grid(x = c(Range$x[1] - diff(Range$x)/20, Range$x[2] + diff(Range$x)/20), 
          y = seq(Range$y[1], Range$y[2], length = Dim$y), z = arb_z), 
       expand.grid(x = seq(Range$x[1], Range$x[2], length = Dim$x), 
          y = c(Range$y[1] - diff(Range$y)/20, Range$y[2] + diff(Range$y)/20), z = arb_z)) 
    g <- ggplot(df2, aes(x, y, z = z)) + labs(x = colname[1], y = colname[2], fill = colname[3]) + 
    stat_contour(geom="polygon", aes(fill=..level..)) + 
    coord_cartesian(xlim=c(Range$x), ylim=c(Range$y), expand = F) 
    return(g) 
} 

library(ggplot2); library(reshape2) 
volcano3d <- melt(volcano) 
names(volcano3d) <- c("xxx", "yyy", "zzz") 
test_f(volcano3d) + scale_fill_gradientn(colours = terrain.colors(10)) 

enter image description here