如何用ax.bar_label()动态更新matplotlib动画柱状图的数值标签
问题原因
你每次在animate函数中调用ax1.bar_label()都会生成新的文本标签对象,旧标签没有被主动移除,所以会不断堆叠在图上。
解决方法
这里提供两种可行方案,第一种简单易改,第二种帧数较多时性能更优:
方案1:每帧先删除旧标签再生成新标签
只需要在调用bar_label生成新标签前,先清理上一轮的旧标签即可,修改后的完整代码如下:
from matplotlib import pyplot as plt from matplotlib import animation import numpy as np fig = plt.figure() x = [1,2,3,4,5] y = [5,7,2,5,3] ax1 = plt.subplot(2, 1, 1) ax2 = plt.subplot(2, 1, 2) data = np.column_stack([np.linspace(0, yi, 50) for yi in y]) rects = ax1.bar(x, data[0], color='c') line, = ax2.plot(x, data[0], color='r') ax1.set_ylim(0, max(y)) # 初始化时存储标签对象方便后续删除 labels = ax1.bar_label(rects, padding=1) ax2.set_ylim(0, max(y)) def animate(i): global labels # 删除上一帧的所有旧标签 for label in labels: label.remove() for rect, yi in zip(rects, data[i]): rect.set_height(yi) # 生成新标签并更新标签存储变量 labels = ax1.bar_label(rects, padding=1) line.set_data(x, data[i]) anim = animation.FuncAnimation(fig, animate, frames=len(data), interval=40) plt.show()
方案2:仅更新标签文本和位置(性能更优)
不需要反复删除重建标签,初始化时拿到所有标签对象,后续逐帧修改内容和位置即可:
from matplotlib import pyplot as plt from matplotlib import animation import numpy as np fig = plt.figure() x = [1,2,3,4,5] y = [5,7,2,5,3] ax1 = plt.subplot(2, 1, 1) ax2 = plt.subplot(2, 1, 2) data = np.column_stack([np.linspace(0, yi, 50) for yi in y]) rects = ax1.bar(x, data[0], color='c') line, = ax2.plot(x, data[0], color='r') ax1.set_ylim(0, max(y)) # 初始化并留存标签对象 labels = ax1.bar_label(rects, padding=1) ax2.set_ylim(0, max(y)) def animate(i): for rect, yi, label in zip(rects, data[i], labels): rect.set_height(yi) # 按需调整数值显示精度,这里保留1位小数 label.set_text(f'{yi:.1f}') # 更新标签位置,偏移量对应你设置的padding大小 label.set_y(yi + 0.1) line.set_data(x, data[i]) anim = animation.FuncAnimation(fig, animate, frames=len(data), interval=40) plt.show()
内容的提问来源于stack exchange,提问作者BeginnersMindTruly
相关产品推荐
相关产品推荐

