본문 바로가기
데이터 분석/혼자 공부하는 데이터 분석 with 파이썬

[혼공분석] 6주차_복잡한 데이터 표현하기

by yEvery 2025. 2. 23.

06-1 객체지향 API로 그래프 꾸미기

 

pyplot 방식: matplotlib.pyplot에 있는 함수를 사용

객체지향 API: 명시적으로 피겨 객체와 서브플롯 객체를 만들고 이 객체의 메서드를 사용

import sys
if 'google.colab' in sys.modules:
  !echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
  #나눔폰트 설치
  !sudo apt-get -qq -y install fonts-nanum
  import matplotlib.font_manager as fm
  font_files = fm.findSystemFonts(fontpaths=['/usr/share/fonts/truetype/nanum'])
  for fpath in font_files:
      fm.fontManager.addfont(fpath)

위와 같은 코드를 통해 한글 폰트를 설치할 수 있다.

#rcParams 객체의 font.family 속성으로 폰트 지정
plt.rcParams['font.family'] = 'NanumGothic'
#rc() 함수로 폰트 지정
plt.rc('font', family='NanumBarunGothic')

두 가지 방식으로 폰트를 지정할 수 있다.

ns_book8 = ns_book7[top30_pubs_idx].sample(1000, random_state=42)
#sample(무작위로 선택할 행 개수, ...)

sample() 메서드: 데이터프레임의 행을 무작위로 선택

random_state 매개변수: 넘파이의 seed() 함수와 비슷한 역할, 예시와 동일한 값을 전달하면 항상 같은 결과

fig, ax = plt.subplots(figsize=(10, 8))
ax.scatter(ns_book8['발행년도'], ns_book8['출판사'])
ax.set_title('출판사별 발행 도서')
plt.show()

객체지향 API 방식으로 산점도를 그린다.

ax.scatter(ns_book8['발행년도'], ns_book8['출판사'], s=ns_book8['대출건수'])

s 매개변수: 마커의 크기를 지정, 하나의 실수로 바꾸면 산점도의 모든 마커 크기가 동일하게 바뀜.

                   입력 데이터와 동일한 길이의 배열을 지정하면 각 데이터마다 마커의 크기가 다른 산점도를 그릴 수 있다.

ax.scatter(ns_book8['발행년도'], ns_book8['출판사'], linewidth=0.5, edgecolor='k', alpha=0.3, s=ns_book8['대출건수']*2, c=ns_book8['대출건수'])

alpha 매개변수: 마커의 투명도 결정

edgecolor 매개변수: 마커 테두리의 색 결정

linewidths 매개변수: 마커 테두리 선의 두께 결정

c 매개변수: 산점도의 지정,

                    s 매개변수와 마찬가지로 데이터 개수와 동일한 길이의 배열을 전달하면,

                   각 데이터를 다른 색깔로 그릴 수 있다.

매개변수 사용 차이

sc = ax.scatter(ns_book8['발행년도'], ns_book8['출판사'], linewidth=0.5, edgecolor='k', alpha=0.3, s=ns_book8['대출건수']*2, c=ns_book8['대출건수'], cmap='jet')
fig.colorbar(sc)

cmap 매개변수: 컬러맵 지정

컬러맵: 값에 따른 색상을 다르게 표현, 자주 사용하는 컬러맵은 jet 컬러맵

colorbar() 메서드: 컬러 막대를 그려준다.

컬러 막대: 컬러맵의 색깔이 어떤 대출건수 값에 대응하는지 참조 정보를 제공


기본 숙제(필수): p. 344의 손코딩(맷플롯립의 컬러맵으로 산점도 그리기)을 코랩에서 그래프 출력하고 화면 캡처하기

 

06-2 맷플롯립의 고급 기능 배우기

fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(line1['발행년도'], line1['대출건수'], label='황금가지')
ax.plot(line2['발행년도'], line2['대출건수'], label='비룡소')
ax.set_title('연도별 대출건수')
ax.legend()
fig.show()

범례(legend): plot 함수를 호출할 때 각 선 그래프에 label을 추가하고, 마지막에 legend() 메서드를 호출하면 범례 추가

범례 없/있


추가 숙제(선택): p. 356 ~ 359의 스택 영역 그래프를 그리는 과정을 정리하기

 

스택 영역 그래프: 하나의 선 그래프 위에 다른 선 그래프를 차례대로 쌓는 것, 그래프 사이의 간격이 y축의 값

stackplot() 메서드: 첫 번째 매개변수 - x축의 값

                               두 번째 매개변수 - y축값을 2차원 배열로 전달

ns_book10 = ns_book9.pivot_table(index='출판사', columns='발행년도')

pivot_table() 메서드: 하나의 열을 2차원 배열로 바꾸는 것처럼 데이터 구조를 바꾸는 방법

index 매개변수: 행 인덱스로 사용할 열 이름 지정

columns 매개변수: 열 인덱스로 사용할 열 이름 지정

ns_book10.columns[:10]

열이 다단으로 구성되어 있다.

year_cols = ns_book10.columns.get_level_values(1) #('대출건수', 1947)에서 1947만 가져오기

get_level_values() 메서드: 다단으로 구성된 열 이름에서 선택한 항목만 가져올 수 있다.

fig, ax = plt.subplots(figsize=(8, 6))
ax.stackplot(year_cols, ns_book10.loc[top10_pubs].fillna(0), labels=top10_pubs)
ax.set_title('연도별 대출건수')
ax.legend(loc='upper left')
ax.set_xlim(1985, 2025)
fig.show()

fillna() 메서드 사용 이유: 맷플롯립은 판다스 데이터프레임의 누락된 값을 제대로 처리하지 못해 그래프가 이상하게 그려지는 경우가 있다. 그래프를 그리기 전에 fillna() 메서드를 사용하면 이런 현상을 막을 수 있다.

pivot_table() 메서드 호출 시 fill_value = 0으로 지정해도 이런 현상을 막을 수 있다.

legend() 메서드의 loc 매개변수: 범례의 위치를 지정


fig, ax = plt.subplots(figsize=(8, 6))
ax.bar(line1['발행년도'], line1['대출건수'], label='황금가지')
ax.bar(line2['발행년도'], line2['대출건수'], label='비룡소')
ax.set_title('연도별 대출건수')
ax.legend()
fig.show()

bar() 메서드를 연이어 호출하면 먼저 그린 막대를 덮어쓰게 되어 올바르게 나타낼 수 없다.

ax.bar(line1['발행년도']-0.2, line1['대출건수'], width=0.4, label='황금가지')
ax.bar(line2['발행년도']+0.2, line2['대출건수'], width=0.4, label='비룡소')

이런 식으로 막대의 너비를 줄이고 x축 조정을 하면 아래와 같이 그릴 수 있다.

많은 출판사의 데이터를 그릴 때는 보기가 어렵다.

height1 = [5, 4, 7, 9, 8]
height2 = [3, 2, 4, 1, 2]

plt.bar(range(5), height1, width=0.5)
plt.bar(range(5), height2, bottom=height1, width=0.5) #height1 막대가 끝나는 위치에서 시작
plt.show()

스택 막대 그래프: 막대그래프를 위로 쌓아 그린다.

bar() 메서드의 bottom 매개변수를 사용하여 수동으로 쌓는다. 막대가 시작할 y좌표를 결정

height3 = [a + b for a, b in zip(height1, height2)]

plt.bar(range(5), height3, width=0.5)
plt.bar(range(5), height1, width=0.5)
plt.show()

아예 막대의 총 길이를 먼저 그리고 그 위에 덮을 막대 그래프를 나중에 그린다.

ns_book10.loc[top10_pubs[:5], ('대출건수', 2013):('대출건수', 2020)]
ns_book10.loc[top10_pubs[:5], ('대출건수', 2013):('대출건수', 2020)].cumsum()

cumsum() 메서드: 판다스 데이터 프레임의 값을 누적

cumsum() 적용

fig, ax = plt.subplots(figsize=(8, 6))
for i in reversed(range(len(ns_book12))):
  bar = ns_book12.iloc[i] #행 추출
  label = ns_book12.index[i] # 출판사 이름 추출
  ax.bar(year_cols, bar, label=label)
ax.set_title('연도별 대출건수')
ax.legend(loc='upper left')
ax.set_xlim(1985, 2025)
fig.show()

for문을 이용하여 역순으로 가장 높이가 높은 막대부터 그린다.

fig, ax = plt.subplots(figsize=(8, 6))
ax.pie(data, labels=labels)
ax.set_title('출판사 도서 비율')
fig.show()

원 그래프: 전체 데이터에 대한 비율을 원의 부채꼴로 나타낸 그래프, 파이 차트

pie() 메서드: 원 그래프 그리기

                     첫 번째 매개변수: 데이터를 전달하면 자동으로 전체에 대한 비율을 계산하여 그래프를 그림

labels 매개변수: 표시할 출판사 이름을 저장

plt.pie([10, 9], labels=['A제품', 'B제품'], startangle=90)

startangle 매개변수: 보통 3시 방향부터 반시계 방향으로 그린다. 시작할 각도를 정하는 매개변수.

ax.pie(data, labels=labels, startangle=90, autopct='%.1f%%', explode=[0.1]+[0]*9)

autopct 매개변수: 파이썬의 %연산자에 적용할 포맷팅 문자열을 전달

explode 매개변수: 중요한 항목을 원 그래프에서 조금 떨어뜨려 부각,

                              떨어뜨리길 원하는 조각의 간격을 반지름의 비율로 지정

fig, axes = plt.subplots(2, 2, figsize=(20, 16))

#산점도
sc = axes[0, 0].scatter(ns_book8['발행년도'], ns_book8['출판사'], linewidth=0.5, edgecolors='k', 
alpha=0.3, s=ns_book8['대출건수']*2, c=ns_book8['대출건수'], cmap='jet')

#스택 영역
axes[0, 1].stackplot(year_cols, ns_book10.loc[top10_pubs].fillna(0), labels=top10_pubs)

#스택 막대
axes[1, 0].bar(year_cols, bar, label=label)

#원
axes[1, 1].pie(data, labels=labels, startangle=90, autopct='%.1f%%', explode=[0.1]+[0]*9)

subplots() 함수의 첫 번째 매개변수와 두 번째 매개변수에 서브플롯의 행 개수와 열 개수를 지정

axes[0, 0], axes[0, 1], axes[1, 0], axes[1, 1]과 같이 지정하여 사용

판다스로 그래프 그리기
fig, ax = plt.subplots(figsize=(8, 6))
ns_book11[top10_pubs].plot.area(ax=ax, title='연도별 대출건수', xlim=(1985, 2025))
ax.legend(loc='upper left')
fig.show()

plot.area() 메서드: ax 매개변수 - 맷플롯립의 Axes 객체를 전달

                              title 매개변수: 그래프 제목 지정

                              xlim 매개변수: x축의 범위설정

fig, ax = plt.subplots(figsize=(8, 6))
ns_book11.loc[1985:2025, top10_pubs].plot.bar(ax=ax, title='연도별 대출건수', stacked=True, width=0.8)
ax.legend(loc='upper left')
fig.show()

 plot.bar() 메서드: stacked 매개변수: True로 지정하면 스택 막대 그래프를 그릴 수 있다.