Nota
Fare clic qui per scaricare il codice di esempio completo
origine ed estensione in #imshow
imshow()
consente di eseguire il rendering di un'immagine (un array 2D che verrà mappato a colori (basato su norm e cmap ) o un array 3D RGB(A) che verrà utilizzato così com'è) in una regione rettangolare nello spazio dati. L'orientamento dell'immagine nel rendering finale è controllato dagli argomenti delle parole chiave origin ed extent
(e dagli attributi sull'istanza risultante AxesImage
) e dai limiti di dati degli assi.
Gli argomenti della parola chiave extent controllano il riquadro di delimitazione nelle coordinate dei dati che l'immagine riempirà specificato come in data coordinates , l' argomento della parola chiave origin controlla come l'immagine riempie il riquadro di delimitazione e anche l'orientamento nell'immagine renderizzata finale è influenzato dai limiti degli assi .(left, right, bottom, top)
Suggerimento
La maggior parte del codice riportato di seguito viene utilizzata per aggiungere etichette e testo informativo ai grafici. Gli effetti descritti di origine ed estensione possono essere visti nelle trame senza la necessità di seguire tutti i dettagli del codice.
Per una rapida comprensione, potresti voler saltare i dettagli del codice di seguito e continuare direttamente con la discussione dei risultati.
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
Estensione predefinita n.
Per prima cosa, diamo un'occhiata al defaultextent=None
generate_imshow_demo_grid(extents=[None])
{'label': [<AxesSubplot: title={'center': 'extent='}>], 'upper': [<AxesSubplot: title={'center': 'origin: upper'}>], 'lower': [<AxesSubplot: title={'center': 'origin: lower'}>]}
Generalmente, per un array di forma (M, N), il primo indice corre lungo la verticale, il secondo indice corre lungo l'orizzontale. I centri dei pixel si trovano in posizioni intere che vanno da 0 a
orizzontalmente e da 0 a verticalmente.
origin determina il modo in cui i dati vengono inseriti nel riquadro di delimitazione.N' = N - 1
M' = M - 1
Per origin='lower'
:
[0, 0] è a (sinistra, in basso)
[M', 0] è a (sinistra, in alto)
[0, N'] è a (destra, in basso)
[M', N'] è a (destra, in alto)
origin='upper'
inverte la direzione degli assi verticali e il riempimento:
[0, 0] è a (sinistra, in alto)
[M', 0] è a (sinistra, in basso)
[0, N'] è a (destra, in alto)
[M', N'] è a (destra, in basso)
In sintesi, la posizione dell'indice [0, 0] e l'estensione sono influenzate dall'origine :
origine |
[0, 0] posizione |
estensione |
---|---|---|
superiore |
in alto a sinistra |
|
minore |
in basso a sinistra |
|
Il valore predefinito di origin è impostato da rcParams["image.origin"]
(default: 'upper'
) che per impostazione predefinita 'upper'
corrisponde alle convenzioni di indicizzazione delle matrici in matematica e alle convenzioni di indicizzazione delle immagini della grafica computerizzata.
Estensione esplicita #
Impostando l' estensione definiamo le coordinate dell'area dell'immagine. I dati dell'immagine sottostante vengono interpolati/ricampionati per riempire quell'area.
Se gli assi sono impostati su scala automatica, i limiti di visualizzazione degli assi sono impostati in modo da corrispondere all'estensione che garantisce che la coordinata impostata da
sia in basso a sinistra degli assi! Tuttavia, ciò potrebbe invertire l'asse in modo che non aumentino nella direzione "naturale".(left, bottom)
Estensione esplicita e limiti degli assi #
Se fissiamo i limiti degli assi impostando esplicitamente set_xlim
/
set_ylim
, forziamo una certa dimensione e orientamento degli assi. Questo può disaccoppiare il senso "sinistra-destra" e "alto-basso" dell'immagine dall'orientamento sullo schermo.
Nell'esempio seguente abbiamo scelto i limiti leggermente più grandi dell'estensione (notare le aree bianche all'interno degli Assi).
Mentre manteniamo le estensioni come negli esempi precedenti, la coordinata (0, 0) è ora esplicitamente posta in basso a sinistra e i valori aumentano verso l'alto e verso destra (dal punto di vista dell'osservatore). Possiamo vederlo:
La coordinata fissa l'immagine che poi riempie la casella andando verso il punto nello spazio dati.
(left, bottom)
(right, top)
La prima colonna è sempre la più vicina a "sinistra".
origin controlla se la prima riga è più vicina a 'top' o 'bottom'.
L'immagine può essere invertita lungo entrambe le direzioni.
Il senso "sinistra-destra" e "alto-basso" dell'immagine può essere disaccoppiato dall'orientamento sullo schermo.
Tempo di esecuzione totale dello script: (0 minuti 4,816 secondi)