Python/데이터 시각화

단순한 3단계 프로세스로 Matplotlib 차트 개선

찐남 2022. 7. 27. 22:08

파이썬에서 그래프를 표현하기 위해

가장 자주 사용되는 라이브러리는 Matplotlib입니다.

사용 방법이 seaborn 보다는

손이 많이 가는 작업을 필요로 합니다. 

이번 포스팅의 목표는 Matplotlib를 사용하라고

강요하는 것이 아니라

Matplotlib를 최대한 단순하면서도 유용하게

활용할 수 있도록 돕는 것입니다.

Python을 배울 때 Pandas로 데이터 작업을 진행하고,

Matplotlib로 그래프를 그리게 됩니다.

 

기본 차트가 다소 밋밋하거나,

밋밋해 보이기 때문에 처음에는 지루하다고 생각합니다.

손이 많이 가는 이유 중 하나는
Matplotlib는 차트 사용자 정의 측면에서 

매우 강력하기 때문입니다. 

오늘 보여드릴 사례는

Matplotlib 라이브러리로 수행된

기본 플롯을 가져오고

3단계로 쉽게 개선하는 것입니다. 

 

 

Libraries and Dataset

우선, 필요한 라이브러리를 import 하겠습니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

 

Kaggle에서 제공하는

"Restaurants Business Rankings 2020"

데이터 세트를 이용해 실습해 보겠습니다.

 

https://www.kaggle.com/datasets/michau96/restaurant-business-rankings-2020 

 

Restaurant Business Rankings 2020

Top 250, Top 100 Independents and Future 50

www.kaggle.com

 

데이터를 메모리에 로드하고,

상위 5개의 데이터를 출력해 보겠습니다.

 

future50 = pd.read_csv("D:/Python_apply/Future50.csv")
future50.head()

 

실습하고자 하는 업무는

이 데이터 세트에서 미국 매출 기준

상위 10개 레스토랑에 대해

좋은 차트를 만드는 것입니다. 

 

Matplotlib를 사용한 기본 차트

기본 가로 막대 차트를 만들어 

다음과 같이 표시해 보겠습니다.

# 연도(2019)를 나타내는 변수 삽입
future50['year'] = 2019

# 그래프 크기 세팅
fig,ax = plt.subplots(figsize=(3,6))

# 데이터 추출
future50Bar = future50[future50['year'] == 2019].sort_values(by='Sales')[-10:]

# 그래프 출력
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'])
ax.set_title('Top 10 U.S.Restaurants by Sales', loc ='center')

 

이제 이 플롯을 개선할 수 있는 방법을 살펴보겠습니다.

 

1단계: "검은 상자" 제거

차트가 더 가볍게 느껴지도록 하는 한 가지 방법은 

주변의 검은 상자를 제거하는 것입니다.

 

필요 없는 척추를 제거합니다.

여기에는 상단, 하단 및 오른쪽이 포함됩니다.

그렇게 하려면 

ax와 set_visible 함수를 호출해야 합니다. 

 

또한 set_linewidth 함수를 사용하여 

왼쪽 척추를 조금 더 잘 보이게 만들 것입니다.

 

# 연도(2019)를 나타내는 변수 삽입
future50['year'] = 2019

# 그래프 크기 세팅
fig,ax = plt.subplots(figsize=(3,6))

# 데이터 추출
future50Bar = future50[future50['year'] == 2019].sort_values(by='Sales')[-10:]

# 그래프 출력
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'])
ax.set_title('Top 10 U.S.Restaurants by Sales', loc ='center')

# 필요 없는 검은 상자 제거
ax.spines[["top","right","bottom"]].set_visible(False)
ax.spines["left"].set_linewidth(1.1)

 

 

2단계: 그리드 추가 및 눈금 레이블 사용자 지정

모든 그래프의 목표는

쉽게 이해할 수 있도록 하는 것입니다.

 

올바르게 수행되면

그리드가 이와 관련하여 도움이 될 것입니다.

 

# 연도(2019)를 나타내는 변수 삽입
future50['year'] = 2019

# 그래프 크기 세팅
fig,ax = plt.subplots(figsize=(3,6))

# 데이터 추출
future50Bar = future50[future50['year'] == 2019].sort_values(by='Sales')[-10:]

# 그래프 출력
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'])
ax.set_title('Top 10 U.S.Restaurants by Sales', loc ='center')

# 필요 없는 검은 상자 제거
ax.spines[["top","right","bottom"]].set_visible(False)
ax.spines["left"].set_linewidth(1.1)

# 그리드 세팅
ax.grid(which="major",axis="x", color='grey')

 

그래프를 보니 몇 가지 문제가 있어 보입니다.

굵은 회색 격자선이 막대 위에 나타나

디자인을 엉망으로 만듭니다.

하지만, 쉽게 고칠 수 있습니다.

  • 격자선의 경우 속성 alpha를 미세 조정하여
    불투명도를 조정할 수 있습니다.
    1에서 0.6으로 줄여볼게요.
  • 막대가 전면에 나타나게 하려면
    zorder 속성을 사용하면 됩니다. 

 

이 경우 그리드에 대해 zorder=1을, 

막대에 대해 zorder=2를 설정하여 

전경에 있도록 합니다.


zorder를 추가하여 코드를 조정해 보겠습니다.

 

# 연도(2019)를 나타내는 변수 삽입
future50['year'] = 2019

# 그래프 크기 세팅
fig,ax = plt.subplots(figsize=(3,6))

# 데이터 추출
future50Bar = future50[future50['year'] == 2019].sort_values(by='Sales')[-10:]

# 그래프 출력
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'])
ax.set_title('Top 10 U.S.Restaurants by Sales', loc ='center')

# 필요 없는 검은 상자 제거
ax.spines[["top","right","bottom"]].set_visible(False)
ax.spines["left"].set_linewidth(1.1)

# 그리드 세팅
ax.grid(which="major",axis="x", color='grey')


# zorder 추가 
ax.grid(which="major",axis="x", color='grey', alpha=0.6, zorder=1)
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'], zorder=2)

 

눈금 레이블

이제 x-ticks과 y-ticks을 다시 살펴보겠습니다.

  • x-ticks: 상단에 배치하면 더 쉽게 읽을 수 있습니다.
  • y-ticks: 레스토랑 레이블을 왼쪽에 조금 더 배치하여
    플롯을 더욱 가볍게 만들 수 있습니다.

코드는 아래와 다음과 같습니다.

set_tick_params 함수를 사용합니다.

아래의 다양한 속성을 통해 x-레이블을 상단에 배치하고 

크기를 사용자 정의하는 것이 

얼마나 쉬운지 알 수 있습니다. 

 

y 레이블의 경우 더 높은 패드 번호로 

가시성을 위해 레이블과 y 축 사이에 

더 많은 공간을 두기로 선택했습니다.

 

# 연도(2019)를 나타내는 변수 삽입
future50['year'] = 2019

# 그래프 크기 세팅
fig,ax = plt.subplots(figsize=(3,6))

# 데이터 추출
future50Bar = future50[future50['year'] == 2019].sort_values(by='Sales')[-10:]

# 그래프 출력
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'])
ax.set_title('Top 10 U.S.Restaurants by Sales', loc ='center')

# 필요 없는 검은 상자 제거
ax.spines[["top","right","bottom"]].set_visible(False)
ax.spines ["left"]. set_linewidth(1.1)

# Set the grid
ax.grid(which="major",axis="x", color='grey')


# zorder 추가 
ax.grid(which="major",axis="x", color='grey', alpha=0.6, zorder=1)
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'], zorder=2)

# x-axis tick labels 재설정
ax.xaxis.set_tick_params(labeltop=True, labelbottom=False, bottom=False, labelsize=11, pad=-1)

# y-axis tick labels 재설정
ax.set_yticklabels(future50Bar['Restaurant'],ha='left')
ax.yaxis.set_tick_params(pad=100, labelsize=11,bottom=False)

 

 

3단계: 텍스트 추가(제목, 자막, 출처)

마지막 단계.
text 함수를 사용하여 그래프에 텍스트를 추가해야 합니다.

여기서 핵심은 transform = fig.transFigure입니다.

다음은 수행하는 작업입니다.

 

Matplotlib 문서에서:
"그림의 좌표계: (0,0)은 그림의 왼쪽 하단이고
(1,1)은 그림의 오른쪽 상단입니다."

 

x와 y에 대한 올바른 좌표를 찾으려면 

프로세스가 경험적이므로 

필요한 것에 따라 보정해야 합니다. 

이러한 것들을 시작점으로 사용할 수 있습니다.

 

# 연도(2019)를 나타내는 변수 삽입
future50['year'] = 2019

# 그래프 크기 세팅
fig,ax = plt.subplots(figsize=(3,6))

# 데이터 추출
future50Bar = future50[future50['year'] == 2019].sort_values(by='Sales')[-10:]

# 그래프 출력
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'])
ax.set_title('Top 10 U.S.Restaurants by Sales', loc ='center')

# 필요 없는 검은 상자 제거
ax.spines[["top","right","bottom"]].set_visible(False)
ax.spines["left"].set_linewidth(1.1)

# Set the grid
ax.grid(which="major",axis="x", color='grey')


# zorder 추가 
ax.grid(which="major",axis="x", color='grey', alpha=0.6, zorder=1)
ax.barh(future50Bar['Restaurant'], future50Bar['Sales'], zorder=2)

# x-axis tick labels 재설정
ax.xaxis.set_tick_params(labeltop=True, labelbottom=False, bottom=False, labelsize=11, pad=-1)

# y-axis tick labels 재설정
ax.set_yticklabels(future50Bar['Restaurant'],ha='left')
ax.yaxis.set_tick_params(pad=190, labelsize=11,bottom=False)

# 제목과 부제목 추가
ax.text(x=-.35, y=.99, s="Top 10 U.S.Restaurants by Sales", transform=fig.transFigure, ha='left', fontsize=12, weight='bold', alpha=.8)
ax.text(x=-.35, y=.958, s="2020, millions of USD", transform=fig.transFigure, ha='left', fontsize=11, alpha=.8)

# 텍스트 추가
ax.text(x=-.35, y=.08, s="""Source: "Restaurant Business Rankings 2020" via Kaggle.com""", transform=fig.transFigure, ha='left', fontsize=9, alpha=.7)

 

최초 그래프와 비교해 보면, 

많이 세련되었음을 알 수 있습니다. 

 

결론

이번 포스팅에서의 이 단계별 가이드가 

Matplotlib 차트를 개선하는 데 

도움이 되기를 바랍니다. 

 

차트를 더 좋게 만들 수 있는 

가능성이 훨씬 더 많습니다. 

 

이 3단계를 통해 좋은 출발의 기반을 

마련했으면 합니다.

 

 

 

반응형