[python] matplotlib 서브 플로트에 대한 일반적인 xlabel / ylabel

나는 다음과 같은 줄거리를 가지고있다 :

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

이제이 플롯에 일반적인 x 축 레이블과 y 축 레이블을 지정하고 싶습니다. “공통”을 사용하면 서브 플롯의 전체 그리드 아래에 하나의 큰 x 축 레이블이 있고 오른쪽에 하나의 큰 y 축 레이블이 있어야합니다. 에 대한 문서에서 이것에 대해 아무것도 찾을 수 없으며 plt.subplots, 인터넷 검색을 통해 큰 plt.subplot(111)것을 만들어야한다고 제안 하지만 5 * 2 하위 플로트를 plt.subplots어떻게 사용 합니까?



답변

이것은 실제로 원하는 것 같습니다. 이 답변 의 동일한 접근 방식을 특정 사례에 적용합니다 .

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True, figsize=(6, 6))

fig.text(0.5, 0.04, 'common X', ha='center')
fig.text(0.04, 0.5, 'common Y', va='center', rotation='vertical')

공통 축 레이블이있는 여러 플롯


답변

텍스트를 배치하기 위해 좌표를 지정할 필요가없는 관련성과 우아함을 고려하기 때문에 다른 관련 질문에 대한 답변을 약간 수정하여 복사 합니다.

import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, sharex=True, sharey=True, figsize=(6,15))
# add a big axis, hide frame
fig.add_subplot(111, frameon=False)
# hide tick and tick label of the big axis
plt.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False)
plt.xlabel("common X")
plt.ylabel("common Y")

결과는 다음과 같습니다 (matplotlib 버전 2.2.0 사용).

공통 x 및 y 축 레이블이있는 5 개의 행 및 2 개의 열 서브 플롯


답변

sharex=True, sharey=True당신이 하지 않으면 :

여기에 이미지 설명을 입력하십시오

그것으로 당신은 그것을 더 잘해야합니다 :

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))

plt.tight_layout()

여기에 이미지 설명을 입력하십시오

그러나 레이블을 더 추가하려면 가장자리 플롯에만 레이블을 추가해야합니다.

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))
        if i == len(axes2d) - 1:
            cell.set_xlabel("noise column: {0:d}".format(j + 1))
        if j == 0:
            cell.set_ylabel("noise row: {0:d}".format(i + 1))

plt.tight_layout()

여기에 이미지 설명을 입력하십시오

각 플롯에 레이블을 추가하면 레이블이 손상 될 수 있습니다 (반복 된 레이블을 자동으로 감지하는 방법이있을 수 있지만 알 수는 없습니다).


답변

명령 이후 :

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

당신은 (내가 변경 한 것을 마음처럼 뭔가를 이미 충분하다, 튜플은 그림과 축 인스턴스의 목록으로 구성된 수익률을 사용 fig,axfig,axes) :

fig,axes = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

for ax in axes:
    ax.set_xlabel('Common x-label')
    ax.set_ylabel('Common y-label')

특정 서브 플롯에서 일부 세부 사항을 변경하려는 경우 서브 플롯을 반복하는 axes[i]위치 를 통해 액세스 할 수 있습니다 i.

포함하는 것이 매우 도움이 될 수 있습니다.

fig.tight_layout()

plt.show()라벨이 겹치지 않도록 파일 끝에서 .


답변

왼쪽 하단에서 서브 플롯에 보이지 않는 레이블을 만들어 공통 레이블을위한 공간을 확보하면 더 나아질 것입니다. rcParams에서 fontsize를 전달하는 것도 좋습니다. 이런 식으로 공통 레이블은 rc 설정에 따라 크기가 변경되고 공통 레이블을위한 공간을 남겨 두도록 축도 조정됩니다.

fig_size = [8, 6]
fig, ax = plt.subplots(5, 2, sharex=True, sharey=True, figsize=fig_size)
# Reserve space for axis labels
ax[-1, 0].set_xlabel('.', color=(0, 0, 0, 0))
ax[-1, 0].set_ylabel('.', color=(0, 0, 0, 0))
# Make common axis labels
fig.text(0.5, 0.04, 'common X', va='center', ha='center', fontsize=rcParams['axes.labelsize'])
fig.text(0.04, 0.5, 'common Y', va='center', ha='center', rotation='vertical', fontsize=rcParams['axes.labelsize'])

여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오


답변

그래프 그리드를 그릴 때 비슷한 문제가 발생했습니다. 그래프는 두 부분 (상단 및 하단)으로 구성됩니다. y- 라벨은 두 부분의 중앙에 위치해야했습니다.

외부 그림의 위치를 ​​아는 것에 의존하는 솔루션을 사용하고 싶지 않았으므로 (figure.text ()와 같이) set_ylabel () 함수의 y 위치를 조작했습니다. 일반적으로 플롯의 중간에 0.5가 추가됩니다. 내 코드에서 부분 (hspace) 사이의 패딩이 0이므로 두 부분 중 중간 부분을 위쪽 부분을 기준으로 계산할 수 있습니다.

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

# Create outer and inner grid
outerGrid = gridspec.GridSpec(2, 3, width_ratios=[1,1,1], height_ratios=[1,1])
somePlot = gridspec.GridSpecFromSubplotSpec(2, 1,
               subplot_spec=outerGrid[3], height_ratios=[1,3], hspace = 0)

# Add two partial plots
partA = plt.subplot(somePlot[0])
partB = plt.subplot(somePlot[1])

# No x-ticks for the upper plot
plt.setp(partA.get_xticklabels(), visible=False)

# The center is (height(top)-height(bottom))/(2*height(top))
# Simplified to 0.5 - height(bottom)/(2*height(top))
mid = 0.5-somePlot.get_height_ratios()[1]/(2.*somePlot.get_height_ratios()[0])
# Place the y-label
partA.set_ylabel('shared label', y = mid)

plt.show()

그림

단점 :

  • 플롯까지의 수평 거리는 상단 부분을 기준으로하며 하단 눈금은 레이블로 확장 될 수 있습니다.

  • 공식은 부품 사이의 공간을 고려하지 않습니다.

  • 상단 부분의 높이가 0 인 경우 예외가 발생합니다.

그림 사이에 패딩을 고려한 일반적인 솔루션이있을 수 있습니다.


답변

최신 정보:

이 기능은 이제 최근에 pypi에서 릴리스 한 proplot matplotlib 패키지의 일부입니다 . 기본적으로 그림을 만들 때 레이블은 축간에 “공유”됩니다.


원래 답변 :

더 강력한 방법을 발견했습니다.

당신이 알고있는 경우 bottomtop에 갔다 kwargs로 GridSpec초기화하거나, 그렇지 않으면 당신의 축 가장자리 위치 알 Figure좌표를 , 당신은 또한에 ylabel 위치를 지정할 수 있습니다 Figure약간의 공상과 좌표를 마법을 “변환”. 예를 들면 다음과 같습니다.

import matplotlib.transforms as mtransforms
bottom, top = .1, .9
f, a = plt.subplots(nrows=2, ncols=1, bottom=bottom, top=top)
avepos = (bottom+top)/2
a[0].yaxis.label.set_transform(mtransforms.blended_transform_factory(
       mtransforms.IdentityTransform(), f.transFigure # specify x, y transform
       )) # changed from default blend (IdentityTransform(), a[0].transAxes)
a[0].yaxis.label.set_position((0, avepos))
a[0].set_ylabel('Hello, world!')

여전히 레이블 이 왼쪽과 오른쪽 으로 적절히 조정 되어 눈금 레이블 과 겹치지 않도록 정상과 마찬가지로 항상 원하는 서브 플로트 사이 에서 정확하게 조정됩니다 .

또한조차 사용하지 않으면 set_positionylabel은 기본적으로 그림의 절반에 정확하게 나타납니다 . 레이블이 마지막으로 그려 질 때 기본 좌표 변환이 변경되었는지 여부를 확인하지 않고-좌표에 matplotlib0.5를 사용 하기 때문 y입니다.