我有一个表格,其中列出了不同的类别和一些相关的子类别。类似的东西:
一般类型 | 特殊食物 |
---|---|
水果 | 苹果 |
水果 | 苹果 |
肉 | 火腿 |
水果 | 香蕉 |
肉 | 猪肉 |
蔬菜 | 生菜 |
现在我想在堆叠条形图中显示它,其中每个一般类型都有自己的条形图。每个条形都应细分为子类别(在本例中为特定食物)。
最后会有三个条形(fruit、meat 和 蔬菜)。其中 fruit 的高度为 3,有两个不同的区域(apple 的大小为 2, 的大小为 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()