适当处理具有不同颜色和标记大小的Pandas数据框散点图

时间:2017-04-28 03:17:09

标签: python pandas matplotlib dataframe scatter

给定具有列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()函数是错误的。图例中列出的组具有正确的名称,但颜色和大小不正确(颜色应因组而异,并且所有标记的大小应相同)。

enter image description here

我尝试手动设置图例,我可以近似颜色,但不能让尺寸相等。最后,我想要第二个传奇,将尺寸与适当的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])  

enter image description here

1 个答案:

答案 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})

sized, grouped scatter plot

<强>更新
给定来自OP的更新示例数据,相同的lmplot()方法应满足规范:组图例按颜色跟踪,图例指标的大小相等。

sns.lmplot(x='A', y='B', hue='D', data=df, 
           scatter_kws={'s':df.C**2}, fit_reg=False,)

scatter2