Je ne peux pas obtenir que la barre de couleur sur les graphiques imshow tels que celui-ci ait la même hauteur que le graphique, à moins d'utiliser Photoshop après coup. Comment puis-je obtenir les hauteurs pour correspondre?
Vous pouvez le faire facilement avec un matplotlib AxisDivider .
L'exemple de la page liée fonctionne également sans sous-parcelles:
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)
Cette combinaison (et les valeurs proches de celles-ci) semble "magiquement" me permettre de garder la barre de couleur à l'échelle du tracé, quelle que soit la taille de l'affichage.
plt.colorbar(im,fraction=0.046, pad=0.04)
Il n’exige pas non plus de partager l’axe, ce qui peut rendre l’intrigue déséquilibrée.
@bogatron a déjà donné la réponse suggérée par le matplotlib docs , qui produit la bonne hauteur, mais pose un problème différent. Maintenant, la largeur de la barre de couleur (ainsi que l'espace entre la barre de couleur et le tracé) change avec la largeur du tracé. En d'autres termes, le rapport hauteur/largeur de la barre de couleur n'est plus fixe.
Pour obtenir à la fois la bonne hauteur et un rapport d'aspect donné, vous devez creuser un peu plus profondément dans le mystérieux module axes_grid1
.
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)
Notez que ceci spécifie la largeur de la barre de couleurs w.r.t. la hauteur du tracé (par opposition à la largeur de la figure , comme c'était avant).
L'espacement entre la barre de couleur et le tracé peut maintenant être spécifié en tant que fraction de la largeur de la barre de couleur, ce qui représente à mon humble avis un nombre beaucoup plus significatif que celui d'une fraction de la largeur de la figure.
MISE À JOUR:
J'ai créé n bloc-notes IPython sur le sujet , où j'ai condensé le code ci-dessus dans une fonction facilement réutilisable:
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)
Il peut être utilisé comme ceci:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Lorsque vous créez le colorbar
essayez d'utiliser les paramètres de fraction et/ou de réduction.
Parmi les documents:
fraction 0,15; fraction d'axes d'origine à utiliser pour la barre de couleur
rétrécir 1,0; fraction par laquelle réduire la barre de couleur
Toutes les solutions ci-dessus sont bonnes, mais j'aime bien @ Steve's et @ bejota's car ils n'impliquent pas d'appels sophistiqués et sont universels.
Par universel, je veux dire qui fonctionne avec tout type d’axes, y compris GeoAxes
. Par exemple, si vous avez projeté des axes pour la cartographie:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
un appel à
cax = divider.append_axes("right", size=width, pad=pad)
échouera avec: KeyException: map_projection
Par conséquent, la seule façon universelle de traiter la taille de la barre de couleur avec tous les types d’axes est la suivante:
ax.colorbar(im, fraction=0.046, pad=0.04)
Travaillez avec des fractions de 0,035 à 0,046 pour obtenir la meilleure taille. Cependant, les valeurs de la fraction et de la valeur paddig devront être ajustées pour obtenir le meilleur ajustement possible pour votre tracé et différeront selon que l'orientation de la barre de couleur est en position verticale ou horizontale.
J'apprécie toutes les réponses ci-dessus. Cependant, comme certaines réponses et commentaires l'ont souligné, le module axes_grid1
ne peut pas traiter les fichiers GeoAxes, tandis que l'ajustement de fraction
, pad
, shrink
et d'autres paramètres similaires ne peuvent pas nécessairement donner la ordre précis, ce qui me dérange vraiment. Je pense que donner à la colorbar
sa propre axes
pourrait être une meilleure solution pour résoudre tous les problèmes mentionnés.
import matplotlib.pyplot as plt
import numpy as np
fig=plt.figure()
ax = plt.gca()
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)