Я не могу получить colorbar на графиках imshow, как этот, чтобы быть той же высотой, что и график, не используя Photoshop после факта. Как получить высоту, чтобы соответствовать?
Установите цветной размер матрицы Matplotlib для соответствия графику
Ответ 1
Вы можете сделать это легко с помощью matplotlib AxisDivider.
Пример со связанной страницы также работает без использования подзаголовков:
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)
Ответ 2
Эта комбинация (и значения, близкие к этим), кажется, "магически" работает для меня, чтобы сохранить цветную шкалу, масштабированную до графика, независимо от размера дисплея.
plt.colorbar(im,fraction=0.046, pad=0.04)
Он также не требует совместного использования оси, которая может получить график из квадрата.
Ответ 3
@bogatron уже дал ответ, предложенный matplotlib docs, который создает правильную высоту, но представляет собой другую проблему. Теперь ширина цветной панели (а также пространство между цветом и сюжетом) изменяется с шириной графика. Другими словами, соотношение сторон цветовой панели больше не фиксируется.
Чтобы получить как правильную высоту, так и заданное соотношение сторон, вам нужно углубиться в загадочный модуль 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)
Обратите внимание, что это указывает ширину цветовой панели w.r.t. высота графика (в отличие от ширины фигуры, как это было раньше).
Интервал между цветовой панелью и графикой теперь может быть задан как часть ширины цветной панели, что является ИМХО гораздо более значимым числом, чем доля ширины фигуры.
UPDATE:
Я создал IPython ноутбук по теме, где я упаковал вышеуказанный код в легко повторно используемую функцию:
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)
Его можно использовать следующим образом:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Ответ 4
При создании colorbar
попробуйте использовать параметры фракции и/или сжатия.
Из документов:
доля 0,15; доля исходных осей для использования в colorbar
уменьшить 1,0; фракция, с помощью которой можно уменьшить цветовую гамму
Ответ 5
Все вышеперечисленные решения хороши, но мне нравится @Steve и @bejota лучшее, поскольку они не связаны с причудливыми вызовами и универсальны.
Универсальным я имею в виду, что работает с любым типом осей, включая GeoAxes
. Например, у вас есть проецируемые оси для отображения:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
вызов
cax = divider.append_axes("right", size=width, pad=pad)
сбой: KeyException: map_projection
Таким образом, единственный универсальный способ определения размера цветной панели со всеми типами осей:
ax.colorbar(im, fraction=0.046, pad=0.04)
Работайте с долей от 0,035 до 0,046, чтобы получить максимальный размер. Тем не менее, значения для фракции и paddig должны быть скорректированы, чтобы наилучшим образом соответствовать вашему сюжету и будут отличаться в зависимости от того, будет ли ориентация цветной панели вертикальной или горизонтальной.
Ответ 6
Я ценю все ответы выше. Однако, как и некоторые ответы и комментарии указали, axes_grid1
модуль не может решить GeoAxes, тогда как регулировка fraction
, pad
, shrink
, и другие подобные параметры не обязательно могут дать очень точный порядок, который действительно беспокоит меня. Я считаю, что предоставление colorbar
собственных axes
может быть лучшим решением для решения всех проблем, которые были упомянуты.
Код
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)