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

Matplotlib滑块绘图函数复用问题:滑块无法实时更新图表

问题描述

在数字调制信号解调的实操作业中,我尝试将带有Matplotlib滑块的图表绘制代码封装为可复用的外部函数,但移到外部文件后滑块无法正常工作,无法实时更新图表。相关代码如下:

functions.py

def Find_Sampling_indexes(phase_shift:float,period:float, sample_rate:int):
    Clk = np.cos(2*np.pi*sample_rate*period-phase_shift)

    indexes = signal.find_peaks(Clk)
    index = indexes[0]

    return index

fig, ax = plt.subplots()

def update(complex_data,period,symbol_rate,val):
        index = Find_Sampling_indexes(val,period,symbol_rate)
        ax.clear()
        ax.plot(np.real(complex_data[index]),np.imag(complex_data[index]), 'g o')
        plt.draw()

def slider_phase_shift(complex_data,period,symbol_rate):
    
    index = Find_Sampling_indexes(0,period,symbol_rate)
    ax.plot(np.real(complex_data[index]),np.imag(complex_data[index]), 'g o')
    plt.xlim(-1,1)
    plt.xlim(-1,1)
    
    plt.subplots_adjust(bottom=0.25, left =0.25)
    ax_Slider = plt.axes([0.25, 0.1, 0.65, 0.03])
    sliders = Slider(ax_Slider, ' Phase', -2, 2,0)

    sliders.on_changed(update(complex_data,period,symbol_rate,sliders.val))
    show()
    return

main.py

import functions as esc

esc.slider_phase_shift(OOK_Complex,t1,93696)

解决方案

问题根源

  1. 回调绑定错误:sliders.on_changed(update(...))是直接执行了update函数,而非传递函数对象作为回调,导致滑块拖动时无法触发更新。
  2. 全局图表对象冲突:fig, ax定义在函数外部作为全局变量,封装性差且多实例调用时会互相干扰。
  3. 轴范围设置遗漏:重复设置x轴范围却未设置y轴,可能导致绘图显示异常。
  4. 模块导入缺失:代码依赖numpy、scipy.signal等模块,未在外部文件中导入会导致运行报错。

修正后的代码

functions.py

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from scipy import signal

def Find_Sampling_indexes(phase_shift: float, period: float, sample_rate: int):
    Clk = np.cos(2 * np.pi * sample_rate * period - phase_shift)
    indexes = signal.find_peaks(Clk)
    index = indexes[0]
    return index

def slider_phase_shift(complex_data, period, symbol_rate):
    # 函数内部创建图表实例,避免全局变量冲突
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.25, left=0.25)

    # 初始绘图
    index = Find_Sampling_indexes(0, period, symbol_rate)
    ax.plot(np.real(complex_data[index]), np.imag(complex_data[index]), 'g o')
    ax.set_xlim(-1, 1)
    ax.set_ylim(-1, 1)  # 补充y轴范围

    # 创建滑块
    ax_Slider = plt.axes([0.25, 0.1, 0.65, 0.03])
    sliders = Slider(ax_Slider, '相位', -2, 2, valinit=0)

    # 闭包形式定义回调,自动捕获外部参数
    def update(val):
        index = Find_Sampling_indexes(val, period, symbol_rate)
        ax.clear()
        ax.plot(np.real(complex_data[index]), np.imag(complex_data[index]), 'g o')
        ax.set_xlim(-1, 1)
        ax.set_ylim(-1, 1)
        fig.canvas.draw_idle()  # 高效触发重绘

    # 正确绑定回调函数(直接传函数对象,不加括号)
    sliders.on_changed(update)
    plt.show()

main.py

import functions as esc

# 确保OOK_Complex、t1已提前定义
esc.slider_phase_shift(OOK_Complex, t1, 93696)

关键修正说明

  • 闭包回调:在slider_phase_shift内部定义update,直接访问外部函数的参数和图表对象,符合Matplotlib回调的参数要求。
  • 独立图表实例:将fig, ax的创建放在函数内部,每次调用生成独立图表,避免多实例冲突。
  • 正确回调绑定:sliders.on_changed(update)传递函数对象,滑块拖动时才会触发更新逻辑。
  • 高效重绘:用draw_idle替代draw,仅在必要时重绘图表,提升性能。

内容的提问来源于stack exchange,提问作者Bernard Nortier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:01:24