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

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

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

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

 

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

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

itadventure.tistory.com


이제 월별 막대 그래프도 진행해보았겠다 해서,
이번에는 일일매출량을 그래프로 그려보려고 했는데,
어라? 중간에 빠진 날짜가 너무 많은게 아니겠습니까?

날짜의 규칙을 잘 살펴보니... 날짜가 일주일 간격으로 건너뛰는걸 이제야 알게 되었지요.
아하... 주간 매출 데이터구나.. 라는 사실을 이제야 알게 되었습니다 ㅎ..

이번에는 이 주간 매출 데이터를 이용해서 가로방향으로 꺾은선 그래프를 그려보는 부분을 다룰텐데요.
이번에는 조금 욕심을 내어 어느 부분까지 완성을 해놓느라 시간이 걸렸습니다.
서서히 보여드릴 것을 기약을 드리며 오늘은 몇가지 알아낸 부분을 공유하겠습니다.

 

기본한글 폰트 지정

 

지난 번에는 폰트를 로드해서 각 요소마다 적용하는 부분을 살펴보았었는데요.
아래 처럼 적용했었지요.
먼저 한글폰트 하나의 속성을 불러와 변수로 보관한 다음에,

// 한글파일 하나 단위로 폰트 변수를 만들고
NanumMyengjo = fm.FontProperties(
  fname='./NANUMMYEONGJO.TTF'
)

제목에 폰트를 적용하거나,

plt.title('월별 아보카도 매출량',  
  fontproperties=NanumMyengjoBold, 
  fontsize=32
);

좌우 축 부분의 제목라벨에 한글을 적용했었지요.
뭐 이 정도까지는 참아줄만 합니다.

plt.xlabel('연도/월',  
  fontproperties=NanumMyengjo, 
  fontsize=16
)
plt.ylabel('매출량(단위:만)',  
  fontproperties=NanumMyengjo, 
  fontsize=16
)


그!런!데, 파이썬 그래프에서 '범레'라고 불리는 이 부분은
어떠한 방법을 동원해도 한글을 표현할 수가 없는 것이 아니겠습니까?


'파이썬에서 헤결했다'는 국내 게시글이나 해외 게시글을 참조해 적용해도,
'파이스크립트'에서는 한글을 불러오는 방식이 달라 해결할 수 없었는데요.

그러던 중 해외 게시글에서 기본 폰트라는 방식을 찾게 되었습니다.
파이 스크립트에서 이렇게 적용해보면 어떨까 기도하는 마음으로 해보니..
웬걸~ 잘 되는게 아니겠습니까!

해당 코드는 아래와 같습니다.
우선 matplotlib 와 폰트 매니저를 선언하는 부분은 동일한데요.

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

다음 3줄이 관건입니다.
이 3줄은 파이스크립트 폰트 시스템에 나눔명조 폰트를 등록하고,
"기본 폰트를 바꿔버려!" 라는 의미거든요. 물론 폰트파일은 서버에 미리 업로드해 놓아야 합니다.
( 폰트 업로드 : https://itadventure.tistory.com/548 참조 )

import matplotlib as mat
fm.fontManager.addfont('./NANUMMYEONGJO.TTF') #  폰트명 : NanumMyeongjo
mat.rc('font', family='NanumMyeongjo')


참고로 family 에 적용할 폰트 이름은 아래 코드를 사용하면 알아 낼 수 있습니다.
이 코드로 알아낸 이름이 바로 NanumMyengjo 인 것이지요.

font_list = [font.name for font in fm.fontManager.ttflist]
for f in font_list:
  print(f)


위 코드를 적용하면, 범례 부분의 한글 문제가 해결됩니다.


그리고 X축 Y축에 제목을 표시하는 코드에도 폰트 이름을 적어줄 필요가 없어 코드가 한결 간결해지지요.
아래처럼 말이지요.

plt.xlabel('날짜', fontsize=16)
plt.ylabel('매출량(단위:만)', fontsize=12)


하지만 뭐.. 개별 폰트 방식도 혼용해 사용 가능합니다.
기본 폰트는 기본폰트고, 개별 폰트는 개별 폰트이니까요. :)

 

한글변수 사용

 

재미있게도 파이스크립트는 한글 변수명 사용이 가능한데요.

매출데이터 = pd.read_csv(open_url(
  "http://dreamplan7.cafe24.com/pyscript/csv/avocado.csv"
))  
매출데이터 = 매출데이터[[
  'Date', 
  'Total Volume'
]]


사실 한글 변수를 사용하면 코드는 알아보기 편리한데, 타이핑하기는 매우 번거롭습니다.
어차피 명령문들은 영어를 써야 하기 때문에 한글과 영어를 혼용해 타이핑하다 보면
한/영키 전환을 매우 빈번하게 사용해야 하는데요.

독자분들의 이해를 쉽게 하기 위해 한글변수로 코드를 정리해보았습니다.
작동은 잘 되는 코드이지만 참고 정도만 하시고 실제코드 작성시에는 영문으로 하실 것을 권장해 드립니다 :)

이번 전체 소스는 아래와 같습니다.

<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 numpy as np

# 판다스에서 csv 를 데이터 프레임으로 읽어옴
매출데이터 = pd.read_csv(open_url(
  "http://dreamplan7.cafe24.com/pyscript/csv/avocado.csv"
))      

# 2개 필드만 추려서 데이터 프레임을 다시 만듬
매출데이터 = 매출데이터[[
  'Date', 
  'Total Volume'
]]   

# 영문 제목을 한글로 변경
매출데이터.columns = [
  '날짜', 
  '매출량'
]

# 주간 매출량 그룹
주간매출데이터 = 매출데이터.fillna(0) \
  .groupby('날짜', as_index=False)[['매출량']] \
  .sum() \
  .sort_values(
    by='날짜', 
    ascending=True
  )

# 10000으로 나눈 매출량 필드 추가
주간매출데이터.insert(2, '매출량(만)', 
  주간매출데이터['매출량']/10000, 
  True)

createElementDiv('output2').write(주간매출데이터)

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib as mat

# 기준 폰트 변경 : legend 의 한글을 적용하려면 필수
fm.fontManager.addfont('./NANUMMYEONGJO.TTF') #  폰트명 : NanumMyeongjo
mat.rc('font', family='NanumMyeongjo')

###################
# 폰트 목록 출력 ( 폰트 추가 후 정확한 이름을 확인하려면 필요
#font_list = [font.name for font in fm.fontManager.ttflist]
#for f in font_list:
#  print(f)      
###################        

# 개별 폰트 적용
NanumMyengjo = fm.FontProperties(
  fname='./NANUMMYEONGJO.TTF'
)
NanumMyengjoBold = fm.FontProperties(
  fname='./NANUMMYEONGJOBOLD.TTF'
)

fig = plt.figure(
  figsize=(15, 7)
)

plt.title('주간 아보카도 매출량',  
  fontproperties=NanumMyengjoBold, 
  fontsize=32
);
plt.xticks(rotation=90, fontsize=8)

# 꺾은선 그래프
plt.plot(        
  주간매출데이터['날짜'].to_list(),
  주간매출데이터['매출량(만)'].to_list(),
  marker='o',
  color='green', 
  label='매출량'
)

# 축 라벨 표시
plt.xlabel('날짜', fontsize=16)
plt.ylabel('매출량(단위:만)', fontsize=12)

# 범례 표시
plt.legend()

ax = plt.gca()
# X축만 그리드
ax.xaxis.grid(True)
# 마진 조정
ax.margins(x=0.01, y=0.02)
# 주위 이상한 여백 없애기
fig.tight_layout() 
fig

</py-script> 
  </body> 
</html>


그러면 출력결과는 아래와 같은데요. 꺾은선 그래프가 뭔가 전문적인 느낌이 있어 보이지 않나요? :)
이 결과는 크레이의 홈페이지에서   고해상도(?)로 확인해 보실 수 있습니다.
http://dreamplan7.cafe24.com/pyscript/py10-1.html

 

이번 소스의 나머지 특징적인 부분 소개드리자면, 아래와 같습니다.

 

데이터 프레임 일부 추리기

 

외부에서 읽어온  csv 파일을 데이터프레임으로 받아온 결과를 가지고,
다시 필요한 데이터 2가지만 먼저 추린다는 점입니다.

매출데이터 = 매출데이터[[
  'Date', 
  'Total Volume'
]]

 

제목 바꾸기

 

그리고 제목을 한글로 바꿔치기합니다.
이제 한국 사람에게 더욱 친숙한 표가 되었군요 :)

매출데이터.columns = [
  '날짜', 
  '매출량'
]

 

날짜 딘위로 그룹 짓기

 

다음으로 매출데이터를 날짜 단위로 그룹으로 합친 다음에,
매출량 ÷ 10,000 을 적용한 수치를 매출량(만)이라는 칸으로 확장합니다.
날짜 단위로 합치지만 일주일 단위의 날짜만 존재하기 때문에 주단위로 집계가 됩니다.

# 주간 매출량 그룹
주간매출데이터 = 매출데이터.fillna(0) \
  .groupby('날짜', as_index=False)[['매출량']] \
  .sum() \
  .sort_values(
    by='날짜', 
    ascending=True
  )
  
# 10000으로 나눈 매출량 필드 추가
주간매출데이터.insert(2, '매출량(만)', 
  주간매출데이터['매출량']/10000, 
  True)

 

범례 표시하기


그래프로 그리는 부분에 대해 추가점은 아래와 같습니다.
먼저 범례를 표시하기 위해 꺾은선 그래프를 그릴 때, label을 주어줍니다.(빨간색)


plt.plot(        
  주간매출데이터['날짜'].to_list(),
  주간매출데이터['매출량(만)'].to_list(),
  marker='o',
  color='green', 
  label='매출량'
)


그리고 아래 코드를 중간에 넣어주면 그래프에 범례가 표시되지요.

plt.legend()

 

 

마무~리

 

명령어 하나 하나 주저리 주저리 설명드리기보다는, 실제 활용예를 보여드리는게 나을것 같아,
그림과 함께 명령어 사용 예를 정리해보았는데요.
필요하신 분께 도움이 되실런지 모르겠습니다 :)

아무쪼록 무더운 여름이지만 모두 힘내세요!

🍦🍹🥤🍉🥝


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

 

파도!(12) - 무신 러닝? 머신러닝! - 리니어 리그레션

'파도'는 파이스크립트 도전기의 줄임말입니다. 지난 게시글까지는 파이스크립트에서 csv 로 된 데이터를 불러와 그래프로 표현하는 것이 중점적인 내용이었지요. https://itadventure.tistory.com/552 파

itadventure.tistory.com