発生したエラー
matplotlibのライブラリを使用したプログラムを実行したい際に以下のエラーが発生しました。
_tkinter.TclError: Can't find a usable init.tcl in the following directories:
{C:\Users\naoki\.pyenv\pyenv-win\versions\3.13.0\tcl\tcl8.6} C:/Users/naoki/.pyenv/pyenv-win/versions/3.12.0/lib/tcl8.6 C:/Users/naoki/.pyenv/pyenv-win/versions/lib/tcl8.6 C:/Users/naoki/.pyenv/pyenv-win/lib/tcl8.6 C:/Users/naoki/.pyenv/pyenv-win/versions/library C:/Users/naoki/.pyenv/pyenv-win/library C:/Users/naoki/.pyenv/pyenv-win/tcl8.6.13/library C:/Users/naoki/.pyenv/tcl8.6.13/library
C:/Users/naoki/.pyenv/pyenv-win/versions/3.13.0/tcl/tcl8.6/init.tcl: version conflict for package "Tcl": have 8.6.13, need exactly 8.6.14
version conflict for package "Tcl": have 8.6.13, need exactly 8.6.14
while executing
"package require -exact Tcl 8.6.14"
(file "C:/Users/naoki/.pyenv/pyenv-win/versions/3.13.0/tcl/tcl8.6/init.tcl" line 19)
invoked from within
"source C:/Users/naoki/.pyenv/pyenv-win/versions/3.13.0/tcl/tcl8.6/init.tcl"
("uplevel" body line 1)
invoked from within
"uplevel #0 [list source $tclfile]"
This probably means that Tcl wasn't installed properly.
エラーの原因
matplotlib が内部で Tk/Tcl を使用しており、pyenv がpythonのバージョン毎に複数の Tk/Tcl を管理しているため、正しいパスが通らずエラーが発生している。
Tk/Tclとは
- Tcl(Tool Command Language)と Tk(Toolkit)は、GUI(グラフィカルユーザーインターフェイス)を作るためのライブラリです
- Tcl がスクリプト言語としてコア部分を提供し、Tk がウィンドウやボタンなどの GUI 部品を提供します
- Python では tkinter がこの Tcl/Tk を内部で呼び出して GUI を描画します
- Python の各バージョンには、それぞれ対応する Tcl/Tk が組み込まれています
tkinterとは
- Python 標準ライブラリとして提供される GUI モジュールです
- Tcl/Tk をラップして、Python から簡単にウィンドウやボタン、キャンバスなどを操作できるようにしています
- matplotlibは内部で tkinter を利用しており、plt.show() でインタラクティブなグラフウィンドウを表示するときに使われます
解決方法
使用しているPythonのバージョンに対応したTk/Tclのパスを環境変数に設定することで解決しました。
私の場合、使用していた Python のバージョンは 3.12.0 でした。そのため、以下のように環境変数を設定しました。
$env:TCL_LIBRARY = "C:\Users\naoki\.pyenv\pyenv-win\versions\3.12.0\tcl\tcl8.6"
$env:TK_LIBRARY = "C:\Users\naoki\.pyenv\pyenv-win\versions\3.12.0\tcl\tk8.6"
Tcl/Tk のパスの確認方法
- Pyenv の各バージョンフォルダ内にある tcl フォルダへ移動します
- tcl と tk のディレクトリのパスをコピーします
- このパスを環境変数 TCL_LIBRARY と TK_LIBRARY に設定することで、Python が正しい Tcl/Tk を参照できるようになります