如何在Matplotlib柱状图中添加自定义对比箭头?
为柱状图添加对比箭头的实现方法
基础数据与现有代码
数据定义
import numpy as np base = np.arange(2) y_axis = [32.59, 28.096]
现有绘图代码
import matplotlib.pyplot as plt base = np.arange(2) fig, ax = plt.subplots() fig.set_figheight(10) fig.set_figwidth(15) bars = ax.bar(base, y_axis, width=0.3) bars[0].set_color('g') ax.bar_label(bars, [f'{i}%' for i in y_axis]) ax.set_xticks(base, labels=['Simplificado','Não simplificados'])
具体实现方法
方法1:使用ax.arrow()手动绘制单向对比箭头
直接指定箭头的起点、偏移量,配合样式参数实现清晰的对比效果,适合简单的水平/垂直箭头:
# 获取柱子顶部坐标 top_y1 = y_axis[0] top_y2 = y_axis[1] x1 = base[0] x2 = base[1] # 将箭头置于最高柱子上方,避免与柱子重叠 arrow_height = max(top_y1, top_y2) + 1 # 绘制水平箭头,从第一个柱子顶部指向第二个 ax.arrow(x1, arrow_height, dx=x2 - x1, dy=0, width=0.02, head_width=0.1, head_length=0.1, color='red', linestyle='--') # 添加差值标注 diff = top_y1 - top_y2 ax.text((x1 + x2)/2, arrow_height + 0.5, f'↓ {diff:.2f}%', ha='center', fontsize=12, color='red')
方法2:使用annotate()绘制带标注的箭头
同时实现箭头和说明文本,灵活性更高,支持自定义箭头样式和文本位置:
diff = y_axis[0] - y_axis[1] mid_x = (base[0] + base[1])/2 # 标注位置设为两柱中间上方 mid_y = max(y_axis) + 1.5 # 单向箭头+标注 ax.annotate(f'差值: {diff:.2f}%', xy=(base[0], y_axis[0]), # 箭头起点(第一个柱子顶部) xytext=(mid_x, mid_y), # 文本显示位置 arrowprops=dict(facecolor='blue', shrink=0.05, width=1, headwidth=8), ha='center', fontsize=12) # 双向对比箭头(可选) ax.annotate('', xy=(base[0], y_axis[0]), xy=(base[1], y_axis[1]), arrowprops=dict(arrowstyle='<->', color='green', linewidth=2)) ax.text(mid_x, (y_axis[0]+y_axis[1])/2 + 0.5, f'{diff:.2f}%', ha='center', fontsize=12)
方法3:使用ConnectionPatch绘制精细连接箭头
适合需要跨坐标区域或更复杂样式的箭头,支持自定义箭头的连接方式:
from matplotlib.patches import ConnectionPatch # 获取两个柱子的顶部中心坐标 x0, y0 = base[0], y_axis[0] x1, y1 = base[1], y_axis[1] # 创建连接箭头 conn = ConnectionPatch(xyA=(x0, y0), xyB=(x1, y1), coordsA='data', coordsB='data', axesA=ax, axesB=ax, arrowstyle='->', color='purple', linewidth=2) ax.add_artist(conn) # 添加差值标注 ax.text((x0+x1)/2, max(y0,y1)+1, f'↓ {y0-y1:.2f}%', ha='center', fontsize=12)
内容的提问来源于stack exchange,提问作者INGl0R1AM0R1
相关产品推荐
相关产品推荐

