Jak ustawić legendę alfa za pomocą ggplot2

81

Mam wykres prędkości wiatru względem kierunku, który ma ogromną liczbę punktów, więc używam alfa = I (1/20) oprócz koloru = miesiąc

Oto przykład kodu:

library(RMySQL)
library(ggplot2)
con <- dbConnect(...)
wind <- dbGetQuery(con, "SELECT speed_w/speed_e AS ratio, dir_58 as dir, MONTHNAME(timestamp) AS month, ROUND((speed_w+speed_e)/2) AS speed FROM tablename;");

png("ratio-by-speed.png",height=400,width=1200)
qplot(wind$dir,wind$ratio,ylim=c(0.5,1.5),xlim=c(0,360),color=wind$month,alpha=I(1/30),main="West/East against direction")
dev.off()

Daje to przyzwoity wykres, jednak moim problemem jest to, że alfa legendy również wynosi 1/30, co czyni ją nieczytelną. Czy istnieje sposób, aby zamiast tego wymusić na legendzie 1 alfa?

Oto przykład: Przykładowy wykres

Chris
źródło

Odpowiedzi:

112

Aktualizacja Wraz z wydaniem wersji 0.9.0 można teraz przesłonić wartości estetyczne w legendzie, używając override.aesw guidesfunkcji. Więc jeśli dodasz coś takiego do swojej fabuły:

+ guides(colour = guide_legend(override.aes = list(alpha = 1)))

że należy to zrobić.


Omówiłem to, wykonując zduplikowane wywołanie geom przy użyciu pustego podzbioru danych i używając legendy z tego wywołania. Niestety, to nie działa, jeśli ramka danych jest faktycznie pusta (np. Z której można uzyskać subset(diamonds,FALSE)), ponieważ ggplot2 wydaje się traktować ten przypadek tak samo, jak traktuje NULLzamiast ramki danych. Ale możemy uzyskać ten sam efekt, biorąc podzbiór z tylko jednym wierszem i ustawiając go naNaN na jeden z wymiarów wykresu, co uniemożliwi wykreślenie.

Na podstawie przykładu Chase'a:

# Alpha parameter washes out legend:
gp <- ggplot() + geom_point(data=diamonds, aes(depth, price, colour=clarity), alpha=0.1)
print(gp)

# Full color legend:
dummyData <- diamonds[1, ]
dummyData$price <- NaN
#dummyData <- subset(diamonds, FALSE)   # this would be nicer but it doesn't work!
gp <- ggplot() +
  geom_point(data=diamonds, aes(depth, price, colour=clarity), alpha=0.1, legend=FALSE) + 
  geom_point(data=dummyData, aes(depth, price, colour=clarity), alpha=1.0, na.rm=TRUE)
print(gp)
yoyoyoyosef
źródło
1
Znakomity. To rozwiązanie było niesamowite. Dopiero co udało mi się go wypróbować. Świetnie działa
Chris
3
+1 za aktualizację @ jorana (i świetny hack, który jest teraz niepotrzebny)
Gregor Thomas
Używam wersji 0.9.3.1, ale to nie działa dla mnie. Ustawiłem guides()funkcję w różnych pozycjach, ale nie otrzymuję oczekiwanego zachowania. Jakieś wskazówki?
polaryzuj
Aby dodać do starego wątku, musisz zmienić w colourzależności od tego, czego używasz do ustawiania kolorów. Na przykład użyłem powyższego rozwiązania, guides(fill = guide_legend(...))ponieważ użyłem aes(fill = val)na mojej działce
Mxblsdl
4

Trochę googlowania pojawiło się w tym poście, który nie wydaje się wskazywać, że ggplot obecnie obsługuje tę opcję. Inni rozwiązali podobne problemy, używając gridExtra i viewPorts, jak omówiono tutaj .

Nie jestem aż tak wyrafinowany, ale oto jedno podejście, które powinno dać pożądane rezultaty. Podejście polega na dwukrotnym wykreśleniu geometrii, raz bez parametru alfa i poza rzeczywistym obszarem kreślenia. Drugi geom będzie zawierał parametr alfa i pominie legendę. Następnie określimy region kreślenia za pomocą xlim i ylim. Biorąc pod uwagę, że masz dużo punktów, to z grubsza podwoi czas kreślenia, ale powinno dać ci pożądany efekt.

Korzystanie z zestawu danych diamentów:

#Alpha parameter washes out legend
ggplot(data = diamonds, aes(depth, price, colour = clarity)) + 
geom_point(alpha = 1/10)

#Fully colored legend
ggplot() +
geom_point(data = diamonds, aes(depth, price, colour =clarity), alpha = 1/10, legend = FALSE) + 
geom_point(data = diamonds, aes(x = depth - 999999, y = price - 999999, colour = clarity)) +
xlim(40, 80) + ylim(0, 20000) 
Pościg
źródło