Załóżmy, że mam następującą działkę w ggplot:Jak połączyć kolor, styl linii i legendy kształt w ggplot
został wygenerowany za pomocą poniższego kodu:
x <- seq(0, 10, by = 0.2)
y1 <- sin(x)
y2 <- cos(x)
y3 <- cos(x + pi/4)
y4 <- sin(x + pi/4)
df1 <- data.frame(x, y = y1, Type = as.factor("sin"), Method = as.factor("method1"))
df2 <- data.frame(x, y = y2, Type = as.factor("cos"), Method = as.factor("method1"))
df3 <- data.frame(x, y = y3, Type = as.factor("cos"), Method = as.factor("method2"))
df4 <- data.frame(x, y = y4, Type = as.factor("sin"), Method = as.factor("method2"))
df.merged <- rbind(df1, df2, df3, df4)
ggplot(df.merged, aes(x, y, colour = interaction(Type, Method), linetype = Method, shape = Type)) + geom_line() + geom_point()
bym lubię mieć tylko jedną legendę, która poprawnie wyświetla kształty, kolory i typy linii (legendy interakcji (typu, metody) są najbliższe temu, co bym chciał, ale nie ma właściwych kształtów/typów linii).
Wiem, że jeśli użyję scale_xxx_manual i podam te same etykiety dla wszystkich legend, to zostaną one scalone, ale nie chcę ustawiać etykiet ręcznie: jeśli pojawią się nowe metody lub typy, to ja "Chcę zmodyfikować mój kod: chcę czegoś ogólnego.
Edit
Jak wskazano w odpowiedzi poniżej, istnieje kilka sposobów, aby otrzymać pracę w tym konkretnym przypadku. Wszystkie proponowane rozwiązania wymagają ręcznego ustawiania typów linii i kształtów legendy za pomocą funkcji scale_xxx_manual function
lub z funkcją guides
.
Jednak proponowane rozwiązania nadal nie działają w ogólnym przypadku: na przykład, jeśli dodaję nową ramkę danych do zestawu danych za pomocą nowej metody "method3", to już nie działa, musimy ręcznie dodawać nowe kształty i rodzaje legenda linia:
y5 <- sin(x - pi/4)
df5 <- data.frame(x, y = y5, Type = as.factor("sin"), Method = as.factor("method3"))
df.merged <- rbind(df1, df2, df3, df4, df5)
override.shape <- c(16, 17, 16, 17, 16)
override.linetype <- c(1, 1, 3, 3, 4)
g <- ggplot(df.merged, aes(x, y, colour = interaction(Type, Method), linetype = Method, shape = Type)) + geom_line() + geom_point()
g <- g + guides(colour = guide_legend(override.aes = list(shape = override.shape, linetype = override.linetype)))
g <- g + scale_shape(guide = FALSE)
g <- g + scale_linetype(guide = FALSE)
print(g)
Daje:
Nasuwa się pytanie: w jaki sposób automatycznie generować override.shape
i override.linetype
wektory?
Należy zauważyć, że wielkość wektor jest 5 ponieważ mamy 5 krzywych, natomiast współczynnik interaction(Type, Method)
ma rozmiar 6 (nie mam danych dla cos/kombinacji method3)
Twoja skala kolorów jest zbędna w połączeniu ze skalą kształtu i rodzaju linii. Powinieneś używać tylko jednego z nich. – Roland
Tak, jest to zbyteczne. Początkowo miałem kolory zmapowane na typ i rodzaj linii odwzorowany na metodę. Ale kiedy krzywe były zbyt blisko siebie, trudno było je odróżnić. Zatem redundancja – Ben
Często właściwe jest posiadanie nadmiarowych definicji grup kształtów/kolorów. W wielu publikacjach naukowych kolor jest najbardziej wizualnie skutecznym sposobem rozróżniania grup, ale wiesz również, że duża część czytelników będzie drukować czarno-białe kopie papieru, a więc chcesz również dodać wizualną sygnaturę, która nie jest ". t zależy od koloru. – neuropsych