2015-02-12 10 views
8

Sto cercando modi per riempire completamente il contorno generato da stat_contour di ggplot2. Il risultato corrente è così:Come compilare completamente il profilo utilizzando 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

il risultato desiderato può essere prodotto modificando manualmente i codici come segue.

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

La mia domanda: esiste un modo per riempire completamente la trama senza specificare manualmente il colore o utilizzando geom_tile()?

+0

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

+0

Per quanto posso dire, è necessario espandere il vostro set di dati manualmente. La tua soluzione sembra più semplice, quindi se sei soddisfatto, lascia perdere. – tonytonov

+0

Ho visto anche quel post ma geom_tile() usa piccoli rettangoli e quindi non è l'effetto che sto cercando. filled.contour ha prodotto il miglior risultato finora ma la sua incompatibilità con il plotting multiplo mi ha portato a provare con ggplots. Mi chiedo cosa abbia prodotto le regioni trasparenti. – chengvt

risposta

9

Come suggerito da @tonytonov questo thread, le aree trasparenti possono essere eliminate chiudendo i poligoni.

# 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

Il problema è rimasto con questo tweak è trovare metodi a parte tentativi ed errori per determinare la arbitaryValue.

[modifica da qui]

Basta un rapido aggiornamento per mostrare come sto determinare la arbitaryValue, senza dover indovinare per ogni set di dati.

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

Questo sembra funzionare bene per il set di dati su cui sto lavorando ora. Non sono sicuro se applicabile con gli altri. Inoltre, tieni presente che il fatto che imposti il ​​valore BINS qui richiede che dovrò utilizzare bins=BINS in stat_contour.

+0

Contento di aver potuto aiutare. Bella soluzione, specialmente con questi artefatti dall'aspetto disgustoso che ora sono andati. Grazie per la pubblicazione! – tonytonov

0

Grazie per la risposta di @ chengvt. A volte ho bisogno di questa tecnica, quindi ho fatto un generalizzato 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

Problemi correlati