web-dev-qa-db-ja.com

Axesクラス-指定された単位で軸のサイズ(幅/高さ)を明示的に設定します

Matplotlibを使用してAxesのサイズを明示的に指定できるFigureを作成したい、つまりAxes bboxの幅と高さを設定したい.

私はあちこち見て回ったが、これに対する解決策は見つからない。私が通常見つけるのは、fig, ax = plt.subplots(figsize=(w, h))などを使用して、完全なFigure(目盛りとラベルを含む)のサイズを調整する方法です

これは私にとって非常に重要です。軸の1:1のスケールが必要なためです。つまり、紙の1単位は実際には1単位に相当します。たとえば、xrangeが0〜10で大目盛り= 1でx軸が10cmの場合、1大目盛り= 1cmです。この図をPDFとして保存して、ラテックスドキュメントにインポートします。

この質問 同様のトピックを取り上げましたが、答えは私の問題を解決しません(plt.gca().set_aspect('equal', adjustable='box')コードを使用)

これから question 軸サイズを取得することは可能ですが、明示的に変更する方法はありません。

Figureのサイズだけでなく、Axesのボックスサイズを設定する方法についてのアイデア。フィギュアのサイズは、軸のサイズに適応する必要があります。

ありがとう!

Latexで pgfplots に精通している人にとっては、scale only axisオプション( here を参照)。

10
Gabriel

軸のサイズは、図のサイズと図の間隔によって決まります。これは、 figure.subplots_adjust() を使用して設定できます。これは逆に、Figureの間隔を考慮してFigureのサイズを設定することにより、Axesのサイズを設定できることを意味します。

import matplotlib.pyplot as plt

def set_size(w,h, ax=None):
    """ w, h: width, height in inches """
    if not ax: ax=plt.gca()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom
    figw = float(w)/(r-l)
    figh = float(h)/(t-b)
    ax.figure.set_size_inches(figw, figh)

fig, ax=plt.subplots()

ax.plot([1,3,2])

set_size(5,5)

plt.show()

Matplotlibには、固定サイズの軸を定義できるヘルパークラスがあります デモ固定サイズ軸

2
Max

ImportanceofBeingErnestsの答えは、軸のサイズを調整するためにその図のサイズを変更すると、出版準備のできたプロットを作成するために使用する特定のmatplotlib設定と矛盾した結果をもたらすことを発見しました。最終的なフィギュアサイズにはわずかなエラーが存在し、彼のアプローチで問題を解決する方法を見つけることができませんでした。ほとんどのユースケースでは、これは問題ではないと思いますが、複数のpdfを公開用に組み合わせるとエラーが顕著になりました。

最小サイズの作業例を開発して、フィギュアのサイズ変更アプローチに伴う実際の問題を見つける代わりに、代わりにディバイダークラスを使用して固定軸サイズを使用する回避策を見つけました。

_from mpl_toolkits.axes_grid1 import Divider, Size
def fix_axes_size_incm(axew, axeh):
    axew = axew/2.54
    axeh = axeh/2.54

    #lets use the tight layout function to get a good padding size for our axes labels.
    fig = plt.gcf()
    ax = plt.gca()
    fig.tight_layout()
    #obtain the current ratio values for padding and fix size
    oldw, oldh = fig.get_size_inches()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom

    #work out what the new  ratio values for padding are, and the new fig size.
    neww = axew+oldw*(1-r+l)
    newh = axeh+oldh*(1-t+b)
    newr = r*oldw/neww
    newl = l*oldw/neww
    newt = t*oldh/newh
    newb = b*oldh/newh

    #right(top) padding, fixed axes size, left(bottom) pading
    hori = [Size.Scaled(newr), Size.Fixed(axew), Size.Scaled(newl)]
    vert = [Size.Scaled(newt), Size.Fixed(axeh), Size.Scaled(newb)]

    divider = Divider(fig, (0.0, 0.0, 1., 1.), hori, vert, aspect=False)
    # the width and height of the rectangle is ignored.

    ax.set_axes_locator(divider.new_locator(nx=1, ny=1))

    #we need to resize the figure now, as we have may have made our axes bigger than in.
    fig.set_size_inches(neww,newh)
_

注目に値するもの:

  • 軸インスタンスでset_axes_locator()を呼び出したら、tight_layout()関数を中断します。
  • 選択した元の図のサイズは無関係であり、最終的な図のサイズは、選択した軸のサイズとラベル/目盛りラベル/外側の目盛りのサイズによって決まります。
  • このアプローチは、カラースケールバーでは機能しません。
  • これは私の初めてのスタックオーバーフローポストです。
0
BongaCodeBuddy