10.2. Daten visualisieren#
In diesem Abschnitt betrachten wir, wie die Daten in einem Pandas Dataframe visualisiert werden können. Dazu lesen wir zunächst den Dataframe comments_df
aus dem vorhergehenden Abschnitt ein. Den Dataframe hatten wir im Pickleformat zur Weiterverarbeitung in Python gespeichert.
import pandas as pd
comments_df = pd.read_pickle("comments_df.pkl")
Wie genau die extrahierten Daten visualisiert und analysiert werden sollen, hängt natürlich vor allem von der Forschungsfrage und der Art der Daten ab. Im Folgenden betrachten wir deswegen nur ganz allgemein zwei Beispiele, wie unsere Kommentardaten visualisiert werden könnten, um einen ersten Überblick über die Zusammensetzung der Daten zu gewinnen. Hierfür verwenden wir beispielhaft die beiden Bibliotheken Matplotlib und Seaborn. Beide werden zunächst installiert:
# import sys
# !conda install --yes --prefix {sys.prefix} matplotlib
# !conda install --yes --prefix {sys.prefix} seaborn
Zuerst visualisieren wir mit Matplotlib die Anzahl der Kommentare je Pin. Dazu muss zuerst eine neue Spalte erstellt werden, welche die Anzahl der Kommentare je Pin enthält.
# Anzahl Kommentare je Pin
comments_per_pin = comments_df.groupby(by="link")["comment"].nunique()
type(comments_per_pin)
comments_per_pin
Durch diese Operation hat sich aber die Struktur des Dataframes verändert. Bevor die Visualisierung erstellt werden kann, muss erst die Struktur des Dataframes angepasst werden:
pin_comments_df = comments_per_pin.to_frame(name="comments_no") # Spaltenname setzen
pin_comments_df
pin_comments_df.columns
pin_comments_df = pin_comments_df.reset_index()
pin_comments_df
max(pin_comments_df["comments_no"])
min(pin_comments_df["comments_no"])
Jetzt kann die Visualisierung erzeugt werden. Mit der Pandas-Methode .plot() können verschiedene einfache Visualisierungen der Daten in einem Pandas Dataframe oder Series-Objekt erstellt werden, hier ein Säulendiagramm:
# Gesamter Link wird auf der x-Achse angezeigt
pin_comments_df.plot(kind="bar", x="link", y="comments_no", legend=False)
Diese Visualisierung ist jedoch nicht besonders gut lesbar, da die Links auf der X-Achse sehr lang sind. Außerdem fehlen Titel für die x- und y-Achse und ein Diagrammtitel. Um die Links auf der x-Achse zu verkürzen, erstellen wir eine neue Spalte pin_id, welche nur die ID des jeweiligen Pins enthält, und erstellen die Visualisierung dann erneut:
# Neue Spalte pin_id erstellen, damit nur Pin-Nummer auf der x-Achse angezeigt werden kann
pin_comments_df["pin_id"] = pin_comments_df['link'].str.extract('(\d+)')
pin_comments_df
# Pin-ID auf der x-Achse anzeigen
pin_comments_df.plot(kind="bar", x="pin_id", y="comments_no", legend=False)
Dieses Diagramm sieht schon besser aus, aber es fehlen immer noch die Titel. Um dem Diagramm Titel hinzuzufügen, kann auf Matplotlib zurückgegriffen werden. Laut der Dokumentationsseite zur Methode .plot() greift Pandas unter der Motorhaube auf das Paket Matplotlib zurück, um die Diagramme zu erzeugen. Der Rückgabewert der .plot()-Methode ist dementsprechend ein spezielles Matplotlib-Objekt, und zwar ein Matplotlib Axes-Objekt.
type(pin_comments_df.plot(kind="bar", x="pin_id", y="comments_no", legend=False))
Das Axes-Objekt wird im Hintergrund aufgerufen und kann dann mithilfe von Matplotlib-Methoden angepasst werden. Ein ähnliches Prinzip kennt ihr bereits von Selenium, wo wir ebenfalls Objekte nicht explizit an Funktionen übergeben mussten, da implizit die Referenz zu dem jeweiligen Objekt gespeichert wurde. Der folgende Code fügt dem mithilfe der Pandas .plot()-Methode erzeugten Matplotlib-Objekt die Titel hinzu:
import matplotlib.pyplot as plt
pin_comments_df.plot(kind="bar", x="pin_id", y="comments_no", legend=False)
plt.xlabel("Pin ID")
plt.ylabel("Anzahl Kommentare")
plt.title("Kommentare je Pin")
plt.show()
Die Methoden plt.xlabel(), plt.ylabel() usw. beziehen sich hier aber immer nur auf das zuletzt erzeugte Objekt. Wenn viele Diagramme erstellt werden sollen oder zu einem späteren Zeitpunkt ein Diagramm angepasst werden soll, muss die Referenz zu dem Axes-Objekt explizit übergeben werden. Die Pandas-Dokumentationsseiten empfehlen in diesem Fall das folgende Vorgehen:
fig, axs = plt.subplots() # Leere Matplotlib Figure und Axes-Objekte erstellen
pin_comments_df.plot(ax=axs, kind="bar", x="pin_id", y="comments_no", legend=False) # Das Pandas-Plot-Objekt auf das Axes-Objekt legen
axs.set_xlabel("Pin ID") # Titel hinzufügen
axs.set_ylabel("Anzahl Kommentare")
axs.set_title("Kommentare je Pin")
Während zum Anpassen des Diagramms das Axes-Objekt verwendet wird, wird das Figure-Objekt zum Speichern des Diagramm verwendet:
fig.savefig("comments_df.png")
Als nächstes interessiert uns, wie lang die Kommentare unter den beiden Pins sind. Um die Länge der Kommentare für die beiden Pins zu vergleichen, wollen wir einen Boxplot erstellen. Bevor die Visualisierung erstellt werden kann, muss jedoch erst wieder eine neue Spalte mit der Länge der Kommentare hinzugefügt werden:
# Länge der Kommentare bestimmen und neue Spalte comment_length erstellen
length_per_comment = comments_df.groupby(by="commentator_id")["comment"]
length_per_comment
# Länge der Kommentare bestimmen und neue Spalte comment_length erstellen
comments_df["comment_length"] = comments_df["comment"].apply(len)
# Fehlermeldung: hier wäre es doch besser, wir hätten die leeren Zeichenketten anstelle der NA-Werte gelassen
Beim Versuch die Funktion len() auf die Einträge in der Spalte comment anzuwenden, bekommen wir eine Fehlermeldung, da wir zuvor leere Strings durch NA-Werte ausgetauscht haben. Das stellt sich also jetzt als voreilig heraus, und wir machen die Operation zunächst rückgängig:
# NA Werte durch leere Zeichenkette ersetzen
comments_df.replace(pd.NA, "", inplace=True)
# Länge der Kommentare bestimmen und neue Spalte comment_length erstellen
comments_df["comment_length"] = comments_df["comment"].apply(len)
comments_df
Jetzt können wir den Boxplot erstellen. Das geht wieder mit der Methode .plot() und dem Argument kind="box"
. Wir verwenden aber stattdessen diesmal die Bibliothek Seaborn, da diese die Erstellung von komplexeren Diagrammen erleichtert und der Code zum Erzeugen der Diagramme etwas kompakter ist:
import seaborn as sns
# Dokumentation zur Funktion catplot(): https://seaborn.pydata.org/generated/seaborn.catplot.html#seaborn.catplot
sns.catplot(data=comments_df, x="link", y="comment_length", kind="box")
Wir haben hier dasselbe Problem, auf das wir auch beim Erzeugen des Säulendiagramms mit der Pandas plot()-Methode gestoßen sind: die langen URLs eignen sich nicht gut zur Beschriftung der x-Achse. Wir erstellen deswegen wieder eine neue Spalte, die nur die Pin-IDs enthält und erstellen dann die Grafik erneut:
# Neue Spalte pin_id erstellen, damit nur Pin-Nummer auf der x-Achse angezeigt werden kann
comments_df["pin_id"] = comments_df['link'].str.extract('(\d+)')
comments_df
sns.catplot(data=comments_df, x="pin_id", y="comment_length", kind="box")
Wenn auf der x-Achse mehrere längere Wörter stehen müssen, kann die Beschriftung der x-Achse zum Beispiel um 90 Grad rotiert werden:
sns.catplot(data=comments_df, x="pin_id", y="comment_length", kind="box").set_xticklabels(rotation=90)
Für mehr Beispiele zur Erstellung von Diagrammen in Pandas/Matplotlib empfehle ich den Pandas Userguide. Für Beispiele zur Erstellung von Seaborn-Diagrammen lohnt sich ein Blick in die Seaborn-Dokumentationsseiten.
10.2.1. Quellen#
Damien Dotta. Matplotlib 3.8 Documentation: Interactive Figures. 2023. URL: https://matplotlib.org/stable/users/explain/figure/interactive.html#interactive-figures.
Damien Dotta. Matplotlib 3.8 Documentation: Matplotlib Application Inferfaces (APIs). 2023. URL: https://matplotlib.org/stable/users/explain/figure/api_interfaces.html#api-interfaces.
Damien Dotta. Matplotlib 3.8 Documentation: Quick Start. The Explicit and Implicit Interfaces. 2023. URL: https://matplotlib.org/stable/users/explain/quick_start.html#the-explicit-and-the-implicit-interfaces.
Matplotlib. Matplotlib 3.8 Documentation: matplotlib.pyplot.yticks. 2023. URL: https://pandas.pydata.org/docs/reference/series.html.
Wes McKinney. Pandas 2.2 Documentation: Chart Visualization. 2024. URL: https://pandas.pydata.org/docs/user_guide/visualization.html.
Wes McKinney. Pandas 2.2 Documentation: How Do I Create Plots in Pandas? 2024. URL: https://pandas.pydata.org/docs/getting_started/intro_tutorials/04_plotting.html.