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

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

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

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

 

파도!(8) - 아보카도 판매량

지난 게시글에 연재되는 글입니다 - https://itadventure.tistory.com/548 파이스크립트 도전기(7) - 한글 그래프! 지난 게시글에 이어지는 연재글입니다 : https://itadventure.tistory.com/547 파이스크립트 도..

itadventure.tistory.com

 

지난 게시글에는 약간 규모 있는 18,000건의 아보카도 매출량을 불러와 월별 매출량 통계를 산출했는데요.
이번에는 그래프를 이용하여 매출량을 표시하는 시간을 가져보겠습니다. ( 사실은 완성해놓았지만요 ㅎㅎ )

 

숫자 단위 줄이기

 

그런데 숫자 단위가 너무 커서 ( 매출량이 3억개... )
이 수치를 좀 낮추어보도록 하겠습니다.
미국이라면 영어 표기상 1,000으로 나누겠지만,
여기서는 한국사람들이 보기 편하게 10,000으로 나누고 라벨에는 이렇게 표시하도록 할 겁니다:)
매출량(단위:만)

지난 게시물까지의 소스는 아래와 같은데요. 
별도 분리한 css 는 기능상 중요하지 않으니 여기서는 패스하도록 하겠습니다.

<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
        - 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
      
      # 판다스에서 csv 를 데이터 프레임으로 읽어옴
      df = pd.read_csv(open_url("http://dreamplan7.cafe24.com/pyscript/csv/avocado.csv"))
      
      df.insert(2, 'month', df['Date'].str[:7], True)
      
      createElementDiv('output1').write(df)
      
      # 월별 매출량 조사
      df_group = df.fillna(0).groupby('month')[['Total Volume']].sum().sort_values(by='month', ascending=True)
      
      createElementDiv('output1').write(df_group)
    </py-script> 
  </body> 
</html>


매출량을 10,000 으로 나눈 값을 하나 추가해보겠습니다.
아래 명령은 Total Volumn 값을 10,000으로 나누어 새로운 Volume2 이라는 값을 생성하는 코드입니다.

df.insert(5, 'Volume2', df['Total Volume']/10000, True)

그리고 월별 매출량 조사하는 부분을 아래와 같이 변경하도록 하겠습니다.
지난번에는 Total Volume 으로 월별 매출량을 조사했지만 이번에는 Volume2 로 구하는데요.
한줄이 너무 길어 여러줄로 나누었습니다.

# 월별 매출량 조사
df_group = df.fillna(0) \
  .groupby('month')[['Volume2']] \
  .sum() \
  .sort_values(
    by='month', 
    ascending=True
  )

결과는 어떨까요? 소숫점이 좀 길게 표시되긴 하지만 일반적으로 알아볼 수 있는 수치로 바뀌었군요.
31808 에 단위 10000을 곱하면 3억 천만개 가량이 됩니다!

만일 소숫점이 너무 길어서 첫째자리까지만 표시하고 싶다면, 
10,000이란 수치로 나눌때 데이터를 추가할 때 아래와 같이 round 함수를 사용하면 됩니다.

df.insert(5, 'Volume2', 
  round(df['Total Volume']/10000, 1), 
  True)

결과는 아래와 같은데요. 크레이는 반올림하지 않은 원본으로 합계를 구할거니 사용하지 않을 겁니다 :)

 

막대 그래프 그리기

 

이제 그래프를 그릴텐데요.
이번에는 막대 그래프를 그려 보도록 하겠습니다.
다른건 다 비슷한데, 막대그래프를 그릴 때는 plt.bar() 함수를 사용합니다.

한글 폰트를 적용해서 아래와 같이 코드를 작성하면, 

      :
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()
plt.title('월별 아보카도 매출량',  fontproperties=NanumMyengjoBold, fontsize=32);
plt.bar(
  df_group.index.to_list(), 
  df_group['Volume2'].to_list()
)      

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

이런 결과가 나타납니다.
그래프 하단에 글씨가 너무 다닥 다닥 붙어서 통 알아볼 수가 없군요.
게다가 그래프가 너무 촘촘해서 왼쪽의 글씨도 잘렸습니다.

 

그래프 크기 조정하기

 

우선 폭을 좀 넉넉하게 조정해볼까요?
fig  변수를 받아오는 부분에서 을 아래와 같이 조정하면 그래프가 커집니다.
가로가 15, 세로가 10인 경우 가로가 세로보다 1.5배 더 넓어지는 효과도 있는 것이지요. ( 기본값은 6.4, 4.8 입니다 )

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

이렇게 조종하면 그래프는 아래와 같이 바뀌는데요.

왼쪽 글씨는 무난하지만 아래쪽 글씨는 다닥 다닥 붙어서 통 알아볼 수가 없습니다.
이럴 때 한가지 좋은 방법이 있는데요.
그것은 바로 글씨를 45도 회전하는 것이지요.

 

그래프 라벨 글씨 회전


뭐.. 90도 회전해도 무방하지만, 크레이는 45도로 하겠습니다 :)
아래 코드를 추가해주면 되는데요.

plt.xticks(rotation=45)

그 결과는 아래와 같습니다. 꽤 쓸만해 보이지 않으신가요? ㅎㅎ

그리드라는 안내선을 추가할 수도 있는데요,
이 명령어는 미관에 영향을 끼치므로 필요할 때만 적용하면 좋을것 같군요.

plt.grid()

결과


여기까지 내용이 반영된 최종 소스는 아래와 같습니다.
http://dreamplan7.cafe24.com/pyscript/py9-2.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
        - 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
      
      # 판다스에서 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, 10))
      plt.title('월별 아보카도 매출량',  fontproperties=NanumMyengjoBold, fontsize=32);
      plt.xticks(rotation=45)
      plt.bar(
        df_group.index.to_list(), 
        df_group['Volume2'].to_list()
      )      

      plt.xlabel('연도/월',  fontproperties=NanumMyengjo, fontsize=16)
      plt.ylabel('매출량(단위:만)',  fontproperties=NanumMyengjo, fontsize=16)
      plt.grid()
      fig
    </py-script> 
  </body> 
</html>

 

보너스 스테이지!

 

일부 더 알아낸 부분이 있어 마저 끄적입니다.
판매량을 보면 제일 낮은 지점이 2016년 11월이 2억 6천만개인데요.
상대 변화를 확실히 보기 위해 2억 5천만부터 시작해서 6억까지 Y축을 지정하는 방법도 있습니다.

그 때 사용하는 함수가 xlim, ylim입니다.
y축에만 적용할거니까 ylim을 다음과 같이 사용하고 ( 25000 부터 30000까지 표시 )

plt.ylim(25000, 60000)


눈금도 1억단위보다는 5천만 단위가 되는 것이 좋겠지요.
눈금을 지정하는 함수는 금방 회전을 위해 사용했던 xticks와  yticks 함수입니다.
y축의 눈금을 지정해야 하기 때문에 아래와 같이  사용할 눈금 목록을 지정하는 코드를 써줍니다.

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

아울러 아보카도 색상에 맞게 눈금바의 색상도 변경해볼까요?

# 막대 그래프
plt.bar(
  df_group.index.to_list(), 
  df_group['Volume2'].to_list(),
  color='forestgreen'
)

결과는 아래와 같습니다. 뭐 소스는.. 아래 페이지에서 소스 보기하시면 보실수 있을 겁니다 :)
http://dreamplan7.cafe24.com/pyscript/py9-3.html

 

마무~리

 

오늘은 파이스크립트를 이용하여 월 매출 그래프를 그리는 부분을 살펴보았는데요.
매출량 수치 단위가 너무 커서 10,000으로 나눈 수치를 데이터에 추가하는 부분,
막대 그래프를 표시하고 크기를 확대하는 부분과 화면 하단의 라벨이 겹쳐 알아보기 어려울 떄 이를 45도 회전하여 겹치지 않게 표시하는 부분과 부가적으로 Y 축의 시작 눈금과 끝 눈금을 변화시켜 살펴보았습니다.


아무쪼록 방문하신 분들, 내용 읽어주신 모든 분들 감사드립니다.
유익하셨다면, 공감 한방, 댓글은 굿잡!
감사합니다~


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

 

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

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

itadventure.tistory.com