matplotlibをインストールしてグラフの描画を行おうとした際に予想以上に詰まったので、メモ。
環境
自機:Yosemite 10.10.3
python: 2.6.6
error一覧
- install時にfreetypeがbuild出来ない
- ライブラリのImportError
- 実行時のRuntimeError
- グラフが一瞬で閉じてしまう(エラーではない)
1. pipでのインストール時のエラーと対処法
pip install matplotlib
でインストールを行うと
===================================================
The following required packages can not be built:
freetype
Command "python setup.py egg_info" failed with error code 1
というエラーを吐いて停止する。
検索すると、今はfixされているバグらしい。
手っ取り早くインストールするには、エラーメッセージにあるようにfreetypeをbrew install freetype
で入れる。
その後再度pip install matplotlib
を行うと、問題なくインストールが終了する。
2. コード内でimportする際のエラーと対処法
いざmatplotlibをコード中でimportして実行しようとすると
ImportError:dlopen(~): Library not loaded:
Reason: image not found
などとエラーを吐いて停止。
どうやらダイナミックリンクライブラリを読み込めていないようで、メッセージを見るとlibpngとfreetypeがダメになっている模様。
そこで、一旦
pip uninstall matplotlib
を行った後
brew reinstall libpng --universal
brew reinstall freetype --universal
でdllを再度インストール。
しかしここでも以下のエラーで停止した。
Error: The brew link
step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink share/man/man5/png.5
/usr/local/share/man/man5 is not writable.
You can try again using:
brew link libpng
権限の問題で書き込みが出来ないようなのでこちらを参考に
sudo chown -R $(whoami) /usr/local/lib/pkgconfig
sudo chown -R $(whoami) /usr/local/share/man/man5
で所有者を変更。
再度brew link libpng
を行って、成功。
brew reinstall freetype --universal
は問題なく成功。
その後改めてpip install matplotlib
を行って、インポートエラーは解消。
3. 実行時のエラーと対処法
importは出来るようになったものの、実行すると
RuntimeError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends.
というエラーを吐いて停止。
解決法はこちらの投稿に詳しく書かれているように
~/.matplotlib
にmatplotlibrc
ファイルを作成して
backend : TkAgg
のようにmacosx以外のバックエンドを指定すればいい、らしい。
以上で、ようやくグラフの描画を行えた。
4. グラフ描画が一瞬で終わってしまう
エラーではないが、知らなくて少しハマった。
import matplotlib.pyplot as plt
とimportしたとすると、描画を止めたい部分に
plt.show()
と記述すればOK.