Scalabilità automatica #

I limiti su un asse possono essere impostati manualmente (ad esempio ) oppure Matplotlib può impostarli automaticamente in base ai dati già presenti sugli assi. Esistono diverse opzioni per questo comportamento di scalabilità automatica, discusse di seguito.ax.set_xlim(xmin, xmax)

Inizieremo con un semplice grafico a linee che mostra che il ridimensionamento automatico estende i limiti dell'asse del 5% oltre i limiti dei dati (-2π, 2π).

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

x = np.linspace(-2 * np.pi, 2 * np.pi, 100)
y = np.sinc(x)

fig, ax = plt.subplots()
ax.plot(x, y)
scala automatica
[<matplotlib.lines.Line2D object at 0x7f2cde5343a0>]

Margini #

Il margine predefinito intorno ai limiti di dati è del 5%:

(0.05, 0.05)

I margini possono essere ingranditi utilizzando margins:

fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(0.2, 0.2)
scala automatica

In generale, i margini possono essere compresi nell'intervallo (-0,5, ∞), dove i margini negativi impostano i limiti degli assi su un sottointervallo dell'intervallo di dati, ovvero tagliano i dati. L'utilizzo di un singolo numero per i margini influisce su entrambi gli assi, un singolo margine può essere personalizzato utilizzando argomenti di parole chiave xo y, ma l'interfaccia posizionale e di parole chiave non può essere combinata.

scala automatica

Bordi adesivi #

Ci sono elementi di trama ( Artists) che di solito vengono usati senza margini. Ad esempio le immagini in falsi colori (es. create con Axes.imshow) non vengono considerate nel calcolo dei margini.

xx, yy = np.meshgrid(x, x)
zz = np.sinc(np.sqrt((xx - 1)**2 + (yy - 1)**2))

fig, ax = plt.subplots(ncols=2, figsize=(12, 8))
ax[0].imshow(zz)
ax[0].set_title("default margins")
ax[1].imshow(zz)
ax[1].margins(0.2)
ax[1].set_title("margins(0.2)")
margini di default, margini(0.2)
Text(0.5, 1.0, 'margins(0.2)')

Questa sovrascrittura dei margini è determinata da "bordi adesivi", una proprietà di Artistclasse che può sopprimere l'aggiunta di margini ai limiti dell'asse. L'effetto dei bordi appiccicosi può essere disabilitato su un Asse modificando use_sticky_edges. Gli artisti hanno una proprietà Artist.sticky_edgesei valori dei bordi adesivi possono essere modificati scrivendo a Artist.sticky_edges.xo Artist.sticky_edges.y.

L'esempio seguente mostra come funziona l'override e quando è necessario.

fig, ax = plt.subplots(ncols=3, figsize=(16, 10))
ax[0].imshow(zz)
ax[0].margins(0.2)
ax[0].set_title("default use_sticky_edges\nmargins(0.2)")
ax[1].imshow(zz)
ax[1].margins(0.2)
ax[1].use_sticky_edges = False
ax[1].set_title("use_sticky_edges=False\nmargins(0.2)")
ax[2].imshow(zz)
ax[2].margins(-0.2)
ax[2].set_title("default use_sticky_edges\nmargins(-0.2)")
default use_sticky_edges margins(0.2), use_sticky_edges=False margins(0.2), default use_sticky_edges margins(-0.2)
Text(0.5, 1.0, 'default use_sticky_edges\nmargins(-0.2)')

Possiamo vedere che l'impostazione use_sticky_edgessu False rende l'immagine con i margini richiesti.

Sebbene i bordi appiccicosi non aumentino i limiti dell'asse attraverso margini extra, i margini negativi vengono comunque presi in considerazione. Questo può essere visto nei limiti ridotti della terza immagine.

Controllo della scalabilità automatica #

Per impostazione predefinita, i limiti vengono ricalcolati ogni volta che aggiungi una nuova curva al grafico:

fig, ax = plt.subplots(ncols=2, figsize=(12, 8))
ax[0].plot(x, y)
ax[0].set_title("Single curve")
ax[1].plot(x, y)
ax[1].plot(x * 2.0, y)
ax[1].set_title("Two curves")
Curva singola, due curve
Text(0.5, 1.0, 'Two curves')

Tuttavia, ci sono casi in cui non si desidera adattare automaticamente il viewport ai nuovi dati.

Un modo per disabilitare la scalabilità automatica consiste nell'impostare manualmente il limite dell'asse. Diciamo che vogliamo vedere più in dettaglio solo una parte dei dati. L'impostazione xlimpersiste anche se aggiungiamo più curve ai dati. Per ricalcolare i nuovi limiti, la chiamata Axes.autoscaleattiverà manualmente la funzionalità.

fig, ax = plt.subplots(ncols=2, figsize=(12, 8))
ax[0].plot(x, y)
ax[0].set_xlim(left=-1, right=1)
ax[0].plot(x + np.pi * 0.5, y)
ax[0].set_title("set_xlim(left=-1, right=1)\n")
ax[1].plot(x, y)
ax[1].set_xlim(left=-1, right=1)
ax[1].plot(x + np.pi * 0.5, y)
ax[1].autoscale()
ax[1].set_title("set_xlim(left=-1, right=1)\nautoscale()")
set_xlim(sinistra=-1, destra=1) , set_xlim(sinistra=-1, destra=1) autoscale()
Text(0.5, 1.0, 'set_xlim(left=-1, right=1)\nautoscale()')

Possiamo verificare che il primo grafico abbia la scalabilità automatica disabilitata e che il secondo grafico lo abbia nuovamente abilitato usando Axes.get_autoscale_on():

print(ax[0].get_autoscale_on())  # False means disabled
print(ax[1].get_autoscale_on())  # True means enabled -> recalculated
False
True

Gli argomenti della funzione di scalabilità automatica ci danno un controllo preciso sul processo di scalabilità automatica. Una combinazione di argomenti enablee axisimposta la funzione di ridimensionamento automatico per l'asse selezionato (o entrambi). L'argomento tight imposta il margine dell'asse selezionato su zero. Per conservare le impostazioni di uno enableo tightpuoi impostare quello opposto su None , in questo modo non dovrebbe essere modificato. Tuttavia, l'impostazione enablesu None e tight su True influisce su entrambi gli assi indipendentemente axisdall'argomento.

fig, ax = plt.subplots()
ax.plot(x, y)
ax.margins(0.2, 0.2)
ax.autoscale(enable=None, axis="x", tight=True)

print(ax.margins())
scala automatica
(0, 0)

Lavorare con le raccolte #

La scalabilità automatica funziona immediatamente per tutte le linee, le patch e le immagini aggiunte agli assi. Uno degli artisti con cui non funzionerà è un Collection. Dopo aver aggiunto una raccolta agli assi, è necessario attivare manualmente autoscale_view()per ricalcolare i limiti degli assi.

fig, ax = plt.subplots()
collection = mpl.collections.StarPolygonCollection(
    5, rotation=0, sizes=(250,),  # five point star, zero angle, size 250px
    offsets=np.column_stack([x, y]),  # Set the positions
    offset_transform=ax.transData,  # Propagate transformations of the Axes
)
ax.add_collection(collection)
ax.autoscale_view()
scala automatica

Tempo di esecuzione totale dello script: (0 minuti 6,508 secondi)

Galleria generata da Sphinx-Gallery