グラフ描画してみよう
今現在の仕事で、グラフ描画する可能性があるので、少し練習してみようと思います。
題材について
突然ですが、私は確定拠出型年金に加入しています。証券会社は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"
]
]
おわりに
長くなったので、いったん切ります。
次回は、やっとグラフ表示を行います。