如何在DataFrame直方图循环中为各子图添加对应分位数竖线?
解决直方图分位数竖线仅显示在最后子图的问题
嘿,我一眼就看出问题出在哪了——你用的plt.axvline()默认会把线条画在当前活跃的子图上,而你的循环里每次画完直方图后,活跃子图会自动切换到下一个,但你画竖线的时候没指定对应的子图轴,结果所有竖线都堆到最后一个子图里去了!另外我还注意到你代码里分位数和列的对应关系好像搞反了,比如n=0的时候画的是efg列的分位数,但n=0对应的应该是abc列吧?这也会导致竖线和直方图不匹配。
给你修正后的代码,我还优化了结构,让它更易读和维护:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 加载数据 df4 = pd.read_csv("xyz.csv", index_col="abc_id") # 用字典关联每列和它的分位数,避免冗余的if判断 column_quantiles = { 'abc': df4['abc'].quantile([0.25, 0.5, 0.75, 0.9, 0.95]), 'efg': df4['efg'].quantile([0.25, 0.5, 0.75, 0.9, 0.95]), 'xyz': df4['xyz'].quantile([0.25, 0.5, 0.75, 0.9, 0.95]) } colors = ['r','k','b','g','y'] fig, axs = plt.subplots(len(df4.columns), figsize=(10, 25)) # 遍历每个列和对应的子图轴 for idx, col_name in enumerate(df4.columns): current_ax = axs[idx] # 绘制当前列的直方图(注意原代码里你写的是df[col],应该是df4!) df4[col_name].hist(ax=current_ax, bins=50) # 获取当前列对应的分位数 q_values = column_quantiles[col_name] # 在当前子图上绘制分位数竖线,用current_ax.axvline指定轴 for x_coord, color in zip(q_values, colors): current_ax.axvline(x=x_coord, label=f'分位数: {x_coord:.2f}', c=color) # 给每个子图加标题和图例,让每个图都有自己的说明 current_ax.set_title(f'{col_name} 直方图与分位数') current_ax.legend() # 自动调整子图间距,避免标签重叠 plt.tight_layout() plt.show()
关键修改点说明:
- 指定轴对象绘制竖线:用
current_ax.axvline()替代plt.axvline(),确保竖线精准画在当前循环对应的子图上,而不是最后一个活跃子图。 - 字典关联列与分位数:去掉了繁琐的
if判断,既保证分位数和列严格对应,也让代码更易扩展(比如以后加新列只需要在字典里加一行)。 - 修正DataFrame名称:原代码里的
df[col]应该是df4[col],不然会抛出NameError。 - 子图单独配置:每个子图都添加自己的标题和图例,不会只有最后一个图显示图例,可读性更强。
内容的提问来源于stack exchange,提问作者P. Saha
相关产品推荐
相关产品推荐

