Post

[사전학습] 5.4~5 동적 시각화

동적 시각화

동적 시각화유저시각화 결과상호작용으로 다양한 정보를 즉각적으로 전달하는 것이 특징
=> x축, y축 등에 의존하는 제한된 정보 전달아닌 그 외의 정보까지 하나의 그래프에 담을 수 있음

동적 시각화 예제

대시보드

  • 대시보드는 하나의 화면에서 여러 정보가 연동되어 다양한 정보 제공
  • 동적 시각화는 대시보드의 주된 구성요소이며, 사용자 대화형 특성 제공
  • 업무에 필요한 데이터를 실시간으로 함축하여 정보 전달 -> 의사결정 서포트

    동적 시각화 라이브러리 Plotly

    파이썬의 대표적인 동적 시각화 라이브러리

    Plotly 패키지

    Plotly의 express(px)graph_objects(go) 패키지를 많이 사용

 expressgraph_objects
 고수준 API저수준 API
장점- 쉽고 빠르게 기능 구현
- 하나의 커맨드로 그래프 구현
- 섬세하게 시각화 가능
- 유연하게 원하는 기능 구현 가능
단점- Seaborn에 비해 상대적으로 부족한 정적 시각화 기능
- go에 비해 유연성이 떨어짐
- 하나의 커맨드로 원하는 기능 구현 어려움

graph_objects

graph_objects는 Plotly의 인기 있는 데이터 시각화 모듈로, 3D 형태의 그래프를 포함한 다양한 그래프를 그릴 수 있음
=> go라는 별칭 이용하여 호출

import plotly.graph_objects as go

go 그리는 법

  1. fig = go.Figure()
    • Figure(도화지) 객체 생성
  2. fig.add_traces(그래프)
    • add_traces로 원하는 유형의 그래프 추가 (go의 그래프 유형 설정)
  3. 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)
LowOpenVolumeHighCloseAdjusted Close
Date
04-11-20194.1254.500345734.5754.1554.155
05-11-20194.2004.200193604.5004.3804.380
06-11-20194.2304.395215004.5004.3504.350
07-11-20194.0654.500123474.5154.1254.125
08-11-20193.4203.900628534.0503.6003.600
.....................
06-12-20223.2203.450161003.4683.3003.300
07-12-20223.1133.15392003.2453.2403.240
08-12-20223.1753.220317003.4023.2703.270
09-12-20223.1103.230151003.2703.1553.155
12-12-20223.0703.15068903.1603.1203.120

783 rows × 6 columns

1
2
df.index = pd.to_datetime(df.index, format='%d-%m-%Y')
display(df)
LowOpenVolumeHighCloseAdjusted Close
Date
2019-11-044.1254.500345734.5754.1554.155
2019-11-054.2004.200193604.5004.3804.380
2019-11-064.2304.395215004.5004.3504.350
2019-11-074.0654.500123474.5154.1254.125
2019-11-083.4203.900628534.0503.6003.600
.....................
2022-12-063.2203.450161003.4683.3003.300
2022-12-073.1133.15392003.2453.2403.240
2022-12-083.1753.220317003.4023.2703.270
2022-12-093.1103.230151003.2703.1553.155
2022-12-123.0703.15068903.1603.1203.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)

plotlygraph_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)
LowOpenVolumeHighCloseAdjusted CloseMA30MA10MA3
Date
2019-11-044.1254.500345734.5754.1554.155NaNNaNNaN
2019-11-054.2004.200193604.5004.3804.380NaNNaNNaN
2019-11-064.2304.395215004.5004.3504.350NaNNaN4.295000
2019-11-074.0654.500123474.5154.1254.125NaNNaN4.285000
2019-11-083.4203.900628534.0503.6003.600NaNNaN4.025000
..............................
2022-12-063.2203.450161003.4683.3003.3004.5233673.65023.463333
2022-12-073.1133.15392003.2453.2403.2404.4523673.55323.350000
2022-12-083.1753.220317003.4023.2703.2704.3813673.46103.270000
2022-12-093.1103.230151003.2703.1553.1554.3110673.39303.221667
2022-12-123.0703.15068903.1603.1203.1204.2400673.36153.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 추가

볼린저 밴드는 주가의 변동이 표준정규분포를 따른다고 가정, 주가의 추세를 따라 위아래로 폭이 같이 움직이는 밴드를 만들어 주가를 그 밴드 기준선으로 판단하고자 만들어진 지표.

  1. 기준선을 구한다. (여기서는 ma30으로 설정)
  2. 기준선에 대응하는 표준편차를 구함 -> df.Close.rolling(30).std
  3. 상한선 = 기준선 + (2 * 표준편차)
  4. 하한선 = 기준선 - (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.

[사전학습] 5.1~3 정적 시각화

[사전학습] 6.1 가설의 의의와 검정