데이터 분석 과정 학습 및 시각화 실습(3)-1
2024. 1. 10. 15:53ㆍTIL
matplotlib의 기본문법
시각화(Visualization)는 데이터분석 결과를 Plot이나 Graph등을 통해서 시각적으로 전달할 수 있는 방법이다. 통계수치를 사용한 정량적 분석이 정확한 분석 내용을 전달하는데 강점이 있다면, 시각화는 데이터 분석 내용을 한눈에 볼 수 있게 내용을 효과적으로 전달할 수 있다. 또한, 통계수치상으로는 파악하기 쉽지 않은 내용 또한 분석이 가능한 경우도 존재한다.
예를 들어 데이터 분포를 시각화로 나타낼 때가 있다.
matplotlib은 다양한 데이터를 많은 방법으로 도식화할 수 있도록 하는 파이썬 라이브러리로써, matplotlib의 pyplot을 이용할 것이다. matplotlib을 이용하면 numpy나 pandas에서 사용되는 자료구조를 쉽게 시각화할 수 있다.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 그래프 출력 사이즈 설정
plt.rcParams["figure.figsize"] = (10, 8)
# 기본 문법
plt.plot([1, 2, 3], [3, 6, 9])
plt.plot([1, 2, 3], [2, 4, 9])
plt.show()
# 타이틀 & font 설정
plt.title('이것은 타이틀 입니다', fontsize=20)
# X축 & Y축 Label 설정
plt.xlabel('X축', fontsize=20)
plt.ylabel('Y축', fontsize=20)
# X tick, Y tick 설정
plt.xticks(rotation=90)
plt.yticks(rotation=30)
# 범례(legend) 설정
plt.legend(['10 * 2', '10 ** 2', 'log'], fontsize=15)
# X와 Y의 한계점(Limit) 설정: xlim(), ylim()
plt.xlim(0, 5)
plt.ylim(0.5, 10)
# 마커(marker)
# '.': point marker
# 'o': circle marker
# 'v': triangle_down marker
# '+': plus marker
# '*': star marker
plt.plot(np.arange(10), np.arange(10)*2, marker='o', markersize=10)
# 라인(line)
# '-': solid line style
# '--': dashed line style
# '-.': dash-dot line style
# ':': dotted line style
plt.plot(np.arange(10), np.arange(10)*2, marker='o', linestyle='')
# 컬러(color)
# 'b': blue
# 'g': green
# 'r': red
# 'c': cyan
# 'm': magenta
# 'y': yellow
# 'k': black
# 'w': white
# alpha를 통해 투명도를 조절할 수 있습니다.
plt.plot(np.arange(10), np.arange(10)*2, marker='o', linestyle='-', color='b', alpha=.1)
# Plot 저장하기
plt.savefig('savefig_200dpi.png', dpi=200)
matplotlib plot의 종류 - Scatterplot, Barplot, Histogram
# plt.scatter(s=, c=): x, y 좌표로 이뤄진 데이터들을 점으로 표현하는 플롯
# s는 점 크기, c는 점 색깔을 조절하며 label이나 class에 따른 데이터 분포를 확인할 때 활용 가능
x = np.random.rand(50)
y = np.random.rand(50)
# 각 데이터점마다 class를 가지고 있는 경우, class를 color로도 표현할 수 있다.
colors = [0]*25 + [1]*25
area = x * y * 250
plt.scatter(x, y, s=area, c=colors)
plt.show()
# plt.bar(), plt.barh(): 범주가 있는 데이터 값을 직사각형의 막대로 표현하는 그래프
# width, align 등의 옵션으로 막대 위치 조정
# color와 alpha 옵션을 이용해 각 막대의 색깔 조정
# Barplot: plt.bar()
x = ['Math', 'Programming', 'Data Science', 'Art', 'English','Physics']
y = [66, 80, 60, 50, 80, 10]
plt.figure(figsize=(6, 3))
plt.bar(x, y, align='center', alpha=0.7, color='red')
plt.xticks(x)
plt.ylabel('Number of Students')
plt.title('Subjects')
plt.show()
# Barhplot (축 변환): plt.barh()
# barh 함수에서는 xticks로 설정했던 부분을 yticks로 변경
x = ['Math', 'Programming', 'Data Science', 'Art', 'English','Physics']
y = [66, 80, 60, 50, 80, 10]
plt.barh(x, y, align='center', alpha=0.7, color='green')
plt.yticks(x)
plt.xlabel('Number of Students')
plt.title('Subjects')
plt.show()
# plt.subplots()과 plt.bar나 plt.barh를 함께 사용하면 비교 그래프를 그릴 수 있다.
x_label = ['Math', 'Programming', 'Data Science', 'Art','English', 'Physics']
x = np.arange(len(x_label))
y_1 = [66, 80, 60, 50, 80, 10]
y_2 = [55, 90, 40, 60, 70, 20]
# 넓이 지정
width = 0.35
# subplots 생성
fig, axes = plt.subplots()
# 넓이 설정
axes.bar(x - width/2, y_1, width, align='center', alpha=0.5)
axes.bar(x + width/2, y_2, width, align='center', alpha=0.8)
# xtick 설정
plt.xticks(x)
axes.set_xticklabels(x_label)
plt.ylabel('Number of Students')
plt.title('Subjects')
plt.legend(['john', 'peter'])
plt.show()
# plt.hist(): 히스토그램 (Histogram)은 도수분포표를 그래프로 나타낸 것으로서,
# 가로축은 변수 값, 세로축은 빈도나 비율을 나타낸다
# bins 옵션을 통해 히스토그램 막대 개수 조절
# density=True인 경우에는 frequency 대신 density를 y축에 나타냄
N = 100000
bins = 30
x = np.random.randn(N)
plt.hist(x, bins=bins) # plt.hist(x, bins=bins, density=True)
plt.show()
matplotlib plot의 종류 - Piechart, heatmap
# plt.pie(): 파이 차트는 범주별 구성 비율을 원형으로 표현한 그래프이며,
# 부채꼴의 중심각을 구성 비율에 비례하도록 표현
# explode: 파이에서 툭 튀어져 나온 비율
# autopct: 퍼센트 자동으로 표기 → '%.1f%%': 소수점 1자리까지 표기
# shadow: 그림자 표시
# startangle: 파이를 그리기 시작할 각도
# texts, autotexts 인자를 리턴 받습니다
# texts는 label에 대한 텍스트 효과
# autotexts는 파이 위에 그려지는 텍스트 효과
labels = ['Samsung', 'Huawei', 'Apple', 'Xiaomi', 'Oppo','Etc']
sizes = [20.4, 15.8, 10.5, 9, 7.6, 36.7]
explode = (0.3, 0, 0, 0, 0, 0)
# texts, autotexts 인자를 활용하여 텍스트 스타일링을 적용
patches, texts, autotexts = plt.pie(sizes, explode=explode,
labels=labels,
autopct='%.1f%%',
shadow=True,
startangle=90)
plt.title('Smartphone pie', fontsize=15)
# label 텍스트에 대한 스타일 적용
for t in texts:
t.set_fontsize(12)
t.set_color('gray')
# pie 위의 텍스트에 대한 스타일 적용
for t in autotexts:
t.set_color("white")
t.set_fontsize(18)
plt.show()
# plt.matshow(): 히트맵 (Heatmap)은 다양한 값을 갖는 숫자 데이터를
# 열분포 형태와 같이 색상을 이용해서 시각화
# 지도 이미지 위에 인구의 분포와 같이 2차원(x,y) 형태
# 표현되는 데이터의 빈도 분포를 보여주기에 적합
# Heatmap
import matplotlib.pyplot as plt
import numpy as np
arr = np.random.standard_normal((30, 40))
# 컬러맵 종류 지정
cmap = plt.get_cmap('PiYG')
# cmap = plt.get_cmap('BuGn')
# cmap = plt.get_cmap('Greys')
# cmap = plt.get_cmap('bwr')
plt.matshow(arr, cmap=cmap)
plt.colorbar(shrink=0.8, aspect=10)
plt.show()
matplotlib plot의 종류 - style
# matplotlib.pyplot 모듈은 컬러맵을 간편하게 설정하기 위한 여러 함수를 제공
# plt.plasma(), plt.jet()와 같은 함수를 이용해서 플롯에서 사용되는 색깔들을 다양하게 만듬
# Colormaps
arr = np.random.standard_normal((8, 100))
plt.subplot(2, 2, 1)
plt.scatter(arr[0], arr[1], c=arr[1])
plt.viridis()
plt.title('viridis')
# colorbar() 함수를 사용하면 그래프 영역에 컬러바를 포함
plt.colorbar()
plt.subplot(2, 2, 2)
plt.scatter(arr[2], arr[3], c=arr[3])
plt.plasma()
plt.title('plasma')
plt.colorbar()
plt.subplot(2, 2, 3)
plt.scatter(arr[4], arr[5], c=arr[5])
plt.jet()
plt.title('jet')
plt.colorbar()
plt.subplot(2, 2, 4)
plt.scatter(arr[6], arr[7], c=arr[7])
plt.nipy_spectral()
plt.title('nipy_spectral')
plt.colorbar()
plt.tight_layout()
plt.show()
# plt.text(x위치, y위치, 텍스트, fontdict): 그래프의 적절한 위치에 텍스트를 삽입
# 텍스트 삽입하기
import matplotlib.pyplot as plt
import numpy as np
a = 2.0 * np.random.randn(10000) + 1.0
b = np.random.standard_normal(10000)
c = 20.0 * np.random.rand(5000) - 10.0
font1 = {'color': 'darkred',
'weight': 'normal',
'size': 16}
font2 = {'color': 'blue',
'weight': 'bold',
'size': 12,
'alpha': 0.7}
font3 = {'color': 'forestgreen',
'style': 'italic',
'size': 14}
plt.hist(a, bins=100, density=True, alpha=0.7, histtype='step')
plt.text(1.0, 0.35, 'np.random.randn()', fontdict=font1)
plt.hist(b, bins=50, density=True, alpha=0.5, histtype='stepfilled')
plt.text(2.0, 0.20, 'np.random.standard_normal()', fontdict=font2)
plt.hist(c, bins=100, density=True, alpha=0.9, histtype='step')
plt.text(5.0, 0.08, 'np.random.rand()', fontdict=font3)
plt.show()
# plt.style.use(): 미리 만들어놓은 Matplotlib 그래프 스타일을 사용
# 기본 스타일로 돌아가기 위해서는 plt.style.use(‘default’)를 호출
# plt.style.available를 통해 사용 가능한 스타일을 조회
# 그래프 스타일 설정
np.random.seed(0)
arr = np.random.standard_normal((8, 100))
plt.subplot(2, 2, 1)
plt.scatter(arr[0], arr[1], c=arr[1])
plt.style.use('bmh')
# plt.style.use('ggplot')
# plt.style.use('classic')
# plt.style.use('Solarize_Light2')
plt.title('bmh')
plt.show()
plt.style.use('default')
# 미리 지정해놓은 스타일을 사용하지 않고,
# 각각의 스타일 관련 파라미터 (rcParams)를 지정할 수 있다
# rcParams를 이용해서 커스텀 스타일 설정
import matplotlib.pyplot as plt
plt.style.use('default')
plt.rcParams['figure.figsize'] = (6, 3)
plt.rcParams['font.size'] = 12
plt.rcParams['lines.linewidth'] = 3
plt.rcParams['lines.linestyle'] = '-'
plt.rcParams['xtick.top'] = True
plt.rcParams['ytick.right'] = True
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
plt.plot([1, 2, 3, 4], [4, 6, 2, 7])
plt.show()
plt.style.use('default')
matplotlib plot의 종류 - Subplots
# plt.subplots(행 개수, 열 개수): 하나의 화면 안에 여러 플롯을 넣을 수 있다
# fig, axes 를 plt.subplots()의 인자로 넣은 뒤
# axes[행,열].plot명령어를 입력해 각 subplot에 원하는 플롯을 넣을 수 있다
# Subplots: 여러개의 plot을 그리는 방법
import matplotlib.pyplot as plt
# plt.subplots(행의 갯수, 열의 갯수)
# data 생성
data = np.arange(1, 51)
# 밑 그림: 2행 3열
fig, axes = plt.subplots(2, 3)
axes[0, 0].plot(data)
axes[0, 1].plot(data * data)
axes[0, 2].plot(data ** 3)
axes[1, 0].plot(data % 10)
axes[1, 1].plot(-data)
axes[1, 2].plot(data // 20)
# axes
plt.tight_layout()
plt.show()
# Subplots 스타일 설정하기
# sharex=, sharey=: 중복된 x, y축 표시 공유
x = np.arange(1, 5) # [1, 2, 3, 4]
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True, squeeze=True)
axes[0][0].plot(x, np.sqrt(x), 'gray', linewidth=3, label='y=np.sqrt(x)')
axes[0][0].set_title('Graph 1')
axes[0][0].legend()
axes[0][1].plot(x, x, 'g^-', markersize=10, label='y=x')
axes[0][1].set_title('Graph 2')
axes[0][1].legend(loc='upper left')
axes[1][0].plot(x, -x+5, 'ro--', label='y=-x+5')
axes[1][0].set_title('Graph 3')
axes[1][0].legend(loc='lower left')
axes[1][1].plot(x, np.sqrt(-x+5), 'b.-.', label='y=np.sqrt(-x+5)')
axes[1][1].set_title('Graph 4')
axes[1][1].legend(loc='upper center')
plt.show()
# 두 종류의 데이터를 동시에 하나의 그래프에 표시하기 위해 이중 축을 표시할 수 있다
# ax1.twinx()을 이용해서 ax1과 x축을 공유하는 새로운 Axes 객체인 ax2를 만든다
# 이중 y축 표시하기
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('default')
plt.rcParams['figure.figsize'] = (4, 3)
plt.rcParams['font.size'] = 14
x = np.arange(0, 3)
y1 = x + 1
y2 = -x - 1
fig, ax1 = plt.subplots()
ax1.set_xlabel('X-Axis')
ax1.set_ylabel('1st Y-Axis')
line1 = ax1.plot(x, y1, color='green', label='1st Data')
ax2 = ax1.twinx()
ax2.set_ylabel('2nd Y-Axis')
line2 = ax2.plot(x, y2, color='deeppink', label='2nd Data')
lines = line1 + line2
labels = [l.get_label() for l in lines]
ax1.legend(lines, labels, loc='upper right')
plt.show()
matplotlib plot의 종류 - boxplot, violinplot
# plt.boxplot(): 박스 플롯 (Box plot) 은 수치 데이터의 분포를 표현
# Maximum / minimum value: Q1, Q3로부터 1.5*IQR 내에서 최대/최소값
# notch=True: 중앙값 (Median)의 95% 신뢰 구간을 노치 형태로 표시
# box plot
# 샘플 데이터 생성
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data = np.concatenate((spread, center, flier_high, flier_low))
# 기본 박스플롯 생성
plt.boxplot(data, notch=True)
plt.tight_layout()
plt.show()
# plt.subplots()과 plt.boxplot()을 함께 사용하면 한 그림 안에 여러 boxplot을 그릴 수 있다
# box[‘whiskers’], box[‘median’] 등의 key 호출 후 item.get_ydata()를 통해
# 각 box의 whisker 범위, median, outlier값들을 조회
# 샘플 데이터 생성
spread = np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data_a = np.concatenate((spread, center, flier_high,
flier_low))
spread = np.random.rand(50) * 50
center = np.ones(25) * 25
flier_high = np.random.rand(10) * 50 + 100
flier_low = np.random.rand(10) * -50
data_b = np.concatenate((spread, center, flier_high,
flier_low))
# 두 박스플롯 생성
fig, ax = plt.subplots()
box = ax.boxplot([data_a, data_b])
plt.show()
# whisker 범위, median, outlier값들을 조회
whiskers = [item.get_ydata() for item in box['whiskers']]
medians = [item.get_ydata() for item in box['medians']]
fliers = [item.get_ydata() for item in box['fliers']]
print('whiskers:', whiskers)
print('medians:', medians)
print('fliers:', fliers)
# plt.violinplot(): boxplot에 kde(커널밀도추정)곡선을 같이 그린 형태로 좀 더 세밀한 분포 확인
# quantiles 옵션을 이용해 표시할 분위수를 조절할 수 있다
fig, ax = plt.subplots()
violin = ax.violinplot([data_a, data_b, data_c],
showmeans=True,
showextrema=True,
# showmedians=True,
quantiles=[[0.25, 0.75], [0.1, 0.9], [0.3, 0.7]])
ax.set_ylim(-10.0, 10.0)
ax.set_xticks(np.arange(1, 4))
ax.set_xticklabels(['A', 'B', 'C'])
ax.set_xlabel('Data Type')
ax.set_ylabel('Value')
violin['bodies'][0].set_facecolor('blue')
violin['bodies'][1].set_facecolor('red')
violin['bodies'][2].set_facecolor('green')
violin['cbars'].set_edgecolor('gray')
violin['cmaxes'].set_edgecolor('gray')
violin['cmins'].set_edgecolor('gray')
violin['cmeans'].set_edgecolor('gray')
plt.show()
'TIL' 카테고리의 다른 글
| 데이터 분석 과정 학습 및 시각화 실습(4) (2) | 2024.01.11 |
|---|---|
| 데이터 분석 과정 학습 및 시각화 실습(3)-2 (1) | 2024.01.10 |
| 데이터 분석 과정 학습 및 시각화 실습(2) (2) | 2024.01.09 |
| 데이터 분석 과정 학습 및 시각화 실습(1) (2) | 2024.01.08 |
| Python 프로그래밍 및 Pandas 활용 실습(5)-2 (1) | 2024.01.07 |