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

基于tkinter GUI求解SIR模型ODE系统时绘图异常的问题排查

SIR模型GUI代码错误排查

核心错误点

  • 参数类型定义错误:beta和gamma是小于1的浮点数,但你使用了IntVar(仅支持整数类型)存储这两个参数,输入小数时会直接识别为0,导致模型没有传播动力,最终绘图结果异常。这是问题的核心原因,和lambda函数无关。
  • 冗余代码未生效:你额外定义了intN/intbeta等转换后的变量,但后续计算时仍然使用未转换的readN/readbeta变量,属于无效冗余代码。
  • 绘图归一化硬编码:绘图时固定除以1000做归一化,如果用户输入的总人数N不等于1000,纵轴数值比例会完全错误。

修正后的完整代码

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import IntVar, DoubleVar

def mainwindow():
    root = tk.Tk()
    root.geometry('350x350')
    
    tk.Label(root, text="请输入以下参数").grid(row=1)
    # 给参数设置默认值,和原代码逻辑对齐
    getN = IntVar(value=1000)
    geti0 = IntVar(value=1)
    getr0 = IntVar(value=0)
    getbeta = DoubleVar(value=2/7)
    getgamma = DoubleVar(value=1/7)

    
    tk.Label(root, text="总人数N").grid(row=2)
    tk.Label(root, text="初始感染人数i0").grid(row=3)
    tk.Label(root, text="初始康复人数r0").grid(row=4)
    tk.Label(root, text="传播系数beta").grid(row=5)
    tk.Label(root, text="康复率gamma").grid(row=6)
    
    tk.Entry(root,textvariable = getN).grid(row=2, column=1)
    tk.Entry(root,textvariable = geti0).grid(row=3, column=1)
    tk.Entry(root,textvariable = getr0).grid(row=4, column=1)
    tk.Entry(root,textvariable = getbeta).grid(row=5, column=1)
    tk.Entry(root,textvariable = getgamma).grid(row=6, column=1)
    
    def values():
        # 直接读取参数,无需额外类型转换
        N = getN.get()
        I0 = geti0.get()
        R0 = getr0.get()
        beta = getbeta.get()
        gamma = getgamma.get()
        
        S0 = N - I0 - R0
        t = np.linspace(0, 160, 160)

        def deriv(y, t, N, beta, gamma):
            S, I, R = y
            dS = (-beta * S * I) / N
            dI = (beta * S * I) / N - gamma * I
            dR = gamma * I
            return dS, dI, dR
        
        solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
        S, I, R = solve.T
        
        fig = plt.figure(facecolor='w')
        ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
        # 归一化改为除以总人数N,适配任意输入的总人数
        ax.plot(t, S/N, 'b', alpha=1, lw=2, label='易感人群')
        ax.plot(t, I/N, 'r', alpha=1, lw=2, label='感染人群')
        ax.plot(t, R/N, 'black', alpha=1, lw=2, label='康复人群')
        ax.set_xlabel('时间(天)')
        ax.set_ylabel('人群占比')
        ax.set_ylim(0,1.1)
        ax.grid(b=True, which='major', c='w', lw=2, ls='-')
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        plt.show()

    tk.Button(root, text='求解模型', command=values).grid(row=7, column=1, sticky=tk.W, pady=4)
    root.mainloop()
    
mainwindow()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:48:03