본문 바로가기
카테고리 없음

파도!(10) - 씨본으로 예쁜 그래프 꾸미기

'파도'는 파이스크립트 도전기의 줄임말입니다.

지난 게시글에 연재되는 글입니다 - https://itadventure.tistory.com/550

 

파도!(9) - 아보카도 판매량 그래프

'파도'는 파이스크립트 도전기의 줄임말입니다. 지난 게시글에 연재되는 글입니다 - https://itadventure.tistory.com/549 파도!(8) - 아보카도 판매량 지난 게시글에 연재되는 글입니다 - https://itadventure.t..

itadventure.tistory.com

 

지난 게시글에는 규모 있는 아보카도 판매량을 조사하여 월별 통계에 대한 그래프를 그려주는 부분을 살펴보았습니다. 문제가 되는 글자 겹침 등을 해결하는 것이 큰 과제였었지요.
이번 게시글에서는 그래프 matplotlib와 함께 사용할 수 있는 씨본(seaborn) 모듈의 색상팔레트를 이용하여 그래프를 예쁘게 꾸미는 부분을 살펴보겠습니다.

 

씨본 모듈을 불러와볼까?

 

파이스크립트에서 씨본 라이브러리를 사용하기 위해서는 <py-env> 태그 내에 seaborn 모듈을 포함하여야 하는데요. 아래 빨간색상 부분이 추가되어야 합니다.


<py-env>
  - pandas
  - matplotlib
  - seaborn
  - paths:
    - ./NANUMMYEONGJO.TTF
    - ./NANUMMYEONGJOBOLD.TTF
</py-env>


그리고 모듈을 불러오는 부분 또한 추가되어야 하지요.
특히 이번에는 눈금을 정하는 부분에서 넘파이(numpy)모듈을 사용할 겁니다.
2개의 모듈을 모두 불러오는 부분을 추가하였는데요.
numpy 모듈은 <py-env>태그 내에 적어주지 않아도 됩니다.


      import pandas as pd
      from pyodide.http import open_url
      
      import seaborn as sns      
      import numpy as np


이제 눈금단위를 지정하는 부분에 넘파이(numpy)를 이용하여 표현을 좀 바꿔보도록 하겠습니다.
그래프 Y축의 눈금 단위를 5000 단위로 지정하기 위해 아래 코드를 사용했었는데요.

plt.yticks([
  25000, 30000, 35000, 40000, 
  45000, 50000, 55000, 60000
])

 

넘파이로 눈금지정을 더 간결하게

 

만일 눈금이 5,000단위가 아니라 1,000단위로 표시되어야 한다면 어떨까요?
어휴.. 코드가 꽤 길어지겠지요.

plt.yticks([
  25000, 26000, 27000, 28000, 언제 끝나나...
])

파이썬의 numpy 모듈에는 아주 편리한 기능이 있습니다.
바로 이러한 패턴의 배열을 아주 쉽게 만들어주는데 단 한줄이면 됩니다.
아래 코드는 25000 부터 60000 까지 5000 마다 건너뛴 배열을 만들어 주지요.

np.arange(25000, 60000, 5000)

그래서 아래와 같이 코딩하면 앞과 똑같은 눈금 단위가 됩니다

plt.yticks(np.arange(25000, 60000, 5000))

 

컬러파레트로 막대그래프 꾸미기


이제 하이라이트! 씨본으로 막대 그래프 색상을 꾸며볼까요?
확인해본 결과 sns 에는 색상 팔레트라는게 있어서 막대 그래프 하나 하나마다 다른 색상을 지정할 수 있는데요.
그래서 그런지 예쁘게 나옵니다.
아래 코드는 씨본의 무지개 색상을 적용한건데 컬레 파레트명이 'rainbor_r'입니다.
뒤에 붙은 '_r' 은 reverse, 뒤집었다는 의미일 텐데요.
'rainbow_r'을 붙여어 빨주노초파남보 순으로 나오고, 'rainbow' 팔레트를 사용하면 역순으로 나옵니다.

plt.bar(
  df_group.index.to_list(), 
  df_group['Volume2'].to_list(),
  color=sns.color_palette(
    'rainbow_r', 
    12
  ),
  edgecolor='black'
)

그냥 색상 파레트만 적용하면 어떤 막대는 너무 희미하더군요.
그래서 각 막대의 검정색 경계선을 추가로 넣었는데 그 부분이 edgecolor='black' 입니다.


plt.bar(
  df_group.index.to_list(), 
  df_group['Volume2'].to_list(),
  color=sns.color_palette(
    'rainbow_r', 
    12
  ),
  edgecolor='black'
)


이 코드를 적용하면 결과는 아래와 같은데요.

무지개 색상은 7가지이지만 12단계로 색을 나누도록 정해주어야 12번마다 색상이 무지개 색상이 나누어 표현됩니다.
왜 12개로 했냐구요? 1년이 12월이기 때문에 같은 색상은 같은 월로 보이게 하려구요 :)


color=sns.color_palette(
  'rainbow_r', 
  12
),


 

컬러파레트 목록

 

참고로 씨본의 사용할 수 있는 컬러 파레트명은 아래와 같습니다.
매우 많긴 한데 _r은 색상이 역순으로 나오는거라 절반만 확인하면 될것 같네요 :)

Accent, Accent_r, 
Blues, Blues_r, 
BrBG, BrBG_r, 
BuGn, BuGn_r, 
BuPu, BuPu_r, 
CMRmap, CMRmap_r, 
Dark2, Dark2_r, 
GnBu, GnBu_r,  
Greens, Greens_r, 
Greys, Greys_r, 
OrRd, OrRd_r, 
Oranges, Oranges_r,  
PRGn, PRGn_r, 
Paired, Paired_r, 
Pastel1, Pastel1_r, 
Pastel2,  Pastel2_r, 
PiYG, PiYG_r, 
PuBu, PuBuGn, 
PuBuGn_r, PuBu_r, 
PuOr, PuOr_r, 
PuRd, PuRd_r, 
Purples, Purples_r, 
RdBu, RdBu_r, 
RdGy, RdGy_r, 
RdPu, RdPu_r, 
RdYlBu, RdYlBu_r, 
RdYlGn, RdYlGn_r, 
Reds, Reds_r, 
Set1, Set1_r, 
Set2, Set2_r, 
Set3, Set3_r, 
Spectral, Spectral_r, 
Wistia, Wistia_r, 
YlGn, YlGnBu, 
YlGnBu_r, YlGn_r, 
YlOrBr, YlOrBr_r, 
YlOrRd, YlOrRd_r, 
afmhot, afmhot_r, 
autumn, autumn_r, 
binary, binary_r,  
bone, bone_r, 
brg, brg_r, 
bwr, bwr_r, 
cividis, cividis_r, 
cool, cool_r,  
coolwarm, coolwarm_r, 
copper, copper_r, 
cubehelix, cubehelix_r, 
flag, flag_r,  
gist_earth, gist_earth_r, 
gist_gray, gist_gray_r, 
gist_heat, gist_heat_r, 
gist_ncar,  gist_ncar_r, 
gist_rainbow, gist_rainbow_r, 
gist_stern, gist_stern_r, 
gist_yarg,  gist_yarg_r, 
gnuplot, gnuplot2, 
gnuplot2_r, gnuplot_r, 
gray, gray_r, 
hot, hot_r,  
hsv, hsv_r, 
icefire, icefire_r, 
inferno, inferno_r, 
jet, jet_r, 
magma, magma_r,  
mako, mako_r, 
nipy_spectral, nipy_spectral_r, 
ocean, ocean_r, 
pink, pink_r,  
plasma, plasma_r, 
prism, prism_r, 
rainbow, rainbow_r, 
rocket, rocket_r,  
seismic, seismic_r, 
spring, spring_r, 
summer, summer_r, 
tab10, tab10_r,
tab20′, tab20_r, 
tab20b, tab20b_r, 
tab20c, tab20c_r, 
terrain, terrain_r, 
turbo,  turbo_r, 
twilight, twilight_r, 
twilight_shifted, twilight_shifted_r, 
viridis,  viridis_r, 
vlag, vlag_r, 
winter, winter_r


겸사해서 배경색도 넣어보았습니다.

ax = plt.gca()
ax.set_facecolor('#e8e7d2')

결과는? 아래와 같습니다.
크레이는 꽤 만족스러운데 여러분은 어떠신가요? :)

위의 수정사항들이 반영된 최종 소스는 아래와 같습니다.
크레이가 마련한 다음 URL 에서도 결과를 확인하실 수 있습니다.
http://dreamplan7.cafe24.com/pyscript/py9-4.html

<html> 
    <head> 
      <link rel="stylesheet" 
        href="https://pyscript.net/alpha/pyscript.css" /> 
      <script defer 
        src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
  - pandas
  - matplotlib
  - seaborn
  - paths:
    - ./NANUMMYEONGJO.TTF
    - ./NANUMMYEONGJOBOLD.TTF
</py-env>
    </head>
  <body> 
    <link rel="stylesheet" href="pytable.css"/>
    <py-script>
      def createElementDiv(name):
          element = document.createElement('div')
          element.id = name
          document.body.append(element)
          return Element(name)
          
      import pandas as pd
      from pyodide.http import open_url
      
      import seaborn as sns      
      import numpy as np
      
      # 판다스에서 csv 를 데이터 프레임으로 읽어옴
      df = pd.read_csv(open_url(
        "http://dreamplan7.cafe24.com/pyscript/csv/avocado.csv"
      ))
      
      df.insert(2, 'month', df['Date'].str[:7], True)
      df.insert(5, 'Volume2', 
        df['Total Volume']/10000, 
        True)
      
      createElementDiv('output1').write(df)
      
      # 월별 매출량 조사
      df_group = df.fillna(0) \
        .groupby('month')[['Volume2']] \
        .sum() \
        .sort_values(
          by='month', 
          ascending=True
      )
      
      createElementDiv('output1').write(df_group)
      
      import matplotlib.pyplot as plt      
      import matplotlib.font_manager as fm

      NanumMyengjo = fm.FontProperties(
        fname='./NANUMMYEONGJO.TTF'
      )
      NanumMyengjoBold = fm.FontProperties(
        fname='./NANUMMYEONGJOBOLD.TTF'
      )

      fig = plt.figure(
        figsize=(15, 9)
      )
      
      plt.title('월별 아보카도 매출량',  
        fontproperties=NanumMyengjoBold, 
        fontsize=32
      );
      plt.xticks(rotation=45)
      
      # 눈금 표시 리미트
      plt.ylim(25000, 60000)
      
      # 눈금단위 : 25,000 ~ 60,000 까지 5,000 단위
      plt.yticks(np.arange(25000, 60000, 5000))
      
      # 막대 그래프
      plt.bar(
        df_group.index.to_list(), 
        df_group['Volume2'].to_list(),
        color=sns.color_palette(
          'rainbow_r', 
          12
        ),
        edgecolor='black'
      )
      
      plt.xlabel('연도/월',  
        fontproperties=NanumMyengjo, 
        fontsize=16
      )
      plt.ylabel('매출량(단위:만)',  
        fontproperties=NanumMyengjo, 
        fontsize=16
      )
      plt.grid()
      
      ax = plt.gca()
      ax.set_facecolor('#e8e7d2')
      
      fig
    </py-script> 
  </body> 
</html>

 

마무~리

 

이번 시간에는
씨본 라이브러리를 가져와서 색상 파레트를 막대 그래프에 적용하는 부분과 함께
넘파이의 np.arange()  함수를 이용해  Y축 눈금 목록을 좀 더 간결하게 지정하는 부분을 살펴보았습니다.

오늘도 여기까지 열심히 읽어주신 분들, 방문해주신 분들께 감사드립니다.

오늘은 시간이 허락되어 2개나 글을 쓰네요 :)


다음 게시글 : https://itadventure.tistory.com/552

 

파도!(11) - 꺽은선 그래프 - 주단위 매출

'파도'는 파이스크립트 도전기의 줄임말입니다. 지난 게시글에 연재되는 글입니다. https://itadventure.tistory.com/551 파도!(10) - 씨본으로 예쁜 그래프 꾸미기 '파도'는 파이스크립트 도전기의 줄임말

itadventure.tistory.com