Anordnung und Layout von Abbildungen mit mehreren Panels

Im Kapitel Facets (Teilgrafiken) wurde gezeigt, wie sich mit einer kategorialen Variable mehrere Teilgrafiken (Facets) erstellen lassen, die Untergruppen der Daten darstellen. Dies geschieht mit Funktionen aus ggplot2 (facet_wrap() und facet_grid()). Mit diesen Funktionen lassen sich jedoch keine separaten Grafiken nebeneinander platzieren. Dafür werden Zusatzpackages zu ggplot2 benötigt. Die beiden beliebtesten Packages sind gridExtra und cowplot. Hier wird nur cowplot vorgestellt, da es alle benötigten Funktionen bietet, auch für sehr fortgeschrittene Anwender. Cowplot hat eine intuitive Syntax und erzeugt einheitliche, übersichtliche Layouts mit sehr hoher Flexibilität.

Installieren und laden Sie zunächst cowplot. Laden Sie außerdem tidyverse, das unter anderem ggplot2 enthält, sowie gapminder, das die Übungsdaten enthält.

install.packages("cowplot")

library(cowplot)
library(tidyverse)
library(gapminder)

## Die ersten 5 Zeilen von gapminder ansehen
head(gapminder)
country<fctr> continent<fctr> year<int> lifeExp<dbl> pop<int> gdpPercap<dbl>
Afghanistan Asia 1952 28.801 8425333 779.4453
Afghanistan Asia 1957 30.332 9240934 820.8530
Afghanistan Asia 1962 31.997 10267083 853.1007
Afghanistan Asia 1967 34.020 11537966 836.1971
Afghanistan Asia 1972 36.088 13079460 739.9811
Afghanistan Asia 1977 38.438 14880372 786.1134

Die ersten 5 Zeilen von gapminder.

Um mehrere Grafiken in einem Layout anzuordnen, muss jede Grafik als Objekt gespeichert werden. Die Objekte in diesem Kapitel heißen plot_1, plot_2, plot_3 und plot_4. Die Unterschiede zwischen diesen Grafiken sind gering, für die Demonstration der Anordnung von Grafiken spielt das jedoch keine Rolle.

Wir erstellen zunächst plot_1, plot_2, plot_3 und plot_4 mit Daten aus gapminder. Die folgenden Grafiken unterscheiden sich nur darin, was auf der x-Achse und der y-Achse dargestellt wird, sowie im Farbschema.

## Erste Grafik
plot_1 <- ggplot(gapminder, aes(x=log(pop),
                                y=log(lifeExp),
                                color=year)) +
  geom_point() +
  scale_color_viridis_c(option = "plasma") +
  theme(legend.position = "none")

## Zweite Grafik
plot_2 <- ggplot(gapminder, aes(x=log(pop),
                                y=continent,
                                color=year)) +
  geom_point(size=3, alpha=.5) +
  scale_color_viridis_c(option = "magma") +
  theme(legend.position = "none")

## Dritte Grafik
plot_3 <- ggplot(gapminder, aes(x=log(gdpPercap),
                                y=continent,
                                color=year)) +
  geom_point(size=3, alpha=.5) +
  scale_color_viridis_c(option = "plasma") +
  theme(legend.position = "none")

## Vierte Grafik
plot_4 <- ggplot(gapminder, aes(x=gdpPercap,
                                y=continent,
                                color=year)) +
  geom_point(size=3, alpha=.5) +
  scale_color_viridis_c(option = "magma") +
  theme(legend.position = "none")

Nun verwenden wir plot_grid() aus cowplot, um plot_1 und plot_2 zu einer Abbildung mit 2 Spalten (ncol) zusammenzufügen. Außerdem erstellen wir labels, wie unten zu sehen.

plot_grid(plot_1, plot_2, ncol = 2, labels = c('A', 'B'))
Zwei Streudiagramme nebeneinander, A: log(lifeExp) gegen log(pop) und B: Kontinent gegen log(pop), eingefärbt nach Jahr

Die Abbildungen lassen sich stattdessen auch vertikal anordnen, indem man ncol auf ncol=1 ändert. Unten verwenden wir stattdessen labels="AUTO", um die Beschriftungen automatisch zu erzeugen.

plot_grid(plot_1, plot_2, ncol = 1, labels = "AUTO")
Dieselben zwei Streudiagramme untereinander mit den Beschriftungen A und B, log(lifeExp) bzw. Kontinent gegen log(pop)

Wir können außerdem align="h" für die horizontale Ausrichtung der Abbildungen bzw. align="v" für die vertikale Ausrichtung verwenden.

plot_grid(plot_1, plot_2, aligh = "h")
Zwei Streudiagramme nebeneinander, A: log(lifeExp) gegen log(pop) und B: Kontinent gegen log(pop), eingefärbt nach Jahr

Mit dem Argument rel_widths() lässt sich festlegen, welchen Anteil des Platzes jede Grafik einnehmen soll. Unten erhält die erste Grafik halb so viel Platz (1) wie die zweite Grafik (2).

plot_grid(plot_1, plot_2, ncol=2, rel_widths = c(1, 2))
Zwei Streudiagramme nebeneinander, wobei das rechte Panel, Kontinent gegen log(pop), doppelt so breit ist wie das linke

Beachten Sie in der folgenden Grafik, dass der Titel der y-Achse in der oberen Abbildung weiter von den Zahlen der y-Achse entfernt ist.

plot_grid(plot_1, plot_2, ncol = 1, align = 'v')
Zwei untereinander angeordnete Streudiagramme, bei denen der Titel log(lifeExp) der oberen y-Achse weiter von der Achse entfernt steht als beim unteren

Wenn die Abbildungen in einem plot_grid() hinsichtlich Titeln und Achsen nicht bündig ausgerichtet sind, wird dies mit dem Argument axis korrigiert. Axis nimmt die Werte none, l (left), r (right), b (bottom) und t (top) an. Sie können einen oder mehrere dieser Werte verwenden, um die jeweilige Seite auszurichten. Unten richten wir die Grafiken mit axis="l" nach links aus.

plot_grid(plot_1, plot_2, ncol = 1, align = 'v', axis = 'l')
Zwei untereinander angeordnete Streudiagramme, linksbündig ausgerichtet, sodass die y-Achsen für log(lifeExp) und Kontinent auf einer Linie liegen

Mit dem Argument NULL in plot_grid() können Sie leere Abbildungsflächen erzeugen. Unten erstellen wir eine Matrix mit vier Abbildungen, von denen zwei NULL sind, und fügen die Beschriftungen automatisch hinzu.

plot_grid(
  plot_1, NULL, NULL, plot_2,
  labels = "AUTO",
  ncol = 2
)
Raster aus zwei mal zwei Feldern mit Streudiagrammen in den Feldern A und D sowie leeren Feldern B und C

Sie können Matrizen mit Abbildungen über mehrere Zeilen und mit unterschiedlich großen Zeilen erstellen. Dazu erzeugt man mehrere plot_grid(), die anschließend als Objekte in einem abschließenden plot_grid() verwendet werden.

## Erste Zeile mit plot_grid()
upper_row <- plot_grid(plot_1, plot_2, ncol = 2, labels=c("A", "B"))

## Zweite Zeile mit plot_grid()
middle_row <- plot_grid(plot_3, labels=c("C"))

## Dritte Zeile mit plot_grid()
bottom_row <- plot_grid(plot_4, plot_1, ncol = 2, labels=c("D", "E"))

## Abschließendes plot_grid()
plot_grid(upper_row, middle_row, bottom_row, ncol=1)
Layout in drei Zeilen mit fünf Panels A bis E: zwei Diagramme oben, ein breites in der Mitte und zwei unten, Daten aus gapminder

Gemeinsamer Titel für viele Panels

Mit plot_grid() kann man jedem Panel ein Label geben, und das Panel selbst kann einen mit ggplot() erstellten Titel haben. Oft ist jedoch ein Titel erwünscht, der sich über mehrere Panels erstreckt. Dies erreicht man mit ggdraw() wie folgt:

plot_title <- ggdraw() +
  draw_label(
    "Här skriver vi en titel för samtliga paneler på en gång",
    fontface = 'bold',
    x = 0,
    hjust = 0) +
  # Fügt links einen Rand von 7 Pixeln hinzu, damit der Titel bündig mit dem ersten Panel ist
  theme(plot.margin = margin(0, 0, 0, 7))

plot_row <- plot_grid(plot_1, plot_2, labels="AUTO")

plot_grid(
  plot_title,
  plot_row,
  ncol = 1,
  rel_heights = c(0.1, 1) # der Titel erhält einen kleinen Anteil der Höhe
)
Zwei Streudiagramme A und B unter einem gemeinsamen fett gedruckten Titel, der sich über beide Panels erstreckt

Abbildungen überlagern

Es kann nützlich sein, Abbildungen zu überlagern, um Zusammenhänge deutlicher zu veranschaulichen. Dies bietet sich an, wenn die Abbildungen eine Achse gemeinsam haben (meist die x-Achse). Haben zwei Abbildungen dieselbe x-Achse, aber unterschiedliche y-Achsen, können sie überlagert werden, sodass der Zusammenhang zwischen der x-Achse und beiden y-Achsen durch die Überlagerung sichtbar wird. Dies kann mitunter zu klareren Darstellungen führen, auch wenn der Gewinn (im Vergleich zu zwei separaten, nebeneinander platzierten Abbildungen) eigentlich recht gering ist.

Für diese Übung verwenden wir die Daten mpg (miles per gallon), die Angaben zum Kraftstoffverbrauch (die Variablen cty und hwy) verschiedener Autos enthalten. Diese Daten sind in tidyverse enthalten und sollten daher bereits verfügbar sein (andernfalls muss tidyverse mit dem Befehl library(tidyverse) geladen werden). Sehen Sie sich zunächst die Daten an:

head(mpg)
manufacturer <chr> model <chr> displ <dbl> year <int> cyl <int> trans <chr> drv <chr> cty <int> hwy <int> fl <chr>
audi a4 1.8 1999 4 auto(l5) f 18 29 p
audi a4 1.8 1999 4 manual(m5) f 21 29 p
audi a4 2.0 2008 4 manual(m6) f 20 31 p
audi a4 2.0 2008 4 auto(av) f 21 30 p
audi a4 2.8 1999 6 auto(l5) f 16 26 p
audi a4 2.8 1999 6 manual(m5) f 18 26 p

Wir erstellen die erste Abbildung (Erläuterungen siehe Kommentare) wie folgt:

plot_1 <- ggplot(mpg, aes(x=manufacturer,
                          y=hwy)) +
  geom_boxplot() +
  # Das Theme "half open" hat kein Gitternetz und nur zwei Linien (x-Achse und y-Achse)
  theme_half_open() +
  theme(
    # Dreht die Labels auf der x-Achse um 45°
    axis.text.x = element_text(angle = 45, hjust = 1, vjust= 1),
    # Entfernt den Titel der x-Achse
    axis.title.x = element_blank())

plot_1
Boxplot von hwy nach Autohersteller mit gedrehten Herstellernamen auf der x-Achse, ohne Gitternetz

Beachten Sie, dass die Abbildung rechts und oben keine Linien hat. Wir fahren mit der zweiten Abbildung fort:

plot_2 <- ggplot(mpg, aes(x=manufacturer,
                          y=cty,
                          color=drv)) +
  geom_point(size=3) +
  # Verschiebt die y-Achse auf die rechte Seite
  scale_y_continuous(position = "right") +
  # Dasselbe Theme wie oben
  theme_half_open() +
  # Entfernt Titel und Labels auf der x-Achse
  theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()) +
  # Verwendet ein schönes Farbschema für color=drv
  scale_color_viridis_d()

plot_2
Punktdiagramm von cty nach Hersteller, eingefärbt nach drv, mit der y-Achse rechts und ohne Text auf der x-Achse

Abschließend werden diese beiden Grafiken überlagert. Dies geschieht mit align_plots() und ggdraw() wie folgt:

## Die Grafiken übereinanderlegen
aligned_plots <- align_plots(plot_1, plot_2, align="hv", axis="tblr")

## Die fertige Grafik anzeigen
ggdraw(aligned_plots[[1]]) + draw_plot(aligned_plots[[2]])
Boxplot von hwy und Punktdiagramm von cty nach Autohersteller überlagert, mit hwy-Achse links und cty-Achse rechts