2017-06-02 63 views
8

我想使用matplotlib来生成带有分类行和列标签的pandas DataFrame的散点图。示例DataFrame如下所示:使用分类标记的行/列绘制熊猫DataFrame的散点图

import pandas as pd 
df = pd.DataFrame({"a": [1,2], "b": [3,4]}, index=["c","d"]) 
# a b 
#c 1 2 
#d 3 4 

标记大小是各个DataFrame值的函数。到目前为止,我想出了一个尴尬的解决方案,本质上列举的行和列,绘制数据,然后重建标签:

flat = df.reset_index(drop=True).T.reset_index(drop=True).T.stack().reset_index() 
# level_0 level_1 0 
#0  0  0 1 
#1  0  1 2 
#2  1  0 3 
#3  1  1 4 

flat.plot(kind='scatter', x='level_0', y='level_1', s=100*flat[0]) 
plt.xticks(range(df.shape[1]), df.columns) 
plt.yticks(range(df.shape[0]), df.index) 
plt.show() 

哪种作品。 Which kind of works

现在,问题:是否有更直观,更集成的方式来产生散点图,理想情况下不需要拆分数据和元数据?

+0

,我不认为我们可以用非数值数据绘制。 AFAIK你将不得不单独设置刻度... – MaxU

+1

我想这个问题转化为*“为什么没有库实现我的自定义绘图的愿望功能呢?”*。 – ImportanceOfBeingErnest

回答

7

也许不是一个完整的答案你寻找,但有一个想法,以帮助节省时间和flat=代码行的可读性。

熊猫unstack方法将产生一个系列与MultiIndex

dfu = df.unstack() 

print(dfu.index) 
MultiIndex(levels=[[u'a', u'b'], [u'c', u'd']], 
      labels=[[0, 0, 1, 1], [0, 1, 0, 1]]) 

MultiIndex contains包含构造图的必要x和y点(在labels中)。在这里,我将levelslabels分配给更适合绘图的更多信息丰富的变量名称。

xlabels, ylabels = dfu.index.levels 
xs, ys = dfu.index.labels 

从这里开始绘图很简单。

plt.scatter(xs, ys, s=dfu*100) 
plt.xticks(range(len(xlabels)), xlabels) 
plt.yticks(range(len(ylabels)), ylabels) 
plt.show() 

enter image description here

我想这在几个不同的DataFrame形状,它似乎托起。

4

这不正是你问什么,但它有助于以类似的方式来可视化值:

import seaborn as sns 

sns.heatmap(df[::-1], annot=True) 

结果:

enter image description here

+0

呃...那是海豹,而不是matplotlib。但是,谢谢! – DyZ

3

也许你可以使用numpy的阵列和pd.melt创建散点图,如下图所示:

arr = np.array([[i,j] for i in range(df.shape[1]) for j in range(df.shape[0])]) 
plt.scatter(arr[:,0],arr[:,1],s=100*pd.melt(df)['value'],marker='o') 
plt.xlabel('level_0') 
plt.ylabel('level_1') 
plt.xticks(range(df.shape[1]), df.columns) 
plt.yticks(range(df.shape[0]), df.index) 
plt.show() 

enter image description here