Não consigo fazer com que a barra de cores em gráficos de exibição como esta tenha a mesma altura do gráfico, sem usar o Photoshop depois do fato. Como faço para combinar as alturas?
Não consigo fazer com que a barra de cores em gráficos de exibição como esta tenha a mesma altura do gráfico, sem usar o Photoshop depois do fato. Como faço para combinar as alturas?
Respostas:
Você pode fazer isso facilmente com um AxisDivider matplotlib .
O exemplo da página vinculada também funciona sem o uso de 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
, ele será exibido trocado para a direita. Existe uma maneira de superar isso?
Essa combinação (e valores próximos a esses) parece funcionar "magicamente" para manter a barra de cores dimensionada para o gráfico, independentemente do tamanho da exibição.
plt.colorbar(im,fraction=0.046, pad=0.04)
Também não requer o compartilhamento do eixo que pode obter o gráfico fora do quadrado.
im_ratio = data.shape[0]/data.shape[1]
plt.colorbar(im,fraction=0.046*im_ratio, pad=0.04)
onde data
está sua imagem.
O @bogatron já deu a resposta sugerida pelos documentos do matplotlib , que produz a altura certa, mas apresenta um problema diferente. Agora, a largura da barra de cores (assim como o espaço entre a barra de cores e a plotagem) muda com a largura da plotagem. Em outras palavras, a proporção da barra de cores não é mais fixa.
Para obter a altura correta e uma determinada proporção, você precisa se aprofundar um pouco no 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)
Observe que isso especifica a largura da barra de cores e a altura do gráfico (em contraste com a largura da figura, como era antes).
O espaçamento entre a barra de cores e o gráfico agora pode ser especificado como uma fração da largura da barra de cores, que é um número muito mais significativo do que uma fração da largura da figura.
ATUALIZAR:
Criei um bloco de notas IPython sobre o tópico , onde agrupei o código acima em uma função facilmente reutilizável:
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)
Pode ser usado assim:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Agradeço todas as respostas acima. No entanto, como algumas respostas e comentários apontou, o axes_grid1
módulo pode não GeoAxes de endereços, enquanto ajustando fraction
, pad
, shrink
, e outros parâmetros semelhantes podem não necessariamente dar a ordem muito precisa, o que realmente me incomoda. Acredito que dar o que é colorbar
seu axes
pode ser uma solução melhor para resolver todos os problemas mencionados.
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)
Mais tarde, acho que matplotlib.pyplot.colorbar
a documentação oficial também oferece a ax
opção, que são eixos existentes que fornecerão espaço para a barra de cores. Portanto, é útil para várias subparcelas, veja a seguir.
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)
Novamente, você também pode obter efeitos semelhantes especificando cax, uma maneira mais precisa da minha 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)
Quando você cria a colorbar
tentativa usando os parâmetros de fração e / ou contração.
Dos documentos:
fração 0,15; fração dos eixos originais a serem usados na barra de cores
encolher 1,0; fração pela qual diminuir a barra de cores
colorbar()
função ou método.
Todas as soluções acima são boas, mas eu gosto da @ Steve e da @ bejota as melhores, pois não envolvem chamadas sofisticadas e são universais.
Por universal, quero dizer que funciona com qualquer tipo de eixo, inclusive GeoAxes
. Por exemplo, você projetou eixos para mapeamento:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
uma chamada para
cax = divider.append_axes("right", size=width, pad=pad)
falhará com: KeyException: map_projection
Portanto, a única maneira universal de lidar com o tamanho da barra de cores com todos os tipos de eixos é:
ax.colorbar(im, fraction=0.046, pad=0.04)
Trabalhe com fração de 0,035 a 0,046 para obter o melhor tamanho. No entanto, os valores para a fração e o paddig precisarão ser ajustados para obter o melhor ajuste para sua plotagem e variarão dependendo se a orientação da barra de cores estiver na posição vertical ou horizontal.
shrink
parâmetros quando, em fraction
conjunto pad
, não produzem os resultados desejados o suficiente.