スクリプトのお勉強 技術

seaborn + Pandas + Python によるグラフ描画(その1: 準備編)

投稿日:

グラフ描画してみよう

今現在の仕事で、グラフ描画する可能性があるので、少し練習してみようと思います。

題材について

突然ですが、私は確定拠出型年金に加入しています。証券会社は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"
  ]
]

おわりに

長くなったので、いったん切ります。
次回は、やっとグラフ表示を行います。

-スクリプトのお勉強, 技術
-

執筆者:

関連記事

React.js の Ant Design使ってみる(DateTimePicker編)

DateTimePickerサンプル DateTimePickerを使うサンプルで、いいのがなかなかないです。Dateだけとか、Timeだけってのはあるのですが。 ということで作ってみようと思いました …

Djangoのurls.pyにはまった。。

けっこうハマった。。 Django 2.2.4の話。以下のエラーを修正するのに、とっても時間がかかった。 django.urls.exceptions.NoReverseMatch: Reverse …

新規プロジェクト参入時に考えること

派遣における労働条件 就業予定時間(変形労働時間やフレックスタイム制の適用を含む)残業の有無と量就業場所(交通ルート、オフィスの配置等)業務の継続予定期間 制服の有無 (背広かどうか)福利厚生施設の有 …

小ネタ: Ansible , with_itemsをloopに変える方法

とっても小さい小ネタです。 Ansible 2.4(今現在) -> Ansible 2.9に変えたい Ansibleを使用していますが、だいたい2.4ぐらいを使っています。流石にバージョンアップしない …

Mojolicious XML-RPC Pluginの開発(2)

はじめに 「Mojolicious XML-RPC Pluginの開発」のその2です。 本内容では、前回の内容を踏まえ、XML-RPC実装を、Mojoliciousのプラグイン機能を使用して実装しよう …