Как иметь одну цветовую панель для всех вложенных графиков
Я потратил слишком много времени на изучение того, как заставить два вложенных графика использовать одну и ту же ось y с одной цветовой полосой, разделяемой между ними в Matplotlib.
Что происходило, так это то, что когда я вызывал colorbar() функцию в любом из subplot1 или subplot2, она автоматически масштабировала график таким образом, чтобы цветовая полоса плюс график помещались внутри ограничивающей рамки "подзаголовка", в результате чего два соседних графика имели два очень разных размера.
Чтобы обойти это, я попытался создать третий подзаголовок, который затем взломал для рендеринга без графика с присутствием только цветовой полосы. Единственная проблема в том, что теперь высота и ширина двух графиков неравномерны, и я не могу понять, как сделать так, чтобы это выглядело нормально.
Вот мой код:
from __future__ import division import matplotlib.pyplot as plt import numpy as np from matplotlib import patches from matplotlib.ticker import NullFormatter
# SIS Functions TE = 1# Einstein radius g1 = lambda x,y: (TE/2) * (y**2-x**2)/((x**2+y**2)**(3/2)) g2 = lambda x,y: -1*TE*x*y / ((x**2+y**2)**(3/2)) kappa = lambda x,y: TE / (2*np.sqrt(x**2+y**2))
coords = np.linspace(-2,2,400) X,Y = np.meshgrid(coords,coords) g1out = g1(X,Y) g2out = g2(X,Y) kappaout = kappa(X,Y) for i inrange(len(coords)): for j inrange(len(coords)): if np.sqrt(coords[i]**2+coords[j]**2) <= TE: g1out[i][j]=0 g2out[i][j]=0
Обратите внимание, что цветовой диапазон будет задан последним нанесенным изображением (которое привело к im), даже если диапазон значений задан с помощью vmin и vmax. Если другой график имеет, например, более высокое максимальное значение, точки с более высокими значениями, чем максимальное значение im, будут отображаться однородным цветом.
Ответ 2
Вы можете упростить код Джо Кингтона, используя axпараметр figure.colorbar() со списком осей. Из документации:
топор
Нет объекта (объектов) родительских осей, из которого будет украдено место для новых осей цветовой панели. Если указан список осей, все они будут изменены, чтобы освободить место для осей цветовой панели.
import numpy as np import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=2) for ax in axes.flat: im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)
fig.colorbar(im, ax=axes.ravel().tolist())
plt.show()
Ответ 3
Это решение не требует ручной настройки расположения осей или размера цветовой панели, работает с многорядными и однорядными макетами, а также работает с tight_layout(). Он адаптирован на основе примера из галереи с использованием ImageGrid из matplotlib AxesGrid Toolbox.
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1 import ImageGrid
# Set up figure and image grid fig = plt.figure(figsize=(9.75, 3))
grid = ImageGrid(fig, 111, # as in plt.subplot(111) nrows_ncols=(1,3), axes_pad=0.15, share_all=True, cbar_location="right", cbar_mode="single", cbar_size="7%", cbar_pad=0.15, )
# Add data to image grid for ax in grid: im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)
#plt.tight_layout() # Works, but may still require rect paramater to keep colorbar labels visible plt.show()
Ответ 4
Использование make_axes еще проще и дает лучший результат. Также предоставляет возможности настройки расположения цветовой панели. Также обратите внимание на возможность subplots использовать общие оси x и y.
import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl
fig, axes = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True) for ax in axes.flat: im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)
cax,kw = mpl.colorbar.make_axes([ax for ax in axes.flat]) plt.colorbar(im, cax=cax, **kw)