我正在寻找一种方法来包含描述散点图中点的大小的(matplotlib)图例,因为这可能与另一个变量有关,就像在这个基本示例中一样:
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()
(灵感来自: http://matplotlib.org/examples/shapes_and_collections/scatter_demo.html)
所以在图例中,根据a2
中的s
描述符,理想情况下对应于大小0-400(scatter
变量)的点数很少。
答案 0 :(得分:8)
下面的解决方案使用pandas
将大小分组到集合中(使用groupby
)。它绘制每个组,并为标记分配标签和大小。我使用了this question中的分箱配方。
注意这与您说明的问题略有不同,因为标记大小已分箱,这意味着a2
中的两个元素(例如36和38)将具有相同的大小在同一个binning中。您可以随时增加垃圾箱的数量,使其更适合您。
使用此方法,您可以更改每个bin的其他参数,例如标记形状或颜色。
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()
答案 1 :(得分: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)
答案 2 :(得分:3)
我几乎喜欢mjp的答案,但它并不是很有效,因为plt.plot标记着'这个论点并不意味着与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)
答案 3 :(得分:2)
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)
sc = plt.scatter(x, y, s=a2, alpha=0.5)
plt.legend(*sc.legend_elements("sizes", num=6))
plt.show()
答案 4 :(得分:0)
基于mjp&j;和jpobst的答案,如果你有两个以上的离散大小,你可以制作一个循环并在plt.scatter()调用中包含标签:
msizes = [3, 4, 5, 6, 7]
markers = []
for size in msizes:
markers.append(plt.scatter([],[], s=size, label=size)
plt.legend(handles=markers)
请注意,您可以使用标准字符串格式设置标签格式,例如label = ('M%d' %size)
格式化mjp答案中的标签。
答案 5 :(得分:0)
我找到了这个here,它简单明了。希望它有所帮助
import matplotlib.pyplot as plt
import numpy as np
import plotly.plotly as py
import plotly.tools as tls
fig = plt.figure()
ax = fig.add_subplot(111)
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [100, 400, 490, 600, 240, 160] # Specifies marker size
ax.scatter(x,y,s=s)
ax.set_title('Plot with Different Marker size, matplotlib and plotly')
plotly_fig = tls.mpl_to_plotly( fig )
plotly_fig['layout']['showlegend'] = True
plotly_url = py.plot(plotly_fig, filename='mpl-marker-size')