2014-06-11 3 views
8

scatter 예제에서 점의 크기를 설명하는 (matplotlib) 범례를 포함하는 방법을 찾고 있는데,이 기본 예제에서와 같이 다른 변수와 관련 될 수 있습니다.matplotlib scatter legend size를 만드는 방법

(고무로부터 : http://matplotlib.org/examples/shapes_and_collections/scatter_demo.html)
import numpy as np 
import matplotlib.pyplot as plt 

N = 50 
x = np.random.rand(N) 
y = np.random.rand(N) 
a2 = 400*np.random.rand(N) 

plt.scatter(x, y, s=a2, alpha=0.5) 
plt.show() 

정도로 범례 scatters 디스크립터에있어서, 크기가 0-400합니다 (a2 변수)에 대응 적으로 몇 점있을 것이다.

답변

6

아래의 해결책은 크기를 함께 세트 용지함 (groupby)으로 그룹화하기 위해 pandas을 사용했습니다. 각 그룹을 플롯하고 마커에 레이블과 크기를 지정합니다. 나는 this question에서 binning 제조법을 사용했습니다. 그들은 같은 비닝 (binning) 내에으로

이 비닝 된 마커의 크기가,이 a2 두 요소, 36, 38 말을 의미로 명시된 문제에 대한 약간 다른, 같은 크기로 표시됩니다. 당신은 언제나 당신에게 맞는 것처럼 더 세밀하게 쓰레기통 수를 늘릴 수 있습니다.

이 방법을 사용하면 마커 모양이나 색상과 같이 각 저장소의 다른 매개 변수를 다양하게 지정할 수 있습니다.

import numpy as np 
import matplotlib.pyplot as plt 
import pandas as pd 

N = 50 
M = 5 # Number of bins 

x = np.random.rand(N) 
y = np.random.rand(N) 
a2 = 400*np.random.rand(N) 

# Create the DataFrame from your randomised data and bin it using groupby. 
df = pd.DataFrame(data=dict(x=x, y=y, a2=a2)) 
bins = np.linspace(df.a2.min(), df.a2.max(), M) 
grouped = df.groupby(np.digitize(df.a2, bins)) 

# Create some sizes and some labels. 
sizes = [50*(i+1.) for i in range(M)] 
labels = ['Tiny', 'Small', 'Medium', 'Large', 'Huge'] 

for i, (name, group) in enumerate(grouped): 
    plt.scatter(group.x, group.y, s=sizes[i], alpha=0.5, label=labels[i]) 

plt.legend() 
plt.show() 

Plot

+0

감사; 이것은 여전히 ​​각 bin에 대한 레이블을 갖는 제한이 있습니다. 예를 들어 레이블의 대부분은 범례에 포함되지 않는 한 더 많은 범례 행을 의미합니다. – gluuke

+1

범례에 장소를 지정하지 않고 일부 점을 플롯하려는 경우 범례에 추가되지 않았 음을 의미하는''_ ''레이블을 할당 할 수 있습니다. 예를 들어 "Small"과 "Large"를 "_"로 바꿀 수 있고 전설은 [ "Tiny", "Medium", "Huge"] 일 수 있습니다. – Ffisegydd

4

이 또한 일 것이고, 나는 그것이 약간 간단한 생각 :

msizes = np.array([3, 4, 5, 6, 7, 8]) 

l1, = plt.plot([],[], 'or', markersize=msizes[0]) 
l2, = plt.plot([],[], 'or', markersize=msizes[1]) 
l3, = plt.plot([],[], 'or', markersize=msizes[2]) 
l4, = plt.plot([],[], 'or', markersize=msizes[3]) 

labels = ['M3', 'M4', 'M5', 'M6'] 

leg = plt.legend([l1, l2, l3, l4], labels, ncol=1, frameon=True, fontsize=12, 
handlelength=2, loc = 8, borderpad = 1.8, 
handletextpad=1, title='My Title', scatterpoints = 1) 

부터 촬영 : Point size legends in matplotlib and basemap plots

+0

이것은 내가하려고했던 것입니다. 멀티 포인트 범례는 약간 추한 것이고 출판 품질은 아닙니다. – ryanjdillon

2

나는 거의 MJP의 대답처럼,하지만 아무튼 plt.plot의 'markersize'인수가 plt.scatter 's'인수와 같은 것을 의미하지 않기 때문에 제대로 작동하지 않습니다. plt.plot을 사용하면 크기가 잘못됩니다.

대신 사용

marker1 = plt.scatter([],[], s=a2.min()) 
    marker2 = plt.scatter([],[], s=a2.max()) 
    legend_markers = [marker1, marker2] 

    labels = [ 
     str(round(a2.min(),2)), 
     str(round(a2.max(),2)) 
     ] 

    fig.legend(handles=legend_markers, labels=labels, loc='upper_right', 
     scatterpoints=1) 
관련 문제