对于你的第一个问题,你可能想要弄清楚你正在绘制的数据的一些属性。例如,数据的范围。此外,您可能希望预先选择要显示的 bin 的数量。
tips = sns.load_dataset('tips')
min_val = tips.total_bill.min()
max_val = tips.total_bill.max()
val_width = max_val - min_val
n_bins = 10
bin_width = val_width/n_bins
sns.histplot(x="total_bill",
hue="day", multiple = 'stack', data=tips,
bins=n_bins, binrange=(min_val, max_val),
palette='Paired')
plt.xlim(0, 55)
另外需要记住的是,直方图中一根条形的宽度表示其范围的界限。因此,在x轴上跨越[2,5]的条形表示该条形所代表的值属于该范围。
考虑到这一点,很容易制定出解决方案。假设我们想要原始的条形图 - 识别每个条形图的边界,一个解决方案可能如下:
plt.xticks(np.arange(min_val-bin_width, max_val+bin_width, bin_width))
![Bounded bars](https://istack.dev59.com/XKGYA.webp)
现在,如果我们将刻度偏移半个条形宽度,就可以到达条形的中心。
plt.xticks(np.arange(min_val-bin_width/2, max_val+bin_width/2, bin_width))
![Centered Ticks - Paired](https://istack.dev59.com/MaHcI.webp)
对于您的单值图,想法保持不变。控制bin_width和x轴范围和刻度。必须明确控制bin-width,因为自动推断bin-width可能为1个单位宽,而在绘图上没有厚度。直方图条形始终指示范围 - 即使我们只有一个单一值。这在以下示例和图中说明。
single_val = 23.5
tips['single'] = single_val
bin_width = 4
fig, axs = plt.subplots(1, 2, sharey=True, figsize=(12,4))
sns.histplot(x='single',
hue="day", multiple = 'stack', data=tips,
binwidth=bin_width, binrange=(single_val-bin_width, single_val+bin_width),
palette='rocket',
ax=axs[0])
ticks = [single_val, single_val+bin_width]
axs[0].set(
title='Given value as tick-label starts the bin on x-axis',
xticks=ticks,
xlim=(0, int(single_val*2)+bin_width))
axs[0].xaxis.set_major_formatter(FormatStrFormatter('%.1f'))
sns.histplot(x='single',
hue="day", multiple = 'stack', data=tips,
binwidth=bin_width, binrange=(single_val-bin_width, single_val+bin_width),
palette='rocket',
ax=axs[1])
ticks = [single_val+bin_width/2]
axs[1].set(
title='Bin centre is offset from single_value by bin_width/2',
xticks=ticks,
xlim=(0, int(single_val*2)+bin_width) )
axs[1].xaxis.set_major_formatter(FormatStrFormatter('%.1f'))
输出:
![Single-value chart](https://istack.dev59.com/8e4jK.webp)
从您的描述中,我感觉您真正暗示的是一个分类条形图。居中对齐是自动完成的,因为条形不再是一个范围,而是一个离散的类别。对于示例数据中变量的数字和连续性质,我不建议使用这种方法。Pandas提供了绘制分类条形图的功能。请参见此处。对于我们的示例,可以按以下方式操作:
n_colors = len(tips['day'].unique())
agg_df = tips[['single', 'day']].groupby(['day']).agg(
val_count=('single', 'count'),
val=('single','max')
).reset_index()
agg_df.pivot(columns='day', values='val_count', index='val').plot.bar(
stacked=True,
color=sns.color_palette("Paired", n_colors),
width=0.05
)
plt.show()
这将产生:
![pandas categorical plot](https://istack.dev59.com/1hQlI.webp)