[python] Matplotlib 2 서브 플로트, 1 컬러 바

Matplotlib에서 두 개의 서브 플로트를 사용하여 동일한 y 축을 하나의 컬러 막대로 공유하는 방법을 연구하는 데 너무 오랜 시간을 보냈습니다.

무슨 일이 있었 는지 또는 에서 colorbar()함수를 호출하면 플롯을 자동 스케일링하여 컬러 바와 플롯이 ‘서브 플롯’경계 상자 안에 들어가서 두 개의 나란히 플롯이 두 가지 매우 다르게 나타납니다. 크기.subplot1subplot2

이 문제를 해결하기 위해 세 번째 서브 플롯을 만들려고 시도했는데 컬러 바가있는 플롯을 렌더링하지 않기 위해 해킹했습니다. 유일한 문제는, 이제 두 플롯의 높이와 너비가 고르지 않으며, 어떻게 보이게 만드는지 알 수 없습니다.

내 코드는 다음과 같습니다.

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값의 범위로 설정되어있는 경우에도) vminvmax. 예를 들어 다른 플롯에 최대 값이 높으면 최대 값보다 높은 값을 가진 점이 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()

1


답변

이 솔루션은 축 위치 또는 색상 막대 크기를 수동으로 조정할 필요가 없으며 여러 행 단일 행 레이아웃과 함께 작동합니다 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이 훨씬 쉽고 더 나은 결과를 제공합니다. 또한 컬러 바의 위치를 ​​사용자 지정할 수 있습니다. 또한 subplotsx 및 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()

1 x 3 이미지 배열

년 Colorbar 함수 제공 shrink년 Colorbar 축의 크기 스케일링 인자이다 파라미터. 수동 시험 및 오류가 필요합니다. 예를 들면 다음과 같습니다.

fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)

축소 된 컬러 바가있는 1 x 3 이미지 배열