origine et étendue en #imshow

imshow()vous permet de restituer une image (soit un tableau 2D qui sera mappé en couleur (basé sur norm et cmap ) ou un tableau 3D RGB(A) qui sera utilisé tel quel) dans une région rectangulaire de l'espace de données. L'orientation de l'image dans le rendu final est contrôlée par les arguments des mots-clés origin et extent (et les attributs sur l' AxesImageinstance résultante) et les limites de données des axes.

Les arguments du mot-clé extent contrôlent la zone de délimitation dans les coordonnées de données que l'image remplira spécifiées comme dans les coordonnées de données , l' argument du mot-clé origin contrôle la façon dont l'image remplit cette zone de délimitation, et l'orientation dans l'image finale rendue est également affectée par les limites des axes .(left, right, bottom, top)

Indice

La majeure partie du code ci-dessous est utilisée pour ajouter des étiquettes et du texte informatif aux tracés. Les effets décrits de l' origine et de l' étendue peuvent être vus dans les graphiques sans qu'il soit nécessaire de suivre tous les détails du code.

Pour une compréhension rapide, vous pouvez ignorer les détails du code ci-dessous et poursuivre directement la discussion des résultats.

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

Étendue par défaut #

Tout d'abord, regardons la valeur par défautextent=None

generate_imshow_demo_grid(extents=[None])
extent=, origine : supérieure, origine : inférieure
{'label': [<AxesSubplot: title={'center': 'extent='}>], 'upper': [<AxesSubplot: title={'center': 'origin: upper'}>], 'lower': [<AxesSubplot: title={'center': 'origin: lower'}>]}

Généralement, pour un tableau de forme (M, N), le premier index court le long de la verticale, le deuxième index court le long de l'horizontale. Les centres de pixel sont à des positions entières allant de 0 à horizontalement et de 0 à verticalement. origin détermine la façon dont les données sont remplies dans la boîte englobante.N' = N - 1M' = M - 1

Pour origin='lower':

  • [0, 0] est à (gauche, bas)

  • [M', 0] est à (gauche, haut)

  • [0, N'] est à (droite, bas)

  • [M', N'] est à (droite, haut)

origin='upper'inverse le sens des axes verticaux et le remplissage :

  • [0, 0] est à (gauche, haut)

  • [M', 0] est à (gauche, bas)

  • [0, N'] est à (droite, haut)

  • [M', N'] est à (droite, bas)

En résumé, la position de l'indice [0, 0] ainsi que l'étendue sont influencées par l' origine :

origine

position [0, 0]

Le degré

plus haut

en haut à gauche

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

plus bas

en bas à gauche

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

La valeur par défaut de origin est définie par rcParams["image.origin"](default: 'upper') qui 'upper'correspond par défaut aux conventions d'indexation matricielle dans les conventions d'indexation d'images mathématiques et informatiques.

Étendue explicite #

En définissant l' étendue , nous définissons les coordonnées de la zone de l'image. Les données d'image sous-jacentes sont interpolées/rééchantillonnées pour remplir cette zone.

Si les axes sont réglés sur mise à l'échelle automatique, les limites de vue des axes sont définies pour correspondre à l' étendue , ce qui garantit que la coordonnée définie par se trouve en bas à gauche des axes ! Cependant, cela peut inverser l'axe afin qu'ils n'augmentent pas dans la direction "naturelle".(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])
extent=, origine : supérieure, origine : supérieure, origine : supérieure, origine : supérieure, origine : inférieure, origine : inférieure, origine : inférieure, origine : inférieure

Étendue explicite et limites des axes #

Si nous fixons les limites des axes en définissant explicitement set_xlim/ set_ylim, nous forçons une certaine taille et orientation des axes. Cela peut découpler le sens 'gauche-droite' et 'haut-bas' de l'image de l'orientation sur l'écran.

Dans l'exemple ci-dessous, nous avons choisi des limites légèrement supérieures à l'étendue (notez les zones blanches à l'intérieur des axes).

Alors que nous gardons les étendues comme dans les exemples précédents, la coordonnée (0, 0) est maintenant explicitement placée en bas à gauche et les valeurs augmentent vers le haut et vers la droite (du point de vue du spectateur). On peut voir ça:

  • La coordonnée ancre l'image qui remplit alors la boîte en allant vers le point dans l'espace des données.(left, bottom)(right, top)

  • La première colonne est toujours la plus proche de la "gauche".

  • origin contrôle si la première ligne est la plus proche de 'top' ou 'bottom'.

  • L'image peut être inversée dans les deux sens.

  • Le sens 'gauche-droite' et 'haut-bas' de l'image peut être découplé de l'orientation sur l'écran.

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

plt.show()
extent=, origine : supérieure, origine : supérieure, origine : supérieure, origine : supérieure, origine : supérieure, origine : inférieure, origine : inférieure, origine : inférieure, origine : inférieure, origine : inférieure

Durée totale d'exécution du script : (0 minutes 4,816 secondes)

Galerie générée par Sphinx-Gallery