Matplotlib横向条形图添加百分比列标注时出现TypeError的问题求助
解决Matplotlib横向条形图标注百分比的问题及TypeError错误
首先,我们来拆解你遇到的问题:
错误原因分析
你看到的TypeError: string indices must be integers是因为你在标注条形的循环里误用了之前处理坐标轴边框的变量s——这个s是字符串(比如'top'、'bottom'),自然不能用s["percent"]来索引数据框的列,属于变量名冲突导致的低级错误。
另外,你的代码里还有一个笔误:所有的ay应该改成ax,因为你只创建了ax这个坐标轴对象,不存在ay,这会导致另一个NameError。
修正后的完整代码
下面是修复了所有问题,并且能正确标注百分比的代码:
import matplotlib.pyplot as plt import pandas as pd # 构造测试数据(和你提供的示例一致) data = { 'Gender': ['F', 'F', 'F'], 'Gain/Loss': ['G', 'G', 'G'], 'Final corrected classification': ['Benign', 'Likely Benign', 'Likely Pathogenic'], 'Values': [5619, 7288, 324], 'percent': [11.658886, 15.121901, 0.672269] } df1 = pd.DataFrame(data) # 设置图表尺寸 fig, ax = plt.subplots(figsize=(16, 9)) # 绘制横向条形图 ax.barh(df1['Final corrected classification'], df1['Values']) # 隐藏坐标轴边框 for s in ['top', 'bottom', 'left', 'right']: ax.spines[s].set_visible(False) # 隐藏刻度线 ax.xaxis.set_ticks_position('none') ax.yaxis.set_ticks_position('none') # 调整刻度与标签的间距 ax.xaxis.set_tick_params(pad=5) ax.yaxis.set_tick_params(pad=10) # 添加网格线(使用最新API参数) ax.grid(visible=True, color='grey', linestyle='-.', linewidth=0.5, alpha=0.2) # 反转y轴,让分类从上到下排列 ax.invert_yaxis() # 为每个条形添加百分比标注 for p, percentage in zip(ax.patches, df1['percent']): # 计算标注位置:条形右侧偏移(适配大数值),垂直居中 x = p.get_width() + 50 y = p.get_y() + p.get_height() / 2 # 格式化百分比为保留两位小数的带%格式 ax.annotate(f'{percentage:.2f}%', (x, y), va='center') # 设置图表标题 ax.set_title('Number of variants', loc='left', fontsize=14) # 添加水印文本 fig.text(0.9, 0.15, 'STP', fontsize=12, color='grey', ha='right', va='bottom', alpha=0.7) # 显示图表 plt.show()
关键修正点说明
- 变量名修复:把所有
ay替换为ax,避免未定义变量的报错。 - 标注逻辑修复:使用
zip(ax.patches, df1['percent'])将每个条形和对应的百分比一一绑定,彻底解决变量冲突问题。 - 标注位置优化:把x轴的偏移量从
0.1改为50,因为你的Values列是较大的整数,过小的偏移会导致标注和条形重叠。 - 百分比格式化:用
f'{percentage:.2f}%'将数值转为更直观的百分比格式,提升图表可读性。 - API规范优化:用
visible=True替代旧版的b=True,符合Matplotlib的最新API使用习惯。
运行这段代码后,你就能看到每个条形旁正确显示对应的百分比了。
内容的提问来源于stack exchange,提问作者Manolo Dominguez Becerra
相关产品推荐
相关产品推荐

