您可以创建条形图,使用最小值作为“底部”,使用最大值和最小值之间的差作为高度。
请注意,条形图有一个“粘性”底部,将 y 轴的最低点固定在最低条上。作为补救措施,我们可以更改 ylim。
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({'grup': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'c'],
'X1': [10, 9, 12, 5, 20, 43, 28, 40, 65, 78, 65, 98, 100, 150]})
grups = np.unique(df['grup'])
bottoms = [df[df['grup'] == g]['X1'].min() for g in grups]
heights = [df[df['grup'] == g]['X1'].max() - g_bottom for g, g_bottom in zip(grups, bottoms)]
ax = sns.barplot(x=grups, y=heights, bottom=bottoms, palette="Set3", ec='black')
# for reference, show where the values are; leave this line out for the final plot
sns.stripplot(x='grup', y='X1', color='red', s=10, data=df, ax=ax)
ax.set_xlabel('grup') # needed because the barplot isn't directly using a dataframe
ax.set_ylabel('X1')
ax.set_ylim(ymin=0)
更新:添加最小值和最大值:
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({'grup': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'c'],
'X1': [10, 9, 12, 5, 20, 43, 28, 40, 65, 78, 65, 98, 100, 150]})
grups = np.unique(df['grup'])
bottoms = np.array([df[df['grup'] == g]['X1'].min() for g in grups])
tops = np.array([df[df['grup'] == g]['X1'].max() for g in grups])
ax = sns.barplot(x=grups, y=tops - bottoms, bottom=bottoms, palette="Set3", ec='black')
ax.set_xlabel('grup') # needed because the barplot isn't directly using a dataframe
ax.set_ylabel('X1')
ax.set_ylim(ymin=0)
for i, (grup, bottom, top) in enumerate(zip(grups, bottoms, tops)):
ax.text(i, bottom, f'\n{bottom}', ha='center', va='center')
ax.text(i, top, f'{top}\n', ha='center', va='center')