Matplotlib技巧:实现X轴整数不等间距及无间距比例宽度堆叠直方图
堆叠直方图定制实现
以下是一段用于模拟分布并绘制堆叠直方图的原始代码:
import numpy as np import matplotlib.pyplot as plt f1f2 = [(i**6 - int(i**6))/5 for i in np.random.exponential(0.8, size=100)] widz = [i*(1/max(f1f2)) for i in f1f2] pos = [i for i in range(100)] f1 = [np.random.uniform()*i for i in f1f2] f2 = [s - i for s,i in zip(f1f2, f1)] fig = plt.figure(figsize=(20,2), constrained_layout=False) ax = fig.add_gridspec(nrows=1, ncols=1, hspace=0).subplots(sharex=True) ax.bar(pos, f1, color="red", edgecolor="none",width=widz) ax.bar(pos, f2, bottom=f1, color="blue", edgecolor="none",width=widz)
原始代码生成的堆叠直方图效果为:条形宽度与f1f2成比例但存在间距,X轴为等间距整数刻度。
定制需求
需要调整实现以下效果:
- 每个条形的宽度与
f1和f2的总和(即f1f2)成比例 - 条形之间完全无间距
- X轴上的整数刻度之间为不等间距(已知此设置会降低X轴可读性)
调整后的代码实现
import numpy as np import matplotlib.pyplot as plt # 生成模拟数据 np.random.seed(42) # 设置随机种子,确保结果可复现 f1f2 = [(i**6 - int(i**6))/5 for i in np.random.exponential(0.8, size=100)] f1 = [np.random.uniform() * total for total in f1f2] f2 = [total - val for total, val in zip(f1f2, f1)] # 计算条形位置与宽度:实现无间距排列 widths = np.array(f1f2) # 宽度直接使用f1f2值,保证与总和成比例 # 计算每个条形的起始位置:前一个条形的结束位置即为下一个的起始位置 positions = np.cumsum(widths) - widths # 创建绘图对象 fig, ax = plt.subplots(figsize=(20, 2)) # 绘制堆叠条形图 ax.bar(positions, f1, width=widths, color="red", edgecolor="none") ax.bar(positions, f2, bottom=f1, width=widths, color="blue", edgecolor="none") # 设置不等间距的X轴整数刻度 # 选取间隔为10的整数标签,对应位置为累计宽度的节点 tick_indices = range(0, 100, 10) tick_positions = np.cumsum(widths)[tick_indices] ax.set_xticks(tick_positions) ax.set_xticklabels(tick_indices) plt.show()
核心调整点说明
- 条形布局逻辑:通过
np.cumsum计算每个条形的起始位置,让条形首尾相接,完全消除间距;直接用f1f2作为条形宽度,确保宽度与f1+f2的总和成比例。 - X轴刻度设置:基于条形宽度的累计值设置刻度位置,让整数刻度标签对应不等间距的位置,满足需求。
内容的提问来源于stack exchange,提问作者Raph the raph
相关产品推荐
相关产品推荐

