Non riesco a far sì che la barra dei colori nei grafici imshow come questa abbia la stessa altezza del grafico, a meno di usare Photoshop dopo il fatto. Come faccio ad abbinare le altezze?
Non riesco a far sì che la barra dei colori nei grafici imshow come questa abbia la stessa altezza del grafico, a meno di usare Photoshop dopo il fatto. Come faccio ad abbinare le altezze?
Risposte:
Puoi farlo facilmente con un AxisDivider matplotlib .
L'esempio della pagina collegata funziona anche senza l'utilizzo di sottotrame:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
plt.figure()
ax = plt.gca()
im = ax.imshow(np.arange(100).reshape((10,10)))
# create an axes on the right side of ax. The width of cax will be 5%
# of ax and the padding between cax and ax will be fixed at 0.05 inch.
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
plt.title
, verrà visualizzato scambiato a destra. C'è un modo per superare questo?
Questa combinazione (e valori vicini a questi) sembra "magicamente" funzionare per me per mantenere la barra dei colori adattata alla trama, indipendentemente dalle dimensioni del display.
plt.colorbar(im,fraction=0.046, pad=0.04)
Inoltre non richiede la condivisione dell'asse che può far uscire il diagramma dal quadrato.
im_ratio = data.shape[0]/data.shape[1]
plt.colorbar(im,fraction=0.046*im_ratio, pad=0.04)
dov'è la data
tua immagine.
@bogatron ha già dato la risposta suggerita dai documenti matplotlib , che produce la giusta altezza, ma introduce un problema diverso. Ora la larghezza della barra dei colori (così come lo spazio tra la barra dei colori e la trama) cambia con la larghezza della trama. In altre parole, le proporzioni della barra dei colori non sono più fisse.
Per ottenere sia la giusta altezza che un determinato formato, devi scavare un po 'più a fondo nel axes_grid1
modulo misterioso .
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
import numpy as np
aspect = 20
pad_fraction = 0.5
ax = plt.gca()
im = ax.imshow(np.arange(200).reshape((20, 10)))
divider = make_axes_locatable(ax)
width = axes_size.AxesY(ax, aspect=1./aspect)
pad = axes_size.Fraction(pad_fraction, width)
cax = divider.append_axes("right", size=width, pad=pad)
plt.colorbar(im, cax=cax)
Si noti che questo specifica la larghezza della barra colorata rispetto all'altezza della trama (in contrasto con la larghezza della figura, come era prima).
La spaziatura tra la barra dei colori e la trama può ora essere specificata come una frazione della larghezza della barra dei colori, che è IMHO un numero molto più significativo di una frazione della larghezza della figura.
AGGIORNARE:
Ho creato un notebook IPython sull'argomento , in cui ho inserito il codice sopra in una funzione facilmente riutilizzabile:
import matplotlib.pyplot as plt
from mpl_toolkits import axes_grid1
def add_colorbar(im, aspect=20, pad_fraction=0.5, **kwargs):
"""Add a vertical color bar to an image plot."""
divider = axes_grid1.make_axes_locatable(im.axes)
width = axes_grid1.axes_size.AxesY(im.axes, aspect=1./aspect)
pad = axes_grid1.axes_size.Fraction(pad_fraction, width)
current_ax = plt.gca()
cax = divider.append_axes("right", size=width, pad=pad)
plt.sca(current_ax)
return im.axes.figure.colorbar(im, cax=cax, **kwargs)
Può essere usato in questo modo:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Apprezzo tutte le risposte sopra. Tuttavia, come alcune risposte e commenti hanno sottolineato, il axes_grid1
modulo può non GeoAxes di indirizzo, mentre la regolazione fraction
, pad
, shrink
, e altri parametri simili può non necessariamente dare l'ordine ben preciso, che in realtà mi disturba. Credo che dare il colorbar
proprio axes
potrebbe essere una soluzione migliore per affrontare tutti i problemi che sono stati menzionati.
import matplotlib.pyplot as plt
import numpy as np
fig=plt.figure()
ax = plt.axes()
im = ax.imshow(np.arange(100).reshape((10,10)))
# Create an axes for colorbar. The position of the axes is calculated based on the position of ax.
# You can change 0.01 to adjust the distance between the main image and the colorbar.
# You can change 0.02 to adjust the width of the colorbar.
# This practice is universal for both subplots and GeoAxes.
cax = fig.add_axes([ax.get_position().x1+0.01,ax.get_position().y0,0.02,ax.get_position().height])
plt.colorbar(im, cax=cax) # Similar to fig.colorbar(im, cax = cax)
In seguito, trovo matplotlib.pyplot.colorbar
che anche la documentazione ufficiale offra l' ax
opzione, che sono assi esistenti che offriranno spazio per la barra dei colori. Pertanto, è utile per più sottotrame, vedere di seguito.
fig, ax = plt.subplots(2,1,figsize=(12,8)) # Caution, figsize will also influence positions.
im1 = ax[0].imshow(np.arange(100).reshape((10,10)), vmin = -100, vmax =100)
im2 = ax[1].imshow(np.arange(-100,0).reshape((10,10)), vmin = -100, vmax =100)
fig.colorbar(im1, ax=ax)
Ancora una volta, puoi anche ottenere effetti simili specificando cax, un modo più accurato dal mio punto di vista.
fig, ax = plt.subplots(2,1,figsize=(12,8))
im1 = ax[0].imshow(np.arange(100).reshape((10,10)), vmin = -100, vmax =100)
im2 = ax[1].imshow(np.arange(-100,0).reshape((10,10)), vmin = -100, vmax =100)
cax = fig.add_axes([ax[1].get_position().x1-0.25,ax[1].get_position().y0,0.02,ax[0].get_position().y1-ax[1].get_position().y0])
fig.colorbar(im1, cax=cax)
Quando si crea il file colorbar
tentativo, utilizzare i parametri frazione e / o riduzione.
Dai documenti:
frazione 0,15; frazione degli assi originali da utilizzare per la barra dei colori
ridurre 1.0; frazione con cui ridurre la barra dei colori
colorbar()
funzione o del metodo.
Tutte le soluzioni di cui sopra sono buone, ma mi piacciono le migliori di @ Steve e @ bejota in quanto non prevedono chiamate fantasiose e sono universali.
Con universale intendo che funziona con qualsiasi tipo di assi compreso GeoAxes
. Ad esempio, hai degli assi proiettati per la mappatura:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
una chiamata a
cax = divider.append_axes("right", size=width, pad=pad)
fallirà con: KeyException: map_projection
Pertanto, l'unico modo universale di trattare le dimensioni della barra dei colori con tutti i tipi di assi è:
ax.colorbar(im, fraction=0.046, pad=0.04)
Lavora con una frazione da 0,035 a 0,046 per ottenere la tua taglia migliore. Tuttavia, i valori per la frazione e il paddig dovranno essere regolati per adattarsi al meglio alla trama e differiranno a seconda che l'orientamento della barra dei colori sia in posizione verticale o orizzontale.
shrink
parametri quando fraction
insieme pad
non producono abbastanza risultati desiderati.