Matplotlibで入れ子の図を作成するときのちょっとしたテクニック
Matplotlibで図の中に図が入っているような図(ややこしいなw)を作成するときにいくつかはまったのでメモしておく.
図が規則的に並んでいるときはsubplotを使えば良いが, 特定の場所に表示したいときはaxesを利用する. 普通一つの図しか作らない場合はmatplotlib.pylab.plot等とするし, 複数つくる場合でもmatplotlib.pylab.subplotなどとしてできる.
しかし, 実際には一度figureを作成してから処理する必要のある場合がある. このfigureが曲者で, figureのメンバ変数はmatplotlib.pylabに対して呼んでいた関数と微妙に名前も引数も違う. 具体的には,
import matplotlib.pylab as plt plt.subplot(111) plt.axes((0.1, 0.1, 0.5, 0.5)) plt.legend(loc='best') plt.xticks((0, 1, 2), ('zero', 'one', 'two'))
とできるところ, figureの場合,
import matplotlib.pylab as plt fig = plt.figure() ax1 = fig.add_subplot(111) ax2 = fig.add_axes((0.1, 0.1, 0.5, 0.5)) h, l = ax1.get_legend_handles_labels() fig.legend(h, l, 'best') # ax2.legend() ax2.set_xticks((0, 1, 2)) ax2.set_xticklabels(('zero', 'one', 'two'))
というふうな感じ. matplotlib.pylabでsubplotなどしている場合と比べてaxesを明確に扱った方が自分がどこに描画しているのかがわかりやすく, 制御できるため良いのだが, いかんせん混乱させられる.
http://d.hatena.ne.jp/bettamodoki/20111208/1323317469
以下に簡単な入れ子の図を作成してレジェンドをまとめたものをメモしておく.
import numpy import matplotlib.pylab as plt fig = plt.figure() # Figureの作成 ax1 = fig.add_subplot(111) # 通常の描画領域(全体)を指定するaxes ax2 = fig.add_axes([0.2, 0.2, 0.3, 0.3]) # 左下の小窓を指定するaxes x = numpy.linspace(0, 1, 100) # , 101)とすると0.5が入ってtanがふっとびます ax1.plot(x, numpy.sin(x * numpy.pi * 2), 'r-', label='Sin') ax1.plot(x, numpy.cos(x * numpy.pi * 2), 'g-', label='Cos') ax2.plot(x, numpy.tan(x * numpy.pi), 'b-', label='Tan') h1, l1 = ax1.get_legend_handles_labels() # ax1のartist(Line2D)とlabelの取得 h2, l2 = ax2.get_legend_handles_labels() # ax2のartistとlabelの取得 ax1.legend(h1 + h2, l1 + l2, 'upper right') # ax1のレジェンドとしてまとめて表示 fig.show()
ax1.legendをfig.legendとしても良いが位置指定が異なるので注意. また, ax1.legendでloc='best'としてもどうやらax2のことは無視してbestな場所を選ぶので, ax2で隠れてしまう可能性がある.
変なエラーが出たらコメント内の日本語のせいかもしれないので消してください.
http://matplotlib.sourceforge.net/users/artists.html
http://matplotlib.sourceforge.net/users/legend_guide.html
http://matplotlib.sourceforge.net/api/figure_api.html