2017年4月5日水曜日

Raspberry PiとPython3でグラフを作成する

Raspberry PiのPython3とmatplotlibライブラリでグラフを作成するまでの手順。OSはRaspbian Jessie。ここでは、気象庁が提供している台風情報から、年ごとの発生台風数を棒グラフにする。この台風情報はcsvでダウンロード可能。

まずは環境を確認。RaspbianのバージョンはJessie。


Python3のバージョン。



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


csvファイルの読み込みにPythonライブラリのpandasを使うのでインストールする。コンパイルに20~30分かかった。


続いて、グラフ作成ライブラリのmatplotlibもインストールする。



台風情報のダウンロード


requestsライブラリでcsvをダウンロードし、pandasライブラリでcsvを読み込む。このときにひと工夫が必要。参考にしたのはPandas read_csv from url
import requests
import pandas as pd
from io import StringIO

# 台風情報csvのurl
url = 'http://www.data.jma.go.jp/fcd/yoho/typhoon/statistics/generation/generation.csv'
# csvをバイナリとして取得
csv_content = requests.get(url).content
# pandasでcsvの読み込み
data = pd.read_csv(StringIO(csv_content.decode(encoding='shift_jis')), header=0, index_col=0, \
                    skipinitialspace=True).fillna(0).astype(int)

csvでは台風発生がない月は0でなく値が何も入っておらずNaNとなる。fillna(0)でNaNを0に変換。また、カンマのあとに空白が入っていることがある。これをskipinitialspace=Trueで読み飛ばす。

上記コードを実行してcsvの中身を確認してみる。年ごとに、1月から12月、年間の台風発生数が格納されている。



matplotlibのターミナル対応


グラフを作成するためにmatlablibをインポートする場合は「import matplotlib.pyplot as plt」のようにするが、ターミナルソフトでグラフ作成すると以下のようなエラーになる。


これを回避するには以下のように2行追加する。
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt


グラフの日本語対応


matplotlibで作成されるグラフの日本語対応をする。

まずは、日本語フォントがインストールされているか確認する。Python3を対話モードで起動し、以下のコマンドを実行するとフォントの一覧が表示される。


一覧の中に「IPAexGothic」という日本語フォントがあるのでこれを使う。

日本語対応する方法はいくつかあるが、matplotlibの設定ファイルでデフォルトフォントを日本語フォントに変更してみる。はじめに設定ファイルの場所を確認する。Python3を対話モードで起動し、matplotlib.matplotlib_fname()で確認できる。


設定ファイルを~/.config/matplotlib/にコピーし編集する。


font.familyをIPAexGothicに変更する。


キャッシュファイルを削除。


これでグラフで日本語表示できるはずなのだが、家の環境では反映されない。そこで、プログラム中でデフォルトフォントを変更する方法を試した。コードのライブラリインポートのあとに以下を追加する。
font = {'family' : 'IPAexGothic'}
matplotlib.rc('font', **font)
しかし、この方法でもうまくいかなかった。仕方ないので、デフォルトフォントを変更する方法はあきらめて、タイトルやラベルごとにフォントを指定することにした。
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

# 日本語フォント指定
font = {'family' : 'IPAexGothic'}
# タイトル
plt.title('台風発生数推移', fontdict=font)
# y軸ラベル
plt.ylabel('頻度', fontdict=font)
# x軸ラベル
plt.xlabel('年', fontdict=font)
#凡例
plt.legend(['台風発生数'], prop=font)
この方法ではちゃんと反映された。


グラフ作成


台風年間発生数の棒グラフをpngで作成するコード。
import requests
import pandas as pd
import numpy as np
from io import StringIO

# ターミナルで実行するときは、これがないとエラーになる
import matplotlib
matplotlib.use('Agg')

import matplotlib.pyplot as plt

# デフォルトフォントの変更
# ↓家の環境では反映されない
#font = {'family' : 'IPAexGothic'}
#matplotlib.rc('font', **font)

url = 'http://www.data.jma.go.jp/fcd/yoho/typhoon/statistics/generation/generation.csv'
csv_content = requests.get(url).content

data = pd.read_csv(StringIO(csv_content.decode(encoding='shift_jis')), header=0, index_col=0, \
                    skipinitialspace=True).fillna(0).astype(int)

# 年間合計値の列を取得
df = data[[12]]

# 棒グラフ
df.plot(kind='bar')

# 日本語フォント指定
font = {'family' : 'IPAexGothic'}
# タイトル
plt.title('台風発生数推移', fontdict=font)
# y軸ラベル
plt.ylabel('頻度', fontdict=font)
# x軸ラベル
plt.xlabel('年', fontdict=font)
#凡例
plt.legend(['台風発生数'], prop=font)

# 目盛りの文字サイズを小さくする
plt.tick_params(labelsize=6)

# グラフをpngで出力
plt.savefig('typhoon.png')

出力されたグラフ

0 件のコメント:

コメントを投稿