2012-10-31 12 views
11

Ich möchte ggplot2's stat_binhex() verwenden, um zwei unabhängige Variablen auf dem gleichen Diagramm darzustellen, jede mit einem eigenen Farbverlauf mit scale_colour_gradientn().ggplot2 mehrere Stat_binhex() Plots mit unterschiedlichen Farbverläufen in einem Bild

Wenn wir die Tatsache unberücksichtigt lassen, dass die X-Achsen-Einheiten nicht übereinstimmen, wäre ein reproduzierbares Beispiel, die folgenden in demselben Bild zu zeichnen, während separate Füllgradienten beibehalten werden.

d <- ggplot(diamonds, aes(x=carat,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA) 
try(ggsave(plot=d,filename=<some file>,height=6,width=8)) 

enter image description here

d <- ggplot(diamonds, aes(x=depth,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA) 
try(ggsave(plot=d,filename=<some other file>,height=6,width=8)) 

enter image description here

fand ich einige Gespräche von einem ähnlichen Problem in ggplot2 Google Groups here.

Antwort

10

Hier ist eine weitere mögliche Lösung: Ich habe @ MNEL Idee des Abbildens bin genommen Alpha-Transparenz zählen, und ich habe die x-Variablen umgewandelt, so dass sie auf den gleichen Achsen aufgetragen werden kann.

library(ggplot2) 

# Transforms range of data to 0, 1. 
rangeTransform = function(x) (x - min(x))/(max(x) - min(x)) 

dat = diamonds 
dat$norm_carat = rangeTransform(dat$carat) 
dat$norm_depth = rangeTransform(dat$depth) 

p1 = ggplot(data=dat) + 
    theme_bw() + 
    stat_binhex(aes(x=norm_carat, y=price, alpha=..count..), fill="#002BFF") + 
    stat_binhex(aes(x=norm_depth, y=price, alpha=..count..), fill="#FFD500") + 
    guides(fill=FALSE, alpha=FALSE) + 
    xlab("Range Transformed Units") 

ggsave(plot=p1, filename="plot_1.png", height=5, width=5) 

Gedanken:

  1. versuchte ich (und nicht), eine vernünftige Farbe/alpha-Legende angezeigt werden soll.Scheint knifflig zu sein, sollte aber angesichts der Legenden-Anpassungsfunktionen von ggplot2 möglich sein.

  2. Die Kennzeichnung der X-Achseneinheit erfordert eine Lösung. Das Zeichnen von zwei Einheiten auf einer Achse wird von vielen verpönt, und ggplot2 hat keine solche Funktion.

  3. Die Interpretation von Zellen mit überlappenden Farben scheint in diesem Beispiel klar genug zu sein, könnte aber je nach den verwendeten Datasets und den gewählten Farben sehr unordentlich werden.

  4. Wenn die zwei Farben additive Komplemente sind, dann sehen Sie, wo immer sie sich gleichmäßig überlappen, ein neutrales Grau. Wo die Überlappung ungleich ist, würde sich das Grau zu mehr Gelb oder mehr Blau verschieben. Meine Farben sind nicht ganz komplementär, nach dem leicht rosafarbenen Farbton der grauen Überlappungszellen zu urteilen.

enter image description here

+0

Dies ist die richtige Richtung. Irgendeine Idee darüber, wie man jedem stat_binhex() einen scale_fill_gradientn() zuweist? Denken Sie auch an # 2 - Ihre beabsichtigte Anwendung verwendet die gleiche Einheit für beide x Variablen – metasequoia

+0

Sie können nur eine 'fill'-Skala in jedem' ggplot' Aufruf haben. Ich kann mir eine Art Hack vorstellen, bei dem Sie 'scale_fill_manual' mit manuell festgelegten Farben für jede Kombination von Wertebereich * Variable definieren. Dann würde jeder Aufruf von 'stat_binhex'' fill' auf einen variablenspezifischen Faktor abbilden ... aber jetzt plappere ich nur ... – bdemarest

5

Ich denke, was Sie wollen, geht gegen die Prinzipien von ggplot2 und die Grammatik von Grafiken Ansatz allgemeiner. Bis die issue gerichtet (für die ich nicht meinen Atem halten), haben Sie ein paar Möglichkeiten

Verwenden facet_wrap und alpha

Dies ist eine schöne Legende nicht produzieren, sondern führt Sie someway zu was du willst.

können Sie den alpha Wert von ..Frequency..

ich Ihnen die Legenden obwohl schön verschmelzen können nicht denken, durch die berechnete Frequency, zugegriffen zu skalieren.

library(reshape2) 
# in long format 
dm <- melt(diamonds, measure.var = c('depth','carat')) 

ggplot(dm, aes(y = price, fill = variable, x = value)) + 
    facet_wrap(~variable, ncol = 1, scales = 'free_x') + 
    stat_binhex(aes(alpha = ..count..), colour = 'grey80') + 
    scale_alpha(name = 'Frequency', range = c(0,1)) + 
    theme_bw() + 
    scale_fill_manual('Variable', values = setNames(c('darkblue','yellow4'), c('depth','carat'))) 

enter image description here

Verwenden gridExtra mit grid.arrange oder arrangeGrob

können Sie getrennte Diagramme erstellen und gridExtra::grid.arrange auf einem einzigen Bild zu arrangieren verwenden. (@bdemarest Kommentar unten und @baptiste Dank)

ersetzen grid.arrange mit arrangeGrob so etwas wie

d_carat <- ggplot(diamonds, aes(x=carat,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA) 

d_depth <- ggplot(diamonds, aes(x=depth,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA) 

library(gridExtra) 


grid.arrange(d_carat, d_depth, ncol =1) 

enter image description here

Wenn Sie wollen, dass diese mit ggsave arbeiten.

ggsave(plot=arrangeGrob(d_carat, d_depth, ncol=1), filename="plot_2.pdf", height=12, width=8) 
+2

Sie können 'ggsave()', wenn Sie für '' grid.arrange' arrangeGrob' ersetzen. Zum Beispiel: 'ggsave (plot = arrangeGrob (d_carat, d_depth, ncol = 1), Dateiname =" plot_2.pdf ", height = 12, width = 8)'. (@baptiste wies mich in einem früheren Kommentar darauf hin.) – bdemarest

+0

Danke @bdemarest, sehr nützlich. – mnel

+0

Die erste Antwort möglicherweise nicht mehr auf neuere Version von ggplot arbeiten, siehe [hier] (https://stackoverflow.com/questions/39446852/geom-hexbin-map-bincount-to-alpha/). – Axeman

Verwandte Themen