No puedo obtener la barra de color en gráficos como este para que tenga la misma altura que el gráfico, salvo el uso de Photoshop después del hecho. ¿Cómo consigo que coincidan las alturas?
No puedo obtener la barra de color en gráficos como este para que tenga la misma altura que el gráfico, salvo el uso de Photoshop después del hecho. ¿Cómo consigo que coincidan las alturas?
Respuestas:
Puede hacerlo fácilmente con un matplotlib AxisDivider .
El ejemplo de la página vinculada también funciona sin usar subtramas:
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
, se mostrará intercambiado a la derecha. ¿Hay una manera de superar esto?
Esta combinación (y valores cercanos a estos) parece funcionar "mágicamente" para mí para mantener la barra de colores ajustada a la trama, sin importar el tamaño de la pantalla.
plt.colorbar(im,fraction=0.046, pad=0.04)
Tampoco requiere compartir el eje que puede sacar la trama de forma cuadrada.
im_ratio = data.shape[0]/data.shape[1]
plt.colorbar(im,fraction=0.046*im_ratio, pad=0.04)
dónde data
está su imagen.
@bogatron ya dio la respuesta sugerida por los documentos matplotlib , que produce la altura correcta, pero presenta un problema diferente. Ahora, el ancho de la barra de colores (así como el espacio entre la barra de colores y el gráfico) cambia con el ancho del gráfico. En otras palabras, la relación de aspecto de la barra de colores ya no está fija.
Para obtener la altura correcta y una relación de aspecto dada, debes profundizar un poco más en el misterioso axes_grid1
módulo.
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)
Tenga en cuenta que esto especifica el ancho de la barra de colores y la altura del gráfico (en contraste con el ancho de la figura, como era antes).
El espacio entre la barra de colores y la gráfica ahora se puede especificar como una fracción del ancho de la barra de colores, que en mi humilde opinión es un número mucho más significativo que una fracción del ancho de la figura.
ACTUALIZAR:
He creado un cuaderno de IPython sobre el tema , en el que lleno el código anterior en función de un lugar fácilmente reutilizable:
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)
Se puede usar así:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Agradezco todas las respuestas anteriores. Sin embargo, como señalaron algunas respuestas y comentarios, el axes_grid1
módulo no puede abordar GeoAxes, mientras que al ajustar fraction
,pad
, shrink
, y otros parámetros similares puede no necesariamente dar la orden muy precisa, lo que realmente me molesta. Creo que dar el colorbar
suyo propio axes
podría ser una mejor solución para abordar todos los problemas que se han mencionado.
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)
Más tarde, encuentro matplotlib.pyplot.colorbar
la documentación oficial también daax
opción, que son ejes existentes que proporcionarán espacio para la barra de colores. Por lo tanto, es útil para múltiples subtramas, vea a continuación.
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)
De nuevo, también puede lograr efectos similares especificando cax, una forma más precisa desde mi perspectiva.
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)
Cuando creas el colorbar
intento, use los parámetros de fracción y / o reducción.
De los documentos:
fracción 0,15; fracción de ejes originales para usar para la barra de colores
reducir 1.0; fracción por la cual reducir la barra de colores
colorbar()
función o método.
Todas las soluciones anteriores son buenas, pero me gustan las mejores de @ Steve y @ bejota, ya que no implican llamadas elegantes y son universales.
Por universal quiero decir que funciona con cualquier tipo de ejes incluidos GeoAxes
. Por ejemplo, si ha proyectado ejes para el mapeo:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
una llamada a
cax = divider.append_axes("right", size=width, pad=pad)
fallará con: KeyException: map_projection
Por lo tanto, la única forma universal de tratar el tamaño de la barra de colores con todos los tipos de ejes es:
ax.colorbar(im, fraction=0.046, pad=0.04)
Trabaja con una fracción de 0.035 a 0.046 para obtener tu mejor tamaño. Sin embargo, los valores para la fracción y el paddig deberán ajustarse para obtener el mejor ajuste para su gráfico y diferirán dependiendo de si la orientación de la barra de colores está en posición vertical u horizontal.
shrink
parámetros cuando, fraction
junto con pad
no producir los resultados deseados lo suficiente.