시각화 기초
데이터 분석
| 단계 | 설명 |
|---|
| 문제 정의 | 어떤 문제를 해결하고자 하는가? 이를 위해서는 어떠한 데이터가 필요한가? |
| 데이터 수집 | 기존에 존재하는 데이터인가? 수집을 하기 위해서 어떠한 파이프라인 구축해야하는가? requests, Selenium |
| 데이터 전처리 | 데이터가 프로그래밍으로 처리할 수 있게 정제된 데이터인가? 결측치(빈 데이터)는 없는가? 어떻게 채울 것인가? (숫자로 되어 있을 것) Numpy, Pandas |
| 데이터 모델링 | 데이터를 가지고 어떠한 알고리즘, 어떠한 순서로 모델을 만들 것? (모델=데이터를 가지고 예측, 분류 등을 하는 프로그램) Scikit-Learn, Keras, Pytorch |
| 시각화 및 탐색 | 모델의 결과를 가지고 다른 사람들에게, 조직에게 어떤 식으로 보여줄 것이냐? 어떤 인사이트를 추출할 것이냐? |
Matplotlib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# pip install matplotlib
import matplotlib.pyplot as plt # 기억
라인 플롯
- 간단한 선을 그리는 차트 (line plot)
- 데이터가 시간, 순서 등에 따라서 어떻게 변화하는지 보여주기 위해 사용
# plt
plt.title("Line Plot #1") # 제목
# 1개의 매개변수(인자) => y축에 표시될 데이터
data = [i ** 2 for i in range(1, 5)] # 1, 4, 9, 16
plt.plot(data) # x축? -> index. (자동으로 지정 => 정수 인덱스)
# plt.plot(연속된 데이터: 리스트, 배열, 튜플, range...)
plt.show()

# plt.plot(np.arange(20))
# plt.plot(np.arange(0,20,5))
plt.plot(np.random.randint(5, size=5))
plt.show()

plt.title("X tick") # x축(가로축)에 표시될 데이터 위치를 잡고 싶다면?
# 2개 : x축 데이터, y축 데이터
xdata = np.arange(10, 50, 10)
ydata = [i ** 2 for i in range(1, 5)]
plt.plot(xdata, ydata)
plt.show()

# 한글은 깨져보임
plt.title("한글")
xdata = np.arange(10, 50, 10)
ydata = [i ** 2 for i in range(1, 5)]
plt.plot(xdata, ydata)
plt.show()

# 1. 나눔폰트
!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf
# 2. 런타임 재시작 -> 런타임 / 런타임 다시 시작 (Ctrl + M .)
# 3. 기본 폰트를 나.바.고로 세팅
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 한글 제대로 표시됨
plt.title('한글')
plt.plot(np.arange(10, 50, 10), [i ** 2 for i in range(1, 5)])
plt.show()

plt.title('나이와 재산의 상관관계')
plt.plot(range(10, 50, 10), [1, 4, 9, 16])
# plt.xlabel('x축 라벨')
plt.xlabel('나이')
# plt.ylabel('y축 라벨')
plt.ylabel('재산')
plt.show()

plt.title('나이와 재산의 상관관계')
plt.plot(
range(10, 50, 10), # x축 데이터
[1, 4, 9, 16], # y축 데이터
# 'rs--', # 차트 스타일
'go-', # 차트 스타일
)
# plt.xlabel('x축 라벨')
plt.xlabel('나이')
# plt.ylabel('y축 라벨')
plt.ylabel('재산')
plt.show()


그리드 설정 (grid)
# 보조선 활성화/비활성화 : plt.grid(T/F)
# def draw_line(style):
def draw_line(grid=False, style='b-'):
plt.title('나이와 재산의 상관관계')
plt.plot(
range(10, 50, 10), # x축 데이터
[1, 4, 9, 16], # y축 데이터
style # 차트의 스타일
)
# plt.xlabel('x축 라벨')
plt.xlabel('나이')
# plt.ylabel('y축 라벨')
plt.ylabel('재산')
plt.grid(grid)
plt.show()
draw_line()
draw_line(True)
draw_line(True, 'go:')

여러 개의 선 그어보기
t = np.arange(0., 5., 0.2)
# 1. 여러 개의 선 그리기 (하나의 plot 사용)
plt.title('라인 플롯에서 여러 개의 선')
plt.plot(
t, t, 'r--',
t, t ** 2, 'bs:',
t, t ** 3, 'g^-',
)
plt.show()

plt.title('라인 플롯에서 여러 개의 선')
charts = [t, t, 'r--',
t, t ** 2, 'bs:',
t, t ** 3, 'g^-',]
plt.plot(*charts)
plt.show()
plt.title('라인 플롯에서 여러 개의 선')
chart1 = [t, t, 'r--']
chart2 = [t, t ** 2, 'bs:']
chart3 = [t, t ** 3, 'g^-']
plt.plot(*chart1, *chart2, *chart3)
plt.show()

# 2. 하나의 plot이 아니라 여러 개 -> 겹치는.
plt.title('여러 개의 plot 명령으로 한 그림에 겹쳐서 표현')
# for i in range(10):
# plt.plot((np.arange(4) + (1 if not i % 2 else -1)) ** (i+2))
# plt.plot((np.arange(4) + 1) ** 2)
# plt.plot((np.arange(4) - 1) ** 3)
[plt.plot((np.arange(4) + (1 if not i % 2 else -1)) ** (i+2)) for i in range(3)]
plt.show()

그림의 구조
# 그래프의 크기 조정 plt.figure(figsize=(가로 너비, 세로 길이))
plt.figure(figsize=(25, 1))
plt.plot(np.random.randn(100))
plt.show()

subplot
- plot 명령을 여러 번 실행 => 같은 그래프 내부에 여러 직선 표시
- subplot : 행과 열 단위로 묶어서 여러 데이터를 병행해서 표시
# 위아래 행 배치
# 행, 열, 서브플롯의 위치
plt.subplot(2, 1, 1) # plt <- subplot(2, 1, 1) 지정해줄 수 있는...
plt.plot(np.arange(5) ** 2)
plt.title('차트1')
plt.subplot(2, 1, 2)
plt.plot(np.arange(10), np.arange(10) ** 3, 'r--')
plt.plot(np.arange(10), np.arange(10) ** 2, 'g--')
plt.title('차트2')
# 겹치는 문제
plt.tight_layout() # 안 겹치게 레이아웃 조정
plt.show()

# 양옆 열 배치
# 행, 열, 서브플롯의 위치
plt.subplot(1, 2, 1)
plt.plot(np.arange(5) ** 2)
plt.title('차트1')
plt.subplot(1, 2, 2)
plt.plot(np.arange(10), np.arange(10) ** 3, 'r--')
plt.title('차트2')
# 겹치는 문제
plt.tight_layout() # 안 겹치게 레이아웃 조정
plt.show()

# 2x2 플롯 배치
plt.figure(figsize=(10,6))
plt.subplot(2, 2, 1)
plt.plot(np.arange(5) ** 2)
plt.title('차트1')
plt.xlabel('x축')
plt.ylabel('y축')
plt.subplot(2, 2, 2)
plt.plot(np.arange(10), np.arange(10) ** 3, 'r--')
plt.title('차트2')
plt.subplot(2, 2, 3)
plt.plot(np.arange(5) ** 3, 'g-')
plt.title('차트3')
plt.subplot(2, 2, 4)
plt.plot(np.arange(10), np.arange(10) ** 2, 'b^-')
plt.title('차트4')
plt.tight_layout() # 안 겹치게 레이아웃 조정
plt.show()

yfinance
!pip install yfinance -q
import yfinance as yf
prices = [
yf.Ticker('AAPL').history().Close, # 가격 시리즈
yf.Ticker('TSLA').history().Close,
yf.Ticker('AMZN').history().Close,
yf.Ticker('MSFT').history().Close,
]
titles = ['애플', '테슬라', '아마존', '마이크로소프트']
styles = ['rs-', 'gs-', 'bs-', 'cs-']
for i, v in enumerate(prices):
plt.subplot(2, 2, i+1)
plt.title(titles[i])
plt.plot(range(len(v)), v, styles[i])
plt.tight_layout()
plt.show()

다양한 차트 활용
lineplot 선 차트
- 그외에 여러 가지 차트가 존재
y = [2, 3, 1]
x = np.arange(3)
xlabel = ['가', '나', '다'] # len(x) 길이 같아야함
plt.title('바 차트')
plt.xticks(x, xlabel) # x축의 개별 값에다가 이름 붙여줌
plt.yticks(sorted(y)) # y축에다가 기준이 되는 이름을 붙여주기
plt.bar(x, y)
plt.show()

import numpy as np
import matplotlib.pyplot as plt
y = [2, 3, 1]
x = np.arange(3)
xlabel = ['가', '나', '다']
colors = ['red', 'green', 'blue'] # 각 값에 적용할 색상 지정
plt.title('바 차트')
plt.xticks(x, xlabel)
plt.bar(x, y, color=colors) # 색상을 막대에 적용
plt.show()
# https://shareg.pt/iJwursY

y = [2, 3, 1]
x = np.arange(3)
xlabel = ['가', '나', '다'] # len(x) 길이 같아야함
plt.title('가로 바 차트')
plt.yticks(x, xlabel) # x축의 개별 값에다가 이름 붙여줌
plt.xticks(sorted(y)) # y축에다가 기준이 되는 이름을 붙여주기
plt.barh(x, y)
plt.show()

people = ['james', 'john', 'kate', 'alice']
y_pos = np.arange(4)
performance = 3 + 10 * np.random.rand(4)
error = np.random.rand(4)
plt.title('Bar-h Chart')
plt.grid(True)
plt.barh(y_pos, performance, xerr=error, alpha=0.4)
plt.yticks(y_pos, people)
plt.xlabel('x축')
plt.show()

파이 차트
labels = ['호박파이', '사과파이', '정어리파이', '엄마손파이']
# sizes = [15, 30, 45, 10]
sizes = [15, 50, 72, 10]
# colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
colors = ['purple', 'gold', 'lightskyblue', 'lightcoral']
# explode = (0, 0.1, 0.2, 0.3)
explode = (0.1, 0.1, 0.1, 0.3)
plt.title("파이 차트")
# plt.pie(sizes)
plt.pie(sizes, explode=explode, labels=labels, colors=colors,
autopct='%1.1f%%', shadow=True, startangle=45)
plt.axis('equal')
plt.show()

히스토그램 (Histogram)
x = np.random.randn(100)
plt.figure(figsize=(15, 5))
plt.title('히스토그램')
arrays, bins, patches = plt.hist(x, bins=10)
plt.show()

스캐터 플롯 (산점도)
- x과 y 값 사이의 상관성이 있는 변수들
- 두 변수 사이의 상관관계를 점들의 밀집 정도를 통해서 확인하는 그래프
X = np.random.normal(0, 1, 100)
Y = np.random.normal(0, 1, 100)
plt.title("산점도")
plt.scatter(X, Y)
plt.show()
