如何让Matplotlib堆叠水平条形图的各行共享100%宽度的X轴
如何让Matplotlib堆叠水平条形图的各行共享100%宽度的X轴
嘿,我明白你的问题啦——你希望colours和styles这两行堆叠条形图各自都占满整个X轴的宽度(也就是每行总宽度为100%),但目前colours行的总宽度是11*(11/100)=1.21,styles行是14*(14/100)=1.96,两者宽度不一致,而且都没对齐到100%的X轴范围。
问题根源
你现在给每个条形分段赋值的逻辑是len(y_labels)/100,这会导致每行的总宽度等于len(y_labels) * (len(y_labels)/100),显然不是1(即100%)。正确的做法应该是每个分段的宽度等于1除以该行的分段数量,这样每行的总宽度加起来正好是1,也就是占满整个X轴。
修改后的代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt plt.rcParams.update(plt.rcParamsDefault) dummy = { 'colours': ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'], 'style': ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', '13', '14'] } df = pd.DataFrame.from_dict(dummy, orient="index") y_labels_colors = df.loc["colours"].dropna().tolist() # 每个分段宽度为1/分段数,确保总行宽为1(100%) y_values_colors = np.full(len(y_labels_colors), 1 / len(y_labels_colors)) y_labels_styles = df.loc["style"].dropna().tolist() y_values_styles = np.full(len(y_labels_styles), 1 / len(y_labels_styles)) fig, ax = plt.subplots(figsize=(12, 1)) cumulative_size_colors = 0 for label, value in zip(y_labels_colors, y_values_colors): ax.barh("colours", value, left=cumulative_size_colors, color='lightskyblue', edgecolor='white', linewidth=1) cumulative_size_colors += value ax.text(cumulative_size_colors - value / 2, 0, label, ha='center', va='center') cumulative_size_styles = 0 for label, value in zip(y_labels_styles, y_values_styles): ax.barh("styles", value, left=cumulative_size_styles, color='lightsteelblue', edgecolor='white', linewidth=1) cumulative_size_styles += value ax.text(cumulative_size_styles - value / 2, 1, label, ha='center', va='center') # 设置X轴范围为0到1,明确100%的边界 ax.set_xlim(0, 1) ax.set_frame_on(False) ax.set_xticks([]) plt.show()
关键改动说明
- 分段宽度计算:把
len(y_labels_colors)/100改成1/len(y_labels_colors),这样每行所有分段的总和正好是1,完美占满X轴的100%宽度。 - X轴范围锁定:添加
ax.set_xlim(0, 1),强制X轴从0到1,确保两行的条形都对齐到相同的宽度边界。
额外优化建议
如果想让X轴显示百分比刻度(比如0%、25%、50%等),可以替换ax.set_xticks([])为以下代码,让图表更直观:
ax.set_xticks(np.arange(0, 1.01, 0.25)) ax.set_xticklabels(['0%', '25%', '50%', '75%', '100%'])
这样修改后,colours和styles两行的堆叠条形就都会各自占满整个X轴宽度啦~
备注:内容来源于stack exchange,提问作者dimButTries
相关产品推荐
相关产品推荐

