Umfrageergebnisse zur Sonntagswahl als Balkendiagramm darstellen

Seit einiger Zeit habe ich in diesem Blog kein Matplotlib/Pandas-Beispiel mehr veröffentlicht. Zeit, dies nun nachzuholen. In diesem Beispiel geht es darum, mit Pandas folgende JSON-Datei zu lesen:

{
    "Partei": {
        "0": "SPD",
        "1": "CDU",
        "2": "Grüne",
        "3": "FDP",
        "4": "AfD",
        "5": "Linke",
        "6": "Freie Wähler",
        "7": "BSW",
        "8": "Sonstige"
    },
    "Prozent": {
        "0": 13,
        "1": 31,
        "2": 14,
        "3": 4,
        "4": 22,
        "5": 4,
        "6": 4,
        "7": 4,
        "8": 4
    }
}

Diese Daten sollen anschließend als Balkendiagramm visualisiert werden. Bei diesem Datensatz handelt es sich übrigens um die Umfrageergebnisse zur sogenannten Sonntagswahl (14. Januar 2024), veröffentlicht vom ZDF-Politbarometer.

Beginnen wir damit die erforderlichen Module zu importieren und die Daten zu lesen bzw. daraus ein Pandas-Dataframe zu erstellen:

#!/usr/bin/env python3

import matplotlib.pyplot as plt
import pandas as pd

# JSON-Datei lesen und Dataframe (df) erzeugen
df = pd.read_json("Umfrage.json")

Mit df(info) könnte ich mir nun Infos zum Datensatz anzeigen lassen:

<class 'pandas.core.frame.DataFrame'>
Index: 9 entries, 0 to 8
Data columns (total 2 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   Partei   9 non-null      object
 1   Prozent  9 non-null      int64 
dtypes: int64(1), object(1)

Und mit print(df.to_string()) lassen sich die Daten anzeigen:

        Partei  Prozent
0          SPD       13
1          CDU       31
2        Grüne       14
3          FDP        4
4          AfD       22
5        Linke        4
6  Freie Wähle        4
7          BSW        4
8     Sonstige        4

Hinsichtlich des übrigen Codes möchte ich auf meine bisher veröffentlichten Beispiele hinweisen (insbesondere auf das Balkendiagramm zur Bundestagswahl. Daher werde ich mich kurz fassen.

Zunächst werden die Werte der Spalten „Partei“ und „Prozent“ in Arrays überführt:

parteien = df["Partei"].values
prozent = df["Prozent"].values

Wir benötigen auch noch die Farbwerte für die Balken:

color = [
    "#b72d13",
    "#000000",
    "#52cf06",
    "#f9d91a",
    "#4ac5fb",
    "#a02d5f",
    "#f18019",
    "#54125a",
    "#6e6f0f",
]

Dann kann das Balkendiagramm erzeugt werden:

fig, ax = plt.subplots()

plt.title("Sonntagsumfrage - 14.01.2024")
plt.ylabel("Stimmen in %")
plt.xlabel("Parteien")
plt.ylim(0, 40)

c_rects = plt.bar(parteien, prozent, align="center", alpha=0.6, color=color)

ax.set_xticks(range(len(parteien)))
ax.set_xticklabels(parteien, rotation="vertical")

Mit plt.show() würde jetzt das Balkendiagramm angezeigt werden. Allerdings möchte ich oberhalb eines jeden Balkens die dazugehörigen Prozente anzeigen lassen. Dies erledigen folgende Codezeilen:

def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        ax.text(
            rect.get_x() + rect.get_width() / 2.0,
            height + 1.5,
            int(height),
            ha="center",
            va="bottom",
        )

autolabel(c_rects)

Zum Abschluss nochmal der vollständige Code:

#!/usr/bin/env python3

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# JSON-Datei lesen und Dataframe (df) erzeugen
df = pd.read_json("Umfrage.json")

# Arrays erstellen
parteien = df["Partei"].values
prozent = df["Prozent"].values

# Farben für die Balken
color = [
    "#b72d13",
    "#000000",
    "#52cf06",
    "#f9d91a",
    "#4ac5fb",
    "#a02d5f",
    "#f18019",
    "#54125a",
    "#6e6f0f",
]

# Balkendiagramm mit Beschriftung erzeugen
fig, ax = plt.subplots()

plt.title("Sonntagsumfrage - 14.01.2024")
plt.ylabel("Stimmen in %")
plt.xlabel("Parteien")
plt.ylim(0, 40)

c_rects = plt.bar(parteien, prozent, align="center", alpha=0.6, color=color)

ax.set_xticks(range(len(parteien)))
ax.set_xticklabels(parteien, rotation="vertical")

# Prozentzahlen oberhalb der Balken hinzufügen
def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        ax.text(
            rect.get_x() + rect.get_width() / 2.0,
            height + 1.5,
            int(height),
            ha="center",
            va="bottom",
        )

autolabel(c_rects)

# Balkendiagramm anzeigen lassen
plt.show()

Zuletzt aktualisiert am 16. Januar 2024