matplotlib动画中set_xticks等方法放置位置解决坐标轴标签闪烁问题
解决方案
问题根源
- 闪烁原因:每次
update_graph执行时清空坐标轴、重绘热图、重设刻度标签的全量重绘操作,会触发文本元素反复渲染,产生闪烁 - 标签失效原因:
sns.heatmap默认会覆写坐标轴的刻度与标签属性,在函数外提前设置的自定义标签会被update内每次调用的heatmap覆盖为默认数字索引
核心优化思路
所有固定样式(刻度、标签、colorbar、柱图坐标范围)仅初始化一次,update阶段仅更新动态变化的数值,不触发全轴重绘:
- 初始化热图时直接通过
sns.heatmap的xticklabels/yticklabels参数传入自定义标签,无需后续反复设置 - 缓存热图、柱图的可操作对象,update阶段仅更新数据,不执行清空坐标轴、重绘整图的操作
- 固定colorbar配置,无需每次刷新时清空重建
修改后完整代码
import numpy as np import random import seaborn as sns import matplotlib.pyplot as plt from tkinter import Toplevel, TOP, BOTH from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from mpl_toolkits.axes_grid1 import make_axes_locatable # 此处自行导入你已实现的Player类 def heatplot_barplot_animation_combined(root,channels,M_list,bar_list): num_times=len(M_list)-1 Nc = len(channels) fig, ax = plt.subplots(2) plot_window = Toplevel(root) canvas = FigureCanvasTkAgg(fig, master=plot_window) canvas.draw() canvas.get_tk_widget().pack(side=TOP,fill=BOTH,expand=1) # 提前配置热图的colorbar,仅初始化一次 divider = make_axes_locatable(ax[0]) cbar_ax = divider.append_axes("right", size="5%", pad=0.05) # 初始化热图:直接传入自定义标签,后续无需反复设置 heatmap = sns.heatmap( ax = ax[0], data = M_list[0], cmap = "coolwarm", cbar_ax = cbar_ax, vmin=0, vmax=1, xticklabels=channels, yticklabels=channels ) # 刻度大小仅设置一次 ax[0].tick_params(axis='both', labelsize=10) # 初始化柱状图,缓存柱对象后续更新高度即可 bars = ax[1].bar(channels, bar_list[0]) ax[1].set_ylim(0, 1) def update_graph(i): # 仅更新热图数据,不修改轴属性 heatmap.set_data(M_list[i]) # 仅更新柱图高度,不重绘整组柱 for bar, height in zip(bars, bar_list[i]): bar.set_height(height) # 仅更新标题 fig.suptitle('Frame: '+str(i), fontsize=12) ani = Player(fig, update_graph, maxi=num_times) return ani
调用示例保持不变
channels=['a','b','c','d','e','f','g','i'] Nc=len(channels) Nt=50 M_list=[np.random.rand(Nc,Nc) for i in range(Nt)] bar_list=[[random.uniform(0,1) for i in range(Nc)] for t in range(Nt)] # root为你定义的tkinter主窗口对象 heatplot_barplot_animation_combined(root,channels,M_list,bar_list)
内容的提问来源于stack exchange,提问作者fishbacp
相关产品推荐
相关产品推荐

