Komplexe und semantische Figurenkomposition #

Warnung

Dieses Tutorial dokumentiert die experimentelle/vorläufige API. Wir veröffentlichen dies in v3.3, um Benutzerfeedback zu erhalten. Wir können in zukünftigen Versionen ohne Vorankündigung bahnbrechende Änderungen vornehmen.

Das Anordnen von Äxten in einer Figur in einem ungleichmäßigen Raster kann sowohl mühsam als auch ausführlich sein. Für dichte, gleichmäßige Gitter haben wir Figure.subplotsaber für komplexere Layouts, wie Achsen, die sich über mehrere Spalten/Zeilen des Layouts erstrecken oder einige Bereiche der Figur leer lassen, können Sie Ihre verwenden gridspec.GridSpec(siehe Mehrere Achsen in einer Figur anordnen ) oder manuell platzieren Achsen. Figure.subplot_mosaiczielt darauf ab, eine Schnittstelle bereitzustellen, um Ihre Achsen visuell anzuordnen (entweder als ASCII-Grafik oder verschachtelte Listen), um diesen Prozess zu rationalisieren.

Diese Schnittstelle unterstützt natürlich die Benennung Ihrer Achsen. Figure.subplot_mosaicgibt ein Wörterbuch zurück, das auf den Beschriftungen basiert, die zum Layout der Abbildung verwendet wurden. Indem Datenstrukturen mit Namen zurückgegeben werden, ist es einfacher, einen Plotcode zu schreiben, der unabhängig vom Layout der Figur ist.

Dies ist von einem vorgeschlagenen MEP und der Patchwork -Bibliothek für R inspiriert. Obwohl wir den Operatorüberladungsstil nicht implementieren, stellen wir eine Pythonic-API zum Angeben (verschachtelter) Axes-Layouts bereit.

import matplotlib.pyplot as plt
import numpy as np


# Helper function used for visualization in the following examples
def identify_axes(ax_dict, fontsize=48):
    """
    Helper to identify the Axes in the examples below.

    Draws the label in a large font in the center of the Axes.

    Parameters
    ----------
    ax_dict : dict[str, Axes]
        Mapping between the title / label and the Axes.
    fontsize : int, optional
        How big the label should be.
    """
    kw = dict(ha="center", va="center", fontsize=fontsize, color="darkgrey")
    for k, ax in ax_dict.items():
        ax.text(0.5, 0.5, k, transform=ax.transAxes, **kw)

Wenn wir ein 2x2-Gitter wollen, können wir verwenden, Figure.subplotsdas ein 2D-Array zurückgibt, in axes.Axesdas wir indizieren können, um unser Plotten durchzuführen.

np.random.seed(19680801)
hist_data = np.random.randn(1_500)


fig = plt.figure(constrained_layout=True)
ax_array = fig.subplots(2, 2, squeeze=False)

ax_array[0, 0].bar(["a", "b", "c"], [5, 7, 9])
ax_array[0, 1].plot([1, 2, 3])
ax_array[1, 0].hist(hist_data, bins="auto")
ax_array[1, 1].imshow([[1, 2], [2, 1]])

identify_axes(
    {(j, k): a for j, r in enumerate(ax_array) for k, a in enumerate(r)},
)
Mosaik-

Mit Figure.subplot_mosaickönnen wir dasselbe Mosaik erzeugen, aber den Achsen semantische Namen geben

fig = plt.figure(constrained_layout=True)
ax_dict = fig.subplot_mosaic(
    [
        ["bar", "plot"],
        ["hist", "image"],
    ],
)
ax_dict["bar"].bar(["a", "b", "c"], [5, 7, 9])
ax_dict["plot"].plot([1, 2, 3])
ax_dict["hist"].hist(hist_data)
ax_dict["image"].imshow([[1, 2], [2, 1]])
identify_axes(ax_dict)
Mosaik-

Ein wesentlicher Unterschied zwischen Figure.subplotsund Figure.subplot_mosaicist der Rückgabewert. Während Ersteres ein Array für den Indexzugriff zurückgibt, gibt Letzteres ein Wörterbuch zurück, das die Labels den axes.Axeserstellten Instanzen zuordnet

print(ax_dict)
{'bar': <AxesSubplot: label='bar'>, 'plot': <AxesSubplot: label='plot'>, 'hist': <AxesSubplot: label='hist'>, 'image': <AxesSubplot: label='image'>}

Saitenkürzel #

Indem wir unsere Achsenbeschriftungen auf einzelne Zeichen beschränken, können wir die gewünschten Achsen als "ASCII-Art" "zeichnen". Folgende

mosaic = """
    AB
    CD
    """

gibt uns 4 Achsen, die in einem 2x2-Gitter angeordnet sind, und erzeugt das gleiche Figurenmosaik wie oben (aber jetzt mit statt gekennzeichnet ).{"A", "B", "C", "D"}{"bar", "plot", "hist", "image"}

fig = plt.figure(constrained_layout=True)
ax_dict = fig.subplot_mosaic(mosaic)
identify_axes(ax_dict)
Mosaik-

Alternativ können Sie die kompaktere String-Notation verwenden

mosaic = "AB;CD"

erhalten Sie die gleiche Zusammensetzung, wobei ";"anstelle von Zeilenumbrüchen das als Zeilentrennzeichen verwendet wird.

fig = plt.figure(constrained_layout=True)
ax_dict = fig.subplot_mosaic(mosaic)
identify_axes(ax_dict)
Mosaik-

Achsen über mehrere Zeilen/Spalten #

Etwas, das wir tun können, Figure.subplot_mosaicwas Sie nicht tun können, Figure.subplotsist anzugeben, dass eine Achse mehrere Zeilen oder Spalten umfassen soll.

Wenn wir unsere vier Achsen so anordnen möchten, dass "C"sie unten eine horizontale Spanne und "D"rechts eine vertikale Spanne haben, würden wir das tun

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    """
    ABD
    CCD
    """
)
identify_axes(axd)
Mosaik-

Wenn wir nicht alle Felder in der Abbildung mit Achsen ausfüllen möchten, können wir einige Felder im Raster als leer angeben

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    """
    A.C
    BBB
    .D.
    """
)
identify_axes(axd)
Mosaik-

Wenn wir es vorziehen, ein anderes Zeichen (anstelle eines Punkts ".") zu verwenden, um das Leerzeichen zu markieren, können wir empty_sentinel verwenden , um das zu verwendende Zeichen anzugeben.

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    """
    aX
    Xb
    """,
    empty_sentinel="X",
)
identify_axes(axd)
Mosaik-

Intern haben die von uns verwendeten Buchstaben keine Bedeutung, jeder Unicode-Codepunkt ist gültig!

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    """αб
       ℝ☢"""
)
identify_axes(axd)
Mosaik-

Es wird nicht empfohlen, Leerzeichen als Bezeichnung oder als leeren Wächter mit der Zeichenfolgen-Kurzschrift zu verwenden, da sie während der Verarbeitung der Eingabe entfernt werden können.

Steuern der Mosaik- und Subplot-Erstellung #

Dieses Feature baut auf auf gridspecund Sie können die Schlüsselwortargumente an das darunter liegende weitergeben gridspec.GridSpec (dasselbe wie Figure.subplots).

In diesem Fall möchten wir die Eingabe verwenden, um die Anordnung festzulegen, aber die relativen Breiten der Zeilen / Spalten über gridspec_kw festlegen .

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    """
    .a.
    bAc
    .d.
    """,
    # set the height ratios between the rows
    height_ratios=[1, 3.5, 1],
    # set the width ratios between the columns
    width_ratios=[1, 3.5, 1],
)
identify_axes(axd)
Mosaik-

Oder verwenden Sie die Schlüsselwortargumente { left , right , bottom , top } , um das Gesamtmosaik zu positionieren und mehrere Versionen desselben Mosaiks in einer Figur darzustellen

mosaic = """AA
            BC"""
fig = plt.figure()
axd = fig.subplot_mosaic(
    mosaic,
    gridspec_kw={
        "bottom": 0.25,
        "top": 0.95,
        "left": 0.1,
        "right": 0.5,
        "wspace": 0.5,
        "hspace": 0.5,
    },
)
identify_axes(axd)

axd = fig.subplot_mosaic(
    mosaic,
    gridspec_kw={
        "bottom": 0.05,
        "top": 0.75,
        "left": 0.6,
        "right": 0.95,
        "wspace": 0.5,
        "hspace": 0.5,
    },
)
identify_axes(axd)
Mosaik-

Alternativ können Sie die Sub-Figure-Funktionalität verwenden:

mosaic = """AA
            BC"""
fig = plt.figure(constrained_layout=True)
left, right = fig.subfigures(nrows=1, ncols=2)
axd = left.subplot_mosaic(mosaic)
identify_axes(axd)

axd = right.subplot_mosaic(mosaic)
identify_axes(axd)
Mosaik-

Wir können auch Argumente übergeben, die zum Erstellen der Nebenplots verwendet werden (wieder dasselbe wie Figure.subplots).

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    "AB", subplot_kw={"projection": "polar"}
)
identify_axes(axd)
Mosaik-

Verschachtelte Listeneingabe #

Alles, was wir mit der String-Kurzschrift tun können, können wir auch tun, wenn wir eine Liste übergeben (intern konvertieren wir die String-Kurzschrift in eine verschachtelte Liste), zum Beispiel mit spans, blanks und gridspec_kw :

axd = plt.figure(constrained_layout=True).subplot_mosaic(
    [
        ["main", "zoom"],
        ["main", "BLANK"],
    ],
    empty_sentinel="BLANK",
    width_ratios=[2, 1],
)
identify_axes(axd)
Mosaik-

Darüber hinaus können wir mit der Listeneingabe verschachtelte Mosaike spezifizieren. Jedes Element der inneren Liste kann ein weiterer Satz verschachtelter Listen sein:

inner = [
    ["inner A"],
    ["inner B"],
]

outer_nested_mosaic = [
    ["main", inner],
    ["bottom", "bottom"],
]
axd = plt.figure(constrained_layout=True).subplot_mosaic(
    outer_nested_mosaic, empty_sentinel=None
)
identify_axes(axd, fontsize=36)
Mosaik-

Wir können auch ein 2D-NumPy-Array übergeben, um Dinge zu tun wie:

mosaic = np.zeros((4, 4), dtype=int)
for j in range(4):
    mosaic[j, j] = j + 1
axd = plt.figure(constrained_layout=True).subplot_mosaic(
    mosaic,
    empty_sentinel=0,
)
identify_axes(axd)
Mosaik-

Gesamtlaufzeit des Skripts: ( 0 Minuten 9.170 Sekunden)

Galerie generiert von Sphinx-Gallery