235 votes

Définir la taille de la barre de couleur Matplotlib pour qu'elle corresponde au graphique

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 ? Example of the colorbar size mismatch

287voto

bejota Points 1749

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é.

248voto

bogatron Points 4412

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)

enter image description here

55voto

Fei Yao Points 884

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

enter image description here

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

enter image description here

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

enter image description here

43voto

Matthias Points 177

@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.

image plot with colorbar

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)

14voto

Steve Barnes Points 9505

Lorsque vous créez le colorbar essayez d'utiliser les paramètres de fractionnement et/ou de rétrécissement.

D'après les documents :

fraction 0.15 ; fraction des axes originaux à utiliser pour la barre de couleur

shrink 1.0 ; fraction par laquelle réduire la barre de couleur

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X