【问题标题】:Slider is unresponsive when figure contains two plots当图形包含两个图时,滑块无响应
【发布时间】:2022-01-24 23:06:46
【问题描述】:

Python 3.9、matplotlib 3.4、Mac OS 11.6.1

我在 tkinter Toplevel 上有一个滑块,其中包含一个显示两组轴的图形 convas。随着滑块的前进,轴显示了两个 4×300 矩阵序列随时间变化的热图。滑块值每增加一次,每个矩阵的描绘列数就会增加 10。我遇到的问题是滑块在几帧后变得无响应。

import numpy as np
import matplotlib.pyplot as plt
import random
from matplotlib.widgets import Slider
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from tkinter import Tk,TOP,BOTH,Toplevel
import matplotlib
matplotlib.use('TkAgg',force=True)

def scrolling_matrix_viewer(M,channels,win_size):    
    plot_window = Toplevel(bg="lightgray") 
    plot_window.geometry('1000x900')
    plot_window.attributes('-topmost', 'true')

    fig, ax = plt.subplots(2,sharex=True)

    canvas = FigureCanvasTkAgg(fig, master=plot_window)
    canvas.draw()
    canvas.get_tk_widget().pack(side=TOP,fill=BOTH,expand=1)
    
    ax[0].invert_yaxis

    fig.subplots_adjust(left=.09, bottom=.2, right=None, top=.9, wspace=.2, 
    hspace=.2)
    ax_time=fig.add_axes([0.15, 0.1, 0.65, 0.03]) # axis for slider
    spos = Slider(ax_time, '',valinit=0,valmin=0,valmax=M.shape[1]- 
    win_size,valstep=win_size)

    def update_graph(val):
            start=spos.val #starting column index of M used for this frame
            stop=spos.val+win_size #ending column index of M used for this frame
            if stop<=M.shape[1]:
               ax[0].cla
               ax[1].cla
               heatmap0=ax[0].imshow(M[:,start:stop],vmin=0, vmax=1, cmap='coolwarm', 
               aspect='auto',extent=[0,win_size,M.shape[0],0])
               heatmap1=ax[1].imshow(N[:,start:stop],vmin=0, vmax=1, cmap='coolwarm', 
               aspect='auto',extent=[0,win_size,N.shape[0],0])
               ax_time.set_xlabel('time (sec)',fontsize=12)
               ax[0].set_ylabel('channel',fontsize=12)
               ticks=ax[0].get_xticks()
               x_labels=[str(start+ticks[i]) for i in range(len(ticks))] 
               ax[0].set_yticks(range(len(channels)))
               ax[0].set_yticklabels(channels,fontsize=12)

               ax[1].set_ylabel('channel',fontsize=12)
               ax[1].set_yticks(range(len(channels)))
               ax[1].set_yticklabels(channels,fontsize=12)
           
    spos.on_changed(update_graph)
    spos.set_val(0)

# Example
root=Tk()

M=np.random.rand(4,300)
N=np.random.rand(4,300)
channels=['A','B','C','D']
win_size=10 # the number of columns of M we advance by from frame to frame

scrolling_matrix_viewer(M,channels,win_size)

root.mainloop()

下图显示了结果。当spos.val为 20 时,滑块无响应

我注意到,当只使用一个矩阵,因此只有一组轴时,一切正常。此外,当我只是使用 matplotlib 创建动画而不将结果放在图形画布上时,两个矩阵的动画都可以正常工作。

另外:所有动画都发生在函数内部这一事实可能是问题的根源。具体来说,当在文件开头输入矩阵 M 和 N 并且所有命令都在函数之外执行时,除了更新之外,一切正常。

【问题讨论】:

    标签: python matplotlib matplotlib-animation matplotlib-widget


    【解决方案1】:

    可以通过将每个轴的 ax.cla 更改为 ax.cla() 并让函数返回 spos 来解决此问题。因此,在示例中,我们将函数称为 spos=scrolling_matrix_viewer(M,channels,win_size)

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多