Herkunft und Umfang in #imshow

imshow()ermöglicht es Ihnen, ein Bild (entweder ein 2D-Array, das farblich abgebildet wird (basierend auf norm und cmap ) oder ein 3D-RGB(A)-Array, das unverändert verwendet wird) in einen rechteckigen Bereich im Datenraum zu rendern. Die Ausrichtung des Bildes im endgültigen Rendering wird durch die Schlüsselwortargumente Ursprung und Ausdehnung (und Attribute der resultierenden AxesImageInstanz) und die Datengrenzen der Achsen gesteuert.

Die Argumente des Schlüsselworts Extent steuern den Begrenzungsrahmen in Datenkoordinaten, den das Bild ausfüllt, wie in Datenkoordinaten angegeben , das Argument des Schlüsselworts origin steuert, wie das Bild diesen Begrenzungsrahmen ausfüllt, und die Ausrichtung im endgültig gerenderten Bild wird auch von den Achsenbegrenzungen beeinflusst .(left, right, bottom, top)

Hinweis

Der größte Teil des folgenden Codes wird zum Hinzufügen von Beschriftungen und informativem Text zu den Diagrammen verwendet. Die beschriebenen Auswirkungen von Ursprung und Ausmaß können in den Diagrammen gesehen werden, ohne dass alle Code-Details befolgt werden müssen.

Für ein schnelles Verständnis können Sie die folgenden Codedetails überspringen und direkt mit der Diskussion der Ergebnisse fortfahren.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec


def index_to_coordinate(index, extent, origin):
    """Return the pixel center of an index."""
    left, right, bottom, top = extent

    hshift = 0.5 * np.sign(right - left)
    left, right = left + hshift, right - hshift
    vshift = 0.5 * np.sign(top - bottom)
    bottom, top = bottom + vshift, top - vshift

    if origin == 'upper':
        bottom, top = top, bottom

    return {
        "[0, 0]": (left, bottom),
        "[M', 0]": (left, top),
        "[0, N']": (right, bottom),
        "[M', N']": (right, top),
    }[index]


def get_index_label_pos(index, extent, origin, inverted_xindex):
    """
    Return the desired position and horizontal alignment of an index label.
    """
    if extent is None:
        extent = lookup_extent(origin)
    left, right, bottom, top = extent
    x, y = index_to_coordinate(index, extent, origin)

    is_x0 = index[-2:] == "0]"
    halign = 'left' if is_x0 ^ inverted_xindex else 'right'
    hshift = 0.5 * np.sign(left - right)
    x += hshift * (1 if is_x0 else -1)
    return x, y, halign


def get_color(index, data, cmap):
    """Return the data color of an index."""
    val = {
        "[0, 0]": data[0, 0],
        "[0, N']": data[0, -1],
        "[M', 0]": data[-1, 0],
        "[M', N']": data[-1, -1],
    }[index]
    return cmap(val / data.max())


def lookup_extent(origin):
    """Return extent for label positioning when not given explicitly."""
    if origin == 'lower':
        return (-0.5, 6.5, -0.5, 5.5)
    else:
        return (-0.5, 6.5, 5.5, -0.5)


def set_extent_None_text(ax):
    ax.text(3, 2.5, 'equals\nextent=None', size='large',
            ha='center', va='center', color='w')


def plot_imshow_with_labels(ax, data, extent, origin, xlim, ylim):
    """Actually run ``imshow()`` and add extent and index labels."""
    im = ax.imshow(data, origin=origin, extent=extent)

    # extent labels (left, right, bottom, top)
    left, right, bottom, top = im.get_extent()
    if xlim is None or top > bottom:
        upper_string, lower_string = 'top', 'bottom'
    else:
        upper_string, lower_string = 'bottom', 'top'
    if ylim is None or left < right:
        port_string, starboard_string = 'left', 'right'
        inverted_xindex = False
    else:
        port_string, starboard_string = 'right', 'left'
        inverted_xindex = True
    bbox_kwargs = {'fc': 'w', 'alpha': .75, 'boxstyle': "round4"}
    ann_kwargs = {'xycoords': 'axes fraction',
                  'textcoords': 'offset points',
                  'bbox': bbox_kwargs}
    ax.annotate(upper_string, xy=(.5, 1), xytext=(0, -1),
                ha='center', va='top', **ann_kwargs)
    ax.annotate(lower_string, xy=(.5, 0), xytext=(0, 1),
                ha='center', va='bottom', **ann_kwargs)
    ax.annotate(port_string, xy=(0, .5), xytext=(1, 0),
                ha='left', va='center', rotation=90,
                **ann_kwargs)
    ax.annotate(starboard_string, xy=(1, .5), xytext=(-1, 0),
                ha='right', va='center', rotation=-90,
                **ann_kwargs)
    ax.set_title('origin: {origin}'.format(origin=origin))

    # index labels
    for index in ["[0, 0]", "[0, N']", "[M', 0]", "[M', N']"]:
        tx, ty, halign = get_index_label_pos(index, extent, origin,
                                             inverted_xindex)
        facecolor = get_color(index, data, im.get_cmap())
        ax.text(tx, ty, index, color='white', ha=halign, va='center',
                bbox={'boxstyle': 'square', 'facecolor': facecolor})
    if xlim:
        ax.set_xlim(*xlim)
    if ylim:
        ax.set_ylim(*ylim)


def generate_imshow_demo_grid(extents, xlim=None, ylim=None):
    N = len(extents)
    fig = plt.figure(tight_layout=True)
    fig.set_size_inches(6, N * (11.25) / 5)
    gs = GridSpec(N, 5, figure=fig)

    columns = {'label': [fig.add_subplot(gs[j, 0]) for j in range(N)],
               'upper': [fig.add_subplot(gs[j, 1:3]) for j in range(N)],
               'lower': [fig.add_subplot(gs[j, 3:5]) for j in range(N)]}
    x, y = np.ogrid[0:6, 0:7]
    data = x + y

    for origin in ['upper', 'lower']:
        for ax, extent in zip(columns[origin], extents):
            plot_imshow_with_labels(ax, data, extent, origin, xlim, ylim)

    columns['label'][0].set_title('extent=')
    for ax, extent in zip(columns['label'], extents):
        if extent is None:
            text = 'None'
        else:
            left, right, bottom, top = extent
            text = (f'left: {left:0.1f}\nright: {right:0.1f}\n'
                    f'bottom: {bottom:0.1f}\ntop: {top:0.1f}\n')
        ax.text(1., .5, text, transform=ax.transAxes, ha='right', va='center')
        ax.axis('off')
    return columns

Standard-Extent #

Schauen wir uns zunächst die Voreinstellung anextent=None

generate_imshow_demo_grid(extents=[None])
Umfang =, Ursprung: oben, Ursprung: unten
{'label': [<AxesSubplot: title={'center': 'extent='}>], 'upper': [<AxesSubplot: title={'center': 'origin: upper'}>], 'lower': [<AxesSubplot: title={'center': 'origin: lower'}>]}

Im Allgemeinen verläuft für ein Array der Form (M, N) der erste Index entlang der Vertikalen, der zweite Index entlang der Horizontalen. Die Pixelzentren befinden sich an ganzzahligen Positionen im Bereich von 0 bis horizontal und von 0 bis vertikal. origin bestimmt, wie die Daten in den Begrenzungsrahmen gefüllt werden.N' = N - 1M' = M - 1

Für origin='lower':

  • [0, 0] ist bei (links, unten)

  • [M', 0] ist bei (links, oben)

  • [0, N'] ist bei (rechts, unten)

  • [M', N'] ist bei (rechts, oben)

origin='upper'Kehrt die Richtung der vertikalen Achse und das Füllen um:

  • [0, 0] ist bei (links, oben)

  • [M', 0] ist bei (links, unten)

  • [0, N'] ist bei (rechts, oben)

  • [M', N'] ist bei (rechts, unten)

Zusammenfassend wird die Position des [0, 0]-Index sowie der Umfang von der Herkunft beeinflusst :

Ursprung

[0, 0]-Position

Ausmaß

Oberer, höher

oben links

(-0.5, numcols-0.5, numrows-0.5, -0.5)

niedriger

unten links

(-0.5, numcols-0.5, -0.5, numrows-0.5)

Der Standardwert von Ursprung wird durch rcParams["image.origin"](Standard: 'upper') festgelegt, was standardmäßig auf entspricht 'upper', um den Indexierungskonventionen für Mathematik und Computergrafikbilder zu entsprechen.

Explizite Ausdehnung #

Durch die Einstellung der Ausdehnung definieren wir die Koordinaten des Bildbereichs. Die zugrunde liegenden Bilddaten werden interpoliert/neu abgetastet, um diesen Bereich zu füllen.

Wenn die Achsen auf Autoskalierung eingestellt sind, dann werden die Sichtgrenzen der Achsen so eingestellt, dass sie der Ausdehnung entsprechen , die sicherstellt, dass die von eingestellte Koordinate unten links auf den Achsen liegt! Dies kann jedoch die Achse umkehren, sodass sie nicht in der „natürlichen“ Richtung zunehmen.(left, bottom)

extents = [(-0.5, 6.5, -0.5, 5.5),
           (-0.5, 6.5, 5.5, -0.5),
           (6.5, -0.5, -0.5, 5.5),
           (6.5, -0.5, 5.5, -0.5)]

columns = generate_imshow_demo_grid(extents)
set_extent_None_text(columns['upper'][1])
set_extent_None_text(columns['lower'][0])
Umfang=, Ursprung: oben, Ursprung: oben, Ursprung: oben, Ursprung: oben, Ursprung: unten, Ursprung: unten, Ursprung: unten, Ursprung: unten

Explizite Ausdehnung und Achsenbegrenzungen #

Wenn wir die Achsengrenzen durch explizites Setzen von set_xlim/ festlegen set_ylim, erzwingen wir eine bestimmte Größe und Ausrichtung der Achsen. Dies kann die „Links-Rechts“- und „Oben-Unten“-Richtung des Bildes von der Ausrichtung auf dem Bildschirm entkoppeln.

Im Beispiel unten haben wir die Grenzen etwas größer als die Ausdehnung gewählt (beachten Sie die weißen Bereiche innerhalb der Achsen).

Während wir die Ausmaße wie in den vorherigen Beispielen beibehalten, wird die Koordinate (0, 0) jetzt explizit unten links gesetzt und die Werte werden nach oben und rechts (aus Sicht des Betrachters) erhöht. Wir können das sehen:

  • Die Koordinate verankert das Bild, das dann die Box füllt, die in Richtung des Punktes im Datenraum geht.(left, bottom)(right, top)

  • Die erste Spalte ist immer „links“ am nächsten.

  • Ursprung steuert, ob die erste Zeile am nächsten an „oben“ oder „unten“ liegt.

  • Das Bild kann entlang jeder Richtung invertiert werden.

  • Die „Links-Rechts“- und „Oben-Unten“-Richtung des Bildes kann von der Ausrichtung auf dem Bildschirm entkoppelt werden.

generate_imshow_demo_grid(extents=[None] + extents,
                          xlim=(-2, 8), ylim=(-1, 6))

plt.show()
Umfang=, Ursprung: oben, Ursprung: oben, Ursprung: oben, Ursprung: oben, Ursprung: oben, Ursprung: unten, Ursprung: unten, Ursprung: unten, Ursprung: unten, Ursprung: unten

Gesamtlaufzeit des Skripts: (0 Minuten 4,816 Sekunden)

Galerie generiert von Sphinx-Gallery