Matplotlib에서 두 개의 서브 플로트를 사용하여 동일한 y 축을 하나의 컬러 막대로 공유하는 방법을 연구하는 데 너무 오랜 시간을 보냈습니다.
무슨 일이 있었 는지 또는 에서 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()
답변
컬러 바를 자체 축 subplots_adjust
에 놓고 공간을 확보하는 데 사용 하십시오.
간단한 예를 들면 다음과 같습니다.
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.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)
plt.show()
색상 범위가 마지막 이미지로 설정한다는 주 (초래했다 그 플롯 im
값의 범위로 설정되어있는 경우에도) vmin
와 vmax
. 예를 들어 다른 플롯에 최대 값이 높으면 최대 값보다 높은 값을 가진 점이 im
균일 한 색상으로 표시됩니다.
답변
축 목록과 함께 ax
매개 변수를 사용하여 Joe Kington의 코드를 단순화 할 수 있습니다 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()
답변
이 솔루션은 축 위치 또는 색상 막대 크기를 수동으로 조정할 필요가 없으며 여러 행 및 단일 행 레이아웃과 함께 작동합니다 tight_layout()
. matplotlib의 AxesGrid Toolbox를 사용하여 갤러리 예제 에서 수정되었습니다 .ImageGrid
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)
# Colorbar
ax.cax.colorbar(im)
ax.cax.toggle_label(True)
#plt.tight_layout() # Works, but may still require rect paramater to keep colorbar labels visible
plt.show()
답변
사용 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)
plt.show()
답변
이 스레드를 우연히 발견 한 초보자로서 abevieiramota 의 매우 깔끔한 답변에 대한 Python-for-dummies 적응을 추가하고 싶습니다. 그들의 코드는하고 있었다) :
import numpy as np
import matplotlib.pyplot as plt
fig, ((ax1,ax2,ax3),(ax4,ax5,ax6)) = plt.subplots(2,3)
axlist = [ax1,ax2,ax3,ax4,ax5,ax6]
first = ax1.imshow(np.random.random((10,10)), vmin=0, vmax=1)
third = ax3.imshow(np.random.random((12,12)), vmin=0, vmax=1)
fig.colorbar(first, ax=axlist)
plt.show()
pythonic이 훨씬 적고, 나와 같은 멍청한 놈들이 실제로 무슨 일이 일어나고 있는지 쉽게 알 수 있습니다.
답변
다른 답변에서 지적했듯이 아이디어는 일반적으로 컬러 바가 상주 할 축을 정의하는 것입니다. 다양한 방법이 있습니다. 아직 언급되지 않은 것은 서브 플롯 생성시 컬러 바 축을 직접 지정하는 것입니다 plt.subplots()
. 이점은 축 위치를 수동으로 설정할 필요가 없으며 자동 종횡비를 사용하는 경우 모든 색상 막대가 서브 플로트와 정확히 동일한 높이가됩니다. 이미지가 많이 사용되는 경우에도 결과는 다음과 같이 만족 스럽습니다.
사용하는 경우 plt.subplots()
, 사용 gridspec_kw
인수는 다른 축보다 년 Colorbar 축이 훨씬 작게 만들 수 있습니다.
fig, (ax, ax2, cax) = plt.subplots(ncols=3,figsize=(5.5,3),
gridspec_kw={"width_ratios":[1,1, 0.05]})
예:
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
fig, (ax, ax2, cax) = plt.subplots(ncols=3,figsize=(5.5,3),
gridspec_kw={"width_ratios":[1,1, 0.05]})
fig.subplots_adjust(wspace=0.3)
im = ax.imshow(np.random.rand(11,8), vmin=0, vmax=1)
im2 = ax2.imshow(np.random.rand(11,8), vmin=0, vmax=1)
ax.set_ylabel("y label")
fig.colorbar(im, cax=cax)
plt.show()
플롯의 가로 세로 비율이 자동으로 조정되거나 가로 방향으로 가로 세로 비율로 인해 이미지가 축소되는 경우 (위와 같이) 잘 작동합니다. 그러나 이미지가 더 넓고 높으면 결과는 다음과 같으며 바람직하지 않을 수 있습니다.
하기 용액 부가 적 줄거리 높이로 년 Colorbar 높이를 수정 사용하는 것 mpl_toolkits.axes_grid1.inset_locator.InsetPosition
, 화상 부가 적 줄거리 축에 상대적인 년 Colorbar 축을 설정.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
from mpl_toolkits.axes_grid1.inset_locator import InsetPosition
fig, (ax, ax2, cax) = plt.subplots(ncols=3,figsize=(7,3),
gridspec_kw={"width_ratios":[1,1, 0.05]})
fig.subplots_adjust(wspace=0.3)
im = ax.imshow(np.random.rand(11,16), vmin=0, vmax=1)
im2 = ax2.imshow(np.random.rand(11,16), vmin=0, vmax=1)
ax.set_ylabel("y label")
ip = InsetPosition(ax2, [1.05,0,0.05,1])
cax.set_axes_locator(ip)
fig.colorbar(im, cax=cax, ax=[ax,ax2])
plt.show()
답변
abevieiramota 의 축 목록을 사용하는 솔루션은 주석에서 지적한 것처럼 한 행의 이미지 만 사용할 때까지 매우 잘 작동합니다. figsize
도움을 받기 위해 적절한 가로 세로 비율을 사용 하지만 여전히 완벽하지는 않습니다. 예를 들면 다음과 같습니다.
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
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()
년 Colorbar 함수 제공 shrink
년 Colorbar 축의 크기 스케일링 인자이다 파라미터. 수동 시험 및 오류가 필요합니다. 예를 들면 다음과 같습니다.
fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)