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

[범례(Legend)] 2. Matplotlib를 이용한 범례 그리기 - 텍스트 꾸미기

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

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

 

이번 시간에는 Matplotplib을 이용한 범례 그리기 제2편으로 범례 안에 표시되는 텍스트를 꾸며볼 거예요. 1편의 내용이 궁금하시다면 아래 링크를 참고하세요.

 

[범례(Legend)] 1. Matplotlib를 이용한 범례 그리기 - 기본

 

이번 포스팅에서 다루는 내용은 다음과 같아요


1. 텍스트 크기/모양 설정

2. 텍스트 색상


LIST

   1. 텍스트 크기/모양 설정

텍스트 크기와 텍스트 글씨 모양은 legend 메서드의 prop이라는 인자를 이용하여 설정할 수 있어요. prop인자는 텍스트 크기와 모양을 딕셔너리 형태로 받게 되어있지요.

 

다음은 prop인자 사용 방법을 나타낸거예요.

 


prop = dict( family='fantasy', style='italic', size=20 )


위에서 텍스트 모양과 관련된 키(Key)는 familystyle입니다. family는 고딕, 돋움과 같은 글씨체를 style은이탤릭, 기울임처럼 글자 형식을 나타내는 키에요. 그리고 size는 이름에서 알 수 있듯이 글씨의 크기를 설정할 수 있는 키예요.

 

코드를 통하여 확인해볼까요?

 

먼저 아래 코드를 실행하여 데이터를 만들어 줍니다.

## 데이터
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 ## 성별

텍스트 모양과 크기를 설정하는 부분은 선 그래프와 바 차트가 비슷하기 때문에 선 그래프 위주로 설명하겠습니다.

## 범례 - 선 그래프 텍스트
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 # 글씨 크기
)

ax.legend(prop=prop) ## 범례

plt.show()

line 22~26

prop인자에 들어갈 딕셔너리를 만들었습니다.

 

line 28

이렇게 만들어진 딕셔너리를 legend메서드의 prop인자에 넣어줍니다.

반응형

※ 참고

legend메서드 내부에서는 prop인자에 들어가는 딕셔너리를 matplotlib.font_manager.FontProperties라는 클래스로 변환시켜줍니다. 그리고 여기서 사용한 키(family, style, size)는 이 클래스의 인자로 넘아가는 것이지요. family, style, size 외에 prop인자에 들어갈 수 있는 키와 가질 수 있는 값은 여기를 참고하세요.

 

그럼 위 코드를 실행해 볼까요?

 

실행 결과

보시는 것처럼 텍스트의 크기와 모양이 바뀐 것을 알 수 있습니다.

 

아래 코드는 바 차트에 대해서도 동일하게 설정한 것입니다.

## 범례 -바 차트 텍스트
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 # 글씨 크기
)

ax.legend(handles=bars,labels=list(total_df['days']),prop=prop) ## 그래프 요소와 라벨을 넣어서 범례를 만든다.

plt.show()

실행 결과


   2. 텍스트 색상 설정

다음은 텍스트 색상인데요. 이걸 따로 소개하는 이유는 텍스트 색상의 경우 위에서 살펴본 prop인자에서 설정할 수 없고 다른 방법을 사용해야 하기 때문이에요(그냥 prop에 color라는 키를 넣을 수 있었으면 좋겠지만요 ㅠ.ㅠ). 

 

이 부분은 선 그래프와 바 차트가 살짝 달라요. 따라서 선 그래프에서 텍스트 색상을 설정하는 방법에 대해서 먼저 소개하고  바 차트를 뒤에서 설명하겠습니다 

 

자 아래 코드를 볼게요.

leg = ax.legend(prop=prop) ## 범례

handles, _ = ax.get_legend_handles_labels() ## 그래프 요소와 해당 라벨을 가져옵니다.

for i, le in enumerate(leg.get_texts()): ## 범례 텍스트 클래스를 하나씩 돌면서 색을 설정한다.
    le.set_color(handles[i].get_color()) ## 선 그래프의 색상을 가져온다.

이 부분이 조금 어려울 수 있어요. 꽁냥이가 최대한 풀어서 잘 설명해볼게요.

 

line 1

먼저 leg에 범례 요소를 담습니다(line 1). leg는 matplotlib.legend.Legend라는 클래스를 넘겨받게 됩니다. 이렇게 해준 이유는 이 클래스가 가지고 있는 get_texts라는 메서드를 통해 범례에 들어가는 모든 텍스트(정확히 말하면 matplotlib.text.Text 클래스입니다)를 알 수 있기때문입니다. 


색상은 취향에 따라서 결정하면 되는데 꽁냥이는 선과 동일한 색상을 사용하려고 해요. 


line 3

선의 색상을 알려면 먼저 선 요소를 가져와야 해요. get_legend_handles_labels 메서드를 사용해서 가져옵니다. 이 메서드는 선 요소와 해당 라벨을 리턴(Return)하지요. 하지만 라벨은 여기서 필요 없으니 handles라는 변수에 선 요소만 담을 거예요

 

line 5~6

꽁냥이는 leg.get_texts메서드를 통해 얻은 텍스트를 이용할 거예요(line 5).  이 텍스트를 돌면서 색상을 설정하려고 하는데 이때 사용하는 메서드가 set_color입니다. 그리고 색상은  handles안의 원소가 가지고 있는 get_color메서드를 사용해서 가져옵니다(line 6).

전체 코드는 아래와 같아요. 한번 실행해 보세요.

## 범례 - 선 그래프 텍스트 색상
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 # 글씨 크기
)

leg = ax.legend(prop=prop) ## 범례

handles, _ = ax.get_legend_handles_labels() ## 그래프 요소와 해당 라벨을 가져옵니다.

for i, le in enumerate(leg.get_texts()): ## 범례 텍스트 클래스를 하나씩 돌면서 색을 설정한다.
    le.set_color(handles[i].get_color()) ## 선 그래프의 색상을 가져온다.

plt.show()

실행 결과

 

다음은 바 차트에서 텍스트 색상을 막대기 색상과 동일하게 설정하는 코드입니다.

## 범례 -바 차트 텍스트 - 색상
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 # 글씨 크기
)

leg = ax.legend(handles=bars,labels=list(total_df['days']),prop=prop) ## 그래프 요소와 라벨을 넣어서 범례를 만든다.

for i, le in enumerate(leg.get_texts()): ## 범례 텍스트 클래스를 하나씩 돌면서 색을 설정한다.
    le.set_color(bars[i].get_facecolor()) ## 선 그래프의 색상을 가져온다.

plt.show()

위에서 말씀드린 바와 같이 텍스트 색상을 지정하는 방법은 선 그래프와 바 차트에서 약간 차이가 있어요. 그것은 바로 선 그래프에서는 ax.get_legend_handles_labels 메서드를 사용하지 않고 17번째 줄 bars 변수를 이용했다는 것이지요.

 

왜냐하면 ax.get_legend_handles_labels 메서드를 수행하는 경우 다음과 같이 빈 리스트만 나오기 때문에 이 메서드를 사용하지 않았지요.

 

 

관련 문서(Legend guide)를 찾아보니 다음과 같은 문구를 찾을 수 있었습니다.

 

문서에 따르면, get_legend_handles_labels는 모든 요소를 포함하는 건 아니라고 하네요. 여기서는 요소가 막대기이므로 막대기는 포함이 안되나 봐요 ㅠ.ㅠ

 

자 그럼 위의 코드를 실행해 볼까요?

 

실행 결과

텍스트 색상이 막대기 색깔과 동일하게 나온 것을 확인할 수 있습니다.


범례에서 텍스트 색상을 설정하는 부분은 그렇게 단순하지가 않아서

처음 하시는 분들은 어려울 수 있어요.

하지만 연습을 조금만 하시면 쉽게 할 수 있어요.


이번 포스팅에서는 Matplotlib에서 범례 텍스트를 설정하는 방법에 대해서 알아보았습니다. 궁금한 점, 잘못된 점, 그 밖에 하고 싶은 말은 댓글로 남겨주세요~

 

그리고 도움이 되셨다면, 아래 ♥버튼 눌러주시면 감사해요~ >0<

 

다음 포스팅에서는 범례 위치를 설정하는 방법에 대해서 소개하겠습니다. 지금까지 꽁냥이의 글 읽어주셔서 감사합니다.

 


댓글


맨 위로