[사전학습] 5.4~5 동적 시각화
동적 시각화
동적 시각화는 유저와 시각화 결과의 상호작용으로 다양한 정보를 즉각적으로 전달하는 것이 특징
=> x축, y축 등에 의존하는 제한된 정보 전달이 아닌 그 외의 정보까지 하나의 그래프에 담을 수 있음
동적 시각화 예제
대시보드
- 대시보드는 하나의 화면에서 여러 정보가 연동되어 다양한 정보 제공
- 동적 시각화는 대시보드의 주된 구성요소이며, 사용자 대화형 특성 제공
- 업무에 필요한 데이터를 실시간으로 함축하여 정보 전달 -> 의사결정 서포트
동적 시각화 라이브러리 Plotly
파이썬의 대표적인 동적 시각화 라이브러리
Plotly 패키지
Plotly의 express(px)와 graph_objects(go) 패키지를 많이 사용
express | graph_objects | |
---|---|---|
고수준 API | 저수준 API | |
장점 | - 쉽고 빠르게 기능 구현 - 하나의 커맨드로 그래프 구현 | - 섬세하게 시각화 가능 - 유연하게 원하는 기능 구현 가능 |
단점 | - Seaborn에 비해 상대적으로 부족한 정적 시각화 기능 - go에 비해 유연성이 떨어짐 | - 하나의 커맨드로 원하는 기능 구현 어려움 |
graph_objects
graph_objects는 Plotly의 인기 있는 데이터 시각화 모듈로, 3D 형태의 그래프를 포함한 다양한 그래프를 그릴 수 있음
=> go라는 별칭 이용하여 호출
import plotly.graph_objects as go
go 그리는 법
fig = go.Figure()
- Figure(도화지) 객체 생성
fig.add_traces(그래프)
add_traces
로 원하는 유형의 그래프 추가 (go의 그래프 유형 설정)
fig.update_layout(옵션)
- 레이아웃 설정
- 대표적인 옵션 :
title
,yaxis_title
등
실습
1
2
3
4
import plotly.graph_objects as go
import pandas as pd
import numpy as np
1
2
df = pd.read_csv('./data/ALIM.csv', index_col=0)
display(df)
Low | Open | Volume | High | Close | Adjusted Close | |
---|---|---|---|---|---|---|
Date | ||||||
04-11-2019 | 4.125 | 4.500 | 34573 | 4.575 | 4.155 | 4.155 |
05-11-2019 | 4.200 | 4.200 | 19360 | 4.500 | 4.380 | 4.380 |
06-11-2019 | 4.230 | 4.395 | 21500 | 4.500 | 4.350 | 4.350 |
07-11-2019 | 4.065 | 4.500 | 12347 | 4.515 | 4.125 | 4.125 |
08-11-2019 | 3.420 | 3.900 | 62853 | 4.050 | 3.600 | 3.600 |
... | ... | ... | ... | ... | ... | ... |
06-12-2022 | 3.220 | 3.450 | 16100 | 3.468 | 3.300 | 3.300 |
07-12-2022 | 3.113 | 3.153 | 9200 | 3.245 | 3.240 | 3.240 |
08-12-2022 | 3.175 | 3.220 | 31700 | 3.402 | 3.270 | 3.270 |
09-12-2022 | 3.110 | 3.230 | 15100 | 3.270 | 3.155 | 3.155 |
12-12-2022 | 3.070 | 3.150 | 6890 | 3.160 | 3.120 | 3.120 |
783 rows × 6 columns
1
2
df.index = pd.to_datetime(df.index, format='%d-%m-%Y')
display(df)
Low | Open | Volume | High | Close | Adjusted Close | |
---|---|---|---|---|---|---|
Date | ||||||
2019-11-04 | 4.125 | 4.500 | 34573 | 4.575 | 4.155 | 4.155 |
2019-11-05 | 4.200 | 4.200 | 19360 | 4.500 | 4.380 | 4.380 |
2019-11-06 | 4.230 | 4.395 | 21500 | 4.500 | 4.350 | 4.350 |
2019-11-07 | 4.065 | 4.500 | 12347 | 4.515 | 4.125 | 4.125 |
2019-11-08 | 3.420 | 3.900 | 62853 | 4.050 | 3.600 | 3.600 |
... | ... | ... | ... | ... | ... | ... |
2022-12-06 | 3.220 | 3.450 | 16100 | 3.468 | 3.300 | 3.300 |
2022-12-07 | 3.113 | 3.153 | 9200 | 3.245 | 3.240 | 3.240 |
2022-12-08 | 3.175 | 3.220 | 31700 | 3.402 | 3.270 | 3.270 |
2022-12-09 | 3.110 | 3.230 | 15100 | 3.270 | 3.155 | 3.155 |
2022-12-12 | 3.070 | 3.150 | 6890 | 3.160 | 3.120 | 3.120 |
783 rows × 6 columns
1
df.index
1
2
3
4
5
6
7
8
DatetimeIndex(['2019-11-04', '2019-11-05', '2019-11-06', '2019-11-07',
'2019-11-08', '2019-11-11', '2019-11-12', '2019-11-13',
'2019-11-14', '2019-11-15',
...
'2022-11-29', '2022-11-30', '2022-12-01', '2022-12-02',
'2022-12-05', '2022-12-06', '2022-12-07', '2022-12-08',
'2022-12-09', '2022-12-12'],
dtype='datetime64[ns]', name='Date', length=783, freq=None)
plotly
의 graph_objects
1
fig = go.Figure()
1
type(fig)
1
plotly.graph_objs._figure.Figure
1
print(fig)
1
2
3
Figure({
'data': [], 'layout': {'template': '...'}
})
1
fig
add_trace
: 캔들스틱 차트 구현
1
2
3
4
5
6
7
8
9
10
11
fig.add_trace(
go.Candlestick( # go.Candlestick 그래프
x=df.index, # x축은 날짜로 표기
open=df.Open, # 시초가
high=df.High, # 고가
low=df.Low, # 저가
close=df.Close, # 종가
increasing_line_color='red', # 주가 상승은 빨간색
decreasing_line_color='blue', # 주가 하락은 파란색
)
)
update_layout
: 그래프 레이아웃 설정
1
print(fig)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Figure({
'data': [{'close': array([4.15500021, 4.38000011, 4.3499999 , ..., 3.26999998, 3.15499997,
3.11999989]),
'decreasing': {'line': {'color': 'blue'}},
'high': array([4.57499981, 4.5 , 4.5 , ..., 3.40199995, 3.26999998,
3.16000009]),
'increasing': {'line': {'color': 'red'}},
'low': array([4.125 , 4.19999981, 4.23000002, ..., 3.17499995, 3.1099999 ,
3.06999993]),
'open': array([4.5 , 4.19999981, 4.39499998, ..., 3.22000003, 3.23000002,
3.1500001 ]),
'type': 'candlestick',
'x': array([datetime.datetime(2019, 11, 4, 0, 0),
datetime.datetime(2019, 11, 5, 0, 0),
datetime.datetime(2019, 11, 6, 0, 0), ...,
datetime.datetime(2022, 12, 8, 0, 0),
datetime.datetime(2022, 12, 9, 0, 0),
datetime.datetime(2022, 12, 12, 0, 0)], dtype=object)}],
'layout': {'template': '...'}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
fig = go.Figure(
data = [go.Candlestick( # go.Candlestick 그래프
x=df.index, # x축은 날짜로 표기
open=df.Open, # 시초가
high=df.High, # 고가
low=df.Low, # 저가
close=df.Close, # 종가
increasing_line_color='red', # 주가 상승은 빨간색
decreasing_line_color='blue', # 주가 하락은 파란색
)]
)
fig.show()
1
2
3
4
fig.update_layout(title='Stock Price of XXX', yaxis_title='$',)
fig.layout.height = 600
fig.show()
이동 평균성 생성 (Moving Average)
1
2
3
ma_3 = df.Close.rolling(3).mean()
ma_10 = df.Close.rolling(10).mean()
ma_30 = df.Close.rolling(30).mean()
1
2
3
df['MA3'] = ma_3
df['MA10'] = ma_10
df['MA30'] = ma_30
1
display(df)
Low | Open | Volume | High | Close | Adjusted Close | MA30 | MA10 | MA3 | |
---|---|---|---|---|---|---|---|---|---|
Date | |||||||||
2019-11-04 | 4.125 | 4.500 | 34573 | 4.575 | 4.155 | 4.155 | NaN | NaN | NaN |
2019-11-05 | 4.200 | 4.200 | 19360 | 4.500 | 4.380 | 4.380 | NaN | NaN | NaN |
2019-11-06 | 4.230 | 4.395 | 21500 | 4.500 | 4.350 | 4.350 | NaN | NaN | 4.295000 |
2019-11-07 | 4.065 | 4.500 | 12347 | 4.515 | 4.125 | 4.125 | NaN | NaN | 4.285000 |
2019-11-08 | 3.420 | 3.900 | 62853 | 4.050 | 3.600 | 3.600 | NaN | NaN | 4.025000 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2022-12-06 | 3.220 | 3.450 | 16100 | 3.468 | 3.300 | 3.300 | 4.523367 | 3.6502 | 3.463333 |
2022-12-07 | 3.113 | 3.153 | 9200 | 3.245 | 3.240 | 3.240 | 4.452367 | 3.5532 | 3.350000 |
2022-12-08 | 3.175 | 3.220 | 31700 | 3.402 | 3.270 | 3.270 | 4.381367 | 3.4610 | 3.270000 |
2022-12-09 | 3.110 | 3.230 | 15100 | 3.270 | 3.155 | 3.155 | 4.311067 | 3.3930 | 3.221667 |
2022-12-12 | 3.070 | 3.150 | 6890 | 3.160 | 3.120 | 3.120 | 4.240067 | 3.3615 | 3.181667 |
783 rows × 9 columns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ma3 = go.Scatter(
x = df.index,
y = df.MA3,
line = dict(color='black', width=0.5),
name = 'MA(3)'
)
ma10 = go.Scatter(
x = df.index,
y = df.MA10,
line = dict(color='red', width=0.5),
name = 'MA(10)'
)
ma30 = go.Scatter(
x = df.index,
y = df.MA30,
line = dict(color='green', width=0.5),
name = 'MA(30)'
)
1
2
fig.add_traces(ma3)
fig.show()
1
2
3
4
fig.add_traces(ma3)
fig.add_traces(ma10)
fig.add_traces(ma30)
fig.show()
Bollinger Bands
추가
볼린저 밴드는 주가의 변동이 표준정규분포를 따른다고 가정, 주가의 추세를 따라 위아래로 폭이 같이 움직이는 밴드를 만들어 주가를 그 밴드 기준선으로 판단하고자 만들어진 지표.
- 기준선을 구한다. (여기서는
ma30
으로 설정) - 기준선에 대응하는 표준편차를 구함 ->
df.Close.rolling(30).std
- 상한선 = 기준선 + (2 * 표준편차)
- 하한선 = 기준선 - (2 * 표준편차)
1
std_30 = df.Close.rolling(30).std()
1
df['STD30'] = std_30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
upper_bound = go.Scatter(
x = df.index,
y = df.MA30 + (df.STD30 * 2),
line = dict(dash='dash', color='gray', width=1),
name = 'upper bounds'
)
lower_bound = go.Scatter(
x = df.index,
y = df.MA30 - (df.STD30 * 2),
line = dict(dash='dash', color='gray', width=1),
fill = 'tonexty', # 상한선과 하한선 사이 면적 채우기
opacity = 0.5, # 투명도 조절
name = 'lower bounds'
)
1
fig.add_traces([upper_bound, lower_bound])
바 그래프 : 거래량 추가
1
trading_volume = go.Bar(x=df.index, y=df.Volume)
1
import plotly.subplots as ms
1
2
3
4
5
6
fig = ms.make_subplots(
rows=2,
cols=1,
shared_xaxes=True,
subplot_titles=('Stock Prices of XXX', 'Trading Volumes') # 두 개의 플롯에 타이틀 생성
)
1
fig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# add_trace를 사용함, add_trace's' 아님!
fig.add_trace(
go.Candlestick(
x = df.index,
open = df.Open,
high = df.High,
low = df.Low,
close = df.Close,
increasing_line_color = 'red',
decreasing_line_color = 'blue',
),
row = 1,
col = 1
)
fig.layout.height = 600
fig.show()
1
2
3
4
fig.add_trace(ma3, row=1, col=1)
fig.add_trace(ma10, row=1, col=1)
fig.add_trace(ma30, row=1, col=1)
fig.show()
1
2
fig.add_trace(upper_bound, row=1, col=1)
fig.add_trace(lower_bound, row=1, col=1)
1
2
fig.add_trace(trading_volume, row=2, col=1)
fig.show()
1
2
3
4
5
6
7
8
9
fig.update_layout(
yaxis1_title = 'Stock Price ($)',
yaxis2_title = 'Trading Volumes',
xaxis2_title = 'Periods',
xaxis1_rangeslider_visible = False,
xaxis2_rangeslider_visible = True,
)
fig.show()
1
2
# 동적 요소 포함한 html 파일로 저장
fig.write_html('./data/interactive_candle_stick.html')
1
This post is licensed under CC BY 4.0 by the author.