Notiz
Klicken Sie hier , um den vollständigen Beispielcode herunterzuladen
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 AxesImage
Instanz) 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])
{'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 - 1
M' = 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 |
|
niedriger |
unten links |
|
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)
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.
Gesamtlaufzeit des Skripts: (0 Minuten 4,816 Sekunden)