Balkendiagramm zur Wahl in Mecklenburg-Vorpommern mit Python und bokeh erstellen

In der Vergangenheit hatte ich bereits Artikel zur Datenvisualisierung mit Python und bokeh veröffentlicht. In diesem neuen Beispiel geht es wieder um ein Balkendiagramm. Es sollen die Wahlergebnisse zur Wahl in Mecklenburg-Vorpommern 2026 dargestellt werden. Im Gegensatz zu den älteren Blogbeiträgen sind die Werte nicht Bestandteil des Python-Skripts, sondern in einer separaten CSV-Datei gespeichert, deren Inhalt wie folgt aussieht:

Partei;Stimmenanteile
AfD;38.2
SPD;35.5
Linke;6.5
Grüne;5.7
CDU;4.9
BSW;4.8
Partei Mensch Klima Tierschutz;1.1
FDP;1.0
Handwerker Partei Deutschland;0.5
Freie Wähler;0.4
Sonstige;1.5

Voraussetzung ist, dass bokeh auf Eurem System installiert ist:

$ pip install bokeh  # Windows
$ pip3 install bokeh # Linux, macOS

Im Python-Skript beginnen wir mit den Importanweisungen:

import pandas as pd
from bokeh.io import output_file, show
from bokeh.models import (
    BoxZoomTool,
    ColumnDataSource,
    FactorRange,
    HoverTool,
    PanTool,
    ResetTool,
    SaveTool,
    DataRange1d,
)
from bokeh.plotting import figure

Für das Lesen der CSV-Datei kommt pandas zum Einsatz, wobei sich die Datei hier im selben Verzeichnis befindet.

# Daten mit pandas lesen
df = pd.read_csv("Wahl-MV-2026.csv", sep=";")

Als nächstes wird aus dem Dataframe (df) die Pandas-Serie in eine herkömmliche Python-Liste umgewandelt:

parteien: list[str] = df["Partei"].astype(str).tolist()

Außerdem muss dass Dataframe in eine Bokeh-Datenquelle um:

source = ColumnDataSource(df)

Jeder Balken soll in einer anderen Farbe dargestellt werden. Dies erreichen wir über die Liste palette:

# Farben für die Balken
palette = [
    "#73C0E9",
    "#EC5F52",
    "#AA366B",
    "#7CC35F",
    "#615747",
    "#8C2742",
    "#4E8437",
    "#ECBF46",
    "#866423",
    "#C47A1A",
    "#D4D4CA",
]

Diese Farben müssen den Balken zugewiesen werden, weswegen im Dataframe eine neue Spalte color erstellt wird. Es werden dabei aus der Farbliste palette genauso viele Farben entnommen, wie es Zeilen im Dataframe gibt.

df["color"] = palette[: len(df)]
source = ColumnDataSource(df)

Mit figure() wird anschließend das Diagramm-Objekt erzeugt und verschiedene Eigenschaften zugewiesen (z.B. der Titel):

p = figure(
    x_range=FactorRange(factors=parteien),
    y_range=DataRange1d(start=0),
    height=500,
    width=900,
    title="Wahlergebnisse (Stimmenanteile)",
    toolbar_location="above",
)

Der folgende Code ist für die Erstellung des Balkendiagramms nicht erforderlich, fügt aber zur Darstellung nützliche Funktionen hinzu, wie beispielsweise die Option, den aktuellen Plot als PNG-Datei zu speichern:

p.add_tools(PanTool(), BoxZoomTool(), ResetTool(), SaveTool())

Die Achsen sollen beschriftet sein. Mit vbar werden die Balken gezeichnet und die Eigenschaften festgelegt:

p.xaxis.axis_label = "Partei"
p.yaxis.axis_label = "Stimmenanteil in %"

p.vbar(
    x="Partei",
    top="Stimmenanteile",
    width=0.6,
    source=source,
    color="color",
    line_color="black",
)

Es ist übrigen möglich, xaxis.axis_label und yaxis.axis_label in der Funktion figure() unterzubringen. Im Internet werdet ihr auch entsprechende Beispiele finden. Hier haben ich dies nicht getan, da ich vermeiden möchte, dass MyPy eine Warnung ausgibt.

Da manche Parteinamen recht lang sind, werden sie gedreht, um die Lesbarkeit zu gewährleisten:

p.xaxis.major_label_orientation = 0.7

Anschließend wird ein HoverTool erstellt und festgelegt, welche Informationen angezeigt werden sollen:

hover = HoverTool()
hover.tooltips = [("Partei", "@Partei"), ("Stimmenanteil", "@Stimmenanteile{0.0}%")]
p.add_tools(hover)

Die HTML-Datei wird unter dem Namen „Wahlergebnisse.html“ gespeichert und angezeigt:

output_file("Wahlergebnisse.html")
show(p)

Geschafft! Abschließend zeige ich den kompletten Code, der als Ausgangspunkt für eure Projekte dienen mag.

import pandas as pd
from bokeh.io import output_file, show
from bokeh.models import (
    BoxZoomTool,
    ColumnDataSource,
    FactorRange,
    HoverTool,
    PanTool,
    ResetTool,
    SaveTool,
    DataRange1d,
)
from bokeh.plotting import figure

df = pd.read_csv("Wahl-MV-2026.csv", sep=";")

parteien: list[str] = df["Partei"].astype(str).tolist()
source = ColumnDataSource(df)

palette = [
    "#73C0E9",
    "#EC5F52",
    "#AA366B",
    "#7CC35F",
    "#615747",
    "#8C2742",
    "#4E8437",
    "#ECBF46",
    "#866423",
    "#C47A1A",
    "#D4D4CA",
]

df["color"] = palette[: len(df)]
source = ColumnDataSource(df)

p = figure(
    x_range=FactorRange(factors=parteien),
    y_range=DataRange1d(start=0),
    height=500,
    width=900,
    title="Wahlergebnisse (Stimmenanteile)",
    toolbar_location="above",
)

p.add_tools(PanTool(), BoxZoomTool(), ResetTool(), SaveTool())

# Achsen beschriften
p.xaxis.axis_label = "Partei"
p.yaxis.axis_label = "Stimmenanteil in %"

p.vbar(
    x="Partei",
    top="Stimmenanteile",
    width=0.6,
    source=source,
    color="color",
    line_color="black",
)

p.xaxis.major_label_orientation = 0.7

hover = HoverTool()
hover.tooltips = [("Partei", "@Partei"), ("Stimmenanteil", "@Stimmenanteile{0.0}%")]
p.add_tools(hover)

output_file("Wahlergebnisse.html")
show(p)