【plotlyで時系列】plotlyで動的な可視化をする【python,株価】

時系列をグリグリしていきます



![c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/75c510b9-41b0-6aa9-4646-841450a9df50.gif)





#環境
python==3.8
plotly==4.10.0

#plotlyを使った時系列の可視化

時系列データは前処理も大変ですが、綺麗な可視化も同じように大変です

時系列の可視化ではおかしなピークがあると、
・それが何月何日のことだったのか
・異常ならその時のコメントを参照できないか
・もう少しスケールを拡大したり、変化させられないか
というリクエストが発生します

そのたびにソースデータ側を見に行くのは大変ですが、plotlyの動的な可視化ならば
その時点が何月何日なのかを特定することも簡単ですし
特定の期間に絞る、半年オーダーだけに拡大することも可能です



#まずline plot

plotlyのラインplotをつかってみる


```python
import plotly.express as px
fig = px.line(x=[1,2,3,4,5], y=[10,11,15,16,8], title="line plot")
fig.show()
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d0dee130-a4a2-10a1-014f-74d4c29486d1.png)


普通の線形plotがかけた

plotlyのdatasetsから呼び出せる株価データを使ってみる



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3c6f2d12-8190-0112-3d63-a74a5816bda6.png)






```python
import plotly.express as px
import pandas as pd
df = px.data.stocks()
fig = px.line(df,x='date', y='NFLX', title="NFLX stocks plot")
fig.show()
```

日付が認識できるフォーマットで入力されている場合、X軸に指定することで時刻にしてくれる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c113766e-e990-cc10-d878-6abc81313aba.png)


#表示期間を指定するrange



```python
import plotly.express as px
import pandas as pd
df = px.data.stocks()
fig = px.line(df,x='date', y='NFLX', title="NFLX stocks plot", range_x=['2018-07-01','2019-12-31'])
fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/119037ea-6bfd-1d75-adc8-f375fec4e016.png)






#Y軸に複数を指定する

```python
import plotly.express as px
import pandas as pd
df = px.data.stocks()
fig = px.line(df,x='date', y=df.columns[1:6], title="6 company stocks plot")
fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2366be94-a572-402c-800e-d57f313f444c.png)


#目盛り間隔を変更する


```python
import plotly.express as px
import pandas as pd
df = px.data.stocks()
fig = px.line(df,x='date', y=df.columns[1:6], title="6 company stocks plot")
fig.update_xaxes(
    dtick="M1",
    tickformat="%b\n%Y")
fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2ac0857c-fea4-9e18-9380-2fb67ced6d5d.png)


〇か月区切りをdtickにM〇で渡す
目盛りラベルのフォーマットは文字型で渡し、改行記号等を使って表示形式を変更できる


例えば

```python
fig.update_layout(
    title="6 company stocks plot",
    xaxis_tickformat = '%d %B (%a)<br>%Y'
)
```

として指定してやれば曜日や年月日の表示を操作できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d257754c-ec68-a947-2f8e-2b5674972aea.png)




#マウスをかざした時の挙動を変える

通常の場合、マウスをかざしても一点の情報を参照できるが、
layoutを変更して全データに対して情報を表示させることもできる

通常の場合

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/6e24a44a-6f19-ca23-df57-92515b26b814.gif)




```python
import plotly.express as px
import pandas as pd
df = px.data.stocks()
fig = px.line(df,x='date', y=df.columns[1:6], title="6 company stocks plot")
fig.update_xaxes(
    dtick="M1",
    tickformat="%b\n%Y")

fig.update_layout(template=go.layout.Template())

fig.show()
```




![b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/845b7c0a-0d52-969c-32e6-b3ed0a294d20.gif)







#表示区間をインタラクティブにするrange selector

update_layoutをつかうことで、figに入れたグラフに表示区間を指定する機能がつけられる
go.Figureから作ったものに対しても、plotly.expressから作ったものに対しても適応できる
コピペして使いまわせるので便利


graph_objectsに付け加える

```python
import plotly.graph_objects as go
import pandas as pd

fig = go.Figure()

fig.add_trace(go.Scatter(x=list(df.date), y=list(df.GOOG)))

fig.update_layout(
    title_text="range slider and selectors"
)

fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1m",
                     step="month",
                     stepmode="backward"),
                dict(count=6,
                     label="6m",
                     step="month",
                     stepmode="backward"),
                dict(count=1,
                     label="YTD",
                     step="year",
                     stepmode="todate"),
                dict(count=1,
                     label="1y",
                     step="year",
                     stepmode="backward"),
                dict(step="all")
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

fig.show()
```

plotly.expressに付け加える


```python
import plotly.express as px
fig = px.line(df,x='date', y=df.columns[1:6])

fig.update_layout(
    title_text="range slider and selectors"
)

fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1m",
                     step="month",
                     stepmode="backward"),
                dict(count=6,
                     label="6m",
                     step="month",
                     stepmode="backward"),
                dict(count=1,
                     label="YTD",
                     step="year",
                     stepmode="todate"),
                dict(count=1,
                     label="1y",
                     step="year",
                     stepmode="backward"),
                dict(step="all")
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

fig.show()
```






![c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/75c510b9-41b0-6aa9-4646-841450a9df50.gif)














#scatterを使ったplot

```python
import plotly.express as px
fig = px.scatter(df,x=df['date'], y=df.columns[1:6])
fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/cbec3921-c2c5-8c3d-5f84-12baa540cd45.png)





#graph_objectsを使ったplot

```python

import plotly.graph_objects as go

fig = go.Figure([
    go.Scatter(
        x=df['date'], y=df[df.columns[i]],
        opacity=.5
    )
    for i in range(1,len(df.columns))
])

fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/6b02248d-324d-43b1-fe30-e87a1b3f2d11.png)




graph_objectsはキャンパスに上から付け足していくような描画が得意
go.Figureで作ったキャンバスにgo.scatterを付け足していく
今回はforで列を変更しながら5回go.scatterを付け足したが、
個別にadd_traceで付け足してもいい
その場合、ある線は破線、ある線は実線にしていすることも可能

以下はlineのタイプを変更したもの


```python
import plotly.graph_objects as go

fig = go.Figure([
    go.Scatter(
        x=df['date'], y=df[df.columns[i]], 
        opacity=.5, 
        line=dict(dash='dash')
    )
    for i in range(1,len(df.columns))
])

fig.show()
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/84147c2b-256b-1119-85aa-a275ee71e3ad.png)



#株価のキャンドルチャート

株価の始値;高値;安値;終値を指定することで簡単にキャンドルチャートを作れる


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

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

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.update_layout(
    title_text="Candle"
)

fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1m",
                     step="month",
                     stepmode="backward"),
                dict(count=6,
                     label="6m",
                     step="month",
                     stepmode="backward"),
                dict(count=1,
                     label="YTD",
                     step="year",
                     stepmode="todate"),
                dict(count=1,
                     label="1y",
                     step="year",
                     stepmode="backward"),
                dict(step="all")
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

fig.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9f887faf-7a1e-3295-92b8-1a380bdcf1d9.png)



#以上

値を参照できるって素晴らしいよね