表格的堆叠条形图

时间:2021-04-07 12:17:07

标签: python pandas matplotlib seaborn

我有一个表格,其中列出了不同的类别和一些相关的子类别。类似的东西:

<头>
一般类型 特殊食物
水果 苹果
水果 苹果
火腿
水果 香蕉
猪肉
蔬菜 生菜

现在我想在堆叠条形图中显示它,其中每个一般类型都有自己的条形图。每个条形都应细分为子类别(在本例中为特定食物)。

最后会有三个条形(fruitmeat蔬菜)。其中 fruit 的高度为 3,有两个不同的区域(apple 的大小为 2, 的大小为 1 >香蕉)等等,我想你明白了……或者你看看我上传的图片:

Basic Idea of what the Plot should look like

我希望有一种我没有找到的简单方法...

1 个答案:

答案 0 :(得分:0)

Seaborn 的 countplot 可以进行计数并自动创建适当的图例。不幸的是,这要么将条形放在一起(默认 dodge=True),要么将它们从 y=0 (dodge=False) 开始放在彼此的顶部。一个想法是遍历生成的条形并通过更改它们的 y 位置来堆叠它们。

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

data = [['fruit', 'apple'],
        ['fruit', 'apple'],
        ['meat', 'ham'],
        ['fruit', 'banana'],
        ['meat', 'pork'],
        ['vegetable', 'lettuce']]
df = pd.DataFrame(data, columns=['General', 'Specific'])
# df_grp = df.groupby(['General', 'Specific']).agg(len).reset_index().rename(columns={0:'Count'})

ax = sns.countplot(data=df, x='General', hue='Specific', dodge=False)
bottoms = {}
for container in ax.containers:
    for bar in container:
        h = bar.get_height()
        if not np.isnan(h) and h > 0:
            x = bar.get_x()
            w = bar.get_width()
            if x in bottoms:
                bar.set_y(bottoms[x])
                bottoms[x] += h
            else:
                bottoms[x] = h
            ax.text(x + w / 2, bottoms[x] - h / 2, f'{h:.0f}', ha='center', va='center')
ax.relim()
ax.autoscale() # recalculates the ylims due to the changed bars
ax.yaxis.major.locator.set_params(integer=True)
plt.tight_layout()
plt.show()

stacked countplot