给定具有列A,B,C和D的数据帧df,
A B C D
0 88 38 15.66 30.0
1 88 34 15.66 40.0
2 15 15 12.00 20.0
3 15 19 8.00 15.0
4 45 12 6.00 15.0
5 45 30 4.00 30.0
6 29 31 3.60 15.0
7 88 20 3.60 10.0
8 64 25 3.60 15.0
9 45 43 3.60 20.0
我想制作一个散点图,图A和B,大小基于C和基于D的颜色。在尝试了很多方法之后,我决定用D对数据进行分组,然后在D中绘制每个组。 :
fig,axes=plt.subplots()
factor=df.groupby('D')
for name, group in factor:
axes.scatter(group.A,group.B,s=(group.C)**2,c=group.D,
cmap='viridis',norm=Normalize(vmin=min(df.D),vmax=max(df.D)),label=name)
这会产生适当的结果,但默认的legend()函数是错误的。图例中列出的组具有正确的名称,但颜色和大小不正确(颜色应因组而异,并且所有标记的大小应相同)。
我尝试手动设置图例,我可以近似颜色,但不能让尺寸相等。最后,我想要第二个传奇,将尺寸与适当的C级相关联。
axes.legend(loc=1,scatterpoints=1,fontsize='small',frameon=False,ncol=2)
leg=axes.get_legend()
for i in range(len(factor)):
z=plt.cm.viridis(np.linspace(0,1,len(factor)))
leg.legendHandles[i].set_color(z[i])
答案 0 :(得分:0)
使用Seaborn的lmplot()
,这是一种似乎满足您要求的方法。 (摘自this post。)
首先,生成一些样本数据:
import numpy as np
import pandas as pd
n = 10
min_size = 50
max_size = 300
A = np.random.random(n)
B = np.random.random(n)*2
C = np.random.randint(min_size, max_size, size=n)
D = np.random.choice(['Group1','Group2'], n)
df = pd.DataFrame({'A':A,'B':B,'C':C,'D':D})
现在情节:
import seaborn as sns
sns.lmplot(x='A', y='B', hue='D',
fit_reg=False, data=df,
scatter_kws={'s':df.C})
<强>更新强>
给定来自OP的更新示例数据,相同的lmplot()
方法应满足规范:组图例按颜色跟踪,图例指标的大小相等。
sns.lmplot(x='A', y='B', hue='D', data=df,
scatter_kws={'s':df.C**2}, fit_reg=False,)