Matplotlib多幅横向条形图共享Y轴时绘图异常及对齐问题
问题根因
你遇到的异常是由pandas条形图的Y轴分类规则导致的:
- 调用
plot.barh('price', ...)时,pandas会将传入的price列作为分类变量处理,Y轴坐标实际是分类的索引值,而非price的数值本身 - 不同时间分组的price值范围不同(比如示例中13:30分组无11.05、13:31分组无11.00),每个子图独立生成的分类索引不统一
- 开启
sharey=True后,matplotlib会强制所有子图共用同一套分类索引,导致部分子图的price值匹配不到对应的索引位置,出现数据缺失、错位的问题,你手动设置的数值型ylim对分类Y轴不生效。
解决方案
先将price列转为覆盖所有取值的有序分类类型,保证所有分组的Y轴分类规则完全统一,修改后的代码如下:
import pandas as pd import matplotlib.pyplot as plt # ====== 新增预处理步骤:统一price的分类规则 ====== # 拿到全量价格的排序后唯一值 all_prices = sorted(data['price'].unique()) # 将price转为有序分类,分类范围覆盖所有价格 data['price'] = pd.Categorical(data['price'], categories=all_prices, ordered=True) # 按时间间隔分组 data_gb = data.groupby([pd.Grouper(freq='1min')]) numplot = len(data_gb) f, axes = plt.subplots(1, numplot, sharey=True, sharex=True, figsize=(numplot*4, 6)) for (t, prices), ax in zip(data_gb, axes): # 不需要手动设ylim,分类统一后sharey会自动对齐 prices.plot.barh(y='price', stacked=True, ax=ax) ax.legend().remove() # 可选:调整子图间距避免拥挤 plt.tight_layout() plt.show()
修改后可以满足所有需求:
- 所有子图Y轴完全对齐,范围覆盖所有price取值
- 开启
sharey=True后默认仅最左侧子图显示Y轴标签,无需额外设置 - 不会再出现数据丢失的问题
内容的提问来源于stack exchange,提问作者John Holmes
相关产品推荐
相关产品推荐

