Je n'arrive pas à faire en sorte que la barre de couleur des graphiques imshow comme celui-ci soit de la même hauteur que le graphique, à moins d'utiliser Photoshop après coup. Comment faire pour que les hauteurs correspondent ?
Réponses
Trop de publicités?Cette combinaison (et des valeurs proches de celles-ci) semble fonctionner "magiquement" pour que la barre de couleur reste à l'échelle du graphique, quelle que soit la taille de l'écran.
plt.colorbar(im,fraction=0.046, pad=0.04)
Il n'est pas non plus nécessaire de partager l'axe, ce qui peut entraîner un déséquilibre du tracé.
Vous pouvez faire cela facilement avec un matplotlib AxisDivider .
L'exemple de la page liée fonctionne également sans utiliser de sous-plots :
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)
J'apprécie toutes les réponses ci-dessus. Cependant, comme l'ont souligné certaines réponses et certains commentaires, la axes_grid1
ne peut pas s'occuper des GeoAxes, alors que l'ajustement du module fraction
, pad
, shrink
et d'autres paramètres similaires ne peuvent pas nécessairement donner l'ordre très précis, ce qui me dérange vraiment. Je crois que le fait de donner l colorbar
son propre axes
pourrait être une meilleure solution pour résoudre tous les problèmes qui ont été mentionnés.
Code
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)
Résultat
Plus tard, je trouve matplotlib.pyplot.colorbar
documentation officielle donne également ax
qui sont des axes existants qui laisseront de la place à la barre de couleur. Elle est donc utile pour les sous-plots multiples, voir ci-dessous.
Code
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)
Résultat
Là encore, vous pouvez également obtenir des effets similaires en spécifiant cax, une méthode plus précise à mon avis.
Code
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)
Résultat
@bogatron a déjà donné la réponse suggérée par le docs matplotlib qui produit la bonne hauteur, mais qui introduit 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 d'aspect 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 dans le mystérieux axes_grid1
module.
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 cela spécifie le largeur de la barre de couleur par rapport au hauteur de la parcelle (contrairement à la largeur de la figure, comme auparavant).
L'espacement entre la barre de couleur et le graphique peut maintenant être spécifié comme une fraction de la largeur de la barre de couleur, ce qui est, à mon avis, un nombre beaucoup plus significatif qu'une fraction de la largeur de la figure.
UPDATE :
J'ai créé un notebook IPython sur le sujet où j'ai intégré 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 suit :
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
- Réponses précédentes
- Plus de réponses