グラフ描画してみよう
今現在の仕事で、グラフ描画する可能性があるので、少し練習してみようと思います。
題材について
突然ですが、私は確定拠出型年金に加入しています。証券会社はSBI証券
にしています。いわゆるiDecoというやつです。
グラフ描画するのは、iDecoの運用商品と、日経平均です。
日々の運用商品データは、CSVとしてSBI証券が提供していまして、それを題材として使用します。
私が保存を始めたのは2017年ぐらいからですので、そこからのデータをグラフ表示しようと思います。
なお、なぜ保存しようとしたかというと、本来はそれらで機械学習 or ディープラーニングをしようと思ってました。
今でもしようと思ってますが、なかなか苦戦中。。その話はまた別の機会に。
なので、先にグラフ描画だけしようと思います。
日経平均
日経平均は、Macrotrendsというところのデータを加工してグラフ描画をしています。
ここのは日経本体と違い、Macrotrendsのデータだ、とブログに書けば使用していいらしいので使用しています。
グラフ描画ライブラリの種類
Pythonによるグラフ描画ライブラリは、以下があるようです。
Matplotlib
Pythonでのグラフ描画ライブラリとしては定番です。検索するとたくさん出てきます。
多くのライブラリが、Matplotlibを元にしています。
元々が有名な、MATLABをベースにしているそうです。
seaborn
ベースはMatplotlibな、グラフ描画ライブラリです。
統計データの表示に特化しているそうです。
デフォルトできれいな画面を描画できる、のかと思ったのですが、そうではないらしいです。。
本記事では、seabornを一部使用してグラフ描画しています。
理由としては、有名そうだから、というところです。
グラフ描画は特に、サンプル見ながらでないと出力するのが難しいです。
有名そうなライブラリだと、サンプルが豊富だろう、という理由で選びました。
使ってみた感想としては、何を使ってるかよく分からない、というところです。
Matplotlibもそうなのですが、暗黙的に「plt」とかが出てきて、どこで何を操作すればいいのか、あるいはなぜここで呼び出す必要があるのか、がいまいち分からないです。
Altair
Vega-Lite、というデータフォーマット(JSON)を用いて描画するタイプのライブラリです。
どちらかというと私の好みなのですが、今回はMatplotlibベースで処理してみることにしました。
軽く見た限りでは、Matplotlibとは考え方が全く異なるので、
両方覚えるのがつらかったという事情もあります。。
Pandasとは
Pandasとは、データ分析用ライブラリです。
ここでは、グラフ用データの格納場所として使用しています。
というか、Matplotlibに統合しているといっていいぐらい、密結合していると思います。
使った感想としては、Python的なライブラリではなく、癖がありすぎる気がします。
こう操作すればこうなるはずだ、という予測がことごとく外れる感じです。
それでも便利なのは確かなので使用しています。
グラフ描画の前準備
グラフ描画をするにあたり、いろいろと前準備が必要になりました。
その準備内容について、先に記述しておきます。
環境
グラフ描画をしてみた環境は以下の通りです。
- OS: ubuntu 18.04
- Python 3.7
- Matplotlib version: 3.1.1
- seaborn version: 0.9.0
使用したライブラリはここに、設定してあります。
日本語表示準備
Matplotlib系、seabornもそうですが、日本語フォントが入っていないようです。
先に日本語を表示できるようにフォントを格納しておきます。
### 日本語フォントインストール $ sudo apt -y install fonts-ipafont-gothic ### キャッシュ削除 $ rm ~/.cache/matplotlib/fontList*.json
あとはソースコード中で以下のように、日本語フォントを指定しておきます。
以下はseabornを使用した際の書き方です。
sns.set(font='IPAGothic')
エラー表示をつぶす
プログラムを起動すると、以下のエラーが出ました。
$ pipenv run python3 seaborn_graph_with_nikkei.py dataset-2017-20190812/ /home/tanino/script-plactice/practice_the_script/python/datagraph/.venv/lib/python3.6/site-packages/pandas/plotting/_matplotlib/converter.py:102: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters. To register the converters: >>> from pandas.plotting import register_matplotlib_converters >>> register_matplotlib_converters() warnings.warn(msg, FutureWarning)
このエラーは、結局のところ、上記のメッセージ通り、以下をソースコードに追加することで解決しました。
from pandas.plotting import register_matplotlib_converters register_matplotlib_converters()
PandasとMatplotlibで、時刻処理が競合しているものと理解しました。
上記だと、Pandas側でMatplotlib側を取り込んでいるような処理になるようですが、これをしたくない人は(いるかどうか分かりませんが)どうするんですかね、、と少しだけ気になりました。
日経平均データの前処理
日経平均のデータ加工
上記のMicrotrentsのデータは、1940年ごろから始まっているので、
私がデータを持っている2017年以降だけ取得し、JSONにしておきます。
なぜJSONにするのかというと、単に私の勉強のためだけです。。
nikkei_csv2json.py
具体的な加工方法は以下プログラムでJSONを生成しました。
$ cat nikkei_csv2json.py import csv import datetime import json def csv2json(csv_file): """ JSON ==[['2017-01-01'..], ['10000.0' ]] """ if csv_file[-3:] != 'csv': return out = None x = [] y = [] with open(csv_file, "r") as csv_data: reader = csv.reader(csv_data) header = next(reader) # ヘッダ無視 for rd in reader: line_date = datetime.datetime.strptime(rd[0], '%Y-%m-%d') if line_date < datetime.datetime(2017, 1, 1): continue x.append(rd[0]) y.append(rd[1]) out = json.dumps([x, y], sort_keys=True, ensure_ascii=False, indent=2) with open("./nikkei-225-index-historical-chart-data.json", "w") as f: f.write(out) if __name__ == '__main__': csv_file = 'nikkei-225-index-historical-chart-data.csv' csv2json(csv_file)
‘nikkei-225-index-historical-chart-data.csv’から
./nikkei-225-index-historical-chart-data.jsonを生成するプログラムです。
処理は見ての通りですが、Python3のcsv.readerで読みだして、jsonで出力しているだけです。
具体的なデータは以下になっています。[[x1…], [y1…]]というデータです。
[ [ "2017-01-04", "2017-01-05", "2017-01-06", "2017-01-10", "2017-01-11", "2017-01-12", "2017-01-13", "2017-01-16", ... "21521.5300", "21521.5300", "21540.9900", "21087.1600", "20720.2900", "20585.3100", "20516.5600", "20593.3500", "20684.8200" ] ]
おわりに
長くなったので、いったん切ります。
次回は、やっとグラフ表示を行います。