2015-02-12 10 views
8

Ich bin auf der Suche nach Möglichkeiten, die von ggplot2 stat_contour generierte Kontur vollständig ausfüllen. Das aktuelle Ergebnis ist wie folgt:So füllen Sie die Kontur vollständig mit 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

Das gewünschte Ergebnis kann durch die Codes manuell modifiziert wie folgt hergestellt werden.

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

Meine Frage: die Farbe zu spezifizieren oder mit geom_tile() ist es eine Möglichkeit, ohne manuell vollständig die Handlung zu füllen?

+0

Verwandte: http://stackoverflow.com/questions/25788727/filled-contour-vs-ggplot2-stat-contour – tonytonov

+0

Soweit ich das beurteilen kann, müssen Sie erweitern Ihre Datensatz manuell Ihre Lösung sieht einfacher aus. Wenn Sie damit zufrieden sind, lassen Sie es einfach. – tonytonov

+0

Ich habe diesen Beitrag auch gesehen, aber geom_tile() benutzt winzige Rechtecke und so ist es nicht der Effekt, nach dem ich suche. filled.contour hat bisher das beste Ergebnis erzielt, aber seine Inkompatibilität mit mehreren Plots hat mich dazu gebracht, mit ggplots zu experimentieren. Ich frage mich, was die transparenten Regionen hervorgebracht hat. – chengvt

Antwort

9

Da @tonytonov diese thread vorgeschlagen hat, können die transparenten Bereiche durch Schließen der Polygone gelöscht werden.

# 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

Das Problem blieb mit diesem Tweak ist Methoden abgesehen von Versuch und Irrtum zu finden, die arbitaryValue zu bestimmen.

[Bearbeiten von hier]

Nur ein kurzes Update zu zeigen, wie ich die arbitaryValue bin zu bestimmen, ohne für alle Datensätze zu erraten ist.

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

Dies scheint für den Datensatz, an dem ich gerade arbeite, gut zu funktionieren. Nicht sicher, ob mit anderen anwendbar. Beachten Sie auch, dass die Tatsache, dass ich hier einen BINS-Wert einstelle, erfordert, dass ich bins=BINS in stat_contour verwenden muss.

+0

Ich bin froh, dass ich helfen konnte. Eine schöne Lösung, besonders bei diesen eklig aussehenden Artefakten, die jetzt verschwunden sind. Danke fürs Schreiben! – tonytonov

0

Danke für @ chengvts Antwort. Manchmal brauche ich diese Technik, also habe ich eine verallgemeinerte function() gemacht.

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

Verwandte Themen