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

[범례(Legend)] 5. Matplotlib을 이용한 범례그리기 - 범례 라벨 순서 바꾸기

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

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

 

이번 포스팅에서는 Matplotlib을 이용한 범례 그리기 제5편으로 범례 라벨 순서를 바꾸는 방법에 대해서 소개하려고 합니다. 1~4편의 내용이 궁금하신 분들은 아래 링크를 참고하세요.

 

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

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

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

4. Matplotlib을 이용한 범례 그리기 - 범례 박스 꾸미기

 


범례 순서 바꾸기 - 선 그래프

먼저 이번 포스팅에서 사용할 데이터를 아래 코드를 통해 만들어 줍니다.

 

## 데이터
import pandas as pd

df = pd.DataFrame()
df['days'] = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']*3 ## 요일
df['num'] = [32,23,14,14,27,40,35,37,28,9,41,29,33,21,45,33,9,11,10,12,27] ## 옷 판매량
df['color'] = ['black']*7 + ['grey']*7 + ['white']*7 ## 옷 색상

그리고 다음 코드를 통해 범례가 표시되도록 선 그래프를 그려 줍니다.

 

## 범례 - 라벨 순서
import matplotlib.pyplot as plt

## 데이터 분리하기
black_df = df.query('color =="black"') ## 검정색 옷 판매량 데이터
black_sales = black_df['num'] ## 검정색 옷 판매량
days = black_df['days'] ## 요일

grey_df = df.query('color == "grey"') ## 회색 옷 판매량 데이터
grey_sales = grey_df['num'] ## 회색 옷 판매량

white_df = df.query('color == "white"') ## 하얀색 옷 판매량 데이터
white_sales = white_df['num'] ## 하얀색 옷 판매량

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

## 선 그래프 생성
ax.plot(days, white_sales, marker='o', label='white')
ax.plot(days, grey_sales, marker='o', label='grey')
ax.plot(days, black_sales, marker='o', label='black') 

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

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

ax.legend(**config_legend)

plt.show()

실행 결과

 

위 그림을 보면 위에서부터 white, grey, black 순서로 범례 라벨이 표시되었습니다. 


만약 범례 라벨을 위에서 부터 black, grey, white로 표시하고 싶다면 어떻게 하면 될까요? 


가장 기본적인 방법은 선 그래프를 black, grey, white 순서대로 그리면 됩니다. 아래 코드를 살펴볼까요?

 

## 범례 - 라벨 순서
import matplotlib.pyplot as plt

## 데이터 분리하기
black_df = df.query('color =="black"') ## 검정색 옷 판매량 데이터
black_sales = black_df['num'] ## 검정색 옷 판매량
days = black_df['days'] ## 요일

grey_df = df.query('color == "grey"') ## 회색 옷 판매량 데이터
grey_sales = grey_df['num'] ## 회색 옷 판매량

white_df = df.query('color == "white"') ## 하얀색 옷 판매량 데이터
white_sales = white_df['num'] ## 하얀색 옷 판매량

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

## 선 그래프 생성
ax.plot(days, black_sales, marker='o', label='black') 
ax.plot(days, grey_sales, marker='o', label='grey')
ax.plot(days, white_sales, marker='o', label='white')

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

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

ax.legend(**config_legend)

plt.show()

 

line 21~23

black, grey, white 순으로 범례 라벨을 표시해야 하므로 이 순서대로 선 그래프를 출력합니다.

 

실행 결과

우리가 원하는 순서대로 범례가 잘 표시된 것을 알 수 있습니다. 

반응형

하지만 이 방법은 선 그래프의 색상도 같이 변하는 것을 알 수 있는데요(아래 그림 참고).

 

 

이런 차이가 상관이 없다면 모르겠지만 선 그래프의 색상은 유지하고 싶은 분들에게는 추천하지 않는 방법입니다.

 

이번에는 선 그래프의 색상을 유지하면서 범례 라벨 순서를 바꿔볼 거예요. 그 방법은 그래프 요소와 범례 라벨 정보를 이용하여 라벨의 순서를 바꾸어주는 것이지요. 

 

아래 코드를 살펴볼게요.

 

## 범례 - 라벨 순서
import matplotlib.pyplot as plt

## 데이터 분리하기
black_df = df.query('color =="black"') ## 검정색 옷 판매량 데이터
black_sales = black_df['num'] ## 검정색 옷 판매량
days = black_df['days'] ## 요일

grey_df = df.query('color == "grey"') ## 회색 옷 판매량 데이터
grey_sales = grey_df['num'] ## 회색 옷 판매량

white_df = df.query('color == "white"') ## 하얀색 옷 판매량 데이터
white_sales = white_df['num'] ## 하얀색 옷 판매량

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

## 선 그래프 생성
ax.plot(days, white_sales, marker='o', label='white')
ax.plot(days, grey_sales, marker='o', label='grey')
ax.plot(days, black_sales, marker='o', label='black') 

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

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

handles, labels = ax.get_legend_handles_labels() ## 범례 처리되는 요소와 해당 라벨 

dict_labels_handles = dict(zip(labels, handles)) ## 라벨을 키로 요소를 밸류로 하는 딕셔너리 생성

labels = ['black','grey','white'] ## 원하는 순서 라벨
handles = [dict_labels_handles[l] for l in labels] ## 라벨 순서에 맞게 요소 재배치

ax.legend(handles,labels,**config_legend) ## 새로운 순서를 갖는 요소와 라벨을 넣어준다.

plt.show()

 

line 38

get_legend_handles_labels메서드를 사용하여 선 그래프 요소와 범례 라벨을 가져옵니다. 

 

line 40

범례 라벨과 선 그래프 요소를 이용하여 딕셔너리를 만들어 줍니다.

 

line 42

원하는 순서에 맞도록 라벨을 리스트로 새로 만들어줍니다. 주의하실 점은 이 리스트 안에 들어가는 원소는 21~23번째 줄에서 정의한 라벨(white, grey, black)이어야 한다는 것입니다.

 

line 43

위에서 만든 딕셔너리와 원하는 순서를 가진 라벨을 이용하여 선 그래프 요소를 재배치합니다.

 

line 45

원하는 순서를 가진 요소와 라벨을 다시 legend메서드에 넣어줍니다.

 

위 코드를 실행해 볼까요?

 

실행 결과

원래의 선 그래프 색상은 유지하면서 범례 순서만 바뀐 것을 알 수 있어요.

다시 말씀드리면 위 방법의 핵심은 하는 라벨의 순서에 맞게 해당 라벨의 선 그래프 요소도 재배치를 하면 된다는 것입니다. 이 원리를 알면 범례 순서를 알파벳 순서로도 배치 할 수 있지요.

 

아래 코드는 범례 라벨을 알파벳 순서로 나타낸 것입니다. 코드 설명은 주석으로 대체합니다.

 

## 범례 - 라벨 순서
import matplotlib.pyplot as plt

## 데이터 분리하기
black_df = df.query('color =="black"') ## 검정색 옷 판매량 데이터
black_sales = black_df['num'] ## 검정색 옷 판매량
days = black_df['days'] ## 요일

grey_df = df.query('color == "grey"') ## 회색 옷 판매량 데이터
grey_sales = grey_df['num'] ## 회색 옷 판매량

white_df = df.query('color == "white"') ## 하얀색 옷 판매량 데이터
white_sales = white_df['num'] ## 하얀색 옷 판매량

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

## 선 그래프 생성
ax.plot(days, white_sales, marker='o', label='white')
ax.plot(days, grey_sales, marker='o', label='grey')
ax.plot(days, black_sales, marker='o', label='black') 

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

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

handles, labels = ax.get_legend_handles_labels() ## 범례 처리되는 요소와 해당 라벨 

list_labels_handles = [(h, v) for h, v in zip(handles, labels)] ## 요소와 라벨을 매핑하는 리스트를 만든다.

list_labels_handles = sorted(list_labels_handles, key=lambda x: x[1]) ## 라벨 알파벳 순서에 맞게 재배치한다.

labels = [x[1] for x in list_labels_handles] ## 새로운 순서의 라벨
handles = [x[0] for x in list_labels_handles] ## 새로운 순서의 요소

ax.legend(handles,labels,**config_legend) ## 새로운 순서를 갖는 요소와 라벨을 넣어준다.

plt.show()

실행 결과

알파벳 순서와 우리가 원했던 순서와 같기 때문에 실행 결과는 앞서 본 것과 동일합니다.


이번 포스팅에서는 범례 라벨 순서를 바꿔보는 법에 대해서 알아보았습니다. 이것으로 범례 관련 포스팅은 마치겠습니다. 궁금한 점, 잘못된 점, 그 밖에 하고 싶은 말은 댓글로 남겨주세요.

 

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

 


댓글


맨 위로