首页 > 解决方案 > Seaborn 条形图 y 值未按预期求和

问题描述

为什么我的 Seaborn 条形图中的 y 值没有正确求和?下表包含预期值,您可以在下图中看到它们不匹配。代码在最后。这不是Seaborn 条形图 y 轴的值与预期不同的副本,因为该问题与日期时间格式有关。

df.groupby(['Category', 'Sub-Category'])['Profit'].sum()

Category    Sub-Category
Furniture   Bookcases        42.4
            Tables          301.3
Supplies    Labels          285.5
            Paper            82.7
Technology  Copiers         -42.1
            Phones          155.0

g = sns.FacetGrid(data=df, col='Category', sharex=False, sharey=False)
g.map_dataframe(sns.barplot, x='Sub-Category', y='Profit', ci=None)

在此处输入图像描述

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

### Create dummy data
cat = [ 'Furniture','Supplies','Furniture',
        'Supplies','Furniture','Technology',
        'Technology','Technology','Supplies',
        'Furniture','Supplies','Furniture',
        'Supplies','Furniture', 'Technology',
        'Technology','Technology','Supplies',
]

scat = ['Bookcases','Labels','Tables',
        'Labels','Bookcases','Copiers',
        'Copiers','Phones','Labels',
        'Bookcases','Paper','Tables',
        'Paper','Tables', 'Phones',
        'Phones','Copiers','Paper',
]

prof = [41.1,219.5,6.8,
        -383,2.5, 12.1,
        -71.2,16,449,
        -1.2,9,313,
        92,-18.5,132,
        7,17,-18.3,
]

df = pd.DataFrame(list(zip(cat, scat, prof)), 
                    columns =['Category', 'Sub-Category', 'Profit']
                    )

print(df.groupby(['Category', 'Sub-Category'])['Profit'].sum())
g = sns.FacetGrid(data=df, col='Category', sharex=False, sharey=False)
g.map_dataframe(sns.barplot, x='Sub-Category', y='Profit', ci=None)
plt.show()


旁白:我也尝试过 catplot,但我无法关闭空类别。例如,“纸”仍然显示在“家具”类别的 x 轴上。我使用g = sns.catplot(data=df, x='Sub-Category', y='Profit', col='Category', kind='bar', ci=None,)并尝试添加sharex=Falseor facet_kws={"dropna": True},但这不起作用。它仍然显示与上述示例相同的 y 轴值。

标签: pythonpandasmatplotlibseaborn

解决方案


sns.barplot不赚钱。它只显示其输入值的条形图。如果多个条形图最终位于同一位置,则取平均值并显示置信区间。

为了显示总和,需要提供一个包含总和的数据框。结果groupby不能直接使用,因为 seaborn 期望它的数据在显式列中。.reset_index()将索引转换为实列。

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

cat = ['Furniture', 'Supplies', 'Furniture', 'Supplies', 'Furniture', 'Technology', 'Technology', 'Technology',
       'Supplies', 'Furniture', 'Supplies', 'Furniture', 'Supplies', 'Furniture', 'Technology', 'Technology',
       'Technology', 'Supplies', ]
scat = ['Bookcases', 'Labels', 'Tables', 'Labels', 'Bookcases', 'Copiers', 'Copiers', 'Phones', 'Labels', 'Bookcases',
        'Paper', 'Tables', 'Paper', 'Tables', 'Phones', 'Phones', 'Copiers', 'Paper']
prof = [41.1, 219.5, 6.8, -383, 2.5, 12.1, -71.2, 16, 449, -1.2, 9, 313, 92, -18.5, 132, 7, 17, -18.3, ]
df = pd.DataFrame({'Category': cat, 'Sub-Category': scat, 'Profit': prof})

df_summed = df.groupby(['Category', 'Sub-Category'])['Profit'].sum().reset_index()
g = sns.FacetGrid(data=df_summed, col='Category', sharex=False, sharey=False)
g.map_dataframe(sns.barplot, x='Sub-Category', y='Profit')
g.map(plt.axhline, y=0, color='black') # horizontal line at y=0
plt.tight_layout()
plt.show()

总和条形图

要使用 来创建情节catplot,还sharex需要设置为False。(请注意,您需要设置显式颜色,因为catplot默认通过它们的 x 位置对条形进行着色,在sharex=False.

正如评论中提到的,barplot有一个estimator可以设置为的参数sum,需要ci关闭。这是一个例子:

g = sns.catplot(kind='bar', data=df, x='Sub-Category', y='Profit', estimator=sum, ci=None,
                col='Category', sharex=False, color='dodgerblue')
g.map(plt.axhline, y=0, color='navy')
g.despine(bottom='True')
for ax in g.axes.flat:
    ax.tick_params(axis='both', length=0)
    ax.grid(axis='y', color='grey', ls=':', zorder=0)

估计量 = 总和的 catplot


推荐阅读