In my last article, I described the SIR model that explains the spread of infectious diseases. At that time, I also posted a Python program for numerical integration that solves the SIR model. In this article, I will try to make the Python program into a GUI.
Previous article: Mathematical prediction model for infectious diseases (SIR model): Case study (1) https://qiita.com/kotai2003/items/d74583b588841e6427a2
The reason for converting the program I made into a GUI is "I want others to use it." In the future, I would like to distribute it in the form of setup.exe, not just the GUI Py code.
First, the screen configuration of the GUI created this time. Enter the infection rate (Beta) and removal rate (Gamma) of the SIR model in the blanks on the right and press the Draw button below it to plot the calculation result of the SIR model on the center screen.
\begin{align}
\frac{dS}{dt} &= -\beta SI \\
\frac{dI}{dt} &= \beta SI -\gamma I \\
\frac{dR}{dt} &= \gamma I \\
\end{align}
\begin{align}
S &:Infectable person\quad \text{(Susceptible)} \\
I &:Infected person\quad \text{(Infectious)} \\
R &:Those who died after infection or who acquired immunity\quad \text{(Removed)} \\
\beta &:Infection rate\quad \text{(The infectious rate)} \quad [1/day] \\
\gamma &:Exclusion rate\quad \text{(The Recovery rate)} \quad [1/day] \\
\end{align}
On the initial screen, "Typical Condition ~" is written, but this is for reference when entering the infection rate (Beta) and removal rate (Gamma).
The next screen shows the calculation result. The numerical integration result of the SIR model is displayed in Line Plot. The newly entered infection rate (Beta) and removal rate (Gamma) values will be updated in the title.
You can exit the GUI by pressing the Quit button at the bottom right.
The GUI library used Tkinter. I will briefly explain the operation of the program.
(1) Prepare Canvas Widget with Tkinter. In Tkinter's Entry Widget, prepare a text box for entering the infection rate (Beta) and removal rate (Gamma). (2) Calculate the SIR model with scipy and plot the result with matplotlib. (3) Draw the matplotlib figure with the Canvas Widget.
Import the required libraries.
import tkinter
import tkinter.messagebox as tkmsg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk
import numpy as np
from functools import partial
from scipy.integrate import odeint
Prepare the functions required for numerical integration of the SIR model.
# SIR Differential Equation
def SIR_EQ(v, t, beta, gamma):
'''
dS/dt = -beta * S * I
dI/dt = beta * S * I - gamma * I
dR/dt = gamma * I
[v[0], v[1], v[2]]=[S, I, R]
dv[0]/dt = -beta * v[0] * v[1]
dv[1]/dt = beta * v[0] * v[1] - gamma * v[1]
dv[2]/dt = gamma * v[1]
'''
return [-beta*v[0]*v[1], beta * v[0] * v[1] - gamma * v[1], gamma * v[1]]
# Solving SIR Equation
def Calc_SIR(var_b, var_r):
# parameters
t_max = 14
dt = 0.01
#beta_const = 0.0026
#gamma_const = 0.5
beta_const = var_b
gamma_const = var_r
# initial_state
S_0 = 762
I_0 = 1
R_0 = 0
ini_state = [S_0, I_0, R_0] # [S[0], I[0], R[0]]
# numerical integration
times = np.arange(1, t_max, dt)
args = (beta_const, gamma_const)
# Solver SIR model
result = odeint(SIR_EQ, ini_state, times, args)
return times,result
Prepare a function to be executed at the time of Tkinter button Event. It is a mechanism to prepare an axes instance (= ax) of matplotlib in the DrawCanvas function and plot that instance. The final canvas.draw () will show the axes instance of matplotlib in the canvas widget.
def Quit():
tkmsg.showinfo("Tomomi Research Inc.","Thank you for running this program!")
root.quit()
root.destroy()
#Draw Button
def DrawCanvas(canvas, ax):
value_beta = EditBox_beta.get()
value_gamma = EditBox_gamma.get()
if value_beta != '':
EditBox_beta.delete(0, tkinter.END)
EditBox_gamma.delete(0, tkinter.END)
ax.cla()
beta = float(value_beta)
gamma = float(value_gamma)
t_r, res_r = Calc_SIR(beta,gamma)
ax.plot(t_r, res_r)
ax.legend(['Susceptible', 'Infectious', 'Removed'])
ax.set_title('Beta='+str(beta)+', Gamma='+str(gamma) )
ax.set_xlabel('time(days)')
ax.set_ylabel('population')
canvas.draw()
This part is the main program. The settings for each Tkinter widget are described here.
if __name__ == '__main__':
try:
# GUI generate
root = tkinter.Tk()
root.title("SIR model")
# Graph setting
fig, ax1 = plt.subplots()
#fig.gca().set_aspect('equal', adjustable='box') #Adjusting the graph area#get current axes
ax1.set_title('Typical Condition: beta=0.0026, gamma=0.5, $S_0$=762, $I_0$=1')
# Generate Canvas
Canvas = FigureCanvasTkAgg(fig, master=root)
Canvas.get_tk_widget().grid(row=0, column=0, rowspan=10)
#Beta
EditBox_beta = tkinter.Entry(width=5) #Generate text box
EditBox_beta.grid(row=1, column=2)
GridLabel_beta = tkinter.Label(text="Beta")
GridLabel_beta.grid(row=1, column=1)
# Gamma
EditBox_gamma = tkinter.Entry(width=5) #Generate text box
EditBox_gamma.grid(row=4, column=2)
GridLabel_gamma = tkinter.Label(text="Gamma")
GridLabel_gamma.grid(row=4, column=1)
#Various settings related to buttons
ReDrawButton = tkinter.Button(text="Draw", width=15, command=partial(DrawCanvas, Canvas, ax1)) #Button generation
ReDrawButton.grid(row=5, column=1, columnspan=2) #Drawing position(Texto)
QuitButton = tkinter.Button(text="Quit", width=15, command=Quit) #Button generation
QuitButton.grid(row=7, column=1, columnspan=2) #Drawing position(Texto)
DrawCanvas(Canvas, ax1)
root.mainloop()
except:
import traceback
traceback.print_exc()
finally:
input(">>") #Waiting for display when an error is spit out
It seems that Tkinter and PyQT are famous as Python GUI libraries, but I heard that Tkiknter is easy to program even for beginners, so I chose Tkinter. I'm still interested in PyQT, so if you've used both, please leave a comment.
I think the advantage of Python GUI is that it is Cross Platform. If you create one program, you can use it for Windows, Mac OS, Linux without any changes. Currently, I am thinking of developing a Deep Learning program on Windows and implementing it on Jetson (Linux) made by Nvidia. At that time, I think the Python GUI will be very useful.