今回は忘備録的ですが、時系列データの可視化について基本的かつほぼ毎日使っている技を説明していきます。
Yahoo!ファイナンスからAPIで株価データを取得
※すでにデータをお持ちの方は飛ばしちゃってください。
これから使用するサンプルデータとしてYahooファイナンスからAPI経由でデータを取得していきます。
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
code = 7911 # 取得したい株価コード
my_share = share.Share(str(code) + '.T')
try:
symbol_data = my_share.get_historical(share.PERIOD_TYPE_DAY,
10, # 取得年数
share.FREQUENCY_TYPE_MINUTE,
5 # 取得単位
)
except YahooFinanceError as e:
print(e.message)
sys.exit(1)
df=pd.DataFrame(symbol_data) # データフレームに保存
df['timestamp']=pd.to_datetime(df['timestamp'], unit='ms')
df.sort_values(by='timestamp',inplace=True)
df.set_index('timestamp',inplace=True)
特に説明はしません。”code”のところに取得した株価コードを入れてもらえればそのまま株価データが得られると思います。
時系列データの可視化① 1つのグラフを描画
さて本題の時系列データの可視化です。
1行でグラフを表示させる
Pythonを使って最も簡単にグラフを表示しようとすると、なんと1行でできてしまいます。
df['open'].plot()
これを実行すると、簡単に次のグラフが得られます。
※注意:1秒単位で数年間に渡るデータなど、データ数が多い場合は処理が重くなります。ここでは全体像をざっくりと見ることが目的なのでresample()関数を使うなどして、データ圧縮してから可視化するのが吉です。
この簡易的な可視化は超ざっくりどんなグラフなのか確認したいときに使う技です。
まずデータを入手してどんなグラフなのか見たいときに結構お世話になってます。
よく見るポイントとしては、
- 異常値的なデータが入っていないか?
- トレンドが見られるか?
- そもそも時系列データとして成り立っているか?(データの無い空白の期間がある等)
もう少し詳しく見るための設定
続いては、もう少しグラフを見やすくしたいといった詳細設定をしていきます。
今回使用しているのは時系列データなので、横軸に時間軸、縦軸に株価を取るのが見やすいですね。
時系列データを見やすくするために、以下の設定をしていきます。
- グラフを大きくする
- グリッド線を入れる
- グラフタイトルをつける
- 軸ラベルを付ける
グラフ描画の準備
まずはグラフ描画の準備から
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.family']='sans-serif'
plt.rcParams['font.sans-serif'] = ['Yu Gothic']
plt.rcParams['font.size'] = 14
おなじみのmatplotlibを使います。seabornも併せて使うことが多いので書いておきます。
そして下3行ですが、この記述によりpltを使う際に日本語があっても文字化けせずにすみます。
この技はJupyter Notebookを開いたら必ずと言っていいほど最初に記述する小技です。
1つのグラフを描画する
target='open'
fig,axs = plt.subplots(figsize=(15,5)) # figsizeはグラフを描画する範囲を指定
axs.plot(df[target]) # グラフを描画
axs.set_xlabel('timestamp') # X軸のラベルを設定
axs.set_ylabel('株価') # Y軸のラベルを設定
axs.set_title(f'{target}の時系列グラフ') # グラフタイトルを設定
axs.grid(alpha=0.3) # グラフに補助線を入れる。alphaは透過度で補助線の場合は0.3くらいがかっこいい
plt.show()
小技というほどでもないのですが、可視化したいカラム名を”target”としています。
カラム名が何度も出てくる場合、可視化対象を変更する際に一か所のみ変更すればよいようにするためです。
続いて次の一文ですが、plt.subplots()によりグラフ全体の設定を行うFigureオブジェクトとグラフ単体のAxesオブジェクトを同時に受け取ることができます。この技は複数グラフを描画する際にとても有効となります。
fig,axs = plt.subplots(figsize=(15,5))
ひとまずFigureオブジェクトとAxesオブジェクトは次のような関係図で抑えるとよいでしょう。
今回の例ではグラフは1つのFigureオブジェクト内に1つのAxesオブジェクトしか指定していないので、”axs”は配列ではありません。
あとは、Axesオブジェクトである”axs”を用いてグラフタイトルや軸の設定を行っています。(ここではとりあえず最低限の設定のみ)
基本は以上になります。
続いては可視化の際の必須スキルでもある複数グラフを見比べるということをやっていきます。
時系列データの可視化② 複数のグラフを表示させる
複数のグラフを表示させる例として、ここではとある企業の1日の午前と午後の株価データをグラフ化して並べて見てみたいと思います。
コードと表示結果
次のようにコードを書き換えます。
target='close'
periods=[('2023-03-17 09:00:00','2023-03-17 12:00:00'),('2023-03-17 13:00:00','2023-03-17 15:00:00')]
fig,axs = plt.subplots(2,1,figsize=(15,8))
for ax,(s,e) in zip(axs,periods):
ax.plot(df[s:e][target])
ax.set_xlabel('timestamp')
ax.set_ylabel('株価')
ax.grid(alpha=0.3)
plt.show()
表示結果は、
午前と午後でグラフを比較しやすくなりました。
コードの解説をしていきます。
コード解説
“periods”では午前と午後の時間をそれぞれタプルで格納し、それを配列に入れています。これはのちほどfor分で回す際に非常に使い勝手が良い小技です。
続いて、
fig,axs = plt.subplots(2,1,figsize=(15,8))
の部分については、plt.subplots(”グラフの行数”,”グラフの列数”,figsize=(15,8))というように一つのFigureオブジェクトの中に並べたグラフ(異なる種類でもOK)を座標のように指定します。
座標とグラフの対応イメージは以下。
※figsizeを調整して見栄えを整えましょう。
そして、最後の特徴であるfor文
for ax,(s,e) in zip(axs,periods):
forとzip()の組み合わせによってaxsとperiodsを抱き合わせて取り出すことができます。(ここ結構重要)
このfor文は2ループだけなので変数の取り出し方は次の通り2パターンになります。
1ループ目
|
2ループ目
|
あとに続くコードは与えられたs(スタート)、e(エンド)の期間のデータを取り出してプロットし、軸の細かい設定を行っています。
ここでsubplots()を用いた妙味がでます。各グラフ同じ設定であればfor文で回すことができます。
まとめ
今回は時系列データの可視化を行う際の初歩的な以下3つのTipsを説明しました。
- 手っ取り早く全体像をみたいときは”df.plot()”を使う!
- “plt.subplots()”を使ってグラフの設定を楽に!
- for文とzip()を組み合わせて期間ごとにグラフを分けて表示させて自由に使いこなす!
時系列Plotだけでなく、ヒストグラムや散布図といったグラフにも拡張可能ですのでまずは手元のデータ可視化してPythonでの可視化スキルを高めていきましょう!
コメント