2015-02-23 25 views
7

W ggplot2 działki, ja łączenia geom_line i geom_point z geom_bar i 'problemów łączących legendy w jednym opakowaniu.ggplot2: połączyć legendy dla geom_line, geom_point i geom_bar

Kod podstawowej działki znajduje się poniżej. Używane dane są niższe.

# Packages 
library(ggplot2) 
library(scales) 

# Basic Plot 
ggplot(data = df1, aes(x = Year, y = value, group = variable, 
    colour = variable, shape = variable)) + 
geom_line() + 
geom_point(size = 3) + 
geom_bar(data = df2, aes(x = Year, y = value, fill = variable), 
    stat = "identity", alpha = 0.8) + 
ylab("Current Account Transactions (Billion $)") + 
xlab(NULL) + 
theme_bw(14) + 
scale_x_discrete(breaks = seq(1999, 2013, by = 2)) + 
scale_y_continuous(labels = dollar, limits = c(-1, 4), 
    breaks = seq(-1, 4, by = .5)) + 
geom_hline(yintercept = 0) + 
theme(legend.key = element_blank(), 
    legend.background = element_rect(colour = 'black', fill = 'white'), 
    legend.position = "top", legend.title = element_blank()) + 
guides(col = guide_legend(ncol = 1), fill = NULL, colour = NULL) 

enter image description here

Moim celem jest, aby połączyć ze sobą legendy. Z jakiegoś powodu "Saldo na rachunku bieżącym" pojawia się w górnej legendzie (nie rozumiem dlaczego), podczas gdy legenda "Wywózki" i "Przywóz" jest pomieszana z czarnym tłem i brakującymi kształtami.

Jeśli biorę fill zewnątrz aes mogę legendę dla „import” i „Eksport”, aby wyświetlić z odpowiednimi kształtami i kolorami i bez czarnym tle, ale potem stracić fill legendę „Balance na rachunku bieżącym. "

Sztuczka użyłem wcześniej z pewnym sukcesem, który jest w użyciu scale_colour_manual, scale_shape_manual i scale_fill_manual (a może scale_alpha) nie wydają się działać tutaj. Sprawienie, że będzie działać, byłoby miłe. Ale pamiętaj, że z tą sztuczką, o ile mi wiadomo, trzeba ręcznie określić kolory, kształty i wypełnienia, których tak naprawdę nie chcę robić, ponieważ jestem całkiem zadowolony z domyślnych kolorów/kształtów/wypełnień.

ja normalnie zrobić coś takiego, ale to nie działa:

library(RColorBrewer) 
cols <- colorRampPalette(brewer.pal(9, "Set1"))(3) 
last_plot() + scale_colour_manual(name = "legend", values = cols) + 
    scale_shape_manual(name = "legend", values = c(0,2,1)) + 
    scale_fill_manual(name = "legend", values = "darkred") 

W powyższym nie określa etykiety, ponieważ w moim problemie będę mieć do czynienia z dużą ilością danych i to nie byłoby praktyczne ręczne określanie etykiet. Chciałbym, aby ggplot2 używał domyślnych etykiet. Z tego samego powodu chciałbym użyć domyślnych kolorów/kształtów/wypełnień.

Podobne trudności zostały zgłoszone gdzie indziej, na przykład tutaj Construct a manual legend for a complicated plot, ale nie udało mi się zastosować rozwiązania mojego problemu.

Wszelkie pomysły?

# Data 

df1 <- structure(list(Year = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 1L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L), .Label = c("1999", 
"2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", 
"2008", "2009", "2010", "2011", "2012", "2013"), class = "factor"), 
    variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Exports of goods and services", 
    "Imports of goods and services"), class = "factor"), value = c(1.304557, 
    1.471532, 1.345165, 1.31879, 1.409053, 1.642291, 1.895983, 
    2.222124, 2.569492, 2.751949, 2.285922, 2.630799, 2.987571, 
    3.08526, 3.178744, 1.600087, 1.882288, 1.740493, 1.776877, 
    1.930395, 2.276059, 2.641418, 3.028851, 3.288135, 3.43859, 
    2.666714, 3.074729, 3.446914, 3.546009, 3.578998)), .Names = c("Year", 
"variable", "value"), row.names = c(NA, -30L), class = "data.frame") 

df2 <- structure(list(Year = structure(1:15, .Label = c("1999", "2000 ", 
"2001", "2002 ", "2003", "2004 ", "2005", "2006 ", "2007", "2008 ", 
"2009", "2010 ", "2011", "2012 ", "2013"), class = "factor"), 
    variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L), .Label = "Balance on current account", class = "factor"), 
    value = c(-0.29553, -0.410756, -0.395328, -0.458087, -0.521342, 
    -0.633768, -0.745434, -0.806726, -0.718643, -0.686641, -0.380792, 
    -0.44393, -0.459344, -0.460749, -0.400254)), .Names = c("Year", 
"variable", "value"), row.names = c(NA, -15L), class = "data.frame") 

EDIT

Po wysłaniu na moje pytanie i czytania odpowiedź Scotta, eksperymentowałem z innym podejściem. W pewnym sensie zbliża się do pożądanego rezultatu, ale dalej w innych. Pomysł polega na scaleniu ramek danych w jedną ramkę danych i przekazaniu koloru/kształtu/wypełnienia do aes w pierwszym wywołaniu ggplot. Problem polega na tym, że dostaję niepożądane "cięcie" przez legendy. Nie udało mi się usunąć ukośników bez usuwania wszystkich kolorów. Innym problemem z tym podejściem, o którym wspomniałem od razu, jest to, że muszę ręcznie określić kilka rzeczy, podczas gdy ja chciałbym zachować domyślne wartości wszędzie tam, gdzie to możliwe.

df <- rbind(df1, df2) 
ggplot(data = df, aes(x = Year, y = value, group = variable, colour = variable, 
    shape = variable, fill = variable)) + 
    geom_line(data = subset(df, variable %in% c("Exports of goods and services", "Imports of goods and services"))) + 
    geom_point(data = subset(df, variable %in% c("Exports of goods and services", "Imports of goods and services")), size = 3) + 
    geom_bar(data = subset(df, variable %in% c("Balance on current account")), aes(x = Year, y = value, fill = variable), 
    stat = "identity", alpha = 0.8) 
cols <- c(NA, "darkgreen", "darkblue") 
last_plot() + scale_colour_manual(name = "legend", values = cols) + 
    scale_shape_manual(name = "legend", values = c(32, 15, 17)) + 
    scale_fill_manual(name = "legend", values = c("orange", NA, NA)) + 
    ylab("Current Account Transactions (Billion $)") + 
    xlab(NULL) + 
    theme_bw(14) + scale_x_discrete(breaks = seq(1999, 2013, by = 2)) + 
    scale_y_continuous(labels = dollar, limits = c(-1, 4), breaks = seq(-1, 4, by = .5)) + 
    geom_hline(yintercept = 0) + 
    theme(legend.key = element_blank(), legend.background = element_rect(colour = 'black', fill = 'white'), legend.position = "top", legend.title = element_blank()) + 
    guides(col = guide_legend(ncol = 1)) 

dodanie + guides(fill = guide_legend(override.aes = list(colour = NULL))) usuwa ukośniki ale darkgreen/Ciemnoniebieski kolory zbyt (to robi zachować pomarańczową syta).

enter image description here

Odpowiedz

3

Aby wyeliminować „saldo na rachunku bieżącym” od pojawiające się w górę legendy można przenieść group, colour i shape estetykę z rozmowy rodzic ggplot() i do geom_line() i geom_point() prawidłowo. Daje to konkretną kontrolę nad tym, który estetyk ma zastosowanie do każdego z dwóch zestawów danych, które mają wspólne nazwy zmiennych. enter image description here

ggplot(data = df1, aes(x = Year, y = value)) + 
    geom_line(aes(group = variable, colour = variable)) + 
    geom_point(aes(shape = variable, colour = variable), size = 3) + 
    geom_bar(data = df2, aes(x = Year, y = value, fill = variable), 
      stat = "identity", position = 'identity', alpha = 0.8, guide = 'none') + 
    ylab("Current Account Transactions (Billion $)") + 
    xlab(NULL) + 
    theme_bw(14) + 
    scale_x_discrete(breaks = seq(1999, 2013, by = 2)) + 
    scale_y_continuous(labels = dollar, limits = c(-1, 4), 
        breaks = seq(-1, 4, by = .5)) + 
    geom_hline(yintercept = 0) + 
    guides(col = guide_legend(ncol = 1)) + 
    theme(legend.key = element_blank(), 
     legend.background = element_rect(colour = 'black', fill = 'white'), 
     legend.position = "top", legend.title = element_blank(), 
     legend.box.just = "left") 

Ta odpowiedź ma pewne braki. Aby nazwać parę: 1) Pozostały dwie oddzielne legendy, które mogą być ukryte, jeśli zdecydujesz się ich nie zamykać (np. Nie ustawiając legend.background). 2) Usunięcie zmiennej df2 z górnej legendy oznacza, że ​​nie zużywa ona pierwszego domyślnego koloru (tak jak poprzednio, przez zwykły zbieg okoliczności), więc teraz "Balance ..." i "Exports ..." obie wyglądają na różowe, ponieważ legenda wypełnienia przetwarza domyślną skalę kolorów.

+0

Dzięki Scott. To naprawdę blisko. Kolor nie powinien być zbyt trudny do naprawienia. Zastanawiam się, czy połączenie dwóch ramek danych i utrzymanie grupy/koloru/kształtu/wypełnienia wewnątrz ggplot aes było drogą do zrobienia. Dam temu szansę. – PatrickT

+0

Zobacz moją edycję. Jak na razie twoja odpowiedź jest lepsza od mojej edycji, chociaż moja ma dobre wyrównanie w legendzie, twoja ma lepszy kolor/wypełnienie. Po prostu zauważam, że twoje rozwiązanie używa tego samego kształtu dwa razy, jeśli widzę poprawnie, co nie jest pożądane. Jeszcze raz dziękuję, utrzymam to na dłużej, na wypadek, gdyby pojawiło się coś lepszego. Jeśli nie, przyjmuję twoją odpowiedź za kilka dni. – PatrickT

+0

To '' geom_line (aes (grupa = zmienna, kolor = zmienna, kształt = zmienna)) '' naprawia kształty w kodzie. – PatrickT

Powiązane problemy