CryptocurrencyPython

【Python】2軸で動的なグラフの作成方法|ビットコインの価格とハッシュレートの時系列推移を表示

Cryptocurrency

どうも、月見(@Suzuka14144156)です。

今回は、2軸で動的なグラフの作成方法を解説します。

解決するお悩み
  • 動的グラフの作成方法が分からない
  • ビットコインの価格のこれまで変化を時系列で追いたい
  • ハッシュレートの推移と合わせて表示したい

この記事のゴール

  • こんなチャートをPythonで表示できるようにします!

・グリーン:ビットコインの価格

・オレンジ:ハッシュレート

月見
月見
  • ビットコインのこれまで成長が理解しやすいですよね!

動的グラフとは?

段々とグラフに点が追加されていき、時間が経つにつれて完成するグラフです。

月見
月見
  • 上の例が分かりやすかったかと思います

2軸のグラフとは?

2軸のグラフとは、以下の図に示すように左右に異なる軸を持ったグラフです。

以下の例では、左の軸にビットコインの価格[BTC/USD]を、右の軸にハッシュレートとしています。

環境の構築

今回は、Pythonを用います。

Pythonのインストール

Anacondaをインストールする方法が一番楽だと思います。

もしインストール方法が分からない方は、以下の記事を参考にして、インストールください。

ライブラリのインストール

Anacondaをインストールした方は、pandasやnumpyなどはインストール済みのはずです。

各々不足しているライブラリをご自身の環境に合わせて、インストールください。

*一部使わないライブラリもインポートしていますが、悪しからず・・・

主に使用するライブラリ
  • pandas:データ処理
  • numpy:配列のデータ処理
  • matplotlib:グラフの表示
  • pandas_data:仮想通貨のデータ取得
  • yfinance:Yahoo Financeからデータを取得

numpyのインストール

コマンドプロンプトから、以下のコードを入力ください。

pip install numpy

pandasのインストール

コマンドプロンプトから、以下のコードを入力ください。

pip install pandas

pandas_dataのインストール

コマンドプロンプトから、以下のコードを入力ください。

pip install pandas_datareader

yfinanceのインストール

コマンドプロンプトから、以下のコードを入力ください。

pip install yfinance

matplotlibのインストール

コマンドプロンプトから、以下のコードを入力ください。

pip install matplotlib

アルゴリズム概要

アルゴリズムは、上の図のような感じです。

日足データを月足に変換して、月毎の変化のグラフとしています。

もちろん週足ベースや日足ベースでの変化のグラフにもできますが、GIFとしては時間が長くなるので、今回は月足にしました。

動的なグラフのキーとなるライブラリ

  • matplotlib.animationのanimation.FuncAnimationです。

matplotlib とは python のグラフ描写モジュールであり、アニメーションも作れます

今回は、FuncAnimationを用いて、動的グラフを作成します。

matplotlibのanimationクラスの詳細は、以下の公式ドキュメントを参照ください。

matplotlib.animation — Matplotlib 3.9.2 documentation

2軸で動的なグラフの作成方法をGitからクローンする

必要なデータやコードをGITに挙げているので、クローンすればご自身のパソコンで動かすことができます。

以下のコードをコマンドプロンプトへ入力ください。

git clone https://github.com/tsukimitech-blog/auto_graph

すると以下のファイルがクローンされます。

2軸で動的なグラフの作成方法のディレクトリ構成

以下4ファイルが含まれています。

  • BCHAIN-HRATE.csv:ハッシュレートのデータ
  • BCHAIN-NADDU.csv:アクティブアドレスのデータ
  • btc.gif:出力物のGIF
  • main.py:コード

今回の例では、ハッシュレートのデータを用いてGIFを出力します。

コードの読み込みするデータをアクティブアドレスに変化させることも可能です。

簡単に切り替えることができるのでその方法も併せて紹介します。

2軸で動的なグラフの作成方法のコード全文

main.pyの中身は以下です。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import pandas as pd  
from pandas_datareader import data as pdr 
import datetime
import yfinance as yf
import numpy as np
 
#アクティブアドレスのデータ
#https://data.nasdaq.com/data/BCHAIN/NADDU-bitcoin-number-of-unique-bitcoin-addresses-used

# 無地のキャンバスを作成する
fig = plt.figure()
time_scale = 'M' #def M

# yの配列を作成する
x = []
y1 = []
y2 = []

def get_active_address(dir = 'BCHAIN-NADDU.csv'):
  #アクティブアドレス(CSV)の読み込み
  active_address = pd.read_csv(dir,index_col=0)
  active_address.index = pd.to_datetime(active_address.index)
  #データを反転
  active_address = active_address.iloc[::-1]
  agg_dict = {"Value": "sum"}
  # 月足に変換する
  active_address = active_address.resample(time_scale).agg(agg_dict)
  return active_address

def get_hasurate(dir = 'BCHAIN-HRATE.csv'):
  #アクティブアドレス(CSV)の読み込み
  active_address = pd.read_csv(dir,index_col=0)
  active_address.index = pd.to_datetime(active_address.index)
  #データを反転
  active_address = active_address.iloc[::-1]
  agg_dict = {"Value": "sum"}
  # 月足に変換する
  active_address = active_address.resample(time_scale).agg(agg_dict)
  return active_address


def get_btc_chart(tickers = ['BTC-USD'],start = "2015-01-01",end = "2022-11-16"):
    #Yahoofinanceから取得するように設定
    yf.pdr_override()

    #データの取得を実行
    crypto_data = pdr.get_data_yahoo(tickers, start, end)
    # カラムごとの計算手法を指定
    agg_dict = {
        "Open": "first", 
        "High": "max",
        "Low": "min",
        "Close": "last",
        "Adj Close":"last",
        "Volume": "sum"
        }
 
    #月足に変換する
    crypto_data = crypto_data .resample(time_scale).agg(agg_dict)
    return crypto_data

def AnimationUpdater(frame):
  # figureオブジェクトを作成
  # 表示されているグラフをリセット
  plt.cla()
  y1.append(btc_chart['Adj Close'][frame])
  y2.append(btc_chart['Value'][frame])
  x.append(btc_chart.index[frame])

  # yのグラフを表示
  ax1.plot(x,y1,color='forestgreen',label='BTC_PRICE')
  ax2.plot(x,y2,color='Orange',label='HASH_RATE')
  
def main():
  global btc_chart, fig, ax1, ax2
  #グラフの箱を用意
  ax1 = fig.subplots()
  ax2 = ax1.twinx()

  #btcの価格を取得
  btc_chart = get_btc_chart()

  #アクティブアドレス数/ハッシュレートを取得
  data = get_hasurate()

  #連結
  btc_chart = pd.concat([btc_chart, data], axis=1).dropna()

  #最終月のデータを削除(ハッシュレートやアクティブアドレスの計算が月末までにならないと総和が取れないため)
  btc_chart = btc_chart[:-1]

  #動的なグラフの作成
  ani = animation.FuncAnimation(fig,AnimationUpdater, interval=500)

  #Xラベルを45度傾ける
  ax1.tick_params(axis='x', labelrotation=45)
  
  #表示
  plt.show()

  #保存
  #ani.save('btc.gif', writer='pillow')

if __name__ == "__main__": 
  main()

コードの解説

要所のみを解説します。

main関数の中で、4変数をグローバル変数にしています。

def main():
  global btc_chart, fig, ax1, ax2

これは、以下の関数の中で、用いるためです。

def AnimationUpdater(frame)

この関数に、引数として渡そうとすると、animation.FuncAnimationでエラーを吐き出されてしまったのでこのようなコードになっています。

以下のfragsの中に変数を渡すことで、animation.FuncAnimationクラスの引数を取ることが可能とされていますが、pandas dataframeで渡そうとするとエラーが出るといった状況でした。

params = {
        'fig': fig,
        'func': _update,
        'fargs': (x, y),  
        'interval': 10,  
        'frames': np.arange(0, 10, 0.1), 
        'repeat': False,  
    }
anime = animation.FuncAnimation(**params)
月見
月見
  • あまり深入りはせず、グローバル変数にして渡してしまいました。
  • もしかすると解決方法があるかもしれないです

アクティブアドレスに切り替える方法

以下の部分に変更を加えます。

data = get_hasurate()

以下のように変更ください。

data = get_active_address()

これでアクティブアドレスとビットコインの価格の推移が表示されます。

Pythonでファイナンスのデータ分析の勉強方法

私は、以下の本で勉強しました。

かなり詳しく書かれており、とてもオススメの本です。

Udemy

Udemyはオンライン口座です。

一度購入すれば、ずっと閲覧できるのでオススメです。

【世界で8万人が受講:Python for Finance】Pythonを使って学ぶ現代ファイナンス理論と実践
ポートフォリオ理論、コーポレートファイナンス、資本資産評価モデル(CAPM)、デリバティブの値決め、モンテカルロシミュレーションといった内容を中心に、Pwcなどで活躍した講師が理論と実践に基づき解説します。

私の記事

私のブログでも解説していますので参考にしてみてください。

まとめ

今回は、2軸で動的なグラフの作成方法を解説しました。

例として、ビットコインと価格とハッシュレートの時系列推移を表示する方法を取り扱いました。

私のブログではほかにも、仮想通貨の自動トレードの方法などを解説しているのでぜひ参考にしてみてください。

無料で閲覧可能で、コードをコピペして動かすことができます。

コメント

タイトルとURLをコピーしました