Formatowanie wykresów z pakietem ggplot2

Statystyczne i graficzne podstawy geowizualizacji

Author

Anna Dmowska, dmowska@amu.edu.pl

Elementy formatowania wykresów obejmują, np.:

library(tidyverse)
library(ggplot2)

1 Dane

  • Wczytanie danych
dane = read.csv("dane/gapminder_regions.csv")
  • Przygotowanie danych
dane = dane |> 
  na.omit() |> 
  mutate(across(where(is.character), as.factor)) |> 
  mutate(income_grp = factor(income_grp, levels = c(1,2,3), labels = c("niski", "średni", "wysoki")),
         pop_mln = pop/1000000)

Selekcja danych dla 2007 roku.

dane2007 = dane |> 
  filter(rok == 2007)

2 Zmiana koloru, kształtu oraz wielkości punktów

W R sposób wyświetlania punktu (kształt) kodowany jest za pomoca numeru.

ggplot(data=dane2007, aes(x=pkb, y=le)) +
  geom_point(size = 3, color = "red", shape = 15)

Wyświetl wykres zależności zmiennych pkb i le używając kształtu wypełnionego trójkąta o kolorze zielonym i wielkości 2.

3 Zmiana koloru oraz grubości linii

W przypadku wyświetlania linii można zmienić:

  • kolor (color),
  • grubość linii (linewidth)
  • typ linii (linetype) - określany za pomocą wartości od 0 do 6 lub nazwy: (0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash, 6 = twodash),
ggplot(data = dane, aes(x = rok, y = le)) + 
  stat_summary(fun = "mean", geom = "line", 
               color = "orange", linewidth = 2, linetype = "dotted")

Zmień typ, grubość oraz kolor linii w powyższym przykładzie.

4 Modyfikacja wykresu względem wartości zmiennej

Wykresy mogą być modyfikowane na podstawie wartości zmiennej. W tym celu można posłużyć się atrybutami:

  • kolor (color) - stosowany dla zmiennej ilościowej oraz jakościowej
  • wielkość (size) - stosowany dla zmiennej ilościowej i jakościowej
  • kształt (shape) - stosowany dla zmiennej jakościowej

4.1 Kształt

ggplot(data=dane2007, aes(x=pkb, y=le, shape = income_grp)) + 
  geom_point()

Wykorzystując scale_shape_manual() można przypisać wybrany kształt do poszczególnych kategorii zmiennej jakościowej.

ggplot(data=dane2007, aes(x=pkb, y=le, shape = income_grp)) + 
  geom_point(size = 3) + 
  scale_shape_manual(name = "Dochód", values = c("niski" = 7, "średni" = 8, "wysoki" = 9)
  )

ggplot(data=dane2007, aes(x=pkb, y=le, shape = income_grp)) + 
  geom_point(size = 3, color = "blue4") + 
  scale_shape_manual(values = c("niski" = 7, "średni" = 8, "wysoki" = 9)
  )

4.2 Wielkość

Wielkość punktów może być użyta do rozróżnienia kategorii zmiennej jakościowej, które mają naturalną kolejność, np. grupy dochodów - niski, średni i wysoki.

ggplot(data=dane2007, aes(x=pkb, y=le, size = income_grp)) + 
  geom_point()
Warning: Using size for a discrete variable is not advised.

Funkcja scale_size_manual() pozwala na przypisanie kategoriom określonych wielkości punktów.

ggplot(data=dane2007, aes(x=pkb, y=le, size = income_grp)) + 
  geom_point() + 
  scale_size_manual(values = c("niski" = 1, 
                               "średni" = 5,
                               "wysoki" = 10))

Dodatkowo można zmienić kolor oraz kształt punktów.

ggplot(data=dane2007, aes(x=pkb, y=le, size = income_grp)) + 
  geom_point(shape = 1, color = "red") + 
  scale_size_manual(name = "Dochód", 
                    values = c("niski" = 1, 
                               "średni" = 5,
                               "wysoki" = 10))

4.2.1 Wielkość - zmienna ilościowa

Wielkość punktów może być także modyfikowana na podstawie zmiennej ilościowej, np. liczby ludności.

ggplot(data=dane2007, aes(x=pkb, y=le, size = pop_mln)) + 
  geom_point() 

Funkcja scale_size() pozwala na określenie przedziałów dla zmiennej ilościowej. Pozwala ona na zdefiniowanie:

  • przedziałów zmiennej ilościowej (breaks)
  • nazwy, która ma się pojawić w legendzie (name)
  • zakresu wielkości punktów (range)

W poniższym przykładzie breaks = seq(0, 1500, 300) oznacza wektor wartości zmiennej pop_mln od 0 do 1500 z krokiem co 300, tj. 0, 300, 600, 900, 1200, 1500.

ggplot(data=dane2007, aes(x=pkb, y=le, size = pop_mln)) + 
  geom_point() +
  scale_size(breaks = seq(0, 1500, 300))

W poniższym przykładzie range = c(2, 10) oznacza, zakres wielkości punktów od 0 do 10.

ggplot(data=dane2007, aes(x=pkb, y=le, size = pop_mln)) + 
  geom_point() +
  scale_size(name = "Liczba ludności [mln]",
            breaks = seq(0, 1500, 300), 
            range = c(2, 10))

Funkcja scale_size_binned() pokazuje przedziały dla zmiennej pop_mln pozwalając na łatwiejsze powiązanie wielkości punktów z konketnymi przedziałami zmiennej.

ggplot(data=dane2007, aes(x=pkb, y=le, size = pop_mln)) + 
  geom_point(alpha = 0.3) + 
  scale_size_binned(name = "Liczba ludności [mln]",
            breaks = seq(0, 1500, 300), 
            range = c(2, 10))
Warning in sqrt(x): NaNs produced
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).

Funkcja scale_size_binned() pokazuje przedziały dla zmiennej pop_mln pozwalając na łatwiejsze powiązanie wielkości punktów z konketnymi przedziałami zmiennej. Za pomocą n.breaks można zdefiniować liczbę przedziałów, a transform pozwla na zastosowanie transformacji zmiennej (w poniższym przykładzie zastosowano log10).

ggplot(data=dane2007, aes(x=pkb, y=le, size = pop_mln)) + 
  geom_point(alpha = 0.3) + 
  scale_size_binned(name = "Liczba ludności [mln]",
                    transform = "log10",
                    n.breaks = 5,
                    range = c(0, 5))

5 Kolor obramowania i wypełnienia

Kolor obramowania zmieniamy za pomocą color, a kolor wypełnienia za pomocą fill.

ggplot(data=dane2007, aes(x=pkb)) + geom_histogram(color = "red") 
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.

ggplot(data=dane2007, aes(x=pkb)) + geom_histogram(fill = "red") 
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.

ggplot(data=dane2007, aes(x=pkb)) + geom_histogram(color = "red", fill = "pink") 
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.

6 Skale kolorystyczne dla zmiennej jakościowej

color = income_grp oznacza, że kolor punktów ma być przypisany na podstawie zmiennej income_grp.

ggplot(data=dane2007, aes(x=pkb, y=le, color = income_grp)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia")

  • scale_color_manual oraz scale_fill_manual pozwala na samodzielne zdefiniowanie kolorów. Można także przypisać wektor z nazwami kategorii - wtedy kolor zostanie przypisany do danej kategorii.
ggplot(data=dane2007, aes(x=pkb, y=le, color = income_grp)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_manual(values = c("orange", "red", "brown"))

ggplot(data=dane2007, aes(x=pkb, y=le, color = income_grp)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_manual(values = c("niski" = "orange",
                                "średni" = "red", 
                                "wysoki" = "brown"))

  • scale_color_brewer oraz scale_fill_brewer z pakietu RColorBrewer pozwala na zdefiniowanie jednej z palet dostarczanych przez pakier RColorBrewer.

Dostępne palety w pakiecieRColorBrewer.

library(RColorBrewer)
RColorBrewer::display.brewer.all(type = "qual")

ggplot(data=dane2007, aes(x=pkb, y=le, color = income_grp)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_brewer(palette = "Set1")

  • scale_color_discrete_qualitative oraz scale_fill_discrete_qualitative z pakietu colorspace (https://colorspace.r-forge.r-project.org/articles/ggplot2_color_scales.html)
library(colorspace)
hcl_palettes("qualitative", plot = TRUE)

library(colorspace)
ggplot(data=dane2007, aes(x=pkb, y=le, color = income_grp)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_discrete_qualitative(palette = "Dark 3")

7 Skale kolorystyczne dla zmiennej ilościowej

color = pop oznacza, że kolor punktów ma być przypisany na podstawie zmiennej pop.

ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia")

  • Wykorzystując scale_color_continuous() lub continuous() można “zbudować” paletę na podstawie podanych nazw kolorów. Kolory można definiować za pomoca nazw lub zapisu szestnastkowego.
ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_continuous(palette = c("#E5F5E0", "#A1D99B", "#31A354"), n.breaks = 3)

ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_colour_continuous(palette = c("lightgreen", "green3", "darkgreen"), n.breaks = 3)

  • scale_color_continuous() oraz scale_fill_continuous() pozwala także na podanie nazwy palety, np. “Greens”.
ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_colour_continuous(palette = "Greens", n.breaks = 3)

  • Skale gradientowe

Skale gradientowe pozwalają na utworzenie dowolnej palety kolorów. Paleta jest tworzona wkorzystując liniową interpolację między kolorami referencyjnymi.

-`scale_color_gradient() oraz `scale_fill_gradient()` generuje gradient dwukolorowy
- `scale_color_gradient2() oraz `scale_fill_gradient2()` generuje gradient trójkolorowy z określonym punktem środkowym
- `scale_color_gradientn()` oraz`scale_fill_gradientn()` generuje gradient n-kolorowy
ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_gradient(low = "orange", high = "brown")

  • scale_fill_gradient2() jest przydatne do tworzenia palet rozbieżnych. W poniższym przykładzie midpoint oznacza medianę liczby ludności
ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_gradient2(low = "blue", mid = "grey", high = "red", midpoint =  10674563)

  • scale_color_viridis_c() lub scale_fill_viridis_c() wykorzystuje paletę Virdis.
ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point(size = 3) + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_viridis_c()

  • scale_color_continuous_sequential z pakietu colorspace korzysta z jednej z palet sekwencyjnych z pakietu colorspace
library(colorspace)
hcl_palettes("sequential", plot = TRUE)

ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
   scale_color_continuous_sequential(palette = "Oranges", n.breaks = 3)

ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_continuous_sequential(trans = "log10", labels = scales::label_comma(), palette = "YlOrRd")

  • Funkcja scale_color_brewer() oraz scale_fill_brewer() została zaprojektowana dla danych dyskretnych. Aby wykorzystać palety dostępne w pakiecie RColorBrewer do danych ciągłych należy użyć scale_colour_distiller() lub scale_fill_distiller(), które interpolują kolory do skali ciągłej.
library(RColorBrewer)
RColorBrewer::display.brewer.all(type = "all")

ggplot(data=dane2007, aes(x=pkb, y=le, color = pop)) + 
  geom_point() + 
  labs(x = "PKB na osobę (USD)", y = "Oczekiwana dalsza długość trwania życia") + 
  scale_color_distiller(palette = "YlOrRd")

8 Łączenie kształtów i kolorów

ggplot(data = dane2007, aes(x = pkb, y = le, shape = income_grp, color = income_grp)) +
  geom_point(size = 3) +
  scale_shape_manual(
    name = "Dochód",
    values = c("niski" = 7, "średni" = 8, "wysoki" = 9)
  ) +
  scale_color_brewer(
    name = "Dochód",
    palette = "Dark2"
  ) +
  labs(
    x = "PKB per capita",
    y = "Oczekiwana długość życia",
    title = "Zależność PKB od długości życia (2007)"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "bottom"
  )

Zwizualizować zależnośc między długością trwania życia a liczbą ludności w Azji w 1952 roku. Wykorzystaj zmienną gdpPercap do przypisania kolorów do poszczególnych punktów.

9 Tekst na wykresach

Przykłady dotyczące formatowania etykiet: https://ggplot2.tidyverse.org/reference/geom_text.html

Do formatowania etykiet wykorzystuje się geom_text() lub geom_label()

europa2007 = dane2007 |> filter(kontynent == "Europa")
  • Zastosowanie geom_text()
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text()

  • Zastosowanie geom_label()
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_label()

  • Formatowanie etykiet: angle służy do zmiany kąta wyświetlania etykiet
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(angle = 45)

  • Formatowanie etykiet: vjust oraz hjust służy do przesunięcia etykiet w pionie i poziomie
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(vjust = 1, hjust = -0.1)

  • Formatowanie etykiet: check_overlap = TRUE spowoduje, że zostaną wyświetlone tylko te etykiety, które na siebie nie nachodzą.
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(vjust = 1, hjust = -0.1, check_overlap = TRUE)

  • Formatowanie etykiet: size służy do zmiany wielkości czcionki
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(vjust = 1, hjust = -0.1, check_overlap = TRUE, size = 6)

  • Formatowanie etykiet: color służy do określenia koloru wyświetlania etykiet
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(color = "red")

  • aes(color = income_grp) wewnątrz geom_text() pozwala przypisanie koloru do etykiet na podstawie zmiennej
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(aes(color = income_grp), check_overlap = TRUE)

  • etykiety dla podzbioru danych: data=filter(europa2007, region == “Europa Wschodnia”) wewnątrz geom_text() służy do wybrania podzbioru danych, dla którego mają być wyświetlone etykiety.
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text(data=filter(europa2007, region == "Europa Wschodnia"), 
            vjust = 1, hjust = 1,
            size = 4, 
            color = "blue",
            check_overlap = TRUE)

9.1 Nakładanie się etykiet

Pakiet ggrepel udostępnia funkcje geom_text_repel i geom_label_repel, które maksymalnie “odpychają” etykiety od siebie.

max.overlaps = 5 - Jeśli etykieta nachodzi na 5 innych, zostanie pominięta.

library(ggrepel)
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text_repel(max.overlaps = 5)
Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider
increasing max.overlaps

  • box.padding = 0.5 Dodaje mały bufor (0,5 jednostki) wokół etykiet tekstowych podczas obliczania unikania nakładania się.
  • min.segment.length = 0 - dodaje linię łączącą punkt z etykietą.
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_text_repel(min.segment.length = 0, box.padding = 0.5)
Warning: ggrepel: 1 unlabeled data points (too many overlaps). Consider
increasing max.overlaps

  • Zastosowanie geom_label_repel
ggplot(europa2007, aes(x = pkb, y = le, label = kraj)) +
  geom_point() +
  geom_label_repel(min.segment.length = 0, box.padding = 0.5, fill = "lightblue")
Warning: ggrepel: 3 unlabeled data points (too many overlaps). Consider
increasing max.overlaps

10 Motywy

Motywy (ang. theme) pozwalają na modyfikację i dostosowanie komponentów wykresów, takich jak tytuł, etykiety, tło, wielkość czcionki, położenie legendy itd. Istnieją wbudowane rozwiązania, np. theme_bw(), theme_classic(), theme_light(), theme_minimal(). Można także użyć funkcji theme() i dowolnie zmodyfikować każdy element.

Więcej informacji: https://ggplot2-book.org/themes.html

  • Zastosowanie theme_bw()
ggplot(europa2007, aes(x = pkb, y = le, color = region)) +
  geom_point(size = 3) + 
  labs(x = "PKB na osobę w USD", y = "Oczekiwana długość trwania życia", 
       title = "Zależność między oczekiwaną długością trwania życia\na PKB na osobę w 2007 roku") + 
  theme_bw()

  • Zastosowanie theme() do formatowania wybranych elementów wykresu
ggplot(europa2007, aes(x = pkb, y = le, color = region)) +
  geom_point(size = 3) + 
  labs(x = "PKB na osobę w USD", y = "Oczekiwana długość trwania życia", labs = "Region", 
       title = "Zależność między oczekiwaną długością trwania życia\na PKB na osobę w 2007 roku") + 
  scale_color_brewer(name = "Region", palette = "Set1") + 
  theme(plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
        panel.background = element_rect(fill = "white"),
        panel.grid.major = element_line(color = "grey70"),
        axis.line = element_line(color = "black"),
        axis.title = element_text(size = 12),
        axis.text  = element_text(size = 14), 
        legend.title = element_text(size = 12, face = "bold"),
        legend.position = "bottom")

11 Zadanie

  1. Wybierz dane dla Afryki dla 1952 i 2007 roku.
  2. Wykonaj wykres pokazujący zależność między zmiennymi pkb, a le.
  3. Zróżnicuj wielkość symbolu na podstawie zmiennej pop_mln.
  4. Zróżnicuj kolor symbolu na podstawie zmiennej income_grp.
  5. Zróżnicuj kształt symbolu na podstawie zmiennej rok.
  6. Dodaj etykiety na podstawie zmiennej kraj.