基于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
相关产品推荐
相关产品推荐

