Blog

Datenvisualisierung: R vs. Python

Ein entscheidender Schritt im Data Science-Prozess ist die Kommunikation von Ergebnissen. Häufig wird man als Data Scientist mit der Situation konfrontiert, Ergebnisse vor Personen zu präsentieren, die keinen oder nur wenig statistischen Hintergrund aufweisen. Es ist daher wichtig, Inhalte verständlich und übersichtlich darstellen zu können. Außerdem ist es zumeist nützlich, für die anfängliche Exploration der Daten – vor der eigentlichen Analyse – einfache Grafiken erstellen zu können. Tools zur Visualisierung in R und Python bieten dafür in unterschiedlicher Weise Unterstützung. Wenn Sie sich noch unschlüssig sind, welches die passende Sprache für Sie und Ihre Projekte ist, könnte dieser Artikel für Sie interessant sein. In diesem Artikel soll es spezifisch um Datenvisualisierung und den Vergleich von R und Python diesbezüglich gehen. Einen allgemeineren Überblick über Gemeinsamkeiten und Unterschiede von R und Python finden Sie auf unserem Blog im Artikel „Python für R-Programmierer“.

Visualisierung in R

Das graphics-Paket zur Datenexploration

R bietet einige Grundpakete, die standardmäßig bei der Installation von R mitinstalliert werden. Eines davon ist das graphics-Paket, welches etwa 100 Funktionen für traditionelle Grafikerstellung beinhaltet. Diese sehr einfachen generischen Funktionen ermöglichen eine schnelle Erstellung simpler Abbildungen wie zum Beispiel Scatterplots, Boxplots oder Histogramme. Insbesondere zur schnellen Exploration von Daten sind diese Funktionen nützlich.

Wenden wir beispielsweise die plot() Funktion auf den Iris-Datensatz an, erhalten wir eine Matrix von Scatterplots, die einer Korrelationsmatrix aller Spalten entspricht. Dies ist nützlich, um sehr einfach einen Überblick über die Beziehungen zwischen den Variablen zu bekommen.

plot(iris)
plot_iris

Wir können hier z.B. sehen, dass die Variablen Petal.Length und Petal.Width positiv miteinander korreliert sind.

Datenvisualisierung mit R-Paketen: ggplot2

R bietet neben den generischen Funktionen auch zahlreiche Bibliotheken wie z.B. ggplot2, lattice oder plotly, um verschiedene Arten von Grafiken zu erstellen und/oder diese optisch ansprechend (oder sogar interaktiv) zu gestalten.

Wenn man von Datenvisualisierung in Zusammenhang mit R spricht kommt man um das Paket ggplot2 nicht herum. Mit ggplot2 bietet R ein elegantes und vielseitiges System zur Erstellung von Grafiken. Das Paket verfolgt einen geschichteten Ansatz, der es ermöglicht, Abbildungen schrittweise zu erstellen: man nehme die Daten, füge Ästhetik (z.B. Achsen, Position von Datenpunkten innerhalb der Grafik) und anschließend jedes andere beliebige Stilelement wie z.B. Linien, Skalen oder Konfidenzintervalle hinzu. Diese sogenannte „Grammar of Graphics“-Philosophie, nach welcher Objekte den Abbildungen „in Schichten“ hinzugefügt werden, erlaubt eine relativ simple und intuitive Erstellung von Abbildungen.

Das Erstellen einer einfachen Grafik basierend auf dem Iris-Datensatz veranschaulicht diese Philosophie. Zunächst erstellen wir das Grundgerüst unserer Abbildung, welches die Daten und die Achsen enthält. Außerdem wird an dieser Stelle spezifiziert, dass die Daten nach Spezies gruppiert präsentiert werden. Im nächsten Schritt kommen die Datenpunkte dazu. Anschließend fügen wir einen Grafiktitel hinzu, verändern die Achsenbeschriftung und den Hintergrund der Grafik.

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, col = Species)) +
  geom_point() +
  labs(title = "A Nice Iris Dataset Graphic", x = "Sepal Length", y = "Sepal Width") +
  theme_minimal()
iris_ggplot

Selbstverständlich lassen sich mit R jedoch auch deutlich aufwendigere Abbildungen erstellen. Ein Beispiel zur Veranschaulichung zeigt die folgende Grafik. Im Blogartikel „Ein nicht ganz so einfaches Balkendiagramm mit ggplot2“ wird die Erstellung dieser Grafik näher erläutert. Um das folgende Beispiel auszuführen, muss der Pfad zu einem Logo und zum Datensatz ipsos.xlsx angepasst werden. Der Datensatz kann via http://extras.springer.com/Zip/2018/978-3-662-54819-6.zip heruntergeladen werden.

# devtools::install_github("INWTlab/ggCorpIdent")
library(ggCorpIdent)

ggCorpIdent(base_family = "Open Sans",
            textColor = "#000000",
            colors = c("#2B4894", "#cd5364", "#93BB51"),
            logo = "path/to/logo.png",
            logoSize = 0.1,
            logoTransparency = 0.8)

ipsos <- openxlsx::read.xlsx("path/to/ipsos.xlsx")
ipsos <- ipsos[order(ipsos$Wert),]
ipsos$Land <- ordered(ipsos$Land, ipsos$Land)
ipsos$textFamily <- ifelse(ipsos$Land %in% c("Deutschland","Brasilien"),
                           "bold", "plain")
ipsos$labels <- paste0(ipsos$Land, ifelse(ipsos$Wert < 10, "     ", "  "),
                       ipsos$Wert)
rect <- data.frame(
  ymin = seq(0, 80, 20),
  ymax = seq(20, 100, 20),
  xmin = 0.5, xmax = 16.5,
  colour = rep(c(grDevices::rgb(241, 243, 244,30,maxColorValue=255),
                 grDevices::rgb(241, 243, 244,0,maxColorValue=255)),
               length.out = 5))


ggBar <- ggplot(ipsos) +
  geom_bar(aes(x = Land, y = Wert), stat = "identity", width=.75) +
  geom_bar(aes(x = Land, y = ifelse(Land %in% c("Brasilien", "Deutschland"), Wert, NA)),
           stat = "identity", fill = "#93BB51", color = "#93BB51", width=.75) +
  geom_rect(data = rect,
            mapping = aes(ymin = ymin, ymax = ymax,
                          xmin = xmin, xmax = xmax),
            fill = rect$colour,
            color = grDevices::rgb(241, 243, 244,0,maxColorValue=255)) +
  geom_hline(aes(yintercept = 45), colour =  "#cd5364", size = 1) +
  scale_y_continuous(breaks = seq(0, 100, 20), limits = c(0, 100), expand = c(0, 0)) +
  scale_x_discrete(labels = ipsos$labels) +  
  coord_flip() +
  labs(y = NULL,
       x = NULL,
       title = NULL) +
  theme(panel.grid.minor = element_blank(),
        panel.grid.major = element_blank(),
        axis.text.y = element_text(
          face = ipsos$textFamily, hjust=0.99,vjust=0.5)) 

ggBar

library("grid")

vp_make <- function(x, y, w, h) 
  viewport(x = x, y = y, width = w, height = h, just = c("left", "bottom"))

main <- vp_make(0.05, 0.05, 0.9, 0.8)
title <- vp_make(0, 0.9, 0.6, 0.1)
subtitle <- vp_make(0, 0.85, 0.4, 0.05)
footnote <- vp_make(0.55, 0, 0.4, 0.05)
annotation1 <- vp_make(0.7, 0.85, 0.225, 0.05)
annotation2 <- vp_make(0.4, 0.85, 0.13, 0.05)

grid.newpage()
print(ggBar, vp = main)

grid.text("'Ich glaube fest an Gott oder ein höheres Wesen'",
          gp = gpar(fontfamily = "Lato Black", fontsize = 14),
          just = "left", x = 0.05, vp = title)

grid.text("...sagten 2010 in:",
          gp = gpar(fontfamily = "Lato Light", fontsize = 12),
          just = "left",
          x = 0.05, vp = subtitle)

grid.text("Quelle: www.ipsos-na.com, Design: Stefan Fichtel, ixtract",
          gp = gpar(fontfamily = "Lato Light", fontsize = 9),
          just = "right",
          x = 0.95, vp = footnote)

grid.text("Alle Angaben in Prozent",
          gp = gpar(fontfamily = "Lato Light", fontsize = 9),
          just = "right",
          x = 1, y = 0.55, vp = annotation1)

grid.text("Durchschnitt: 45",
          gp = gpar(fontfamily = "Lato Light", fontsize = 9),
          just = "right",
          x = 0.95, y = 0.55, vp = annotation2)
ggplot_barplot

Visualisierung in Python

Im Gegensatz zu R werden bei der Installation von Python als „General purpose“-Programmiersprache standardmäßig keine Pakete zur Datenvisualisierung mitgeliefert. In Python steht hierfür jedoch ebenfalls eine Vielzahl an Bibliotheken zur Verfügung. Die bekanntesten Bibliotheken stellen dabei Matplotlib und Seaborn dar.

Neben weiteren zahlreichen Paketen bietet Python mittlerweile z.B. mit plotnine und ggpy auch Äquivalente zu ggplot2 in R an. Mit Hilfe dieser Bibliotheken können Abbildungen in Python nach demselben „Grammar of Graphics“-Prinzip wie in R erstellt werden.

Visualisierung in Python: Matplotlib

Die wohl am häufigsten verwendete Bibliothek für die Visualisierung von Daten in Python ist Matplotlib. Matplotlib basiert auf NumPy-Arrays und wurde ursprünglich als Python-Alternative zu Matlab konzipiert, was sich in einem Großteil der Syntax wiederspiegelt.

Ein Scatterplot mit Grafiktitel und Achsenbeschriftung – ähnlich wie das aus dem R-Beispiel – lässt sich beispielhaft mit Matplotlib mit Hilfe der scatter() Funktion erstellen.

import pandas as pd
import matplotlib.pyplot as plt

iris = pd.read_csv('iris.csv')
plt.scatter(x = 'SepalLengthCm', y = 'SepalWidthCm', data = iris)
plt.title('A Nice Iris Dataset Graphic')
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')
matplotlib_scatter

Visualisierung in Python: Seaborn

Wir können jedoch sehen, dass hier nicht zwischen den verschiedenen Spezies unterschieden wird. Diese Differenzierung in der Abbildung und das Hinzufügen einer Legende ist in Matplotlib mit etwas Aufwand verbunden. Eine neben Matplotlib häufig genutzte Bibliothek in Python ist Seaborn (als Erweiterung zu Matplotlib), die ein vergleichsweise einfacheres Erstellen von Abbildungen ermöglichen soll. Für das Hinzufügen einer Legende und die Differenzierung zwischen Species bietet Seaborn beispielsweise folgende einfachere Lösung:

import seaborn as sns

sns.scatterplot(x = 'SepalLengthCm', y = 'SepalWidthCm', hue = 'Species', data = iris)
seaborn_scatter

Auch um im Rahmen der Datenexploration einen ersten Überblick über die Daten zu erhalten, eignet sich Seaborn. Wir können z.B. die pairplot() Funktion verwenden.

sns.pairplot(iris)
seaborn_pairplot

Wir erhalten eine ähnliche Abbildung wie im R-Beispiel zur Datenexploration, mit deren Hilfe wir einen ersten Eindruck über die Beziehungen der Variablen zueinander erhalten können.

Auch in Python haben wir zur Veranschaulichung eine etwas aufwendigere Grafik erstellt. Um einen direkten Vergleich zu ermöglichen, haben wir uns für die gleiche Grafik wie im R-Beispiel entschieden. Anzumerken ist hierbei der deutlich geringere Umfang des Codes im Vergleich zur Erstellung der Abbildung mit ggplot2.

import pandas as pd
import seaborn as sns
import matplotlib.patches as patches
import matplotlib.pyplot as plt

df = pd.read_excel(r'Downloads/ipsos.xlsx')
df['Land_Wert'] = df['Land'] + ['   ' if len(str(x)) < 2 else ' ' for x in df.Wert ] + df['Wert'].map(str)

sns.set_style("white", {"axes.facecolor": "#E0E4E6",
                       "axes.edgecolor": "1",
                       "patch.force_edgecolor": False,
                       "font.family": "Open Sans"})

barcolor = ["#93bb51" if (x == "Brasilien" or x == "Deutschland") else "#2B4894" for x in df.Land]
plt.figure(figsize=(10,7))
fig, p = plt.subplots(figsize=(10, 7))
p = sns.barplot(x = df.Wert, y = df.Land_Wert, palette = barcolor)
p.set_ylabel('')
p.set_xlabel('')
p.axvline(45, color = "#bc423a")
p.add_patch(patches.Rectangle((20, -1), 20, 20, color = "#f1f3f4", alpha = .25))
p.add_patch(patches.Rectangle((60, -1), 20, 20, color = "#f1f3f4", alpha = .25))
p.text(-20, -2, "'Ich glaube fest an Gott oder ein höheres Wesen'", 
       horizontalalignment='left', size='large', color='black', weight='bold')
p.text(-20, -1, "...sagten 2010 in:")
p.text(33, -1, "Durchschnitt: 45", size = "small")
p.text(80, -1, "Alle Angaben in Prozent", size = "small")
p.text(58, 17, "Quelle: www.ipsos-na.com, Design: Stefan Fichtel, ixtract", size = "small")
p.get_yticklabels()[2].set_fontweight("bold")
p.get_yticklabels()[11].set_fontweight("bold")
im = plt.imread('path/to/logo.png')
newax = fig.add_axes([.7, 0.125, 0.2, 0.2], anchor='SE', zorder = 1)
newax.imshow(im)
newax.axis('off')
seaborn_barplot

Zusammenfassung

Insgesamt sind sowohl R als auch Python hinsichtlich der Datenvisualisierung gut ausgestattet. R ist eine Sprache primär zur Datenanalyse, was sich unter anderem darin manifestiert, dass es eine Vielzahl an Paketen bereitstellt, die auf wissenschaftliche Visualisierung ausgerichtet sind. Python ist dagegen eine „General purpose“-Programmiersprache, die auch zur Datenanalyse genutzt werden kann und die sehr gute Default-Lösungen zur Datenvisualisierung bietet.

Im Vergleich zu Matplotlib ist die Anpassung von Grafiken entsprechend der eigenen Vorstellungen in R mit Hilfe von ggplot2 einfacher und intuitiver umzusetzen. Hierfür bietet es sich an, in Python auf die Bibliothek Seaborn zurückzugreifen, die nebenbei auch gute Standard-Lösungen bietet, die mit relativ wenig Syntax auskommen. In unserem Beispiel zeigt sich deutlich, dass der Umfang des Codes bei der Verwendung von Seaborn im Vergleich zu ggplot2 deutlich geringer ausfällt.

Es herrscht jedoch insgesamt Uneinigkeit darüber, mit welcher Programmiersprache die Erstellung von Abbildungen sparsamer, übersichtlicher und intuitiver gelingt. Auch wir konnten uns hierbei nicht eindeutig festlegen. Grundlegend sollte die Entscheidung zwischen R und Python insbesondere die Vorlieben und die Erfahrungen des Anwenders oder der Anwenderin berücksichtigen. In jedem Fall bieten beide Sprachen die Möglichkeit, Daten ansprechend und übersichtlich zu visualisieren.

Vielleicht kennen Sie ja spezifische Anwendungsfälle, in denen eine der Programmiersprachen Ihrer Meinung nach besser geeignet ist. Oder gibt es aus Ihrer Sicht nennenswerte Vor- oder Nachteile einer der beiden Sprachen in Bezug auf Datenvisualisierung? Lassen Sie es uns wissen!