[python] 줄거리에서 범례를 지우는 방법

단일 그림으로 만들 일련의 20 개의 플롯 (하위 그림이 아님)이 있습니다. 전설이 상자 바깥에 있기를 원합니다. 동시에 그림의 크기가 줄어들어 축을 변경하고 싶지 않습니다. 다음 쿼리에 대해 친절하게 도와주세요.

  1. 범례 상자를 플롯 영역 외부에 유지하고 싶습니다. (범례가 플롯 영역의 오른쪽에 외부에 있기를 원합니다).
  2. 어쨌든 범례 상자 안의 텍스트의 글꼴 크기를 줄여서 범례 상자의 크기가 작습니까?


답변

글꼴 속성을 만들어 범례 텍스트를 더 작게 만들 수 있습니다.

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


답변

원하는 것을하는 방법에는 여러 가지가 있습니다. @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().


답변

범례 배치 ( 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)축 좌표의 위치 에 있도록 범례를 축 외부에 배치 합니다.

추가적으로 다른 인자 사이의 상호 작용이 같은 곳에 추가의 예는 이하와 같다 modencols같다.

여기에 이미지 설명을 입력하십시오

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")

에서 bbox_to_anchor와 같이 4- 튜플 인수를 해석하는 방법에 대한 자세한 내용 l4이 질문 에서 찾을 수 있습니다 . 는 mode="expand"4 튜플 주어진 바운딩 박스 내에 수평으로 범례를 확장한다. 수직 확장 범례에 대해서는 이 질문을 참조하십시오 .

축 좌표 대신 그림 좌표에서 경계 상자를 지정하는 것이 유용한 경우도 있습니다. 이것은 l5위 의 예 에서 볼 수 있는데, bbox_transform인수는 그림의 왼쪽 아래 구석에 범례를 넣는 데 사용됩니다.

후 처리

범례를 축 외부에 배치하면 원치 않는 부분이 그림 캔버스 외부에있는 경우가 종종 있습니다.

이 문제에 대한 해결책은 다음과 같습니다.

  • 서브 플롯 매개 변수 조정 서브 플롯 매개 변수
    를 조정하여을 사용하여 축이 그림 내부의 공간을 덜 차지하므로 범례에 더 많은 공간을 남겨 둘 수 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")
  • 자동으로 부가 적 줄거리를 PARAMS 조정
    캔버스 내부의 전설 적합하도록 자동으로 부가 적 줄거리의 위치를 조정하는 방법 그림 크기를 변경하지 않고는 이 대답에서 찾을 수 있습니다 (축 외부 전설) 정확한 크기와 패딩 그림 만들기

위에서 논의 된 사례들 간의 비교 :

여기에 이미지 설명을 입력하십시오

대안

그림 범례
축 대신 그림에 범례를 사용할 수 있습니다 matplotlib.figure.Figure.legend. 이것은 특별한 인수가 필요하지 않은 matplotlib 버전> = 2.1에 특히 유용합니다.

fig.legend(loc=7) 

그림의 다른 축에있는 모든 아티스트의 범례를 만들 수 있습니다. 범례는 loc축 내부에 배치되는 방식과 유사하지만 인수 전체를 참조 하여 인수를 사용하여 배치되므로 축 외부에 다소 자동으로 배치됩니다. 남아있는 것은 범례와 축이 겹치지 않도록 서브 플롯을 조정하는 것입니다. 여기에서 “서브 플롯 매개 변수 조정” 이 도움이 될 것입니다. 예를 들면 :

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인수는하지만, 그들은 매우 직관적으로 서로 매핑되지 않는 통화는 짧게 숫자 대신 문자열을 취할 수 있습니다. 다음은 참조 용 매핑입니다.

여기에 이미지 설명을 입력하십시오


답변

그냥 전화 legend()애프터 호출 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))

결과는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


답변

플롯 영역 외부에 범례를 배치하려면 locbbox_to_anchor키워드를 사용하십시오 legend(). 예를 들어 다음 코드는 범례를 플롯 영역의 오른쪽에 배치합니다.

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

자세한 내용은 범례 안내서를 참조하십시오


답변

짧은 대답 : 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')

여기에 이미지 설명을 입력하십시오

당신이 매개 변수를 사용할 수 있습니다 그림 저장할 때의 범례 상자를 방지하기 위해, 잘려지고 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])

여기에 이미지 설명을 입력하십시오


답변

여기에 모든 훌륭한 답변의 최신 버전에 추가 matplotlib하고 pylab있습니다 플롯을 방해하지 않고 범례를 넣을 위치를 자동으로 결정 가능하다면.

pylab.legend(loc='best')

가능한 경우 범례를 데이터에서 자동으로 멀리 배치합니다!
loc = 'best'사용 비교

그러나 데이터를 겹치지 않고 범례를 넣을 장소가 없다면 다른 답변 중 하나를 시도해보십시오. 를 사용 loc="best"하면 범례를 플롯 외부 에 두지 않습니다 .