You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

matplotlib动画中set_xticks等方法放置位置解决坐标轴标签闪烁问题

解决方案

问题根源

  • 闪烁原因:每次update_graph执行时清空坐标轴、重绘热图、重设刻度标签的全量重绘操作,会触发文本元素反复渲染,产生闪烁
  • 标签失效原因:sns.heatmap默认会覆写坐标轴的刻度与标签属性,在函数外提前设置的自定义标签会被update内每次调用的heatmap覆盖为默认数字索引

核心优化思路

所有固定样式(刻度、标签、colorbar、柱图坐标范围)仅初始化一次,update阶段仅更新动态变化的数值,不触发全轴重绘:

  1. 初始化热图时直接通过sns.heatmap的xticklabels/yticklabels参数传入自定义标签,无需后续反复设置
  2. 缓存热图、柱图的可操作对象,update阶段仅更新数据,不执行清空坐标轴、重绘整图的操作
  3. 固定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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:15:04