Definition: Kreisdiagramm

Ein Kreisdiagramm (en. Pie Chart) ist ein Diagrammtyp, der verwendet wird, um Daten in Form von Anteilen oder Prozentsätzen zu visualisieren.

Es besteht aus einem Kreis, der in verschiedene Sektoren unterteilt ist, wobei jeder Sektor einen Teil des Ganzen repräsentiert und die Größe jedes Sektors proportional zum Anteil des Gesamtdatenwertes ist.

  • Regeln:
    • Die Daten müssen in Summe “ein Ganzes” ergeben.
    • Es sollte maximal 5 Segmente geben.
    • Das größte Segment sollte oben in der Mitte (i.e. 12 Uhr) anfangen. Die restlichen Segmente sollten im Uhrzeigersinn hinzugefügt werden.
    • Die Proportionen sollten “alltägliche” Proportionen wie x/2, x/3, x/4 umfassen.

Anmerkung

Kritik

Kreisdiagramme werden oft dafür kritisiert, dass sie schwer zu lesen sind.

Die Größe der Segmente ist - insbesondere bei sehr vielen Segmenten - kaum unterscheidbar.

Beispielsweise:

Kreisdiagramm mit matplotlib

In Python erhalten wir ein (bzw. mehrere) Kreisdiagramm durch

from typing import Optional
import matplotlib.pyplot as plt
import seaborn as sns
import math
 
 
def sort_lists(sort_by_list: list, *lists: list):
    return zip(*sorted(zip(sort_by_list, *lists)))
 
 
def plot_pie(title: str, value_counts: list[int], labels: list[str], axis: plt.Axes):
    color_palette = sns.color_palette("pastel")
 
    # sort by labels for consistent baseline ordering
    sorted_labels, sorted_value_counts = sort_lists(labels, value_counts)
 
    # sort by values to ensure largest group comes first, ordered descending
    sorted_value_counts, sorted_labels, sorted_color_palette = sort_lists(
        sorted_value_counts, sorted_labels, color_palette
    )
 
    axis.set_title(title, size=11)
    axis.pie(
        sorted_value_counts,
        labels=sorted_labels,
        startangle=90,
        autopct="%.1f%%",
        colors=sorted_color_palette,
    )
 
 
def choose_display_labels(
    default_labels: list[str], custom_labels: Optional[list[str]]
) -> list[str]:
    labels = custom_labels or default_labels
 
    assert len(labels) == len(
        default_labels
    ), f"expected: {len(default_labels)} labels, actual: {len(labels)} labels. default_labels: {default_labels}, custom_labels: {custom_labels}"
 
    return labels
 
 
def plot_multi_pie(
    figtitle: str,
    df: pd.DataFrame,
    label_dim: str,
    value_dim: str,
    nrows: int,
    figsize: int,
    custom_dim_labels: Optional[list[str]] = [],
    custom_value_labels: Optional[list[str]] = [],
    dpi: int = 250,
):
    # Create subplots
    default_labels = list(df[label_dim].unique())
    display_labels = choose_display_labels(default_labels, custom_dim_labels)
 
    ncols = math.ceil(len(default_labels) / nrows)
    fig, axes = plt.subplots(nrows, ncols, figsize=(figsize, figsize), dpi=dpi)
    axes = axes.flatten()
 
    # Create pie plots
    for idx, (label, current_axis) in enumerate(zip(default_labels, axes)):
        value_counts = df[df[label_dim] == label].value_counts(value_dim)
 
        # Choose value labels directly from table or from custom user input
        default_value_labels = value_counts.index
        value_labels = choose_display_labels(default_value_labels, custom_value_labels)
 
        plot_pie(display_labels[idx], value_counts, value_labels, current_axis)
 
    # Hide any unused subplots
    for ax in axes[len(display_labels) :]:
        ax.set_visible(False)
 
    fig.tight_layout()
    fig.suptitle(figtitle, size=20)
    fig.show()
 
 
plot_multi_pie(
    figtitle="Interesse nach Abteilungen",
    df=df,
    label_dim="abteilung",
    value_dim="interesse",
    nrows=2,
    figsize=10,
    dpi=250,
    # Optional: custom_dim_labels=["Küche", "IT", "Verwaltung", "Entwicklung", "Marketing"],
    # Optional: custom_value_labels=["Interesse", "Kein Interesse"],
)