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

[범례(Legend)] 4. Matplotlib을 이용한 범례 그리기 - 범례 박스 꾸미기

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

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

 

현재 Matplotlib을 이용한 범례 그리기에 대한 내용을 포스팅하고 있어요.

 

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

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

3. Matplotlib을 이용한 범례 그리기 - 범례 위치 바꾸기

 

이번 포스팅에서는 Matplotlib을 이용한 범례 그리기 제4편으로 범례 박스를 꾸미는 방법에 대하여 소개하고요. 그 내용은 다음과 같습니다.


1. 박스 크기

2. 박스 배경색

3. 박스 테두리

4. 박스 타이틀

5. 기타(박스 모양, 그림자 효과, 마커 설정, 범례 배치)


그럼 이제부터 하나씩 살펴볼까요?

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에서 범례 박스 크기를 조절하는 직접적인 방법(폭과 높이를 조절하는 방법 등)은 아직 없는 것 같습니다(알고 계신 분은 꽁냥이에게 알려주시면 감사하겠습니다). 여기서는 간접적으로 범례 박스 크기를 조절하는 방법을 소개합니다. 그 방법은 아래의 2가지가 있습니다. 

 


폰트 사이즈를 이용하는 방법,

안쪽 여백을 이용하는 방법


1) 폰트 사이즈를 이용하는 방법

"폰트 사이즈를 이용하는 방법"이란 범례 안쪽 텍스트 크기를 조절하는 것을 말합니다. 이 방법은 범례 안쪽 내용(범례 기호, 라벨)과 박스의 크기를 동시에 조절하는 방법입니다. 폰트 사이즈를 조절하는 방법은 이미 이전 포스팅에서 다루었으므로 자세한 설명은 생략하겠습니다. 아래 코드를 실행해보세요(25번째 줄이 폰트 사이즈를 조절하는 부분입니다).

 

## 범례 - 박스 크기
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop # 범례 폰트 속성
)

ax.legend(**config_legend)

plt.show()

실행 결과

아래 그림은 여러 폰트 사이즈에 따른 박스 크기의 변화를 나타낸 것입니다.

 

실행 결과

 

앞에서 말했던 것처럼 범례 내용과 범례 박스의 크기가 모두 변하는 것을 알 수 있습니다.

2) 안쪽 여백을 이용하는 방법

이 방법은 범례 안쪽 여백을 조절하는 것입니다. 이 방법은 폰트 사이즈를 이용했던 방법과 다르게 안쪽 내용(범례 기호, 라벨)의 크기는 변하지 않고 박스의 크기와 안쪽 여백을 조절합니다. 안쪽 여백은 legend메서드 내의 borderpad 인자를 이용하여 설정합니다. 아래 코드를 살펴볼게요.

 

## 범례 - 박스 크기
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop # 범례 폰트 속성
)

ax.legend(borderpad=1,**config_legend)

plt.show()

line 33

borderpad인자에 1을 넣었습니다.

 

위 코드를 실행해보세요.

 

실행 결과

아래 그림은 여러가지 borderpad 값에 따른 범례 박스를 나타낸 것입니다.

 

borderpad 값에 따른 범례 박스

 

앞서 말했던 것처럼 박스의 크기와 여백은 변하지만 범례 내용은 크기가 변하지 않는 것을 알 수 있습니다. borderpad를 이용하여 각자 상황에 맞게 박스 사이즈를 조절해보세요~

반응형

   2. 박스 배경색

박스 배경색은 legend메서드의 facecolor 인자를 이용하여 지정할 수 있습니다.

아래 코드를 살펴보겠습니다.

 

## 범례 - 박스 배경색
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop # 범례 폰트 속성
)

ax.legend(facecolor='grey', **config_legend)

plt.show()

line 33

꽁냥이는 범례 박스의 배경색을 회색으로 지정했어요~

 

아래 그림은 위 코드를 실행한 결과입니다.

 

실행 결과


   3. 박스 테두리

박스 테두리는 legend 메서드의 edgecolor인자를 이용하여 지정합니다.

 

## 범례 - 박스 테두리
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop # 범례 폰트 속성
)

ax.legend(edgecolor='k',**config_legend)

plt.show()

line 33

꽁냥이는 테두리를 검은색으로 지정했어요

 

아래 그림은 위 코드를 실행한 것입니다.

 

실행 결과


   4. 박스 타이틀

범례 박스의 타이틀은 legend 메서드의 title 인자로 추가할 수 있고 title_fontsize인자를 이용하여 타이틀 폰트를 조절할 수 있습니다.

 

## 범례 - 박스 타이틀
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop, # 범례 폰트 속성
    edgecolor='k'
)

ax.legend(title='Gender',title_fontsize=12,**config_legend)

plt.show()

line 34

타이틀 문자열은 'Gender', 타이틀 폰트 사이즈는 12로 지정했습니다.

 

아래 그림은 위 코드를 실행한 것입니다.

 

실행 결과


   5. 기타(박스 모양, 그림자 효과, 마커 설정, 범례 배치)

박스 모양 테두리가 둥근 사각형 또는 테두리가 직각인 사각형을 선택할 수 있는데 이는 legend 메서드의 fancybox인자를 이용하여 설정할 수 있습니다.


fancybox = True <=> 테두리가 둥근 사각형

fancybox = False <=> 테두리가 직각인 사각형


아래 코드를 통해 확인해보겠습니다.

 

## 범례 - 박스 모양
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=20 # 글씨 크기
)

config_legend = dict( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop, # 범례 폰트 속성
    edgecolor='k'
)

ax.legend(fancybox=True,**config_legend)

plt.show()

line 34

꽁냥이는 박스 모양을 테두리가 둥근 사각형으로 선택했습니다.

 

실행 결과

아래 그림은 테두리가 직각인 사각형인 경우(fancybox = False)를 나타낸 것입니다.

 

사실 두개의 차이가 그렇게 크진 않네요~

 

그림자 효과는 shadow인자로 설정할 수 있습니다.


shadow = True <=> 그림자 효과 적용

shadow = False <=> 그림자 효과 미적용


아래 코드를 실행해보세요(34번째 줄에 shadow인자에 True를 넣었습니다).

## 범례 - 박스 그림자 효과
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop, # 범례 폰트 속성
    edgecolor='k'
)

ax.legend(shadow=True,**config_legend)

plt.show()

그림자 효과가 살짝(?) 추가되었네요.

다음은 범례 기호의 마커를 설정하는 방법입니다.

Matplotlib에서는 선 그래프의 마커가 있다면 범례 기호에 마커가 기본적으로 포함되어 있는 것을 알 수 있습니다.

 

 

 

마커 설정은 markerscale과 numpoints를 이용합니다. 이 2개 인자의 의미는 다음과 같습니다.


markerscale : 마커 크기 설정

numpoints : 마커 개수 설정


아래 코드는 markerscale은 1.5, numpoints를 2로 설정하여 마커가 2개 생기도록 했습니다(34번째 줄).

 

## 범례 - 박스 그림자 효과
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( ## 범례 설정
    loc = 'upper left', # 범례 위치 설정
    prop=prop, # 범례 폰트 속성
    edgecolor='k'
)

ax.legend(markerscale=1.5,numpoints=2,**config_legend)

plt.show()

실행 결과

참고로 범례 기호의 마커를 안 보이게 하고 싶다면 markerscale을 0으로 설정하면 됩니다.

반응형

다음은 범례 배치에 대한 내용입니다.

 

범례 라벨이 많아지게 되면 범례 박스가 세로로 길어지게 되어 그래프를 가릴 수가 있습니다. 아래와 같이 말이죠.

 

 

이럴 때는 범례를 한 줄이 아닌 여러 줄로 적절히 나누어주면 되는데 ncol인자를 이용하면 가능합니다.

아래 코드는 범례를 3줄로 나누었습니다(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(ncol=3,**config_legend) ## 범례를 3줄로 배치

plt.show()

실행 결과

범례를 3줄로 배치했더니 그래프를 가리지 않게 되었습니다.


이번 포스팅은 범례 박스를 꾸미는 여러 가지 방법에 대해서 알아보았습니다. 궁금하신 점, 잘못된 점 그리고 그 밖에 하고 싶은 말은 댓글로 남겨주세요. 

 

다음 포스팅에서는 범례 순서를 바꾸는 방법에 대해서 알아보겠습니다. 지금까지 꽁냥이의 글 읽어주셔서 감사합니다.

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

 

Matplotlib Legend 관련 문서 : https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.legend.html

 

matplotlib.pyplot.legend — Matplotlib 3.1.2 documentation

Other Parameters: loc : str or pair of floats, default: rcParams["legend.loc"] = 'best' ('best' for axes, 'upper right' for figures) The location of the legend. The strings 'upper left', 'upper right', 'lower left', 'lower right' place the legend at the co

matplotlib.org


댓글


맨 위로