python/pandas/matplotlibを使ってcsvファイルを読み込んで素敵なグラフを描く方法(Mac/Raspberry Pi)

f:id:karaage:20170516224815p:plain:w640

gnuplotはもう嫌だ!pythonでグラフを書きたい!

 以前こんな感じにRaspberry Piでセンサのデータを取得して可視化していました。

 グラフ描くとき、昔ながらのgnuplotを使ったのですが、こんなコメントが。

Raspberry Pi + BME280モジュールで自動で温度・湿度・気圧を測定してグラフ化する - karaage. [からあげ]

せっかくなのでグラフにしよう、と思って調べて最初にみつかったのがgnuplotだった。お、おぅ。(昔はgnuplotかなり使い込んでた)

2017/02/17 19:10

 ぐ、ぐぬぬ(gnuplotだけに)。やはり今どきはgnuplotはスマートじゃないのだろうか。どうせならpythonで完結したいよねということで、pythonでグラフを描く方法を調べてグラフを描いて見ました。

 色々調べた結果、以下のようないかにも「gnuplotで描きました!」というようなグラフが

f:id:karaage:20160504162345p:plain:w640

 以下のようなスタイリッシュでオシャレンティ(死語)なグラフだったり f:id:karaage:20170516224649p:plain:w640

 以下のようなユニークな漫画チックなグラフを描くことができるようになりました f:id:karaage:20170516224815p:plain:w640

 この後は、宇宙語が続きますので「私もおしゃれなグラフ描きたいワン!」というワンちゃんは、尻尾振りながら続きを見ると良いです。

pythonとpandasとmatplotlibでcsvを読み込んでグラフ化する方法

 MacとRaspberry Piでのセットアップに関して記載します。Windowsでも頑張ればできるんじゃないかな(適当)。自分の環境は以下の通りですが、他の機種やバージョンでも基本的には問題無いと思います。参考まで。

  • Mac Book Pro Retina, Mid 2012(OS X Yosemite 10.10.5)
  • Raspberry Pi 3(Raspbian Jessie with PIXEL 2016-11-25)

 必要なライブラリはpythonpandasmatplotlibseabornになります。seabornライブラリはグラフのスタイルに拘りがなければ必須ではありません。pythonのバージョンは今回はpython3を使用します。

Macの設定方法

 Macの場合は、anaconda3を使うと、最初から必要なライブラリが入っていて簡単なのでanaconda3を使います。私は、pyenvを使って環境構築をしています。以下記事参照下さい。

 Homebrewがインストールされている前提ですと、以下コマンドで打てばとりあえずセットアップはできる(はず)です。ただ、今後のために上記記事で何をやっているか理解してから実施することをお勧めします。

$ brew install pyenv
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ brew install pyenv-virtualenv
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
$ echo export PYENV_VIRTUALENV_DISABLE_PROMPT=1 >> ~/.bashrc
$ pyenv install anaconda3-2.5.0
$ pyenv global anaconda3-2.5.0

 Macの場合はこれでOKです。

Raspberry Piの設定方法

 以下記事を参考に「基本的なセットアップは完了です」と書いてあるところまで一通りセットアップ実施下さい。

 あとは、ターミナルで以下のコマンドを実行すればOKです。

$ sudo apt-get update
$ sudo apt-get install python3-pip
$ sudo apt-get install python3-pandas
$ sudo apt-get install python3-matplotlib

ちなみにRaspberry Piと書いていますが、他のLinuxでも上記コマンドで基本的にOKだと思います。一応適当なPC(Ubuntu14.04/16.04)を確認したらちゃんと動きました。

基本的なグラフの描き方

 今回は例として、時間(time)、温度(temperature)、湿度(humidity)、気圧(pressure)の時系列が保存されたcsvファイル(sample.csv)を使用します。ファイルの中身は以下のようになっていると思って下さい。

time, temperature, humidity, pressure
2016/05/22 02:10:01,21.0867422231,59.391544507,1017.48927819
2016/05/22 02:20:01,20.7770546449,60.0785619066,1017.44822635
2016/05/22 02:30:01,20.4978290685,60.6284558134,1017.25965455
2016/05/22 02:40:02,20.2490652056,61.1763110852,1017.4253724
2016/05/22 02:50:01,20.1119915389,61.3297823744,1017.40452414
2016/05/22 03:00:01,20.0053788337,61.4981035599,1017.57084668
2016/05/22 03:10:01,19.8835358992,61.701880544,1017.54598541
2016/05/22 03:20:01,19.7515395761,61.9901589655,1017.64427684
2016/05/22 03:30:01,19.6347737619,62.1997188195,1017.62728411
2016/05/22 03:40:01,19.5840060646,62.2786376915,1017.60293839
2016/05/22 03:50:01,19.5078545732,62.4077237848,1017.67772621
2016/05/22 04:00:01,19.426626388,62.6273830313,1017.7166415

 このcsvをpythonで読み込んでグラフ化します。pythonでcsvを読み込むにはcsvライブラリを使う方法とpandasを使う方法の2種類があります。pandasの方が簡単に読み込めるのと、データの処理をする色々な機能があって便利なのでpandasを使うことにします。pandas便利ですね、昔知らずに頑張ってcsvで頑張って読み込んでました。グラフ化するのは、matplotlibというライブラリを使うのが定番のようなのでそうします。

 色々なサイトを調べまわった結果、以下のような10行程度のプログラムでcsvファイルを読み込んでグラフを描くことができました。

# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv("sample_data.csv", index_col='time')
df_tmp_humid = data.iloc[:, [0,1]]
df_tmp_humid.plot()
plt.savefig("tmp_humid.png")
plt.show()

 めずらしくちょっとだけプログラムの解説しますとdata = pd.read_csv("sample_data.csv", index_col='time')でcsvファイルを読み込んでいます。csvファイルの1行目には項目名が入っている前提です(今回だとtime, temperature, humiditypressure)。index_col='time'で、インデックスとなる列を決めます。今回はtimeにしました。これを省略すると、勝手に1から順にインデックスナンバが振られます。

 df_tmp_humid = data.iloc[:, [0,1]] は行と列の抽出です。ここでは、0列(time)と1列(humidity)を全行抽出しています。その後は、プロットして画像に保存して表示しているだけですね。sample_data.csvと同じディレクトリに上記のプログラムをdraw_graph.pyという名前で保存して以下のコマンド実行して下さい。

$ python3 draw_graph.py

 以下のようなグラフが表示されます。ちゃんと日付もそれらしく読み込めていて良い感じですね。 f:id:karaage:20170517122003p:plain:w640

 同じディレクトリにtmp_humid.pngというグラフの画像ファイルも保存できています。

オシャレなグラフの描き方

 オシャレな見た目のグラフにしたい場合は、Seabornライブラリを使うのが良いです。以前はpipでseabornをインストールしないといけなかったようですが、matplotlibのバージョンが1.4以上だと、Seabornライブラリが無くても、matplotlibの機能でseabornのスタイルを使えるようです。詳しくは以下参照下さい。

Matplotlib Style Sheets

 具体的にはグラフをplotする前にplt.style.use('ggplot')と書くだけです。先ほどと同じようにグラフを表示するコマンドを実行すると以下のように表示されます。

f:id:karaage:20170516224649p:plain:w640
 おしゃれグラフ

 Macのanaconda3-2.5.0でもRaspberry PiでもLinux(Ubuntu)でも問題なく表示されました。python3-matplotlibパッケージのバージョンが古いとエラーとなるので$ sudo apt-get install python3-matplotlibしてバージョンを上げましょう。

 どうしても古いmatplotlibでseabornスタイルを使いたい場合は、sudo pip3 install seabornでseabornライブラリをインポートしましょう。詳しくは下記サイトなど参照下さい。基本的には、プログラムの冒頭にimport seaborn as snsを追加すれば使えます。

漫画みたいなグラフの描き方

 漫画みたいなグラフにしたいときは、6行目のplt.style.use('ggplot')plt.xkcd()に書き換えて下さい。以下のようなグラフが表示されます。 f:id:karaage:20170516224815p:plain:w640

 漫画みたいなグラフに関する詳細は以下のサイトを参照下さい。

まとめ

 pythonでcsvファイルを読み込んでグラフをかけるようになりました。pythonでデータ処理、分析から可視化まで完結できると便利ですね。データサイエンティスト的なお仕事するときにも便利に使えそうです(むしろ必須?)。今後は積極的に使っていきたいと思います。

 他に、こんなグラフが描きたいけどどうやって描くんだろう?と思った時は以下のmatplotlibのサイトを見てみると良いと思います。

Thumbnail gallery — Matplotlib 2.0.2 documentation

 今回、簡単にできたら「エクセルなんていますぐ捨てろ!」とかいう過激なタイトルをつけようと思っていたのですが、pythonで調べて思ったようにグラフを描くのは結構大変でした。なんだかんだでエクセルはやはり便利ですねw うまくツールを使い分けて、楽しい可視化ライフを送りましょう!

参考リンク

pandasでcsv/tsvファイルの読み書き | mwSoft

とにかくRaspberry Piにpython2 + numpy + matplotlibをインストールする – 或る阿呆の記

.csvファイルをmatplotlibで描画するまで - くれなゐの雑記

Pandas でデータフレームから特定の行・列を取得する – Python でデータサイエンス

http://installion.co.uk/ubuntu/vivid/universe/p/python3-seaborn/install/index.html

matplotlibで3Dグラフを描画する - white wheelsのメモ