Tkinter中双动画水平堆叠Matplotlib图表显示异常求助
问题解决:Matplotlib+Tkinter双动画堆叠条形图分开展示
问题原因
你的代码出现所有内容绘制到单个图表的核心问题:
- 使用全局的
plt.barh()方法,该方法默认会绘制到当前活跃的Matplotlib画布,而非指定的子图对象 - 动画更新时未清除子图中的旧图形,导致新数据叠加绘制
- 重复执行
fig1.add_subplot(111),覆盖了初始创建的子图对象
修正后的代码
import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import tkinter from matplotlib import animation import random # 创建第一个图表和子图 fig1, b1 = plt.subplots(figsize=(7, 0.5), dpi=80) def grafico_1(i): # 清除子图旧内容 b1.clear() x = [random.randint(1, 10) for _ in range(5)] ws = ['WIRE'] y_fix = [] # 第一层 val = x[0] color = 'green' if val <3 else 'yellow' if 3<=val<6 else 'red' b1.barh(ws, val, color=color) y_fix.append(val) # 后续堆叠层 for c in x[1:]: color = 'green' if c <3 else 'yellow' if 3<c<5 else 'red' b1.barh(ws, c, color=color, left=y_fix) y_fix[0] += c ani1 = animation.FuncAnimation(fig1, grafico_1, interval=3000) # 创建第二个图表和子图 fig2, b2 = plt.subplots(figsize=(7, 0.5), dpi=80) def grafico_2(i2): # 清除子图旧内容 b2.clear() x2 = [random.randint(1, 10) for _ in range(5)] ws2 = ['line 2'] y_fix2 = [] # 第一层 val2 = x2[0] color2 = 'green' if val2 <3 else 'yellow' if 3<=val2<6 else 'red' b2.barh(ws2, val2, color=color2) y_fix2.append(val2) # 后续堆叠层 for c2 in x2[1:]: color2 = 'green' if c2 <3 else 'yellow' if 3<c2<5 else 'red' b2.barh(ws2, c2, color=color2, left=y_fix2) y_fix2[0] += c2 ani2 = animation.FuncAnimation(fig2, grafico_2, interval=3000, frames=100) # Tkinter窗口布局 janela = tkinter.Tk() janela.geometry('1000x1000') canvas1 = FigureCanvasTkAgg(fig1, janela) canvas1.draw() canvas1.get_tk_widget().pack(pady=20) canvas2 = FigureCanvasTkAgg(fig2, janela) canvas2.draw() canvas2.get_tk_widget().pack(pady=20) janela.mainloop()
关键修改点
- 移除重复的
add_subplot(111)调用:plt.subplots()已直接返回子图对象,无需重复创建 - 使用子图对象的
barh()方法(b1.barh()/b2.barh())替代全局plt.barh(),确保绘制到指定画布 - 动画函数开头添加
b1.clear()/b2.clear(),每次更新前清除旧图形 - 简化颜色判断逻辑,用三元表达式替代多分支if,提升可读性
- 优化
y_fix更新逻辑,直接修改列表元素而非反复重建列表 - 改用
pack()布局替代place(),让图表排版更合理
内容的提问来源于stack exchange,提问作者Jose Lotto
相关产品推荐
相关产品推荐

