凡例をプロットから外す方法


988

1つの図で作成する一連の20のプロット(サブプロットではない)があります。伝説は箱の外に置いておきたい。同時に、フィギュアのサイズが小さくなるので、軸を変更したくありません。次のクエリについて、私を助けてください。

  1. 凡例ボックスをプロットエリアの外側に置きたいです。(凡例をプロットエリアの右側に配置します)。
  2. とにかく、凡例ボックス内のテキストのフォントサイズを小さくして、凡例ボックスのサイズを小さくしますか?

14
より新しいmatplotlibバージョンの場合、この回答、プロットを妨げることなく凡例を配置する場所を自動的に決定するようにmatplotlibを設定する方法を示しています
dotancohen 2016

2
同じ質問があり、「箱から出して」私のために機能するこの素晴らしい例を見つけました:matplotlib.org/1.3.1/users/legend_guide.html
robodasha 2017

1
この答えはより深みがありhttps://stackoverflow.com/a/43439132/52074ます。そして2行のコードでそうします!+1200の賛成投票も適切ですが、一般的ではないことがわかりました。
Trevor Boyd Smith、

2
@dotancohen 「プロットに干渉せずに凡例を配置する場所を自動的に決定する」特定のケースでは、プロットに多数の曲線がある場合、残念ながらそれは不可能です。これらの場合、ユーザーは凡例を手動で配置し、実際にプロット領域の外側に配置することができます。今私はそのような陰謀に苦しんでいます。
Ali

ところで、locの選択肢のリスト:best; 右上; 左上; 左下; 右下; 正しい; 左中央; 中央右; 下中央; 上部中央; センター;
Z-Y00

回答:


57

フォントプロパティを作成して、凡例テキストを小さくすることができます。

from matplotlib.font_manager import FontProperties

fontP = FontProperties()
fontP.set_size('small')
legend([plot1], "title", prop=fontP) 
# or add prop=fontP to whatever legend() call you already have

50
plot1この答えには何がありますか?
ポールH

41
legendこの答えには何がありますか?
リチャード

28
これは質問の2番目の部分には答えますが、1次(タイトルの付いたもの)には答えません。
Mateen Ulhaq 2018年

8
また、これを行う適切な方法はplt.legend(fontsize='small')
次のとおり

41
この回答はひどいもので、コンテキストはほとんどありません!
Tekill

1797

やりたいことを行う方法はいくつかあります。@inalisと@Naviがすでに言ったことに追加するには、bbox_to_anchorキーワード引数をて凡例を軸の外側に部分的に配置したり、フォントサイズを小さくしたりできます。

フォントサイズを小さくすることを検討する前に(これにより、非常に読みにくくなる場合があります)、凡例をさまざまな場所に配置してみてください。

それでは、一般的な例から始めましょう:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

代替テキスト

同じことを行いますが、bbox_to_anchorキーワード引数を使用すると、凡例を軸の境界の少し外側に移動できます。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend(bbox_to_anchor=(1.1, 1.05))

plt.show()

代替テキスト

同様に、凡例をより水平にしたり、図の上部に配置したりできます(丸みを帯びたコーナーと単純なドロップシャドウもオンにします)。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05),
          ncol=3, fancybox=True, shadow=True)
plt.show()

代替テキスト

または、現在のプロットの幅を縮小し、凡例を図の軸の完全に外側に配置することもできます(注:tight_layout()を使用する場合は、ax.set_position()を省略します:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# Put a legend to the right of the current axis
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.show()

代替テキスト

同様の方法で、プロットを垂直方向に縮小し、水平方向の凡例を下部に配置できます。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=5)

plt.show()

代替テキスト

見ていmatplotlibの伝説ガイドを。もご覧くださいplt.figlegend()


10
誰かがこれで問題を抱えている場合、tight_layout()が問題を引き起こすことに注意してください!
マシューG.

4
すばらしい答えです!ドキュメントへの正しいリンクは、matplotlib.org
users / legend_guide.html#legend

4
完全性として、一般的に(ドキュメントから要約) " bbox_to_anchorは4つの浮動小数点数(x、y、幅、bboxの高さ)のタプル、または正規化された軸の2つの浮動小数点数(x、y)のタプルであると言えます座標。 "
meduz、2013年

5
これはおそらくこれまでで最も訪問されたSOの回答だと認めなければなりません。合理的な人がこのロジックをここで調べずにこのロジックを思い出すことができないので、私は何度も何度もそれに戻るのを手伝うことができません。
KT。

9
Figureをファイルに保存する場合は、返されたオブジェクトを保存する必要があることに注意してください。つまりlegend = ax.legend()、それ以降fig.savefig(bbox_extra_artists=(legend,))
coldfix

792

凡例を配置する(bbox_to_anchor

凡例は、へのloc引数を使用して、軸の境界ボックスの内側に配置されplt.legendます。
たとえばloc="upper right"、凡例は境界ボックスの右上隅に配置されます。これは、デフォルトで(0,0)(1,1)、軸座標(または境界ボックス表記(x0,y0, width, height)=(0,0,1,1))からまでの範囲です。

凡例を軸の境界ボックスの外側に配置するに(x0,y0)は、凡例の左下隅の軸座標のタプルを指定できます。

plt.legend(loc=(1.04,0))

ただし、より用途の広いアプローチは、bbox_to_anchor引数を使用して、凡例を配置するバウンディングボックスを手動で指定することです。(x0,y0)bboxの一部のみを供給するように制限することができます。これにより、ゼロスパンボックスが作成され、そこから凡例はloc引数で指定された方向に拡張されます。例えば

plt.legend(bbox_to_anchor =(1.04,1)、loc = "上左")

凡例を軸の外側に配置し、凡例の左上隅を(1.04,1)座標軸の座標に配置します。

さらなる例を以下に示します。さらに、modeおよびのような異なる引数間の相互作用ncolsが示されています。

ここに画像の説明を入力してください

l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right", 
                bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")

4タプル引数を解釈する方法についての詳細はするbbox_to_anchor、のようにl4、で見つけることができ、この質問mode="expand"4タプルによって与えられたバウンディングボックス内に水平凡例を拡大します。縦に拡大された凡例については、この質問を参照してください

Axes座標ではなくFigure座標で境界ボックスを指定すると便利な場合があります。これはl5上記の例に示されています。ここでは、bbox_transform引数を使用して、図の左下隅に凡例を配置しています。

後処理

凡例を軸の外側に配置すると、完全にまたは部分的に図のキャンバスの外側にあるという望ましくない状況が発生することがよくあります。

この問題の解決策は次のとおりです。

  • サブプロットパラメーター
    を調整するを使用して、AxesがFigure内のスペースを少なくする(したがって、凡例に多くのスペースを残す)ように、サブプロットパラメーターを調整できますplt.subplots_adjust。例えば

    plt.subplots_adjust(right=0.7)

    図の右側に30%のスペースを残します。ここに凡例を配置できます。

  • タイトレイアウト
    使用plt.tight_layout図形の要素が図形の端にぴったりと合うようにサブプロットパラメーターを自動的に調整できます。残念ながら、この自動化では凡例は考慮されていませんが、サブプロット領域全体(ラベルを含む)が収まる長方形のボックスを提供できます。

    plt.tight_layout(rect=[0,0,0.75,1])
  • 数字を保存するbbox_inches = "tight"
    引数bbox_inches = "tight"するplt.savefig(伝説含む)キャンバス上のすべてのアーティストが保存された領域にフィットしているような姿を保存するために使用することができます。必要に応じて、図のサイズが自動的に調整されます。

    plt.savefig("output.png", bbox_inches="tight")
  • サブプロットのパラメーター
    を自動的に調整する図のサイズを変更せずに凡例がキャンバス内に収まるようにサブプロットの位置を自動的に調整する方法は、この答えにあります:正確なサイズでパディングなしの軸の作成(および軸の外側の凡例)

上記のケースの比較:

ここに画像の説明を入力してください

代替案

図の凡例
軸の代わりに図の凡例を使用できますmatplotlib.figure.Figure.legend。これは、特別な引数を必要としないmatplotlibバージョン> = 2.1で特に役立ちます。

fig.legend(loc=7) 

フィギュアのさまざまな軸ですべてのアーティストの伝説を作成します。凡例はloc、Axes内に配置される方法と同様に、引数を使用して配置されますが、Figure全体を参照します。したがって、凡例は自動的にAxesの外側になります。残りは、凡例とAxesが重ならないようにサブプロットを調整することです。ここで、 上記の「サブプロットパラメータの調整」のポイントが役立ちます。例:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
    axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))

fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)   
plt.show()

ここに画像の説明を入力してください

専用サブプロット軸内の凡例
を使用bbox_to_anchorする代わりに、凡例を専用サブプロット軸(lax)に配置することもできます。凡例サブプロットはプロットよりも小さくなければならないためgridspec_kw={"width_ratios":[4,1]}、軸の作成時に使用できます。軸を非表示にしてlax.axis("off")、凡例を挿入することができます。凡例のハンドルとラベルはh,l = ax.get_legend_handles_labels()、を介して実際のプロットから取得する必要があり、laxサブプロットの凡例に提供できlax.legend(h,l)ます。完全な例を以下に示します。

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2

fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")
....

h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)
lax.axis("off")

plt.tight_layout()
plt.show()

これにより、上記のプロットと視覚的に非常によく似たプロットが生成されます。

ここに画像の説明を入力してください

最初の軸を使用して凡例を配置することもできますbbox_transformが、凡例の軸を使用します。

ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)
lax.axis("off")

このアプローチでは、凡例ハンドルを外部から取得する必要はありませんが、bbox_to_anchor引数を指定する必要があります。

さらに読むとメモ:

  • 凡例で実行したいその他の例のいくつかを含むmatplotlib 凡例ガイドを検討してください。
  • 円グラフの凡例を配置するためのいくつかのサンプルコードは、この質問への回答で直接見つけることができます。 Python-凡例が円グラフと重複しています
  • loc引数は数字の代わりに通話を短くする文字列を、取ることができ、しかし、彼らは非常に直感的に相互にマップされていません。参照用のマッピングは次のとおりです。

ここに画像の説明を入力してください


凡例を専用のサブプロット軸に配置すると、と非常にうまく相乗効果がありfig.tight_layoutます。を使用plt.subplotsして軸を作成している場合はgridspec_kw={'height_ratios': [100, 1]}、凡例の軸が小さいように(またはwidth_ratios)のように指定します。次に、それfig.tight_layout()を拡大してフィットさせます。少なくともmatplotlib 3.0.3の場合。
travc

161

次のlegend()ように、呼び出しの後にcallを呼び出すだけplot()です。

# matplotlib
plt.plot(...)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

# Pandas
df.myCol.plot().legend(loc='center left', bbox_to_anchor=(1, 0.5))

結果は次のようになります。

ここに画像の説明を入力してください


4
同じパラメータをmatplotlib.pyplot.legendにも渡すと機能します
kidmose

8
これは他の誰かのために伝説の言葉を断ち切りますか?
user1717828

85

凡例をプロット領域の外に配置するにはloc、およびのbbox_to_anchorキーワードを使用しますlegend()。たとえば、次のコードは凡例をプロットエリアの右側に配置します。

legend(loc="upper left", bbox_to_anchor=(1,1))

詳細については、凡例ガイドを参照してください


10
わかりました-実装は好きですが、Figureを保存しようとすると(ウィンドウで手動でサイズを変更せずに、毎回行う必要はありません)、凡例が途切れます。それをどのように修正するかについてのアイデアはありますか?
astromax

@astromaxわからないけど、たぶん電話してみるplt.tight_layout()
クリスチャンアリス

81

短い答え:bbox_to_anchor+ bbox_extra_artists+ を使用できますbbox_inches='tight'


より長い答え:あなたは使うことができます bbox_to_anchor他の人が回答で指摘したように、して、凡例ボックスの場所を手動で指定ます。

ただし、通常の問題は、凡例ボックスがトリミングされることです。たとえば、次のようになります。

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')

fig.savefig('image_output.png', dpi=300, format='png')

ここに画像の説明を入力してください

凡例ボックスがトリミングされないようにするために、Figureを保存するときにパラメーターbbox_extra_artistsを使用して、保存された画像にトリミングされた要素を含めるbbox_inchesよう要求できますsavefig

fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')

例(2つのパラメーターをに追加するために最後の行のみを変更しましたfig.savefig()):

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# Plot
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(all_x, all_y)

# Add legend, title and axis labels
lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
ax.set_title('Title')
ax.set_xlabel('x label')
ax.set_ylabel('y label')    

fig.savefig('image_output.png', dpi=300, format='png', bbox_extra_artists=(lgd,), bbox_inches='tight')

ここに画像の説明を入力してください

MatplotlibがMatlabと同じように、凡例ボックスの外側の場所をネイティブに許可することを望みます。

figure
x = 0:.2:12;
plot(x,besselj(1,x),x,besselj(2,x),x,besselj(3,x));
hleg = legend('First','Second','Third',...
              'Location','NorthEastOutside')
% Make the text of the legend italic and color it brown
set(hleg,'FontAngle','italic','TextColor',[.3,.2,.1])

ここに画像の説明を入力してください


6
どうもありがとうございます!"bbox_to_anchor"、 "bbox_extra_artist"、および "" bbox_inches = 'tight "パラメータは、正しく機能させるために必要なものでした。素晴らしい!
Demitrian

6
ありがとうございますが、実際bbox_inches='tight'にはbbox_extra_artistがなくても完全に機能します
avtomaton

1
@avtomatonよろしくお願いします。matplotlibのどのバージョンを使用していますか?
フランクダーノンコート16年

1
@FranckDernoncourt python3、matplotlibバージョン1.5.3
avtomaton

68

ここでのすべての優れた回答に加えて、matplotlibおよびの新しいバージョンで、可能であれば、プロットを妨げることなく凡例を配置する場所を自動的に決定pylabできます

pylab.legend(loc='best')

これにより、可能な場合は凡例がデータから自動的に離れます。 loc = 'best'の使用を比較する

ただし、データを重ねずに凡例を配置する場所がない場合は、他の回答のいずれかを試してみてください。を使用してloc="best"も、凡例がプロットのに出ることはありません。


2
これを指摘してくれてありがとう!私はこれを数年前に探しましたが、見つかりませんでした。それは私の生活を本当に楽にするものです。
Edgar H

4
このオプションは役に立ちますが、質問に答えないため、反対票を投じました。私の知る限りでは、伝説をプロットの外に
Tommy

3
@Tommy:OPのコメント(現在はなくなっているようです)で、OPが凡例にグラフデータを含めないようにしたいことを明確に明らかにし、プロットの外側がそれを行う唯一の方法であると考えました。これは、mefathy、Mateo Sanchez、Bastiaan、およびradtekからの回答で確認できます。OP はXを要求しましたが、彼はYを望んでいました
dotancohen

1
実際にはそうではありません。彼/彼女は特に伝説が陰謀の外にいるように頼みました。それは質問の名前です;)「凡例をプロットから外す方法」。
durbachit

4
これは、凡例がデータを不明瞭にしないことを保証するものではありません。非常に密なプロットを作成するだけです。凡例を配置する場所はありません。たとえば、これを試してみてください... numpy import arange、sin、pi import matplotlib.pyplot as plt t = arange(0.0、100.0、0.01)fig = plt.figure(1)ax1 = fig.add_subplot(211)ax1。 scatter(t、sin(2 * pi * t)、label = 'test')ax1.grid(True)#ax1.set_ylim((-2、2))ax1.set_ylabel( '1 Hz')ax1.set_title( 「1つまたは2つの正弦波」)ax1.get_xticklabels()のラベル:label.set_color( 'r')plt.legend(loc = 'best')plt.show()
adam.r

56

短い答え:凡例上でドラッグ可能を呼び出し、インタラクティブに移動します。

ax.legend().draggable()

長い答え:プログラムではなくインタラクティブ/手動で凡例を配置したい場合は、凡例のドラッグ可能モードを切り替えて、好きな場所に凡例をドラッグできます。以下の例を確認してください:

import matplotlib.pylab as plt
import numpy as np
#define the figure and get an axes instance
fig = plt.figure()
ax = fig.add_subplot(111)
#plot the data
x = np.arange(-5, 6)
ax.plot(x, x*x, label='y = x^2')
ax.plot(x, x*x*x, label='y = x^3')
ax.legend().draggable()
plt.show()

よくわかりません。これで、凡例をどこにでも「ドラッグ」できますか?私はPython 3.6とJupyter Notebookを使用しています
sb2020

14

正確にはあなたが求めたものではありませんが、同じ問題の代替手段であることがわかりました。以下のように、凡例を半透明にします。 半透明の凡例と半透明のテキストボックスを使用したmatplotlibプロット

これを行うには:

fig = pylab.figure()
ax = fig.add_subplot(111)
ax.plot(x,y,label=label,color=color)
# Make the legend transparent:
ax.legend(loc=2,fontsize=10,fancybox=True).get_frame().set_alpha(0.5)
# Make a transparent text box
ax.text(0.02,0.02,yourstring, verticalalignment='bottom',
                     horizontalalignment='left',
                     fontsize=10,
                     bbox={'facecolor':'white', 'alpha':0.6, 'pad':10},
                     transform=self.ax.transAxes)

8

前述のように、凡例をプロットに配置したり、凡例を端から少し離したりすることもできます。これは、IPython Notebookで作成されたPlotly Python APIの使用例です。私はチームにいます。

まず、必要なパッケージをインストールします。

import plotly
import math
import random
import numpy as np

次に、Plotlyをインストールします。

un='IPython.Demo'
k='1fw3zw2o13'
py = plotly.plotly(username=un, key=k)


def sin(x,n):
sine = 0
for i in range(n):
    sign = (-1)**i
    sine = sine + ((x**(2.0*i+1))/math.factorial(2*i+1))*sign
return sine

x = np.arange(-12,12,0.1)

anno = {
'text': '$\\sum_{k=0}^{\\infty} \\frac {(-1)^k x^{1+2k}}{(1 + 2k)!}$',
'x': 0.3, 'y': 0.6,'xref': "paper", 'yref': "paper",'showarrow': False,
'font':{'size':24}
}

l = {
'annotations': [anno], 
'title': 'Taylor series of sine',
'xaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
'yaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
'legend':{'font':{'size':16},'bordercolor':'white','bgcolor':'#fcfcfc'}
}

py.iplot([{'x':x, 'y':sin(x,1), 'line':{'color':'#e377c2'}, 'name':'$x\\\\$'},\
      {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\\frac{x^3}{6}$'},\
      {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\\frac{x^3}{6}+\\frac{x^5}{120}$'},\
      {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\\frac{x^5}{120}$'}], layout=l)

これによりグラフが作成され、凡例をプロット自体に保持する機会が与えられます。ここに示すように、凡例が設定されていない場合のデフォルトは、凡例をプロットに配置することです。

ここに画像の説明を入力してください

別の配置の場合は、グラフの端と凡例の境界を密接に合わせ、境界線を削除してよりぴったり合わせることができます。

ここに画像の説明を入力してください

コードまたはGUIを使用して、凡例とグラフを移動してスタイルを変更できます。凡例をシフトするには、xとyの値を1以下に割り当てることにより、凡例をグラフ内に配置する次のオプションがあります。例:

  • {"x" : 0,"y" : 0} - 左下
  • {"x" : 1, "y" : 0} - 右下
  • {"x" : 1, "y" : 1} - 右上
  • {"x" : 0, "y" : 1} - 左上
  • {"x" :.5, "y" : 0} -下中央
  • {"x": .5, "y" : 1} -トップセンター

この場合、右上のを選択します。これlegendstyle = {"x" : 1, "y" : 1}ドキュメントに記載されています

ここに画像の説明を入力してください


3

これらの線に沿って何かが私のために働いた。このメソッドは、ジョーから取得した少しのコードから始めて、ウィンドウの幅を変更して、凡例を図の右側に自動的に合わせるようにします。

import matplotlib.pyplot as plt
import numpy as np

plt.ion()

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Put a legend to the right of the current axis
leg = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.draw()

# Get the ax dimensions.
box = ax.get_position()
xlocs = (box.x0,box.x1)
ylocs = (box.y0,box.y1)

# Get the figure size in inches and the dpi.
w, h = fig.get_size_inches()
dpi = fig.get_dpi()

# Get the legend size, calculate new window width and change the figure size.
legWidth = leg.get_window_extent().width
winWidthNew = w*dpi+legWidth
fig.set_size_inches(winWidthNew/dpi,h)

# Adjust the window size to fit the figure.
mgr = plt.get_current_fig_manager()
mgr.window.wm_geometry("%ix%i"%(winWidthNew,mgr.window.winfo_height()))

# Rescale the ax to keep its original size.
factor = w*dpi/winWidthNew
x0 = xlocs[0]*factor
x1 = xlocs[1]*factor
width = box.width*factor
ax.set_position([x0,ylocs[0],x1-x0,ylocs[1]-ylocs[0]])

plt.draw()

これは非常に便利で、うまくいきました。wxバックエンド(たとえば、windowsを使用している)にいる場合は、mgr.window.wm_geometry( "%ix%i"%(winWidthNew、mgr.window.winfo_height()))をmgr.window.SetClientSizeWH(winWidthNewに置き換えます。 、winHeightNew)など
Ezekiel Kruglick 2014

Qt4Aggバックエンド(matplotlibのLinuxインストールのデフォルト)を使用している場合は、行mgr.window.wm_geometry(...)をに置き換えmgr.window.setFixedWidth(winWidthNew)ます。
Filip S.

そして、今発見したように、ウィンドウを表示しないバックエンド(SVGやAGGバックエンドなど)を直接ファイルに保存するためのバックエンドを使用している場合は、ウィンドウのサイズ変更を完全にスキップします。fig.set_size_inches(...)必要なサイズ変更を処理します。
Filip S.

3

Matplotlibの新しいバージョンでは、凡例をプロットの外側に配置することがはるかに簡単になったため、この質問を更新する価値があります。私はこの例をMatplotlibバージョンで作成しました3.1.1

ユーザーは2タプルの座標をlocパラメーターに渡して、凡例を境界ボックス内の任意の場所に配置できます。唯一の落とし穴はplt.tight_layout()、凡例が表示されるようにmatplotlibにプロットの次元を再計算させるために実行する必要があることです。

import matplotlib.pyplot as plt

plt.plot([0, 1], [0, 1], label="Label 1")
plt.plot([0, 1], [0, 2], label='Label 2')

plt.legend(loc=(1.05, 0.5))
plt.tight_layout()

これにより、次のプロットが得られます。

凡例を外側にしてプロット

参照:


2

あなたも試すことができfiglegendます。Axesオブジェクトから独立した凡例を作成することが可能です。ただし、オブジェクトのフォーマットが正しく渡されるようにするには、いくつかの「ダミー」パスを作成する必要がある場合があります。


1

ここにあるmatplotlibチュートリアルの例です。これはより単純な例の1つですが、凡例に透明度を追加し、plt.show()を追加したので、これをインタラクティブシェルに貼り付けて結果を取得できます。

import matplotlib.pyplot as plt
p1, = plt.plot([1, 2, 3])
p2, = plt.plot([3, 2, 1])
p3, = plt.plot([2, 3, 1])
plt.legend([p2, p1, p3], ["line 1", "line 2", "line 3"]).get_frame().set_alpha(0.5)
plt.show()

1

私が大きな伝説を持っていたときに私のために働いた解決策は、余分な空の画像レイアウトを使用することでした。次の例では、4つの行を作成し、下部に凡例のオフセット(bbox_to_anchor)を使用してイメージをプロットしましたが、カットされません。

f = plt.figure()
ax = f.add_subplot(414)
lgd = ax.legend(loc='upper left', bbox_to_anchor=(0, 4), mode="expand", borderaxespad=0.3)
ax.autoscale_view()
plt.savefig(fig_name, format='svg', dpi=1200, bbox_extra_artists=(lgd,), bbox_inches='tight')

1

ここで追加するのと同様の別の解決策、だbbox_extra_artistsbbox_inchesあなたの範囲にあなたの余分なアーティストを持っている必要はありません、savefig呼び出しが。関数内でプロットのほとんどを生成したので、これを思いつきました。

書き出すときにすべての追加をバウンディングボックスに追加する代わりに、事前にFigureのアーティストに追加できます。上記のフランクダーノンコートの回答に似たものを使用する:

import matplotlib.pyplot as plt

# data 
all_x = [10,20,30]
all_y = [[1,3], [1.5,2.9],[3,2]]

# plotting function
def gen_plot(x, y):
    fig = plt.figure(1)
    ax = fig.add_subplot(111)
    ax.plot(all_x, all_y)
    lgd = ax.legend( [ "Lag " + str(lag) for lag in all_x], loc="center right", bbox_to_anchor=(1.3, 0.5))
    fig.artists.append(lgd) # Here's the change
    ax.set_title("Title")
    ax.set_xlabel("x label")
    ax.set_ylabel("y label")
    return fig

# plotting
fig = gen_plot(all_x, all_y)

# No need for `bbox_extra_artists`
fig.savefig("image_output.png", dpi=300, format="png", bbox_inches="tight")

これが生成されたプロットです。


-1

あなたがすでにあなたの問題を整理したかどうかわからない...おそらくはい、しかし...私はMATLABのように、場所に文字列「外」を単に使用しました。pylabをmatplotlibからインポートしました。次のコードを参照してください。

from matplotlib as plt
from matplotlib.font_manager import FontProperties
...
...
t = A[:,0]
sensors = A[:,index_lst]

for i in range(sensors.shape[1]):
    plt.plot(t,sensors[:,i])

plt.xlabel('s')
plt.ylabel('°C')
lgd = plt.legend(b,loc='center left', bbox_to_anchor=(1, 0.5),fancybox = True, shadow = True)

クリックしてプロットを表示

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.