matplotlib を gnuplot っぽく使う

matplotlib の魅力はグラフの見た目を細かく整えられることだと思います。
一方で、データをこねくり回したり、関数のパラメータへの依存の仕方をチェックしながらプロットしたい時には、どうすればよいのか分かっていませんでした。 
最後に plt.show() して一枚のグラフを得るだけでは、物足りない時があるということです。Jupyter Notebook の新しい絵がどんどん作られて行くのもちょっと違うかんじ。
gnuplot のような手軽さがほしかったんです。
最近、その手がかりを見つけたので、メモしておきます。

基本的には、python のインタラクティブモード(IDLEや、コマンドラインなどからpython とだけ打って入るモード)で、最初に以下の2行を順に打ち込むだけです。

>>> import matplotlib.pyplot as plt
>>> plt.ion() # matplotlib のインタラクティブモードをオンにする

以降通常の手順でプロット用のコマンドを入れていけば、逐次、 figure や axes が生成・描画されたり、プロットができたりします。

ただ、これだけだと最初の決まり文句を打つのがめんどくさかったり、データを用意するのがめんどくさかったりするので、もうちょっとTips を考えました。

gnuplot でいうところの load (gnuplot コマンドが書かれたテキストファイルを読み込んで実行するコマンド)を実現するにはどうしたらよいのでしょう? import だと、importしたファイル内で定義した変数とかがローカル扱いで持ち越せないんですよね。

これの解決策としては、コマンドラインから

python -i 最初の処理を書いたpythonスクリプトファイル

を入力すればよさそうです。

オプション -i を指定すると、ファイルの内容を実行した後、処理を終了せずにそのまま対話モードに突入できます。(今回調べるまで知らなかった。)

また、plt.show() は、plt.ion() のときは処理をブロックしない(plt.ioff() のときはブロックする)そうです。

例えば、以下のコードを -i オプションつきで実行すると、

#"ion_test.py"
 #python -i ion_test.py で実行してね
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
xlim = [-1,1]
ax.set_xlim(xlim)
x = np.linspace(xlim[0],xlim[1],100)
y = lambda x, a=1: a*x**2
l, = ax.plot(x,y(x))
plt.ion()
plt.show() #インタラクティブモードのときはブロックしない

下のようなグラフが表示され、さらに引き続きコマンドが入力できるようになります。

ion_test.py を -i オプション付きで実行後に表示されるグラフ

たとえば、

>>> l2, = ax.plot(x, y(x,0.8))

と打ち込めば、下のように、2本目の線がひけました。

ion_test.py を -i オプション付きで実行後、インタラクティブモードで追加プロットした結果

さらに、

>>> l2.set_ydata(y(x,0.5))

としてやると、1本目のデータはそのままで2本目だけ書き換えることもできます。

l2 の ydataを書き換えて、違う係数の2次関数を表示したところ

>>> l2.remove()

remove で、いらなくなった線だけ消すことも可能です。


l2 をグラフから取り除いたところ

savefig によるグラフ保存もいつでもできます。
便利ですね。

参考URL:

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.isinteractive.html

https://docs.python.org/ja/3/using/cmdline.html#cmdoption-i

↓対話とスクリプト実行を混ぜて行う方法について、まとめていらっしゃいます。python -i を使う方法以外も今度使ってみたいです。


この記事が気に入ったらサポートをしてみませんか?