yooonicode
python 데이터 분석 - ch 6 본문
- 맷플롯립의 고급 기능 및 새로운 그래프(스택, 막대, 원)
📖 6-1 객체지향 API
그래프를 그리는 방식으로는
matplotlib.pyplot의 pyplot 방식
피겨 객체와 서브플롯 객체를 만들고 메서드를 사용하는 객체지향 API 방식
- 복잡한 그래프 그릴때는 객체지향 방식이 좋음(하나의 피겨에 여러가지 서브플롯)
✔️ 한글 출력 방법
- 맷플롯립의 기본 폰트가 한글을 지원하지 않음
폰트 설치 이후 맷플롯립 임포트, DPI 기본값의 변경
- sans-serif 폰트로 되어있음을 확인하는 코드를 rcParams의 font.family 속성에서 찾을 수 있음
- 나눔고딕으로 변경 - rc()
> 설정할 그룹이 첫번째 매개변수, font가 그룹이고 family는 그룹의 하위 속성이므로 첫 매개변수는 font, 둘째 매개변수에는 그룹 하위 속성을 지정함, rc()를 사용하면 여러 설정을 동시에 지정할 수 있으며 rc.Params 객체로 다시 확인도 가능함
- findSystemFonts() 를 사용하여 맷플롯립에서 사용가능한 전체 폰트 목록 불러오기
✔️ 출판사별 발행 도서 산점도
- value_counts()는 고유한 출판사 목록을 만드는데, 내림차순 정렬이 기본값으로 되어있어 슬라이스 연산자를 사용하여 상위 30개를 슬라이싱함
- ns_book7에서 상위 30개인지 행을 표시하는 불리언 인덱스를 만듬 - isin()메서드를 활용
- sample() 메서드를 활용하여 데이터프레임의 행을 무작위로 선택, 산점도로 그릴 수 있는 양을 추출함
- random_state는 넘파이의 seed() 함수와 같은 역할을 하는 가짜 난수 생성기와 유사함
- 일부러 subplots를 지정하여 자연스러운 객체지향 API 사용
- 값에 따라서 마커 크기를 변경하여 어떤 연도에 많이 대출되었는지 시각적으로 보이도록 함
- scatter()는 마커의 크기를 지정할 수 있는 s 매개변수를 제공하는데, 기본값은 6임
➡️ 실수값으로 전달하면 모든 마커크기가 동일하므로 대출건수 열을 마커 크기로 전달하여 상대적으로 크게 그릴 수 있도록 함
- 투명도 조절하여 책 권수 가늠 가능하게 변경
- 마커 테두리 색, 겹칠 때 경계를 구분할 수 있도록 함
- 테두리 선의 두께 바꾸기
- 산점도 색의 변경
- s 매개변수는 대출건수 *2로 변경
https://matplotlib.org/stable/gallery/color/colormap_reference.html
- 컬러맵 변경 관련 레퍼런스 문서
Colormap reference — Matplotlib 3.8.0 documentation
Colormap reference Reference for colormaps included with Matplotlib. A reversed version of each of these colormaps is available by appending _r to the name, as shown in Reversed colormaps. See Choosing Colormaps in Matplotlib for an in-depth discussion abo
matplotlib.org
- 기본값에서 jet 컬러맵으로 변경
- 컬러 막대를 옆에 그리기
📖 6-2 고급 기능
- 하나의 피겨에 여러가지 그래프 그리기, 명확한 표현을 위한 고급 기능
- 서브 플롯을 활용한 하나의 피겨에 다양한 그래프 그리는 법
- csv 불러오고, 대출 건수를 value_count()로 하여 상위 30개 추출
- 상위 30개에 해당하는지 여부를 담은 불리언 배열을 top_30_idx에 담은 후
- ns_book9에 상위 30개 출판사이며, 발행년도와 대출건수, 출판사 열만을 담은 데이터프레임 만들기
- ns_book9에 출판사와 발행년도를 기준으로 묶은 후, 합을 계산함
- 인덱스 리셋
- 황금가지를 line1, 비룡소를 line2에 배치하여 두 출판사의 발행년도와 대출건수를 비교
- 범주를 추가함
- 상위 5개의 출판사 대상, 반복문을 이용하여 다섯개의 그래프를 동시에 그리는 코드
- xlim을 1985부터 2025까지 두어 현실적인 데이터만 추가
⭐ 피벗테이블 기능 - 엑셀의 피벗테이블과 유사함
멀티인덱스를 사용하여 3차원으로 나타낼 필요 없이 2차원으로 나타낼 수 있음
- 데이터의 재정렬을 통한 관점 전환까지 기대할 수 있음
✔️ 스택 그래프 그리기 - stackplot()
- 각 출판사의 연도별 대출건수를 쌓아 그리려면, y축에 들어갈 2차원 배열은 행이 출판사, 열이 발행년도로 구성되어야함
- x축에는 발행년도를 전달하고, y축에는 2차원 배열을 전달함
30개의 출판사 중에서, 상위 10개의 출판사만 간단히 한 후
year_cols에 x축이 될 발행년도를 리스트형태로 변경하여 저장하였음
- get_level_values는 멀티인덱스로 되어있는 열 이름에서 ('대출건수', 연도) 첫 번째 인덱스인 연도만 추출할 수 있게 함
- stackplot()으로 스택영역 그래프 그리기
y축에는 ns_book10에서 상위 10개에 해당하는 열을 골라서 NaN 채워서 제공하고
fillna() 하지 않으면 맷플롯립에서 오류 발생할 수 있음
- 피벗테이블 만들때 pivot_table() 에서 fill_value = 0으로 지정하면 저거 안해도 됨
legend, 범례는 loc 매개변수로 위치 지정 가능함(기본값은 best)
- 그래프 사이의 값은 자동으로 채워 출력됨
✔️ 하나의 피겨에 여러 막대그래프
- 겹쳐서 아래 그래프 보이지 않는 현상 발생, 이럴 때 폭을 줄이고 위치를 이동시킬 수 있음
이를 보완하기 위해서 그래프를 쌓아 그리는 방법이 존재함
⭐ 스택 막대 그래프
- bottom 인자에 height1을 전달함으로써 가능케함
- 시작 위치를 누적하여 보관하기 번거로우니, 길이를 누적해놓고 막대 그래프를 그리는 방법도 존재함
+ bottom 매개변수의 사용 없이 그래프를 그릴 수 있음
- 만약 출판사 여러개인 그래프를 그려야 한다면 두 번째 방법이 적합함
상위 5개의 출판사만 loc를 이용하여 슬라이싱 한 뒤, cumsum() 메서드를 호출하여 연도별 대출건수의 누적합을 담기
- ns_book12에 저장한 후, 가장 큰 막대를 먼저 그리게 되므로 reversed() 함수를 사용하여 인덱스 역순으로 반복
- range 함수로 행 개수만큼 인덱스 번호를 만들기
✔️ 원 그래프 그리기 - 파이차트, pie()
top30pubs의 상위 10개를 선택하여 저장하고, 상위 10개 출판사의 인덱스를 저장하여 labels 매개변수에 저장하였음
발행 도서 비율이 3시부터 반시계방향으로 그려지고, 자동으로 계산되어 구성되었음
크기 순서대로 data값이 정렬되어 있기 때문에, 정렬되어 있지 않다면 사진상으로는 확인할 수 없을 것
- 원그래프는 시각적으로 데이터의 대소를 판단할 수 없음(특히 3차원)
➡️따라서 잘못된 정보 제공을 조심해야 함
- startangle을 지정하여 12시 방향부터 그래프를 그림
✔️ 원 그래프 비율 표시하고 강조하기
- autopct에는 % 연산자의 문자열을 전달할 수 있음, &d는 문자열 -> %d%와 같이 표기
- explode에 떨어뜨리기 원하는 조각의 간격을 반지름 비율로 지정하기, explode에 전달하는 리스트 길이는 data 배열의 길이와 항상 같아야함
✔️ 여러 종류 그래프를 포함한 서브플롯
- 산점도, 스택 영역그래프, 스택막대그래프, 원그래프를 한꺼번에 모두 그리기 위하여
- 2차원 배열 형태로 4개의 서브플롯을 그림(2,2)
fig, axes = plt.subplots(2, 2, figsize=(20, 16))
# 산점도
ns_book8 = ns_book7[top30_pubs_idx].sample(1000, random_state=42)
sc = axes[0, 0].scatter(ns_book8['발행년도'], ns_book8['출판사'],
linewidths=0.5, edgecolors='k', alpha=0.3,
s=ns_book8['대출건수'], c=ns_book8['대출건수'], cmap='jet')
axes[0, 0].set_title('출판사별 발행도서')
fig.colorbar(sc, ax=axes[0, 0])
# 스택 선 그래프
axes[0, 1].stackplot(year_cols, ns_book10.loc[top10_pubs].fillna(0),
labels=top10_pubs)
axes[0, 1].set_title('년도별 대출건수')
axes[0, 1].legend(loc='upper left')
axes[0, 1].set_xlim(1985, 2025)
# 스택 막대 그래프
for i in reversed(range(len(ns_book12))):
bar = ns_book12.iloc[i] # 행 추출
label = ns_book12.index[i] # 출판사 이름 추출
axes[1, 0].bar(year_cols, bar, label=label)
axes[1, 0].set_title('년도별 대출건수')
axes[1, 0].legend(loc='upper left')
axes[1, 0].set_xlim(1985, 2025)
# 원 그래프
axes[1, 1].pie(data, labels=labels, startangle=90,
autopct='%.1f%%', explode=[0.1]+[0]*9)
axes[1, 1].set_title('출판사 도서비율')
fig.savefig('all_in_one.png')
fig.show()
✔️ 판다스로 그래프 그리기
피벗테이블 지정, 인덱스에는 발행년도, columns에는 출판사 열을 지정하여 2000년~2005년 사이의 데이터를 확인
pivot_table()의 values에 열을 지정한다면, 열 이름이 다단으로 구성되지 않아서 get_level_values() 사용 안해도 됨

values에 지정한 열을 집계한다는건?
pivot_table()과 groupby()는 유사하나, groupby()는 집계 기준이 되는 열이 모두 행 인덱스로 바뀌지만 피벗테이블은 집계 기준이 행, 열 인덱스로 나뉜다.
만약 집계하지 않았던(groupby() 하지 않았던) ns_book7에서 바로 ns_book11로 넘어오는 코드를 만든다면 윗 코드와 같아짐 단, aggfunc의 기본값은 평균이나 sum으로 지정해주어 값을 모두 더해줄 수 있음
결과적으로, 행이 발행년도이고 열이 출판사인 데이터프레임을 이용하여 plot.area()를 이용하여 스택영역 그래프를 그릴 수 있음
✔️ 스택 막대 그래프 - 판다스가 더 쉬움
ns_book11을 이용하여 막대 그래프를 쌓으면
stacked = True로 지정한다면 그릴 수 있고, 맷플롯립처럼 cumsum() 사용 없이 한번에 가능
- 판다스는 막대의 두께가 0.5 디폴트이기 때문에 맷플롯립과 유사하게 0.8을 사용하면 위와 같이 그려짐
'데이터분석' 카테고리의 다른 글
머신러닝 + 딥러닝 - ch 1-3, 2-1, 2-2 (1) | 2023.10.06 |
---|---|
python 데이터 분석 ch 7-1, 7-2 (0) | 2023.09.30 |
python 데이터 분석 - ch 5 (0) | 2023.09.22 |
python 데이터 분석 - ch 4 (1) | 2023.09.15 |
python 데이터 분석 - ch 3 (0) | 2023.09.15 |