[Python] Matplotlib정리(그래프 데이터 시각화 라이브러리)

Matplotlib

다양한 형태의 그래프를 통해서 데이터 시각화를 할 수 있는 라이브러리

import matplotlib.pyplot as plt

1. 그래프 기본

x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x2240f664dc0>]

print(plt.plot(x, y)) # print를 하면 출력(리턴값)이 나오는건데, print안해도 나오니까 그냥 쓰자
[<matplotlib.lines.Line2D object at 0x000002240FDEC760>]

plt.plot(x, y)
plt.show() # 이것은 리턴값도 안나오고 그래프만 뜨게하는 show()함수이다.

Title 설정

plt.plot(x, y)
plt.title('Line Graph')
Text(0.5, 1.0, 'Line Graph')

plt.plot(x, y)
plt.title('꺾은선 그래프')

한글 폰트 설정

import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows사용시 이렇게(맑은 고딕)
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기(여기까지만 해도 한글 깨짐 해결)
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
import matplotlib.font_manager as fm
fm.fontManager.ttflist # 사용 가능한 폰트 확인(상세하게 나옴)
[f.name for f in fm.fontManager.ttflist] # 폰트 이름만 확인(상세하게는 X)
['STIXGeneral',
 'STIXSizeFourSym',
 'DejaVu Serif',
 'STIXNonUnicode',
 'cmmi10',
 'cmr10',
 'DejaVu Serif',
 ...]
plt.plot(x, y)
plt.title('꺾은선 그래프') # 제목만 따로 폰트 설정도 가능
# plt.title('꺾은선 그래프', fontdict={'family':'HYGungSo-Bold', 'size':20}) # 개별 폰트 설정
Text(0.5, 1.0, '꺾은선 그래프')

plt.plot([-1, 0, 1], [-5, -1, 2]) # 마이너스가 깨지는 현상 발생하는데, 아래 코드 사용
# matplotlib.rcParams['axes.unicode_minus'] = False
[<matplotlib.lines.Line2D at 0x2241001b220>]

2. 축

데이터는 위에랑 동일하게 다시 가져오겠다.

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y)
plt.title('꺾은선 그래프', fontdict={'family':'HYGungSo-Bold', 'size':20}) # 개별 폰트 설정
Text(0.5, 1.0, '꺾은선 그래프')

plt.plot(x, y)
plt.xlabel('X축')
plt.ylabel('Y축')
Text(0, 0.5, 'Y축')

plt.plot(x, y)
plt.xlabel('X축', color='red')
plt.ylabel('Y축', color='#00aa00')
Text(0, 0.5, 'Y축')

plt.plot(x, y)
plt.xlabel('X축', color='red', loc='right') # left, center, right
plt.ylabel('Y축', color='#00aa00', loc='top') # top, center, bottom
Text(0, 1, 'Y축')

plt.plot(x, y)
plt.xticks([1, 2, 3])
plt.yticks([3, 6, 9, 12])
plt.show()

3. 범례 (legend)

범례의 위치를 조정하는 값을 좀 더 알고싶다면?

  • matplotlib legend검색후 공식 사이트
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y, label='무슨 데이터')
plt.legend() # 위치 기본값 : 'best'이며, 그래프 제일 빈공간에 자동 위치
<matplotlib.legend.Legend at 0x2a6aee086a0>

plt.plot(x, y, label='무슨 데이터')
plt.legend(loc='upper right')
<matplotlib.legend.Legend at 0x2a6b1773760>

plt.plot(x, y, label='무슨 데이터')
plt.legend(loc='lower right')
<matplotlib.legend.Legend at 0x2a6b1890ee0>

plt.plot(x, y, label='범례')
plt.legend(loc=(0.7, 0.8)) # x축, y축 (0~1 사이) 즉, 위치 아무곳이나 넣을 수 있겠죠.
<matplotlib.legend.Legend at 0x2a6b19159d0>

4. 스타일

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26f3d3a2b50>]

plt.plot(x, y, linewidth=5) # 선두께 조정
[<matplotlib.lines.Line2D at 0x26f3db81730>]

마커 (marker)

좀더 마커 모양들이 궁금하다면?

  • matplotlib marker검색후 공식홈페이지
plt.plot(x, y, marker='o') # 데이터 존재하는 부분에 마커설정
[<matplotlib.lines.Line2D at 0x26f3dbd6eb0>]

plt.plot(x, y, marker='o', linestyle='None') # 선까지 없애기
[<matplotlib.lines.Line2D at 0x26f3dc34910>]

plt.plot(x, y, marker='v') # v모양으로 마커
[<matplotlib.lines.Line2D at 0x26f3dc87f40>]

plt.plot(x, y, marker='v', markersize=10) # 마커 사이즈 또한 조정 가능
[<matplotlib.lines.Line2D at 0x26f3dce66d0>]

plt.plot(x, y, marker='X', markersize=10) # X모양으로 마커 설정
[<matplotlib.lines.Line2D at 0x26f3dd37df0>]

plt.plot(x, y, marker='o', markersize=20, markeredgecolor='red') # 마커 모서리 빨간색
[<matplotlib.lines.Line2D at 0x26f3de465b0>]

plt.plot(x, y, marker='o', markersize=20, markeredgecolor='red', markerfacecolor='yellow') # 마커 내부까지 색조정
[<matplotlib.lines.Line2D at 0x26f3dc100a0>]

선 스타일

선 스타일이 좀 더 궁금하다면?

  • matplotlib linestyle 검색후 공식홈페이지
plt.plot(x, y, linestyle=':') # 그래프 선 스타일을 조정
[<matplotlib.lines.Line2D at 0x26f3e273f10>]

plt.plot(x, y, linestyle='--')
[<matplotlib.lines.Line2D at 0x26f3df2cb20>]

plt.plot(x, y, linestyle='-.')
[<matplotlib.lines.Line2D at 0x26f3df8e2b0>]

plt.plot(x, y, linestyle='-')
[<matplotlib.lines.Line2D at 0x26f3e2d26d0>]

색깔

좀더 다양한 색깔이 궁금하다면?

  • matplotlib color 검색후 공식홈페이지

(RGB값을 이용해서 하는것도 추천)

plt.plot(x, y, color='pink') # 선 색깔 변경(기본값 : blue)
[<matplotlib.lines.Line2D at 0x26f3f2f2dc0>]

plt.plot(x, y, color='#ff0000') # RGB값으로도 가능
[<matplotlib.lines.Line2D at 0x26f3f354580>]

plt.plot(x, y, color='b')
[<matplotlib.lines.Line2D at 0x26f3f3a5c10>]

plt.plot(x, y, color='g')
[<matplotlib.lines.Line2D at 0x26f3f405400>]

포맷

plt.plot(x, y, 'ro--') # color, marker, linestyle
[<matplotlib.lines.Line2D at 0x26f3dfbe1c0>]

plt.plot(x, y, 'bv:')
[<matplotlib.lines.Line2D at 0x26f3f425430>]

plt.plot(x, y, 'go') # linestyle이 없으면, None으로 한거와 똑같은 결과
[<matplotlib.lines.Line2D at 0x26f3f4e8d30>]

plt.plot(x, y, color='g', marker='o', linestyle='None')
[<matplotlib.lines.Line2D at 0x26f3f5464f0>]

축약어

예로 마커의 색지정의 경우 너무 긴데, 이것을 줄이는 경우,, 등

  • matplotlib markerfacecolor mfc 검색후 공식홈페이지(축약어 좀 더 알고싶다면)
plt.plot(x, y, marker='o', mfc='red', ms=10, mec='blue', ls=':')
[<matplotlib.lines.Line2D at 0x26f3f596d30>]

투명도

plt.plot(x, y, marker='o', mfc='red', ms=10, alpha=0.2) # alpha : 투명도 (0~1)
[<matplotlib.lines.Line2D at 0x26f3f6fba30>]

그래프 크기

plt.figure(figsize=(10, 5)) # width:10, height:5
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26f3f75b160>]

plt.figure(figsize=(5, 10))
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26f3f7b2df0>]

plt.figure(figsize=(10, 5), dpi=150) # dots per inch, 확대 즉, 해상도조절
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26f3f521f40>]

배경색

plt.figure(facecolor='yellow')
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26f3f84caf0>]

plt.figure(facecolor='#a1c3ff')
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26f3fa178e0>]

5. 파일 저장

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y)

plt.savefig('graph.png', dpi=100) # 파일저장(dpi=해상도)

plt.figure(dpi=200)
plt.plot(x, y)
plt.savefig('graph_200.png', dpi=100) # dpi 200에서 100으로 다시 저장

6. 텍스트

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x18536892b80>]

plt.plot(x, y, marker='o')

for idx, txt in enumerate(y): # idx는 인덱스정보, txt에는 2,4,8 정보가 들어감
    plt.text(x[idx], y[idx] + 0.3, txt, ha='center', color='blue') # x, y는 위치!!

7. 여러 데이터

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
x = [1, 2, 3]
y = [2, 4, 8]
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x22801e71b80>]

COVID-19 백신 종류별 접종 인구

days = [1, 2, 3] # 1일, 2일, 3일
az = [2, 4, 8] # (단위 : 만명) 1일부터 3일까지 아스트라제네카 접종인구
pfizer = [5, 1, 3] # 화이자
moderna = [1, 2, 5] # 모더나

plt.plot(days, az)
plt.plot(days, pfizer)
plt.plot(days, moderna)
[<matplotlib.lines.Line2D at 0x228025fb430>]

plt.plot(days, az, label='az')
plt.plot(days, pfizer, label='pfizer', marker='o', linestyle='--')
plt.plot(days, moderna, label='moderna', marker='s', ls='-.')

plt.legend()
<matplotlib.legend.Legend at 0x22802656cd0>

plt.plot(days, az, label='az')
plt.plot(days, pfizer, label='pfizer', marker='o', linestyle='--')
plt.plot(days, moderna, label='moderna', marker='s', ls='-.')

plt.legend(ncol=3) # 3개 컬럼만큼 레전드를 표시할 수 있다
<matplotlib.legend.Legend at 0x228026c7d30>

8. 막대 그래프 (기본)

  • 이때까지 plot이였는데, bar하면 막대 그래프이다.
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
labels = ['강백호', '서태웅', '정대만'] # 이름
values = [190, 187, 184] # 키

plt.bar(labels, values) # bar를 하면 막대그래프
<BarContainer object of 3 artists>

labels = ['강백호', '서태웅', '정대만'] # 이름
values = [190, 187, 184] # 키

plt.bar(labels, values, color='r')
<BarContainer object of 3 artists>

labels = ['강백호', '서태웅', '정대만'] # 이름
values = [190, 187, 184] # 키
colors = ['r', 'g', 'b']

plt.bar(labels, values, color=colors, alpha=0.5) # 데이터별 다른색 지정 및 투명도 0.5
<BarContainer object of 3 artists>

labels = ['강백호', '서태웅', '정대만'] # 이름
values = [190, 187, 184] # 키

plt.bar(labels, values)
plt.ylim(175, 195) # y축에 제한을 둠
(175.0, 195.0)

plt.bar(labels, values, width=0.5) # bar두께 너비도 조절
<BarContainer object of 3 artists>

plt.bar(labels, values, width=0.3)
plt.xticks(rotation=45) # x 축의 이름 데이터 각도를 45 도로 설정
plt.yticks(rotation=45) # y 축의 키 데이터 각도를 45도로 설정
(array([  0.,  50., 100., 150., 200.]),
 [Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, ''),
  Text(0, 0, '')])

labels = ['강백호', '서태웅', '정대만'] # 이름
values = [190, 187, 184] # 키
ticks = ['1번학생', '2번학생', '3번학생']

plt.bar(labels, values)
plt.xticks(labels, ticks, rotation=90) # x축에 ticks도 바꾸고 싶다면, ticks넣을수 있다.
([<matplotlib.axis.XTick at 0x1e95b35ce20>,
  <matplotlib.axis.XTick at 0x1e95b35cdf0>,
  <matplotlib.axis.XTick at 0x1e95b35c0d0>],
 [Text(0.0, 0, '1번학생'), Text(1.0, 0, '2번학생'), Text(2.0, 0, '3번학생')])

9. 막대 그래프 (심화)

  • plot, bar가 아닌 barh를 통해 수평으로 가는 그래프

  • set_hatch()의 무늬가 더 궁금하다면?

  • matplotlib hatch 검색 후 공식문서

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
labels = ['강백호', '서태웅', '정대만'] # 이름
values = [190, 187, 184] # 키

plt.barh(labels, values) # 수평으로 가는 그래프
plt.xlim(175, 195) # x축 제한을 둠
(175.0, 195.0)

bar = plt.bar(labels, values)
bar[0].set_hatch('/') # ////
bar[1].set_hatch('x') # xxxx
bar[2].set_hatch('..') # ...

bar = plt.bar(labels, values)
plt.ylim(175, 195)

for idx, rect in enumerate(bar): # rect.get_height()는 바의 높이 가져옴!!
    plt.text(idx, rect.get_height() + 0.5, values[idx], ha='center', color='blue')

10. DataFrame 활용

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
df = pd.read_excel('../Pandas/score.xlsx')
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기
0 1번 채치수 북산고 197 90 85 100 95 85 Python
1 2번 정대만 북산고 184 40 35 50 55 25 Java
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN
4 5번 강백호 북산고 188 15 20 10 35 10 NaN
5 6번 변덕규 능남고 202 80 100 95 85 80 C
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON
7 8번 윤대협 능남고 190 100 85 90 95 95 C#
plt.plot(df['지원번호'], df['키'])
[<matplotlib.lines.Line2D at 0x238e446d550>]

plt.plot(df['지원번호'], df['영어'])
plt.plot(df['지원번호'], df['수학'])
[<matplotlib.lines.Line2D at 0x238e4bd0f10>]

plt.plot(df['지원번호'], df['영어'])
plt.plot(df['지원번호'], df['수학'])
# grid는 격자를 의미
plt.grid(axis='y', color='purple', alpha=0.5, linestyle='--', linewidth=2)

11. 누적 막대 그래프

  • bottom속성을 이용
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
df = pd.read_excel('../Pandas/score.xlsx')
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기
0 1번 채치수 북산고 197 90 85 100 95 85 Python
1 2번 정대만 북산고 184 40 35 50 55 25 Java
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN
4 5번 강백호 북산고 188 15 20 10 35 10 NaN
5 6번 변덕규 능남고 202 80 100 95 85 80 C
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON
7 8번 윤대협 능남고 190 100 85 90 95 95 C#
plt.bar(df['이름'], df['국어'])
plt.bar(df['이름'], df['영어'])
<BarContainer object of 8 artists>

plt.bar(df['이름'], df['국어'])
plt.bar(df['이름'], df['영어'], bottom=df['국어']) # bottom을 활용해 누적된것처럼 보이게 함
<BarContainer object of 8 artists>

plt.bar(df['이름'], df['국어'])
plt.bar(df['이름'], df['영어'], bottom=df['국어'])
plt.bar(df['이름'], df['수학'], bottom=df['국어'] + df['영어'])
<BarContainer object of 8 artists>

plt.bar(df['이름'], df['국어'], label='국어')
plt.bar(df['이름'], df['영어'], bottom=df['국어'], label='영어')
plt.bar(df['이름'], df['수학'], bottom=df['국어'] + df['영어'], label='수학')

plt.xticks(rotation=60)
plt.legend()
<matplotlib.legend.Legend at 0x274ee2ba730>

12. 다중 막대 그래프

  • bar의 위치를 조금 옮겨서 다중으로 그림
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
df = pd.read_excel('../Pandas/score.xlsx')
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기
0 1번 채치수 북산고 197 90 85 100 95 85 Python
1 2번 정대만 북산고 184 40 35 50 55 25 Java
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN
4 5번 강백호 북산고 188 15 20 10 35 10 NaN
5 6번 변덕규 능남고 202 80 100 95 85 80 C
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON
7 8번 윤대협 능남고 190 100 85 90 95 95 C#
import numpy as np
np.arange(5)
array([0, 1, 2, 3, 4])
np.arange(3, 6)
array([3, 4, 5])
arr = np.arange(5)
arr
array([0, 1, 2, 3, 4])
arr + 100 # 아주 쉽게 이렇게 연산이 되니까 numpy의 배열을 이용하려는 것이다.
array([100, 101, 102, 103, 104])
arr * 3
array([ 0,  3,  6,  9, 12])
df.shape[0]
8
N = df.shape[0]
N
8
index = np.arange(N)
index
array([0, 1, 2, 3, 4, 5, 6, 7])
w = 0.25
plt.bar(index - w, df['국어']) # 0.25만큼 x축에서 왼쪽
plt.bar(index, df['영어']) # x축에 정확
plt.bar(index + w, df['수학']) # 0.25만큼 x축에서 오른쪽
<BarContainer object of 8 artists>

w = 0.25
plt.bar(index - w, df['국어'], width=w)
plt.bar(index, df['영어'], width=w)
plt.bar(index + w, df['수학'], width=w)
<BarContainer object of 8 artists>

w = 0.25
plt.bar(index - w, df['국어'], width=w, label='국어')
plt.bar(index, df['영어'], width=w, label='영어')
plt.bar(index + w, df['수학'], width=w, label='수학')
plt.legend(ncol=3)
<matplotlib.legend.Legend at 0x23478b787f0>

plt.figure(figsize=(10, 5))
plt.title('학생별 성적')

w = 0.25
plt.bar(index - w, df['국어'], width=w, label='국어')
plt.bar(index, df['영어'], width=w, label='영어')
plt.bar(index + w, df['수학'], width=w, label='수학')
plt.legend(ncol=3)
plt.xticks(index, df['이름'], rotation=60)
plt.show()

13. 원 그래프 (기본)

  • pie를 이용
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'DejaVu Sans' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
# values = [1,1,1,1,1,1] # 이였다면?? 똑같은 퍼센트로 균일하게 나뉘어져 나옴.
values = [30, 25, 20, 13, 10, 2]
labels = ['Python', 'Java', 'Javascript', 'C#', 'C/C++', 'ETC']

# labels속성을 통해 이름, autopct속성을 통해 퍼센트값, startangle속성을 통해 시작위치, counterclock속성을 통해 방향 조정
plt.pie(values, labels=labels, autopct='%.1f%%', startangle=90, counterclock=False)
plt.show()

values = [30, 25, 20, 13, 10, 2]
labels = ['Python', 'Java', 'Javascript', 'C#', 'C/C++', 'ETC']
# explode = [0.2, 0.1, 0, 0, 0, 0] # 얼만큼 간격을 띄울지 정해줌
explode = [0.05] * 6

plt.pie(values, labels=labels, explode=explode)
plt.show()

plt.pie(values, labels=labels, explode=explode)
plt.legend(loc=(1.2, 0.3)) # 범례의 위치를 1.2, 0.3으로 조정
plt.show()

plt.pie(values, labels=labels, explode=explode)
plt.title('언어별 선호도')
plt.legend(loc=(1.2, 0.3), title='언어별 선호도') # 범례에도 이름설정 가능(이름은 '언어'가 더 어울리는듯)
plt.show()

14. 원 그래프 (심화)

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
values = [30, 25, 20, 13, 10, 2]
labels = ['Python', 'Java', 'Javascript', 'C#', 'C/C++', 'ETC']
# colors = ['b', 'g', 'r', 'c', 'm', 'y']
colors = ['#ffadad', '#ffd6a5', '#fdffb6', '#caffbf', '#9bf6ff', '#a0c4ff']
explode = [0.05] * 6

plt.pie(values, labels=labels, autopct='%.1f%%', startangle=90, counterclock=False, colors=colors, explode=explode)
plt.show()

wedgeprops={'width':0.6} # 그래프의 너비를 0.6 크기로 지정한것임.
plt.pie(values, labels=labels, autopct='%.1f%%', startangle=90, counterclock=False, colors=colors, explode=explode, wedgeprops=wedgeprops)
plt.show()

# explode를 제거하고, wedgeprops의 속성을 변경해서 흰선으로 구분하는 효과를 나타내었다.
wedgeprops={'width':0.6, 'edgecolor':'w', 'linewidth':2}
plt.pie(values, labels=labels, autopct='%.1f%%', startangle=90, counterclock=False, colors=colors, wedgeprops=wedgeprops)
plt.show()

def custom_autopct(pct): # 데이터가 10%이상일때만 글자를 보여주는 함수
    # return ('%.1f%%' % pct) if pct >= 10 else ''
    # return '{:.1f}%'.format(pct) if pct >= 10 else ''
    return '{:.0f}%'.format(pct) if pct >= 10 else ''

plt.pie(values, labels=labels, autopct=custom_autopct, startangle=90, counterclock=False, colors=colors, wedgeprops=wedgeprops, pctdistance=0.7)
plt.show()

DataFrame 활용

import pandas as pd
df = pd.read_excel('../Pandas/score.xlsx')
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기
0 1번 채치수 북산고 197 90 85 100 95 85 Python
1 2번 정대만 북산고 184 40 35 50 55 25 Java
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN
4 5번 강백호 북산고 188 15 20 10 35 10 NaN
5 6번 변덕규 능남고 202 80 100 95 85 80 C
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON
7 8번 윤대협 능남고 190 100 85 90 95 95 C#
grp = df.groupby('학교')
grp
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000028721D0CF70>
grp.size()['북산고']
5
values = [grp.size()['북산고'], grp.size()['능남고']] # [5, 3]
labels = ['북산고', '능남고']

plt.pie(values, labels=labels)
plt.title('소속 학교')
plt.show()

15. 산점도 그래프

  • scatter를 사용해서 두 변수의 상관관계를 보여줌

  • cmap의 속성을 이용해 색깔의 종류를 더 보고 싶다면?

  • matplotlib cmap검색후 공식홈페이지

import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
import pandas as pd
df = pd.read_excel('../Pandas/score.xlsx')
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기
0 1번 채치수 북산고 197 90 85 100 95 85 Python
1 2번 정대만 북산고 184 40 35 50 55 25 Java
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN
4 5번 강백호 북산고 188 15 20 10 35 10 NaN
5 6번 변덕규 능남고 202 80 100 95 85 80 C
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON
7 8번 윤대협 능남고 190 100 85 90 95 95 C#
df['학년'] = [3, 3, 2, 1, 1, 3, 2, 2]
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기 학년
0 1번 채치수 북산고 197 90 85 100 95 85 Python 3
1 2번 정대만 북산고 184 40 35 50 55 25 Java 3
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript 2
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN 1
4 5번 강백호 북산고 188 15 20 10 35 10 NaN 1
5 6번 변덕규 능남고 202 80 100 95 85 80 C 3
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON 2
7 8번 윤대협 능남고 190 100 85 90 95 95 C# 2
plt.scatter(df['영어'], df['수학'])
plt.xlabel('영어 점수')
plt.ylabel('수학 점수')
Text(0, 0.5, '수학 점수')

import numpy as np # random을 사용하기위해 numpy를 import
sizes = np.random.rand(8) * 1000
sizes
array([967.23240474, 919.67463531, 875.30308684, 871.79979536,
        75.82145791, 590.42068742,  67.9515297 , 202.37825985])
plt.scatter(df['영어'], df['수학'], s=sizes)
plt.xlabel('영어 점수')
plt.ylabel('수학 점수')
Text(0, 0.5, '수학 점수')

sizes = df['학년'] * 500 # 1학년 = 500, 2학년 = 1000, 3학년 = 1500 (랜덤으로 하지않고)
plt.scatter(df['영어'], df['수학'], s=sizes)
plt.xlabel('영어 점수')
plt.ylabel('수학 점수')
Text(0, 0.5, '수학 점수')

# c속성은 데이터마다 색깔지정, cmap은 colormap 즉, cmap내에서 '학년'별 데이터 색 지정했음
plt.scatter(df['영어'], df['수학'], s=sizes, c=df['학년'], cmap='viridis', alpha=0.3)
plt.xlabel('영어 점수')
plt.ylabel('수학 점수')
Text(0, 0.5, '수학 점수')

plt.figure(figsize=(7, 7))
plt.scatter(df['영어'], df['수학'], s=sizes, c=df['학년'], cmap='viridis', alpha=0.3)
plt.xlabel('영어 점수')
plt.ylabel('수학 점수')
plt.colorbar(ticks=[1, 2, 3], label='학년', shrink=0.5, orientation='horizontal') # 맨 아래에 있는 그래프를 의미
# shrink는 크기라 보면 됨
<matplotlib.colorbar.Colorbar at 0x2c4bda87520>

16. 여러 그래프

  • 여러 그래프를 넣는법을 배움
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15 # 글자 크기
matplotlib.rcParams['axes.unicode_minus'] = False # 한글 폰트 사용 시, 마이너스 글자가 깨지는 현상을 해결
import pandas as pd
df = pd.read_excel('../Pandas/score.xlsx')
df
지원번호 이름 학교 국어 영어 수학 과학 사회 SW특기
0 1번 채치수 북산고 197 90 85 100 95 85 Python
1 2번 정대만 북산고 184 40 35 50 55 25 Java
2 3번 송태섭 북산고 168 80 75 70 80 75 Javascript
3 4번 서태웅 북산고 187 40 60 70 75 80 NaN
4 5번 강백호 북산고 188 15 20 10 35 10 NaN
5 6번 변덕규 능남고 202 80 100 95 85 80 C
6 7번 황태산 능남고 188 55 65 45 40 35 PYTHON
7 8번 윤대협 능남고 190 100 85 90 95 95 C#
fig, axs = plt.subplots(2, 2, figsize=(15, 10)) # 2 x 2 에 해당하는 plot 들을 생성(4개 그래프 생성)
fig.suptitle('여러 그래프 넣기') # 전체 제목(fig를 통해)

# 사용법이 기존과 조금 조금씩 다르기 때문에 참고할 것
# 첫 번째 그래프(axs를 통해)
axs[0, 0].bar(df['이름'], df['국어'], label='국어점수') # 데이터 설정
axs[0, 0].set_title('첫 번째 그래프') # 제목
axs[0, 0].legend() # 범례
axs[0, 0].set(xlabel='이름', ylabel='점수') # x, y 축 label
axs[0, 0].set_facecolor('lightyellow') # 전면 색
axs[0, 0].grid(linestyle='--', linewidth=0.5)

# 두 번째 그래프
axs[0, 1].plot(df['이름'], df['수학'], label='수학')
axs[0, 1].plot(df['이름'], df['영어'], label='영어')
axs[0, 1].legend()

# 세 번째 그래프
axs[1, 0].barh(df['이름'], df['키'])

# 네 번째 그래프
axs[1, 1].plot(df['이름'], df['사회'], color='green', alpha=0.5)
[<matplotlib.lines.Line2D at 0x14d386f9fd0>]

Matplotlib 퀴즈

다음은 대한민국 영화 중에서 관객 수가 가장 많은 상위 8개의 데이터입니다.

주어진 코드를 이용하여 퀴즈를 풀어보시오.

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # Windows
# matplotlib.rcParams['font.family'] = 'AppleGothic' # Mac
matplotlib.rcParams['font.size'] = 15
matplotlib.rcParams['axes.unicode_minus'] = False

data = {
    '영화' : ['명량', '극한직업', '신과함께-죄와 벌', '국제시장', '괴물', '도둑들', '7번방의 선물', '암살'],
    '개봉 연도' : [2014, 2019, 2017, 2014, 2006, 2012, 2013, 2015],
    '관객 수' : [1761, 1626, 1441, 1426, 1301, 1298, 1281, 1270], # (단위 : 만 명)
    '평점' : [8.88, 9.20, 8.73, 9.16, 8.62, 7.64, 8.83, 9.10]
}
df = pd.DataFrame(data)
df
영화 개봉 연도 관객 수 평점
0 명량 2014 1761 8.88
1 극한직업 2019 1626 9.20
2 신과함께-죄와 벌 2017 1441 8.73
3 국제시장 2014 1426 9.16
4 괴물 2006 1301 8.62
5 도둑들 2012 1298 7.64
6 7번방의 선물 2013 1281 8.83
7 암살 2015 1270 9.10

1) 영화 데이터를 활용하여 x 축은 영화, y 축은 평점인 막대 그래프를 만드시오.

plt.bar(df['영화'], df['평점'])
<BarContainer object of 8 artists>

2) 앞에서 만든 막대 그래프에 제시된 세부 사항을 적용하시오.

  • 제목 : 국내 Top 8 영화 평점 정보

  • x축 label : 영화 (90도 회전)

  • y축 label : 평점

plt.bar(df['영화'], df['평점'])
plt.title('국내 Top 8 영화 평점 정보')
plt.xlabel('영화')
plt.xticks(rotation=90)
plt.ylabel('평점')
plt.show()

3) 개봉 연도별 평점 변화 추이를 꺾은선 그래프로 그리시오.

연도별 평균 데이터를 구하는 코드는 다음과 같습니다.

df_group = df.groupby('개봉 연도').mean()
df_group
관객 수 평점
개봉 연도
2006 1301.0 8.62
2012 1298.0 7.64
2013 1281.0 8.83
2014 1593.5 9.02
2015 1270.0 9.10
2017 1441.0 8.73
2019 1626.0 9.20
plt.plot(df_group.index, df_group['평점'])
[<matplotlib.lines.Line2D at 0x202e3c63340>]

4) 앞에서 만든 그래프에 제시된 세부 사항을 적용하시오.

  • marker : ‘o’

  • x 축 눈금 : 5년 단위 (2005, 2010, 2015, 2020)

  • y 축 범위 : 최소 7, 최대 10

plt.plot(df_group.index, df_group['평점'], marker='o')
plt.xticks([2005, 2010, 2015, 2020])
plt.ylim(7, 10)
(7.0, 10.0)

5) 평점이 9점 이상인 영화의 비율을 확인할 수 있는 원 그래프를 제시된 세부 사항을 적용하여 그리시오.

  • label : 9점 이상 / 9점 미만

  • 퍼센트 : 소수점 첫째자리까지 표시

  • 범례 : 그래프 우측에 표시

filt = df['평점'] >= 9.0
values = [len(df[filt]), len(df[~filt])]
labels = ['9점 이상', '9점 미만']

plt.pie(values, labels=labels, autopct='%.1f%%')
plt.legend(loc=(1, 0.3))
plt.show()

댓글남기기