본문 바로가기

데이터와 함께 탱고를/데이터 시각화

pyplot 그래프의 범주박스 위치 변경하기

matplotlib.pyplot 그래프에서 범주(legend) 의 위치를 조정하고 싶을 때가 있다.

일반적으로, 범주는 다음과 같이 그린다.

print(df)

성별          F         M
년                       
2017  0.380887  0.619113
2018  0.372857  0.627143
df.plot(kind='barh', stacked=True, 
        title="년도별 남녀 이용비율", 
        rot=0, ax=axes[0], colors=['C1', 'C0'])
plt.show()

데이터의 프레임의 열(column) 에 맞춰 라벨(label)이 생기고, 별도로 옵션을 지정해주지 않으면 dataframe.plot() 은 알아서 그려준다.

문제는, 저 범주 박스를 내가 좀 커스터마이징해서, 좀 이쁘게하고 싶은데 어떻게 건드릴 수 있냐는 것이다.
이 글에서는, 저 범주 박스의 위치를 다루는 것에 대해서만 다룬다.
범주 박스 자체를 이쁘게 꾸미는 스타일링에 대해서는 아래 링크를 참고하길 바란다.

Customizing Plot Legends - Python Data Science Handbook

범주 위치 조정

범주를 다루는 pyplot 메쏘드는 일반적으로 다음을 쓴다.

plt.legend(loc, bbox_to_anchor, ...)

plt.legend? 하고 실행시키면 꽤나 많은 인자가 나올텐데, 여기서 우리는 2가지 인자만 다룬다. locbbox_to_anchor 이다.

1. loc, 바운딩 박스 안에서 위치 다루기

loc 인자는 미리 정해진 값들 중 하나를 고르면 된다. 정해진 값들은 다음과 같다.

Location String   Location Code
===============   =============
'best'            0
'upper right'     1
'upper left'      2
'lower left'      3
'lower right'     4
'right'           5
'center left'     6
'center right'    7
'lower center'    8
'upper center'    9
'center'          10
===============   =============

예를 들어,

plt.legend(loc='center left')
plt.show()

위와 같이, center left 로 값을 줄 경우, 가운데에서 왼쪽에 위치하게 된다. Location Code 가 6 이므로, loc = 6 으로 해도 동일하다.

하나만 더 해보자.
이번엔, upper right 를 넣어보자.

plt.legend(loc='upper right')
plt.show()

우측 상단 위에 간 것을 알 수 있다.

2. bbox_to_anchor, 바운딩 박스 밖에서 위치 다루기

bbox_to_anchor 가 어떻게 사용되는지 일단 결과부터 보자.

plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.show()

바운딩 박스 밖에 범주 박스가 위치한 것을 볼 수 있다.

먼저, 바운딩 박스 크기에 대해 이해해야 하는데, 아래 사진을 보자.

출처 : https://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot

다 필요없고, 파란색 글씨만 보자.
figure 박스는 가로, 세로 0~1의 좌표를 가진다. 수학시간에 배운 x,y 좌표계를 생각해보자. 왼쪽 하단부가 (0, 0) 이고, 오른쪽 하단부가 (1, 0)이다. 그럼 왼쪽 상단부가 (0, 1), 오른쪽 상단부가 (1, 1) 임을 알 수 있다.

자 이제 loc='center left', bbox_to_anchor=(1, 0.5) 을 해석하면, 다음과 같다.

figure box 기준 (1, 0.5) 의 좌표에 범주 박스를 위치시킬건데, (1, 0.5) 범주 박스기준 center left, 즉 가운데에서 왼쪽부분을 위치시켜라.

loc 으로 위치시키는 것과는 전혀 달라서 매우 헷갈릴 수 있다. (나도 많이 헷갈렸다.)
locloc 값을 figure box 기준으로 위치시켰다면,
bbox_to_anchor 는 그 값을 figure box 기준으로 위치시킨 후에, loc 값을 범주 박스 기준 어디에 anchor 할 것인지를 정한다.
즉 위치시킬 순서가 bbox_to_anchor 를 정한 후에, loc 을 정한다.

만약 범주박스를 상단부에 수평하게 두고싶다면, 다음과 같이 하면 된다.

plt.legend(loc='upper center', ncol=2, bbox_to_anchor=(0.5, 1))
plt.show()