スクリプトのお勉強 技術

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"
  ]
]

おわりに

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

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

執筆者:

関連記事

Ubuntu 20.04のMySQL8.0.22でrootパスワードをリセットする

小ネタです。 休みなので 久しぶりにローカル環境のUbuntuでMySQLにアクセスしようとして、パスワードを見事に忘れたことに気づきました。 ubuntu 20.04なので、以下の手順でパスワードの …

顔画像のモザイク方法(python + OpenCV + face_recognition)

Python3での顔画像モザイク方法 python3での顔画像モザイクの方法を調べてみました。 仕事とは関係なく、単なる趣味だったりしますが。。 この内容で、Djangoと統合する予定です。 Open …

最近の故障/修正物

近年で故障し、しょうがないから修理、というか購入したもの、及び顛末を書いてみます。 ハードディスク・レコーダー ちょっと前から調子が悪く、電源がつかなかったり、ついたと思ったら、録画物のリストがおかし …

Pythonパッケージ管理の歴史

歴史っても、あまり過去に興味がないので、、 Pythonのパッケージ管理の歴史は、常に流動的で、そもそもからして、とてもじゃないがまとめて説明できるようなものではないです。 はっきり言って昔からよく分 …

SimpleHTTPSAuthUploadServer というPython用モジュールを書いた

書いた動機 リモート開発になっているので、遠くのホストにあるファイルをお手軽に見たい、取ってきたいor編集したい、というニーズが、私の中であります。ftpなんか使わず、全部ブラウザでやりたいわけです。 …