2014-06-06 26 views
15

Chcę nakładać dwa wykresy ggplot2 z kanałami alfa w taki sposób, aby wynikowy obraz pokazywał oba zbiory danych. To jest mój danych testowych:Nakładanie dwóch działek ggplot2 stat_density2d z kanałami alfa

data = read.table(text="P1 -1 0 4\nP2 0 0 2\nP3 2 1 8\nP4 -2 -2 6\nP5 0.5 2 12") 
data2 = read.table(text="Q1 1 1 3\nQ2 1 -1 2\nQ3 -1 1 8") 
colnames(data) = c("name","x","y","score") 
colnames(data2) = c("name","x","y","score") 

A oto jak wykreślić te dane:

ggplot(data, aes(x=x,y=y)) + 
    stat_density2d(data=data,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) + 
    theme(legend.position="none") + scale_fill_gradient (low = "#FFFFFF", high = "#FF0000") + 
    xlim(-3,3) + ylim(-3,3) + 
    geom_point() 

ggplot(data2, aes(x=x,y=y)) + 
    stat_density2d(data=data2,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) + 
    theme(legend.position="none") + 
    scale_fill_gradient (low = "#FFFFFF", high = "#00FF00") + 
    xlim(-3,3) + ylim(-3,3) + 
    geom_point() 

Pierwsza działka pokazuje dane, druga działka dane2:

Plot for dataset *data*Plot for dataset *data2*

Chcę teraz połączenie obu działek. Poniższy obraz jest tym, co chcę uzyskać. Wygenerowałem go za pomocą programu do edycji obrazów na komputerze, mnożąc oba obrazy jako warstwy.

Both datasets in one plot

próbowałem wykreślić jeden zestaw danych na drugim, ale to nie pomnożyć obie warstwy, a drugi kolor nadpisuje pierwszy.

ggplot(data, aes(x=x,y=y)) + 
    stat_density2d(data=data,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) + 
    theme(legend.position="none") + scale_fill_gradient (low = "#FFFFFF", high = "#FF0000") + 
    xlim(-3,3) + ylim(-3,3) + 
    stat_density2d(data=data2,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) + 
    scale_fill_gradient (low = "#FFFFFF", high = "#00FF00") 

enter image description here

Dodatkowo mam to ostrzeżenie: Skala do 'wypełnienia' jest już obecny. Dodanie kolejnej skali dla "wypełnienia", która zastąpi istniejącą skalę.

Czy można to zrobić w R? Lub jest tam inny sposób (przy użyciu innych funkcji, takich jak np. SmoothScatter), aby uzyskać ten lub podobny wynik? Jako pewnego rodzaju obejście myślę, że będę uzyskać podobny rezultat przy użyciu ImageMagick na serwerze, ale wolałbym zrobić to w R.

Update 1

Mnożenie dwóch warstw jest wykonane w ImageMagick w ten sposób;

composite -compose multiply data-red.png data-green.png im-multiply.png 

Daje to taki sam wynik, jak pokazano powyżej.

Aktualizacja 2

@Roland nauczył mnie w swojej odpowiedzi jak wykreślić dwa zestawy danych w obrębie tej samej działce. Chociaż jest to świetne, pozostaje jeden problem: Obraz zależy od kolejności, w jakiej dane są podawane na wykres.

ggplot(rbind(data.frame(data, group="a"), data.frame(data2, group="b")), aes(x=x,y=y)) + 
    stat_density2d(geom="tile", aes(fill = group, alpha=..density..), contour=FALSE) + 
    scale_fill_manual(values=c("a"="#FF0000", "b"="#00FF00")) + 
    geom_point() + 
    theme_minimal() + 
    xlim(-3.3, 3.3) + ylim(-3.3, 3.3) + 
    coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2)) 

daje ten wynik:

First plot dataset "a" then dataset "b2".

Kiedy zamiana kolejności obu zestawów danych (obecnie zbiór danych "b" aka dane2 nastąpi wcześniej, wówczas zbiór danych dane aka "a") , otrzymujesz podobny wynik, ale teraz dominuje kolor czerwony, ponieważ zostanie on wykreślony później i w ten sposób nadpisuje zielone dane.

ggplot(rbind(data.frame(data2, group="a"), data.frame(data, group="b")), aes(x=x,y=y)) + 
    stat_density2d(geom="tile", aes(fill = group, alpha=..density..), contour=FALSE) + 
    scale_fill_manual(values=c("b"="#FF0000", "a"="#00FF00")) + 
    geom_point() + theme_minimal() + 
    xlim(-3.3, 3.3) + ylim(-3.3, 3.3) + 
    coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2)) 

enter image description here

Potrzebuję rozwiązania, które nie zależą od kolejności zbiorów danych.

+1

Niestety [ "Obecnie nie może być tylko jedna skala na powierzchni (na wszystko oprócz X i Y)"] (http://stackoverflow.com/a/3809071/1457051) . A ponieważ jest to Hadley, najprawdopodobniej naprawdę utknąłeś w generowaniu dwóch fabuł i konwersji z ImageMagick. – hrbrmstr

+0

Dziękuję za skierowanie mnie do tego oświadczenia. Potem pójdę w stronę ImageMagick. – z80crew

+0

Kolejność ułożenia stosu wpływającego na ostateczny kolor, istnieje również ten wątek na ten temat: http://www.mail-archive.com/[email protected]/msg84014.html Najlepszym rozwiązaniem byłoby obliczyć kolory samego stosu i narysować je - tutaj jest przykład, choć nie w ggplot2: http://stackoverflow.com/questions/13867782/superimpose-red-green-images-in-r-using-image-or -rasterimage –

Odpowiedz

4

Należy wykreślić obie gęstości w tej samej skali:

ggplot(rbind(data.frame(data, group="a"), data.frame(data2, group="b")), 
     aes(x=x,y=y)) + 
    stat_density2d(geom="tile", aes(fill = group, alpha=..density..), 
       contour=FALSE) + 
    scale_fill_manual(values=c("a"="#FF0000", "b"="#00FF00")) + 
    geom_point() + 
    theme_minimal() + 
    xlim(-3.3, 3.3) + ylim(-3.3, 3.3) + 
    coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2)) 

enter image description here

przeciwnym razie wyświetla zniekształcony obraz swoich danych.

+0

To jest ogromna poprawa moich prób. Dziękuję Ci. Czy są szanse, że te dwie warstwy zostaną pomnożone? Z twoim kodem ostatni zestaw danych jest wizualnie dominujący, stąd zielony kolor jest jaśniejszy niż czerwony. Jeśli wymienię * dane * i * dane2 *, czerwony kolor stanie się jaśniejszy. – z80crew

+0

Maksymalne gęstości lokalne w grupie a są wyższe niż w grupie b. Fabuła to odzwierciedla. Nie mam pojęcia, co masz na myśli mówiąc "pomnożyć". – Roland

+0

Ale kiedy maksima grupy a (wykreślone na czerwono) są wyższe, dlaczego kolor zielony (grupa b) jest jaśniejszy? A jeśli zmienisz * dane * i * dane2 * w swoim kodzie: 'rbind (data.frame (dane2, grupa =" a "), data.frame (dane, grupa =" b ")' i 'wartości = c ("b" = "# FF0000", "a" = "# 00FF00") '- wtedy kolor czerwony jest jaśniejszy niż zielony." Pomnożony "Odnoszę się do trybu mieszania dla dwóch warstw przy edycji obrazu .Ten tryb jest symetryczny, więc kolejność wykonywania nie ma znaczenia – z80crew

9

Oto dokładnie to samo rozwiązanie niż @Roland, z tym wyjątkiem, że sugeruję linię konturu. Pozwala to docenić nakładanie się. Nie widzę, w jaki sposób geom_tile i Twój pomysł "rozmnażania" może umożliwić ci to docenić. Być może, jeśli użyjesz niebieskiego i czerwonego dla żadnego nakładającego się obszaru i "ważonego" fioletowego koloru dla nakładającego się obszaru. Ale myślę, że musiałbyś to wyliczyć w poprzednim kroku, zanim spiskuję, jak sądzę.

contour_line

ggplot(rbind(data.frame(data, group="a"), data.frame(data2, group="b")), 
     aes(x=x,y=y)) + 
    stat_density2d(geom="density2d", aes(color = group,alpha=..level..), 
       size=2, 
       contour=TRUE) + 
    #scale_color_manual(values=c("a"="#FF0000", "b"="#00FF00")) + 
    geom_point() + 
    theme_minimal() + 
    xlim(-3.3, 3.3) + ylim(-3.3, 3.3) + 
    coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2)) 
+0

Chyba chodziło Ci o' scale_color_manual' zamiast 'scale_fill_manual' –

+0

@WilliamZhang. Tak, dziękuję. Actullay I copy/paste Rozwiązanie Rolanda i dokonałem minimalnych zmian. Teraz poprawiam swój post. – Pierre

+0

Dziękuję, to jest interesująca aplikacja wizualna oach. Chociaż działa dobrze dla danych testowych, które pokazałem, nie jestem pewien, czy to zrobi dla moich prawdziwych danych. Niemniej jednak +1. – z80crew

Powiązane problemy