AI SCHOOL/Python

[Python] Plotly / FinanceDataReader

moru_xz 2023. 2. 2. 01:14

high-level interface

: 사람에 더 가까운 -> 사람이 이해하기 더 쉬운 인터페이스, 복잡한 기능을 단순하게 만들어 놓은 인터페이스 / 추상화 

 

그래프를 시각화 하기 위해서 어떤 정보를 API에 주어야 할까? (원래도 궁금했던 거임~)

1) 어떤 그래프로 시각화 할지 고른다 ex) 막대, 선, 산점도, 히스토그램 등

2) 어떤 데이터를 시각화 할지 API에 설정

3) x, y축을 설정 

4) 제목, 그래프 크기, 범례, 서브플롯, 스타일 등을 설정

5) bar(data, x, y)와 유사한 API를 대부분 갖고 있음

 

Plotly 는?

Plotly Express: high-level interface for data visualization

Graph Objects: low-level interface to figures, traces and layout

plotly.graph_objects와 potly.express 차이점 궁금해서 찾아봄

https://en.ai-research-collection.com/plotly-graph_object/

 

What is Plotly graph_object? (How is it different from Express?)

 When drawing graphs in Plotly, if you read the documentation or read about it in various articles, you may wonder what

en.ai-research-collection.com

필요한 라이브러리 로드

# 그래프가 노트북에 표시되지 않을 때
from plotly.offline import iplot, init_notebook_mode
from plotly.subplots import make_subplots
init_notebook_mode()

plotly 최신버전을 사용해 주세요. 최신버전이 아닐 때 동작하지 않을 수 있습니다.
!pip install plotly --upgrade

그래프가 노트북에 표시되지 않을 때 위에 것 해보기, 아나콘다 prompt에 pip 해주기

import plotly

plotly.__version__

예제

# plotly.express
# pandas 를 로드합니다.
import plotly.express as px
df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length", color='petal_length')
fig.show()

잘 import 됐는지 확인하기 위한 예제 코드

plotly 예제 따라하기

https://plotly.com/python/time-series/

 

Time

Over 21 examples of Time Series and Date Axes including changing color, size, log axes, and more in Python.

plotly.com

-> seaborn 에 타이타닉 있듯이

df = px.data.stocks()
df

 

일별 수익률 선그래프 그리기

반응형 그래프 아닌 그냥 캡쳐만 해옴(실제로 해보면 반응형 그래프로 나옴)

# px.line 으로 특정 종목("GOOG")에 대해 선그래프
px.line(df, x = 'date', y = 'GOOG', height= 300)

# pandas API 
df['GOOG'].plot(figsize = (12, 6))

# plotly express API -> pandas 처럼 사용 
px.line(df['GOOG'], height = 300)

px.line(df.set_index('date'), height = 300)

일별 수익률 막대그래프 그리기

일별 수익률에서 - 1

df_1 = df.set_index('date') - 1
df_1

# Pandas API 
df_1.plot(kind = 'bar', figsize = (12, 6))

# plotly express API
px.bar(df_1, height = 300)

- x, y축 따로 지정하지 않아도 됨

facet_col을 사용한 서브플롯 그리기

df_1.columns.name = 'company'
df_1.columns

>> Index(['GOOG', 'AAPL', 'AMZN', 'FB', 'NFLX', 'MSFT'], dtype='object', name='company')
px.area(df_1, height = 300)

px.area로 수익률 분포 그리기

px.area(df_1, facet_col = 'company', facet_col_wrap = 2)

- facet_col 을 통해 서브플롯 그릴 수 있음

- facet_col = 'company' 칼럼 지정

- facet_col_wrap 한 줄에 몇 개 그릴 건지 (facet_col_wrap = 2, 한 줄에 2개씩)

 

여러 종목을 하나의 그래프로 표현

px.line(df, x = 'date', y= 'GOOG', hover_data={"date": "|%Y-%m-%d"} )

- hover_data={"date": "|%Y-%m-%d"} -> 마우스 댔을 때 무슨 정보 볼지

- "|%Y-%m-%d" 앞에 |붙이는거는 plotly 에서의 약속 API 규칙

 

Time Series and Date Axes

 

fig = px.line(df_1['GOOG'], title = '구글 주가')
fig.update_xaxes(rangeslider_visible=True)

- fig.update_xaxes(rangeslider_visible=True) -> 이렇게 기간 정할 수 있게 

- 이런 기능들 다 외울 필요는 없음 -> 있다는 거 알고 사용할 때 이런게 있구나 생각나게 🥹 

- plotly는 한글 폰트 따로 지정하지 않아도 됨 

 

캔들스틱 차트(Candlestick)

- 캔들스틱 차트(영어: Candlestick chart) 또는 봉차트, 일본식 캔들스틱 차트 주식을 비롯한 유가증권 파생상품, 환율의 가격 움직임을 보여주는 금융 차트

- 각각의 "캔들스틱" 또는 "봉"은 일반적으로 "하루"의 가격 움직임을 나타내며, 따라서 20일간의 거래를 보여주는 차트에는 20개의 캔들스틱이 있다.[1]

- 캔들스틱 차트는 기술 통계학에서 사용되는 상자 수염 그림과 외적으로 유사하지만, 상자 수염 그림은 캔들스틱과 달리 금융이 아닌 다른 정보들을 표시한다.

- 출처 : 캔들스틱 차트 - 위키백과

 

import pandas as pd
import plotly.graph_objects as go
from datetime import datetime

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
df

- plotly.graph_objects 를 go라는 별칭으로 불림

fig = go.Figure(data=[go.Candlestick(x=df['Date'],
                open=df['AAPL.Open'],
                high=df['AAPL.High'],
                low=df['AAPL.Low'],
                close=df['AAPL.Close'])])

fig.show()

위 챠트 줌

OHLC(Open-High-Low-Close)

- 왼쪽이 시작가, 오른쪽이 종가

- 외국은 붉은색이 하락(<-> 한국은 붉은색이 상승) 

fig = go.Figure(data=[go.Ohlc(x=df['Date'],
                open=df['AAPL.Open'],
                high=df['AAPL.High'],
                low=df['AAPL.Low'],
                close=df['AAPL.Close'])])

fig.show()

fig = go.Figure(data=[go.Ohlc(x=df['Date'],
                open=df['AAPL.Open'],
                high=df['AAPL.High'],
                low=df['AAPL.Low'],
                close=df['AAPL.Close'])])
fig.update_xaxes(rangeslider_visible=False)
fig.show()

-rangeslider 없이 그리고 싶으면 rangeslider_visible = False하면 됨

 

주가 데이터 직접 수집해서 시각화

- fdr.StockListing('S&P500') -> 종목 데이터 뽑아 오는

https://financedata.github.io/posts/finance-data-reader-users-guide.html

 

FinanceDataReader 사용자 안내서

FinanceDataReader 사용자 안내서

financedata.github.io

특정 주가 불러오기

- FinanceDataReader의 DataReader는 미국 주식의 경우 종목코드 대신 티커(Ticker) 사용

- 약자 같은, 넷플릭스 : NFLX

NFLX = fdr.DataReader('NFLX', start = '2022')
NFLX.tail()

NFLX_df = (NFLX / NFLX.iloc[0])-1
px.line(NFLX_df.iloc[:,:4])

- 이전에는 Adj Close가 전일비였는데 지금은 수정종가 -> 직접 계산할 수 있음

NFLX['Close'].pct_change()
>> 
Date
2022-01-03         NaN
2022-01-04   -0.010412
2022-01-05   -0.039973
2022-01-06   -0.025074
2022-01-07   -0.022104
                ...   
2023-01-25    0.011351
2023-01-26   -0.008398
2023-01-27   -0.011237
2023-01-30   -0.021232
2023-01-31    0.002124
Name: Close, Length: 271, dtype: float64

Adj Close의 히스토그램 그리기 + 박스

px.histogram(NFLX_df['Adj Close'], marginal="box")

- marginal="box" 옵션을 사용 -> 대표값을 표현하는 그래프에 대한 단점 보완 -> box plot

NFLX 캔들스틱 & OHLC 

fig = go.Figure(data=[go.Candlestick(x=NFLX.index,
                open=NFLX['Open'],
                high=NFLX['High'],
                low=NFLX['Low'],
                close=NFLX['Close'])])
fig.update_xaxes(rangeslider_visible=True)

fig.show()
fig = go.Figure(data=[go.Ohlc(x=NFLX.index,
                open=NFLX['Open'],
                high=NFLX['High'],
                low=NFLX['Low'],
                close=NFLX['Close'])])
fig.update_xaxes(rangeslider_visible=True)

fig.show()

여러 종목 수익률 보기

FAANG = ["META", "AMZN", "AAPL", "GOOGL"]

# faang_list 의 종가 가져오기
META = fdr.DataReader('META', start = '2022')
AMZN = fdr.DataReader('AMZN', start = '2022')
AAPL = fdr.DataReader('AAPL', start = '2022')
GOOGL = fdr.DataReader('GOOGL', start = '2022')
META_c = META['Close']
AMZN_c = AMZN['Close']
AAPL_c = AAPL['Close']
GOOGL_c = GOOGL['Close']

# concat 으로 데이터 병합하기
df_faang = pd.concat([META_c,AMZN_c,AAPL_c,GOOGL_c], axis = 1)

df_faang.columns = FAANG
df_faang.columns.name = 'company'

# 일별 수익률 구하기 (첫날 구매를 했다는 가정하에 )
df_faang_data = (df_faang / df_faang.iloc[0])-1

- 나는 이렇게 하나하나 함… 아무튼 구하려던건 구했지만 ! 조금 많이 깔끔하게 하자면

FAANG = ["META", "AMZN", "AAPL", "GOOGL"]
# faang_list 의 종가 가져오기
faang_list =  [fdr.DataReader(ticker, "2022")["Close"] for ticker in FAANG]
# concat 으로 데이터 병합하기
df_faang = pd.concat(faang_list, axis=1)
df_faang.columns = FAANG
df_faang.columns.name = 'company'

# 일별 수익률
df_ratio = (df_faang / df_faang.iloc[0]) - 1

막대 그래프

px.bar(df_faang_data['META'])

- 사이사이 비어있는 곳은 -> 공휴일 : 장이 안 열린 날 

산점도

px.scatter(df_faang_data, x = 'GOOGL', y = 'AAPL', marginal_x = 'box', marginal_y = 'violin')

-> 애플이 오를 때 구글도 오르네~ 이런거 알 수 있음

px.scatter_matrix(df_faang_data)

pd.plotting.scatter_matrix(df_faang_data, alpha = 0.2) ;

https://pandas.pydata.org/docs/reference/api/pandas.plotting.scatter_matrix.html

-> 판다스 그래프

distribution 분포 그리기

df_faang_data.describe()

df_faang_data.quantile()
>>
company
META    -0.502186
AMZN    -0.290218
AAPL    -0.166200
GOOGL   -0.225358
Name: 0.5, dtype: float64

- quantile() 는 백분위수

-quantile(q = ) -> q의 값에 따라 해당 분위수 출력 

https://wikidocs.net/155537

 

14-10 분위수 (quantile)

####DataFrame.quantile(q=0.5, axis=0, numeric_only=True, interpolation='linear') ##개요 `quantile`메서드…

wikidocs.net

# px.box
px.box(df_faang_data, height = 300)

-> 애플, 구글 변동 크지 않음

# px.violin
px.violin(df_faang_data, box = True, points = 'all')

 

-> 박스플롯의 단점 보완해서 만들어짐

# px.strip
px.strip(df_faang_data)

# px.histogram
px.histogram(df_faang_data, marginal="box", nbins=50)

px.histogram(df_faang_data, nbins=50, 
             facet_col="company", facet_col_wrap=2)

 


 

* Graph Objects: low-level interface to figures, traces and layout
https://plotly.com/python-api-reference/plotly.graph_objects.html

* Plotly Express: high-level interface for data visualization
https://plotly.com/python-api-reference/plotly.express.html

 

plotly와 matplotlib의 차이점은?

- plotly는 자바스크립트 기반이고, 동적으로 그래프를 그릴 수 있음
- matplotlib은 python 기반으로, 정적으로 그래프를 그릴 수 있음

박스플롯

https://ko.wikipedia.org/wiki/%EC%83%81%EC%9E%90_%EC%88%98%EC%97%BC_%EA%B7%B8%EB%A6%BC

  1. 백분위 수 : 데이터를 백등분 한 것
  2. 사분위 수 : 데이터를 4등분 한 것
  3. 중위수 : 데이터의 정 가운데 순위에 해당하는 값.(관측치의 절반은 크거나 같고 나머지 절반은 작거나 같다.)
  4. 제 3사분위 수 (Q3) : 중앙값 기준으로 상위 50% 중의 중앙값, 전체 데이터 중 상위 25%에 해당하는 값
  5. 제 1사분위 수 (Q1) : 중앙값 기준으로 하위 50% 중의 중앙값, 전체 데이터 중 하위 25%에 해당하는 값
  6. 사분위 범위 수(IQR) : 데이터의 중간 50% (Q3 - Q1)

 

https://www.autodesk.com/research/publications/same-stats-different-graphs

- 바이올린 : 히스토그램의 밀도 추정해서 그린 것이 바이올린 처럼 생겼다고 해서 바이올린 플롯 

 

코로나 -> 범주형 데이터

주가 -> 수치 데이터