Seaborn 条形图排序

Posted

技术标签:

【中文标题】Seaborn 条形图排序【英文标题】:Seaborn Bar Plot Ordering 【发布时间】:2017-10-01 21:39:54 【问题描述】:

我有一个包含两列的 pandas 数据框。

我需要按“计数”列排序的绘图。

dicti=('37':99943,'25':47228,'36':16933,'40':14996,'35':11791,'34':8030,'24' : 6319 ,'2'  :5055 ,'39' :4758 ,'38' :4611  )
pd_df = pd.DataFrame(list(dicti.iteritems()))
pd_df.columns =["Dim","Count"]
plt.figure(figsize=(12,8))
ax = sns.barplot(x="Dim", y= "Count",data=pd_df )
ax.get_yaxis().set_major_formatter(plt.FuncFormatter(lambda x, loc: "
:,".format(int(x))))
ax.set(xlabel="Dim", ylabel='Count')
for item in ax.get_xticklabels():
    item.set_rotation(90)
for i, v in enumerate(pd_df["Count"].iteritems()):        
    ax.text(i ,v[1], ":,".format(v[1]), color='m', va ='bottom', 
    rotation=45)
plt.tight_layout()

现在情节正在按“Dim”列排序,我需要按“Count”列排序,我该怎么做?

【问题讨论】:

您是否阅读了barplot 的文档?它接受一个名为order 的参数。因此,您可以按 Count 列排序,并将生成的 Dim 值传递给该列。 【参考方案1】:

您必须以所需的方式对数据框进行排序并重新索引它以创建新的升序/降序索引。之后,您可以绘制以索引为 x 值的条形图。然后按数据框的 Dim 列设置标签:

import matplotlib.pylab as plt
import pandas as pd
import seaborn as sns

dicti=('37':99943,'25':47228,'36':16933,'40':14996,'35':11791,'34':8030,'24' : 6319 ,'2'  :5055 ,'39' :4758 ,'38' :4611  )
pd_df = pd.DataFrame(list(dicti.items()))
pd_df.columns =["Dim","Count"]
print (pd_df)
# sort df by Count column
pd_df = pd_df.sort_values(['Count']).reset_index(drop=True)
print (pd_df)

plt.figure(figsize=(12,8))
# plot barh chart with index as x values
ax = sns.barplot(pd_df.index, pd_df.Count)
ax.get_yaxis().set_major_formatter(plt.FuncFormatter(lambda x, loc: ":,".format(int(x))))
ax.set(xlabel="Dim", ylabel='Count')
# add proper Dim values as x labels
ax.set_xticklabels(pd_df.Dim)
for item in ax.get_xticklabels(): item.set_rotation(90)
for i, v in enumerate(pd_df["Count"].iteritems()):        
    ax.text(i ,v[1], ":,".format(v[1]), color='m', va ='bottom', rotation=45)
plt.tight_layout()
plt.show()

【讨论】:

我理解正确吗 - 即使我已经对数据框进行了排序,我也必须首先使用索引作为标签来创建它,以确保 sns 不会根据标签名称按字母顺序对条形图进行排序(而且没有办法传递,例如,sorted = False,以避免这种情况)?【参考方案2】:

您可以为此使用 order 参数。

sns.barplot(x='Id', y="Speed", data=df, order=result['Id'])

感谢韦恩。

查看他的code 的其余部分。

【讨论】:

但是否可以按估计值排序:sns.barplot(x='Id', y="Speed", data=df, estimator=np.mean, order=?) 可能有更好的方法,但这可行:grp_order = df.groupby('Id').Speed.agg('mean').sort_values().index 然后sns.barplot(x='Id', y="Speed", data=df, estimator=np.mean, order=grp_order) 我无法使其正常工作,并且该链接未显示与您的解决方案相关的任何内容。 result 应该是什么或返回什么?返回int的dict?这给了我一个错误 如果您展示如何评估 result 会更好。就目前而言,你只是提出了一个行不通的单行。【参考方案3】:

准备数据框,使其按您想要的列排序。

现在将它作为参数传递给函数。

import pandas as pd
import seaborn as sns

dicti=('37': 99943,'25': 47228,'36': 16933,'40': 14996,'35': 11791,'34': 8030,'24': 6319 ,'2': 5055 ,'39': 4758 ,'38' :4611)
pd_df = pd.DataFrame(list(dicti.items()))
pd_df.columns =["Dim", "Count"]

# Here the dataframe is already sorted if not use the below line
# pd_df = pd_df.sort_values('Count').reset_index()
# or 
# pd_df = pd_df.sort_values('Count',ascending=False).reset_index()

sns.barplot(x='Dim', y='Count', data=pd_df, order=pd_df['Dim'])`

【讨论】:

【参考方案4】:

要进行特定的订单,我建议创建一个列表,然后按它排序:

order_list = ['first', 'second', 'third']
sns.barplot(x=df['x'], y=df['y'], order=order_list)

【讨论】:

【参考方案5】:

您可以使用以下代码

import seaborn as sns

iris = sns.load_dataset("iris")
order = iris.groupby(["species"])["sepal_width"].mean().sort_values().index

sns.barplot(x="species", y="sepal_width", data=iris, order=order)

如果要将它们从大到小排序,请指定 ascending=False

order = iris.groupby(["species"])["sepal_width"].mean().sort_values(ascending=False).index

【讨论】:

【参考方案6】:

尝试使用它。无需对数据框进行排序或创建额外的列表。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

dicti=('34':8030,'37':99943,'38':4611,'25':47228,'39':4758,'36':16933,'2':5055,'40':14996,'24':6319,'35':11791)
pd_df = pd.DataFrame(list(dicti.items()))
pd_df.columns =["Dim","Count"]
plt.figure(figsize=(12,8))
ax = sns.barplot(x="Dim", y= "Count",data=pd_df, order=pd_df.sort_values(by=['Count'], ascending=False).set_index('Dim').index)
ax.get_yaxis().set_major_formatter(plt.FuncFormatter(lambda x, loc: ":,".format(int(x))))
ax.set(xlabel="Dim", ylabel='Count')
for item in ax.get_xticklabels():
    item.set_rotation(90)
#for i, v in enumerate(pd_df["Count"].iteritems()):        
#    ax.text(i ,v[1], ":,".format(v[1]), color='m', va ='bottom', 
#    rotation=45)
plt.tight_layout()

注意:您可能会注意到有 3 行代码转换为 cmets。这是因为@Tronald Dump 专门询问了 Seaborn 条形图功能,但是有显示自定义洋红色标签的代码不考虑使用 seaborn.barplot 函数的可选“order”参数。因此,这对于 OP 来说是一个有效的答案,但特别是对于未来的访问者。

【讨论】:

以上是关于Seaborn 条形图排序的主要内容,如果未能解决你的问题,请参考以下文章

seaborn可视化条形图并按照升序排序条形图进行可视化:Sort Bars in Barplot in Ascending Order in Python

seaborn可视化条形图并按照降序排序条形图进行可视化Sort Bars in Barplot in Descending Order in Python

Python使用seaborn可视化分组条形图并且在分组条形图的条形上添加数值标签(seaborn grouped bar plot add labels)

Seaborn.countplot :按数量排序,也按类别排序?

Python使用seaborn可视化分组条形图(side by side)并且在分组条形图的条形上添加数值标签(seaborn grouped bar plot add labels)

用 Pandas 上的值注释条形图(在 Seaborn factorplot 条形图上)