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)
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).
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
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
To '' geom_line (aes (grupa = zmienna, kolor = zmienna, kształt = zmienna)) '' naprawia kształty w kodzie. – PatrickT