Я потратил слишком много времени на изучение того, как получить два вспомогательных участка, чтобы совместно использовать одну и ту же ось 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 in range(len(coords)):
for j in range(len(coords)):
if np.sqrt(coords[i]**2+coords[j]**2) <= TE:
g1out[i][j]=0
g2out[i][j]=0
fig = plt.figure()
fig.subplots_adjust(wspace=0,hspace=0)
# subplot number 1
ax1 = fig.add_subplot(1,2,1,aspect='equal',xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{1}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
plt.ylabel(r"y ($\theta_{E}$)",rotation='horizontal',fontsize="15")
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.imshow(g1out,extent=(-2,2,-2,2))
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
e1 = patches.Ellipse((0,0),2,2,color='white')
ax1.add_patch(e1)
# subplot number 2
ax2 = fig.add_subplot(1,2,2,sharey=ax1,xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{2}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
ax2.yaxis.set_major_formatter( NullFormatter() )
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
plt.imshow(g2out,extent=(-2,2,-2,2))
e2 = patches.Ellipse((0,0),2,2,color='white')
ax2.add_patch(e2)
# subplot for colorbar
ax3 = fig.add_subplot(1,1,1)
ax3.axis('off')
cbar = plt.colorbar(ax=ax2)
plt.show()
источник
vmin
иvmax
аргументы имеют решающее значение. Они контролируют цветовую гамму каждого участка. Если у вас есть реальные данные, вам может понадобиться пройти через это, чтобы сначала найти минимальное и максимальное значения.Вы можете упростить код Джо Кингтона, используя
ax
параметрfigure.colorbar()
со списком осей. Из документации :источник
fig.colorbar(im, ax=axes.ravel().tolist())
. Если вы пропуститеax=axes.ravel().tolist()
, цветовая шкала будет размещена в пределах одного субплота.Это решение не требует ручной настройки расположения осей или размера цветовой шкалы, работает с многорядными и однорядными макетами и работает с ними
tight_layout()
. Он адаптирован из примера галереи , используяImageGrid
набор инструментов AxesGrid от matplotlib .источник
thecb = ax.cax.colorbar(im)
. Тогда вы можете сделатьthecb.set_label_text("foo")
Использование
make_axes
еще проще и дает лучший результат. Он также предоставляет возможность настроить расположение цветовой панели. Также обратите внимание на возможностьsubplots
совместного использования осей X и Y.источник
nrows=1
, цветовая шкала снова станет больше, чем субплоты.Как новичок, который наткнулся на эту ветку, я хотел бы добавить адаптацию python-for-dummies очень аккуратного ответа abevieiramota (потому что я нахожусь на том уровне, на котором мне пришлось искать 'ravel', чтобы понять, что их код делал)
Намного менее питонно, для таких нубов, как я, гораздо проще увидеть, что на самом деле здесь происходит.
источник
Как указывалось в других ответах, идея обычно состоит в том, чтобы определить оси, в которых должна находиться цветовая панель. Существуют различные способы сделать это; тот, который еще не был упомянут, - это непосредственное указание осей цветовой полосы при создании подзаговора с помощью
plt.subplots()
. Преимущество состоит в том, что положение осей не нужно устанавливать вручную, и во всех случаях с автоматическим аспектом цветовая полоса будет точно такой же высоты, что и вспомогательные участки. Даже во многих случаях, когда используются изображения, результат будет удовлетворительным, как показано ниже.При использовании
plt.subplots()
использованиеgridspec_kw
аргумента позволяет сделать оси цветовой панели намного меньше, чем другие оси.Пример:
Это хорошо работает, если аспект графиков автоматически масштабируется или изображения сжимаются из-за их аспекта в направлении ширины (как показано выше). Однако, если изображения шире, чем высоко, результат будет выглядеть следующим образом, что может быть нежелательным.
Решение для фиксации высоты цветовой шкалы к высоте подплота состояло бы в том, чтобы использовать
mpl_toolkits.axes_grid1.inset_locator.InsetPosition
для установки осей цветовой полосы относительно осей подплота изображения.источник
ax = fig.add_subplot()
вместо этого? Я спрашиваю, потому что я не могу понять, как использовать его с базовой картой.GridSpec
кadd_subplot()
в этом случае.Решение использования списка осей с помощью abevieiramota работает очень хорошо, пока вы не используете только один ряд изображений, как указано в комментариях. Использование разумного соотношения сторон для
figsize
подсказок, но все еще далеко от совершенства. Например:Функция colorbar предоставляет
shrink
параметр, который является масштабным коэффициентом для размера осей colorbar. Это требует ручной проб и ошибок. Например:источник
Чтобы добавить к отличному ответу @ abevieiramota, вы можете получить euqivalent of Proper_layout с constrained_layout. Вы все равно получите большие горизонтальные промежутки, если будете использовать
imshow
вместо из-pcolormesh
за соотношения сторон 1: 1imshow
.источник
Я заметил, что почти каждое опубликованное решение включало
ax.imshow(im, ...)
и не нормализовало цвета, отображаемые на цветовой панели для нескольких подфигур.im
Картографически берется из последней инстанции, но что , если значения множестваim
-s разные? (Я предполагаю, что эти сопоставляемые объекты обрабатываются так же, как обрабатываются наборы контуров и наборы поверхностей.) У меня есть пример с использованием трехмерного графика поверхности ниже, который создает две цветовые полосы для субплота 2x2 (по одной цветовой полосе на одну строку). ). Хотя вопрос явно требует другой договоренности, я думаю, что пример помогает прояснить некоторые вещи. Я не нашел способа сделать это, используя,plt.subplots(...)
к сожалению, из-за 3D-осей.Если бы я только мог лучше расположить цветные полосы ... (Возможно, есть гораздо лучший способ сделать это, но, по крайней мере, это не должно быть слишком сложным для подражания.)
источник
im
s различны, они не должны использовать одну и ту же цветную полосу, поэтому исходный вопрос на самом деле не применимЭта тема хорошо освещена, но я все же хотел бы предложить другой подход в несколько иной философии.
Это немного сложнее в настройке, но это позволяет (на мой взгляд) немного больше гибкости. Например, можно играть с соответствующими соотношениями каждого субплота / цветовой шкалы:
источник