matplotlibで図の縦横比に関するあれこれ

matplotlibを用いて図を作成する際に, 縦横比をどうすれば変えられるのか聞かれたのであれこれ考えてみたが, 今ひとつ決定打が無い.

方法1. Figure自体の縦横比を指定する.

from matplotlib.figure as figure
fig = plt.figure(figsize=matplotlib.figure.figaspect(1))

とすると図全体の縦横比が1になる. 利点は中に描画されるものに係わらず縦横比を指定できる事だが, 逆に言うとプロット部分がこの縦横比になるわけではない.

方法2. Axesのサイズを指定する.

w, h = fig.get_figwidth(), fig.get_figheight()
ax = fig.add_axes((0.5 - 0.5 * 0.8 * h / w, 0.1, 0.8 * h / w, 0.8))

通常, Axesの縦横比は図全体の縦横比にフィットするため, 元々の図の縦横比を考慮してAxesの縦横比が1になるようにしてある. 従って, Figureのサイズが変更されたら, fig.subplots_adjustなどで更新しなければならない.
結局はその1と同じ問題があるが, 複数プロットにも対応できる.

方法3. Axesのaspectを指定する

実は一番最初に考えついたのは以前メモしていたこの方法.

ax.set_aspect('equal')とすれば良さそうなものだが, これは単位あたりの実寸が等比になるだけなので, XY軸のプロット範囲が異なる場合, むしろ変になる. 従って, 正しくはXY軸の範囲によって縦横比を補正してやる必要がある.

すべてのプロットが終了した後, ようするにxlim, ylimが決定した後で,

aspect = (ax.get_xlim()[1] - ax.get_xlim()[0]) / (ax.get_ylim()[1] - ax.get_ylim()[0])                     
ax.set_aspect(aspect)

としてやれば良い. 余段だがこの場合, Axesを作成しなくても"ax = matplotlib.pylab.gca()"としてあれば大丈夫.

この方法はラベルなどを含まない作図部分の縦横比を正確に1にしてくれるので, かなり有効. 難点はlogプロットに対応していない事. というか, 普通のplotでしか試してない.