DISTRICT 37

なにか

matplotlibが描画されない

普段コードを書くときはjupyterを使っていて、matplotlibのプロットがブラウザ内に行われるの為この問題には気付かなかった。改めてpythonのコードを書いてみて描画関連でエラーが出ていることに気が付いた。

環境

  • Ubuntu16.02
  • python 3.5.1 (pyenv)
  • matplotlib 1.5.2

何が起こったか

最初はmatplotlibで描画するコードであるplt.show()としてもウンともスンとも言わなかった。で探しているうちにmatplotlibのbackendにTkを指定しないと描画が行われないとの情報があった。それを指定したのちにplt.show()を実行したら「ImportError: Nomodule named '_tkinter'」と出た。jupyter上では問題無く動くコードなのに、pythonのコードとして実行するとエラーを吐いて描画が行われなかった。

---> 35 import _tkinter # If this fails your Python may not be configured for Tk
     36 TclError = _tkinter.TclError
     37 from tkinter.constants import *

ImportError: No module named '_tkinter'

エラーメッセージには「キミの使っているpythonにTk関連のセットアップが済んでいないよ」と表示されている

解決方法

TK関連のライブラリを入れて、pythonの入れ直しをしたら直る。入れててよかったpyenv。

準備としてpip関連のパッケージ情報を吐きだしておく。何を入れていたかなんて当然覚えちゃいない。

pip freeze > pip.txt

まずはpythonのアンインストール。pyenvでどのバージョンのpythonを使っているか確認してからでもいいかも。

pyenv versions
pyenv uninstall 3.5.1

続いてTK関連のライブラリをインストール

sudo apt install python-tk tk-dev

そのあとでpythonを再インストール

pyenv install 3.5.1

終わったらpipのパッケージを一括インストール

pip install -r pip.txt

注意点としてscikit-learnが入っていた場合は先にScipyを入れないとエラーを起こして止まる。freezeで出力したファイルはアルファベット順にソートされていてscikit-learn、Scipyの順に記述されている。一括インストールではその順にインストールが行われるのでファイル自体の順番を編集するとか、指摘通りにScipyを先に入れちゃうとかやっておくといい。

作業としてはこれでおしまい。

確認

matplotlibrcというファイルにbackendの指定をする必要がある。場所はmatplotlib自身が教えてくれる

import matplotlib
print(matplotlib.matplotlib_fname())

# こんな感じで標準出力に出る
# '/home/yourname/.pyenv/versions/3.5.1/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc'

該当ファイルをエディタで開いて「backend」を「tkagg」に更新する

backend   :tkagg

このbackendが適切なものに指定されていないとmatplotlibはちゃんと描画されない。pythonのコード中に書いて指定することもできるが、そもそもライブラリが入っていなくて使えない場合は指定してもだめ。

以下のサンプルはjupyterだけど、pythonのコードを書いて無事にサインカーブが描画されたら確認完了。

原因

上記のエラーメッセージの通りpythonインストール時にTK関連のライブラリが無いとmatplotlibの描画時にTKが使われないとの事。後付けでできないかいろいろ探し回ったけど、再インストールが手っ取り早かった。

参考

qiita.com