Repository navigation
Expand file tree
/
Copy pathpandasPlotEx.py
More file actions
109 lines (91 loc) · 4.66 KB
/
Copy pathpandasPlotEx.py
File metadata and controls
109 lines (91 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# pandas 로 바로 그리기 — 실무에서 가장 많이 쓰는 방법
#
# DataFrame 에 .plot() 이 붙어 있습니다. 내부적으로 matplotlib 을 부르므로
# 결과는 같고, 데이터가 이미 pandas 에 있다면 훨씬 짧습니다.
import matplotlib.pyplot as plt
import pandas as pd
from pathlib import Path
import krfont
krfont.apply(verbose=False)
SHOW = False
DATA = Path('..') / 'step11_pandas' / 'data'
sales = pd.read_csv(DATA / 'sales.csv', parse_dates=['날짜'])
products = pd.read_csv(DATA / 'products.csv')
df = (sales.drop_duplicates()
.fillna({'지역': '미상'})
.merge(products, on='상품코드', how='left'))
df['매출'] = df['수량'] * df['단가']
df['월'] = df['날짜'].dt.month
print('데이터 :', df.shape)
print('\n========== matplotlib 으로 그리면 ==========')
monthly = df.groupby('월')['매출'].sum()
fig, ax = plt.subplots(figsize=(8, 3.5))
ax.plot(monthly.index, monthly.values, marker='o')
ax.set_title('월별 매출 (matplotlib)')
fig.savefig('output/50_manual.png', dpi=100, bbox_inches='tight')
plt.close(fig)
print('========== pandas 로 그리면 ==========')
ax = monthly.plot(kind='line', marker='o', figsize=(8, 3.5),
title='월별 매출 (pandas)')
ax.get_figure().savefig('output/51_pandas.png', dpi=100, bbox_inches='tight')
plt.close('all')
print('50_manual.png / 51_pandas.png — 같은 그래프, 한 줄 차이')
print(' 인덱스가 x축, 값이 y축이 됩니다. groupby 결과와 궁합이 좋습니다.')
print('\n========== kind 로 종류 바꾸기 ==========')
by_cat = df.groupby('분류')['매출'].sum().sort_values()
for kind in ['bar', 'barh', 'pie']:
# pie 에만 있는 옵션이라 종류에 따라 붙였다 뗀다.
# autopct=None 으로 넘기면 bar 쪽에서 AttributeError 가 납니다 —
# '값이 None' 인 것과 '인자를 안 넘기는 것' 은 다릅니다.
extra = {'autopct': '%1.1f%%'} if kind == 'pie' else {}
ax = by_cat.plot(kind=kind, figsize=(5, 4), title=f"kind='{kind}'", **extra)
ax.get_figure().savefig(f'output/52_kind_{kind}.png', dpi=100, bbox_inches='tight')
plt.close('all')
print("52_kind_*.png — kind: line·bar·barh·hist·box·scatter·pie·area")
print('\n========== 여러 열을 한 번에 ==========')
pivot = df.pivot_table(index='월', columns='분류', values='매출',
aggfunc='sum', fill_value=0)
print(pivot.head(3))
ax = pivot.plot(kind='bar', stacked=True, figsize=(9, 4),
title='월별 분류 매출 (누적)')
ax.set_ylabel('매출 (원)')
ax.legend(title='분류')
ax.get_figure().savefig('output/53_pivot_stacked.png', dpi=100, bbox_inches='tight')
plt.close('all')
print('53_pivot_stacked.png — 열마다 자동으로 색과 범례가 붙습니다.')
print(' 피벗 테이블을 그대로 넘기면 되므로 step11 과 바로 이어집니다.')
print('\n========== subplots=True : 열마다 따로 ==========')
axes = pivot.plot(subplots=True, layout=(1, 3), figsize=(12, 3),
sharey=True, legend=False, title='분류별 월 매출')
axes[0][0].get_figure().savefig('output/54_subplots.png', dpi=100, bbox_inches='tight')
plt.close('all')
print('54_subplots.png')
print('\n========== 분포 그래프도 한 줄 ==========')
ax = df['매출'].plot(kind='hist', bins=25, figsize=(6, 3.5),
title='주문 금액 분포', edgecolor='white')
ax.get_figure().savefig('output/55_hist.png', dpi=100, bbox_inches='tight')
plt.close('all')
ax = df.boxplot(column='매출', by='분류', figsize=(6, 4))
ax.get_figure().suptitle('') # 자동으로 붙는 제목 제거
ax.set_title('분류별 주문 금액 분포')
ax.get_figure().savefig('output/56_box.png', dpi=100, bbox_inches='tight')
plt.close('all')
print('55_hist.png / 56_box.png')
print('\n========== 언제 어느 쪽을 쓸까 ==========')
print('''
pandas .plot() : 데이터가 이미 DataFrame 에 있고, 빠르게 확인만 할 때.
탐색적 분석(EDA)에서는 거의 이것만 씁니다.
matplotlib 직접 : 세밀하게 다듬어 보고서·발표에 넣을 때.
주석·강조·복잡한 배치가 필요하면 이쪽입니다.
섞어 써도 됩니다. .plot() 이 Axes 를 돌려주므로 받아서 계속 손보면 됩니다.
''')
ax = monthly.plot(kind='bar', figsize=(8, 3.5), color='lightsteelblue')
ax.axhline(monthly.mean(), color='crimson', linestyle='--',
label=f'평균 {monthly.mean():,.0f}')
ax.set_title('pandas 로 그리고 matplotlib 으로 다듬기')
ax.legend()
ax.get_figure().savefig('output/57_mixed.png', dpi=100, bbox_inches='tight')
plt.close('all')
print('57_mixed.png')
if SHOW:
plt.show()