본문 바로가기
데이터 분석/시각화

[범례(Legend)] 3. Matplotlib을 이용한 범례 그리기 - 범례 위치 바꾸기

by 부자 꽁냥이 2020. 7. 8.

안녕하세요~ 꽁냥이에요!

 

오늘은 Matplotlib을 이용한 범례 그리기 제3편으로 범례 위치 조절하는 방법을 알아볼 거예요. 1~2편에 대한 내용은 아래 링크를 참고하세요.

 

1. Matplotlib을 이용한 범례 그리기 - 기본

2. Matplotlib을 이용한 범례 그리기 - 텍스트 꾸미기

 

범례 위치를 조절하는 방법은 선 그래프와 바 차트가 동일합니다. 따라서 선 그래프를 위주로 설명하겠습니다.

 

 

범례는 다음 2가지 방식으로 설정할 수 있습니다.


1. 사전에 정의된 위치를 이용하는 방식

2. 좌표를 이용하는 방식


그럼 지금부터 하나씩 살펴볼까요?

LIST

   1. 사전에 정의된 위치를 이용하는 방식

먼저 데이터를 아래 코드를 통해 만들어줍니다.

 

## 데이터
import pandas as pd

df = pd.DataFrame()
df['days'] = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']*2 ## 요일
df['visits'] = [32,23,14,14,27,40,35,37,28,9,41,29,30,51] ## 방문 고객수
df['gender'] = ['male']*7 + ['female']*7 ## 성별

 

이제 사전에 정의된 위치를 이용하는 방식을 알아보겠습니다. 이 방식은 범례의 위치를 미리 정의해둔 문자 또는 코드번호를 이용하여 설정하는 것입니다.

 

Matplotlib에서 정의하고 있는 범례 위치 문자열코드 번호는 다음과 같아요.

 

이미지 출처 https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.legend.html

문자열이 'upper right'인 경우(또는 코드가 1인 경우) 범례를 프레임(axes) 기준으로 우측 상단에 그리겠다는 것이지요. 이런 식으로 코드 번호가 1~10번인 것들은 이름을 통해서 쉽게 유추할 수 있을 거예요.

 

여기서 궁금한 거는 'best'라는 친구인데, 이 친구는 1~10번 중에서 그래프와 최대한 겹치지 않는 위치를 정해준다고 하네요(참고자료).

 

의미를 알았으니 사용법을 알아봐야겠죠. 사용법은 다음과 같아요.


ax.legend(loc = 'upper right') 또는 ax.legend(loc = 1)


그럼 코드를 통해서 확인해볼까요?

 

## 범례 -위치
import matplotlib.pyplot as plt

## 성별 데이터 분리하기
male_df = df.query('gender =="male"') ## 남자 데이터
male_visits = male_df['visits'] ## 남자 방문자수
days = male_df['days'] ## 요일

female_df = df.query('gender == "female"') ## 여자 데이터
female_visits = female_df['visits'] ## 여자 방문자수

## 선그래프 그리기
fig = plt.figure(figsize=(8,8)) ## 캔버스 생성
fig.set_facecolor('white') ## 캔버스 색상 설정
ax = fig.add_subplot() ## 프레임(그림 뼈대) 생성

## 선 그래프 생성
ax.plot(days, male_visits, marker='o', label='male') 
ax.plot(days, female_visits, marker='o', label='female')

## 글씨 설정
prop = dict(
    family='fantasy', # 글씨체
    style='italic', # 글씨 형식 - 이탤릭형식
    size=14 # 글씨 크기
)

config_legend = dict(prop=prop)

ax.legend(loc = 'upper right', **config_legend) ## ax.legend(loc = 1, **config_legend)과 동일

plt.show()

line 30

범례를 우측 상단에 배치했습니다.

 

코드를 실행해볼까요?

 

실행 결과

범례가 우측 상단에 잘 표시되는 것을 확인할 수 있습니다.

반응형

아래는 바 차트에서 범례를 좌측 상단에 배치하는 코드입니다. 여기서는 문자열 대신 코드번호를 사용했습니다. 원리는 선 그래프의 경우와 똑같아서 설명은 생략하겠습니다.

 

## 범례 - 위치
import matplotlib.pyplot as plt
import seaborn as sns

## 성별 데이터 분리하기
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
total_df = df.groupby('days')['visits'].sum().reindex(days).reset_index() ## 데이터를 요일 순으로 정렬

## 바 차트 그리기
colors = sns.color_palette('hls',len(df)) ## 막대기 개수만큼 색상 지정

fig = plt.figure(figsize=(8,8)) ## 캔버스 생성
fig.set_facecolor('white') ## 캔버스 색상 설정
ax = fig.add_subplot() ## 프레임(그림 뼈대) 생성

## 바 차트 생성
bars = ax.bar(total_df['days'],total_df['visits'],color=colors) ## 그래프의 막대기를 모두 가져 온다.

## 글씨 설정
prop = dict(
    family='fantasy', # 글씨체
    style='italic', # 글씨 형식 - 이탤릭형식
    size=14 # 글씨 크기
)

config_legend = dict(
    handles=bars, ## 막대기 요소
    labels=list(total_df['days']), ## 범례 라벨
    prop=prop ## 폰트 속성
)

ax.legend(loc=2,**config_legend) ## 좌측 상단에 범례 배치

plt.show()

 

실행 결과

 

여기서 선 그래프와 바 차트 그리는 방법은 따로 설명하지 않았어요. 궁금하신 분들은 아래 링크를 참고하세요. 꽁냥이가 설명해놓은 포스팅이에요.

 

선 그래프 그리기 : 

 

[선 그래프(Line graph)] 1. Matplotlib을 이용하여 선 그래프 그리기

안녕하세요~ 꽁냥이에요. 이번에는 선 그래프를 그리는 방법에 대해서 알아보려고 해요. 꽁냥이는 이 주제에 대해서 다음과 같이 3편에 걸쳐서 소개할 거예요. 1. Matplotlib을 이용하여 선 그래프 �

zephyrus1111.tistory.com

바 차트 그리기 : 

 

[바 차트(Bar chart)] 1. Matplotlib을 이용하여 바 차트, 수평 바 차트 그리기

안녕하세요~ '꽁냥이'입니다. 이번 포스팅에서는 바 차트(Bar chart)를 그려보는 법에 대해서 알아볼 거예요. 꽁냥이는 "바 차트 그리기"에 대한 내용을 다음과 같이 5편에 걸쳐서 소개할 거예요. 1.

zephyrus1111.tistory.com


   2. 좌표를 이용하는 방식

이번에는 좌표를 이용하여 범례 위치를 조절해보겠습니다. 여기에는 두 가지 방법이 있어요.

 

먼저 첫 번째 방법은 다음과 같이 loc에 숫자 값을 2개 갖는 튜플로 지정하는 방식인데요.


loc = (숫자, 숫자)


아래 그림은 위 2개의 숫자가 의미하는 바를 나타낸 것입니다.

 

즉, 첫 번째 숫자는 원점으로부터 x축으로 범례 박스를 얼마나 이동시킬지 결정하는 값이고요. 그리고두 번째 숫자는 원점으로부터 y축으로 범례 박스를 얼마나 이동시킬지 결정하는 값이에요. 여기서 첫 번째 숫자와 두 번째 숫자는 범례 박스의 좌측 하단 부분이 위치할 곳을 정한다는 것을 기억하세요.

 

여기서 유의할 점이 있는데 그것은 바로 숫자의 범위인데요. 여기에서 중요한 것은 x축 전체를 0 ~ 1, y축 전체를 0 ~ 1이라고 놓고 숫자 2개의 값을 정하셔야 해요.

 

만약 loc인자에 (2, 3)을 넣었을 때 "아! 이건 x축의 방향으로 눈금 2칸을 이동하고 y축으로 눈금 3칸 이동하는 거구나"라고 생각하면 안 된다는 거죠. 아래 그림은 숫자 범위에 따라 범례 박스가 표시되는 영역을 나타낸 것이에요.

 

위 그림을 이해하셨다면 loc에 (2, 3)을 넣으면 오른쪽으로 멀리, 위쪽으로 아주 멀리 배치된다는 것을 직감할 수 있을 거예요.

 

그렇다면 여기서 나올 수 있는 질문은 "위 2개의 숫자에 적절한 범위는 어떻게 되는가?"일 것인데요.

사람마다 다르겠지만 꽁냥이가 생각하는 적절한 숫자의 범위는 2개 모두 -0.4 ~ 1.1 정도입니다.

 

이제 코드로 직접 확인해봐야겠죠? 아래 코드를 실행해주세요. 30번째 줄에 loc에 넣어준 숫자 2개를 주목하고 실행 결과를 보면 이해가 빠르실 거예요.

 

## 범례 -위치
import matplotlib.pyplot as plt

## 성별 데이터 분리하기
male_df = df.query('gender =="male"') ## 남자 데이터
male_visits = male_df['visits'] ## 남자 방문자수
days = male_df['days'] ## 요일

female_df = df.query('gender == "female"') ## 여자 데이터
female_visits = female_df['visits'] ## 여자 방문자수

## 선그래프 그리기
fig = plt.figure(figsize=(8,8)) ## 캔버스 생성
fig.set_facecolor('white') ## 캔버스 색상 설정
ax = fig.add_subplot() ## 프레임(그림 뼈대) 생성

## 선 그래프 생성
ax.plot(days, male_visits, marker='o', label='male') 
ax.plot(days, female_visits, marker='o', label='female')

## 글씨 설정
prop = dict(
    family='fantasy', # 글씨체
    style='italic', # 글씨 형식 - 이탤릭형식
    size=14 # 글씨 크기
)

config_legend = dict(prop=prop)

ax.legend(loc=(0.8,0.8),**config_legend) ## 범례
    
plt.show()

 

실행 결과

 

아래 그림은 loc인자에 다양한 값을 넣은 결과예요. 아래 그림을 참고하셔서 범례 위치를 조절할 때 각자 상황에 맞는 숫자를 정하면 됩니다.

 

loc 값에 따른 범례 위치

 

바 차트도 선 그래프와 동일하게 범례 위치를 조정할 수 있습니다. 32번째 줄의 숫자 값을 주목하세요.

 

## 범례 - 위치
import matplotlib.pyplot as plt
import seaborn as sns

## 성별 데이터 분리하기
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
total_df = df.groupby('days')['visits'].sum().reindex(days).reset_index() ## 데이터를 요일 순으로 정렬

## 바 차트 그리기
colors = sns.color_palette('hls',len(df)) ## 막대기 개수만큼 색상 지정

fig = plt.figure(figsize=(8,8)) ## 캔버스 생성
fig.set_facecolor('white') ## 캔버스 색상 설정
ax = fig.add_subplot() ## 프레임(그림 뼈대) 생성

## 바 차트 생성
bars = ax.bar(total_df['days'],total_df['visits'],color=colors) ## 그래프의 막대기를 모두 가져 온다.

## 글씨 설정
prop = dict(
    family='fantasy', # 글씨체
    style='italic', # 글씨 형식 - 이탤릭형식
    size=14 # 글씨 크기
)

config_legend = dict(
    handles=bars, ## 막대기 요소
    labels=list(total_df['days']), ## 범례 라벨
    prop=prop ## 폰트 속성
)

ax.legend(loc=(0.05,0.6),**config_legend) ## 범례

plt.show()

 

실행 결과

꽁냥이가 아까 전에 loc에 들어가는 숫자 두 개(x, y좌표)는 범례 박스의 좌측 하단의 위치를 결정한다고 했었던 거 기억 나시죠? 근데 필요에 따라서는 좌측 하단 외에 박스의 다른 부분을 위치시키고 싶을 때가 있을 거예요. 아래 그림처럼 말이죠.

 

놀랍게도 Matplotlib 개발자님들은 이런 부분까지도 설정할 수 있게 만들어 주셨어요. 이것이 지금부터 이야기할 "좌표를 이용한 범례 위치 조절 두 번째 방법"이에요.

 

두번째 사용방법은 아래와 같아요.


loc = 문자열 또는 코드번호, bbox_to_anchor = (숫자, 숫자)


bbox_to_anchor에 들어가는 숫자 2개(x, y좌표)는 첫 번째 방법에서의 의미와 똑같아요. 그리고 이 숫자가 가리키는 곳(박스의 좌측 하단, 우측 상단 등)을 loc인자에 정해주면 됩니다. loc에 들어갈 값은 위에서 살펴본 문자열 또는 코드번호를 지정해야 합니다. 

 

아래 코드를 살펴볼까요?

 

## 범례 -위치
import matplotlib.pyplot as plt

## 성별 데이터 분리하기
male_df = df.query('gender =="male"') ## 남자 데이터
male_visits = male_df['visits'] ## 남자 방문자수
days = male_df['days'] ## 요일

female_df = df.query('gender == "female"') ## 여자 데이터
female_visits = female_df['visits'] ## 여자 방문자수

## 선그래프 그리기
fig = plt.figure(figsize=(8,8)) ## 캔버스 생성
fig.set_facecolor('white') ## 캔버스 색상 설정
ax = fig.add_subplot() ## 프레임(그림 뼈대) 생성

## 선 그래프 생성
ax.plot(days, male_visits, marker='o', label='male') 
ax.plot(days, female_visits, marker='o', label='female')

## 글씨 설정
prop = dict(
    family='fantasy', # 글씨체
    style='italic', # 글씨 형식 - 이탤릭형식
    size=14 # 글씨 크기
)

config_legend = dict(prop=prop)

ax.legend(loc='upper right', bbox_to_anchor=(0.5,0.5), **config_legend) ## 범례
    
plt.show()

line 30

x, y좌표를 각각 0.5, 0.5로 설정(프래임 중앙)하고 이 것이 가리키는 곳은 범례 박스의 우측 상단(upper right)이 됩니다.

 

다음은 위 코드를 실행한 결과에 설명을 그림으로 덧붙였습니다.

 

 

loc과 bbox_to_anchor 값을 적절히 활용하시면 각자 상황에 맞는 최적의 범례 위치를 찾을 수 있어요.

바 차트의 경우도 이와 동일합니다. 아래 코드를 실행해 보세요. 

 

## 범례 - 위치
import matplotlib.pyplot as plt
import seaborn as sns

## 성별 데이터 분리하기
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
total_df = df.groupby('days')['visits'].sum().reindex(days).reset_index() ## 데이터를 요일 순으로 정렬

## 바 차트 그리기
colors = sns.color_palette('hls',len(df)) ## 막대기 개수만큼 색상 지정

fig = plt.figure(figsize=(8,8)) ## 캔버스 생성
fig.set_facecolor('white') ## 캔버스 색상 설정
ax = fig.add_subplot() ## 프레임(그림 뼈대) 생성

## 바 차트 생성
bars = ax.bar(total_df['days'],total_df['visits'],color=colors) ## 그래프의 막대기를 모두 가져 온다.

## 글씨 설정
prop = dict(
    family='fantasy', # 글씨체
    style='italic', # 글씨 형식 - 이탤릭형식
    size=14 # 글씨 크기
)

config_legend = dict(
    handles=bars, ## 막대기 요소
    labels=list(total_df['days']), ## 범례 라벨
    prop=prop ## 폰트 속성
)

ax.legend(loc='upper right', bbox_to_anchor=(1,1), **config_legend) ## 범례

plt.show()

 

실행 결과


이번 포스팅에서는 범례의 위치를 조정하는 방법에 대해서 알아보았습니다. 

 

도움이 되셨다면 요 아래 버튼 눌러주시면 감사해요. 꽁냥이에게 힘이 되거든요.. 헤헤

 

또한 궁금하신 점, 잘못된 점 그 밖에 하고 싶은 말은 댓글로 남겨주세요~

 

다음 포스팅에서는 범례 박스 꾸미기에 대해서 알아보겠습니다.

 

지금까지 꽁냥이의 글 읽어주셔서 감사합니다. 

 

이번 포스팅은 아래 사이트를 참고하였습니다.

 

Matplotlib Legend guide : 

 

Legend guide — Matplotlib 3.2.2 documentation

Note Click here to download the full example code Legend guide Generating legends flexibly in Matplotlib. This legend guide is an extension of the documentation available at legend() - please ensure you are familiar with contents of that documentation befo

matplotlib.org


댓글


맨 위로