Не происходит прорисовка каждой линии на графике (анимации) на PyQt5

Делаю GUI для одной программы, в принципе все сделано, но когда запускается программа, она зависает и через некоторое время выходит такая картинка.

1

В принципе это правильно, но вместо анимации выходит одна картинка, которая показывает что происходило с параболами, но мне нужно чтобы показывалась, прорисовка каждой линии на графике (анимации).
До того как я добавил GUI, анимация происходила, после того как я закрываю форму.

Вот сама программа и единственное что я поменял это:
from matplotlib.mlab import griddata

на
from scipy.interpolate import griddata

может это из за этого, пожалуйста помогите, а то я уже не понимаю? что делать.

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QLabel, QPushButton, QLineEdit, QMessageBox
from PyQt5.QtGui import QIcon, QValidator, QDoubleValidator


from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import numpy as np
import threading

from scipy.interpolate import griddata

import pylab
import time

ky1 = 0.8
ky2 = -80.0
ky3 = 1.99
ky4 = 0.3
ky5 = 2.0

kv1 = 1.9
kv2 = -80.0
kv3 = 1.8
kv4 = 0.5
kv5 = 2.0

N1 = 50
tt = 20.
l = 2.
h = l/N1
N2 = 50
t=tt/N2
hh=h*h
rr=hh/t

a11=0.03
a12=0.01
p1=0.03
a21=0.03
a22=0.01
p2=0.03
q1=0.05
q2=0.05

m1=0.75
m2=1.1
d1=0.7
d2=0.5
c1=0.25
c2=0.65
h1=0.15
b1=0.67
x =np.zeros((N1+1), 'float')
y =np.zeros((N1+1), 'float')
v =np.zeros((N1+1), 'float')
a =np.zeros((N1), 'float')
b =np.zeros((N1), 'float')
z =np.zeros((N1+1), 'float')



class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.left = 10
        self.top = 10
        self.title = ''
        self.width = 640
        self.height = 600
        self.initUI()

    def initVars(self):
        global ky1
        global ky2
        global ky3
        global ky4
        global ky5
        global kv1
        global kv2
        global kv3
        global kv4
        global kv5
        global N1
        global tt
        global l
        global h
        global N2
        global t
        global hh
        global rr
        global a11
        global a12
        global p1
        global a21
        global a22
        global p2
        global q1
        global q2
        global m1
        global m2
        global d1
        global d2
        global c1
        global c2
        global h1
        global b1
        global x 
        global y 
        global v 
        global a 
        global b 
        global z 
        
        ky1 = float(self.le_ky1.text())
        ky2 = float(self.le_ky2.text())
        ky3 = float(self.le_ky3.text())
        ky4 = float(self.le_ky4.text())
        ky5 = float(self.le_ky5.text())
        kv1 = float(self.le_kv1.text())
        kv2 = float(self.le_kv2.text())
        kv3 = float(self.le_kv3.text())
        kv4 = float(self.le_kv4.text())
        kv5 = float(self.le_kv5.text())
        #N1  = int(self.le_N1 .text())
        #tt  = float(self.le_tt .text())
        #l   = float(self.le_l  .text())
        #N2  = int(self.le_N2 .text())
        a11 = float(self.le_a11.text())
        a12 = float(self.le_a12.text())
        p1  = float(self.le_p1 .text())
        a21 = float(self.le_a21.text())
        a22 = float(self.le_a22.text())
        p2  = float(self.le_p2 .text())
        q1  = float(self.le_q1 .text())
        q2  = float(self.le_q2 .text())
        m1  = float(self.le_m1 .text())
        m2  = float(self.le_m2 .text())
        d1  = float(self.le_d1 .text())
        d2  = float(self.le_d2 .text())
        c1  = float(self.le_c1 .text())
        c2  = float(self.le_c2 .text())
        h1  = float(self.le_h1 .text())
        b1  = float(self.le_b1 .text())

        if kv4 > 2 or kv4 < 0:
            QMessageBox.about(self, "Ошибка", "Значение kv4 должно быть от 0 до 2")
        else:
            h = l/N1
            t=tt/N2
            hh=h*h
            rr=hh/t
        
            x = np.zeros((N1+1), 'float')
            y = np.zeros((N1+1), 'float')
            v = np.zeros((N1+1), 'float')
            a = np.zeros((N1), 'float')
            b = np.zeros((N1), 'float')
            z = np.zeros((N1+1), 'float')
            self.m.plot()


    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.m = PlotCanvas(self, width=5, height=4)
        self.m.move(0,0)
        
        
        y = 0
        label = QLabel('ky1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('ky2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('ky3:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('ky4:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('ky5:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('kv1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('kv2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('kv3:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('kv4:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('kv5:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        #label = QLabel('N1:', self)
        #label.move(510, y)
        #label.resize(50, 20)
        #y += 20
        #label = QLabel('tt:', self)
        #label.move(510, y)
        #label.resize(50, 20)
        #y += 20
        #label = QLabel('l:', self)
        #label.move(510, y)
        #label.resize(50, 20)
        #y += 20
        #label = QLabel('N2:', self)
        #label.move(510, y)
        #label.resize(50, 20)
        y += 20
        label = QLabel('a11:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('a12:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('p1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('a21:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('a22:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('p2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('q1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('q2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('m1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('m2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('d1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('d2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('c1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('c2:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('h1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y += 20
        label = QLabel('b1:', self)
        label.move(510, y)
        label.resize(50, 20)
        y = 0
        
        
        self.le_ky1  = QLineEdit('0.8', self)
        self.le_ky1.move(550, y)
        self.le_ky1.resize(50, 20)
        y += 20
        self.le_ky2  = QLineEdit('-80.0', self)
        self.le_ky2.move(550, y)
        self.le_ky2.resize(50, 20)
        y += 20
        self.le_ky3  = QLineEdit('1.99', self)
        self.le_ky3.move(550, y)
        self.le_ky3.resize(50, 20)
        y += 20
        self.le_ky4  = QLineEdit('0.3', self)
        self.le_ky4.move(550, y)
        self.le_ky4.resize(50, 20)
        y += 20
        self.le_ky5  = QLineEdit('2.0', self)
        self.le_ky5.move(550, y)
        self.le_ky5.resize(50, 20)
        y += 20
        self.le_kv1  = QLineEdit('1.9', self)
        self.le_kv1.move(550, y)
        self.le_kv1.resize(50, 20)
        y += 20
        self.le_kv2  = QLineEdit('-80.0', self)
        self.le_kv2.move(550, y)
        self.le_kv2.resize(50, 20)
        y += 20
        self.le_kv3  = QLineEdit('1.8', self)
        self.le_kv3.move(550, y)
        self.le_kv3.resize(50, 20)
        y += 20
        self.le_kv4  = QLineEdit('0.5', self)
        self.le_kv4.move(550, y)
        self.le_kv4.resize(50, 20)
        y += 20
        self.le_kv5  = QLineEdit('2.0', self)
        self.le_kv5.move(550, y)
        self.le_kv5.resize(50, 20)
        y += 20
        #self.le_tt  = QLineEdit('20', self)
        #self.le_tt.move(550, y)
        #self.le_tt.resize(50, 20)
        #y += 20
        #self.le_l  = QLineEdit('2',self)
        #self.le_l.move(550, y)
        #self.le_l.resize(50, 20)
        #y += 20
        #self.le_N2  = QLineEdit('500',self)
        #self.le_N2.move(550, y)
        #self.le_N2.resize(50, 20)
        y += 20
        self.le_a11 = QLineEdit('0.03',self)
        self.le_a11.move(550, y)
        self.le_a11.resize(50, 20)
        y += 20
        self.le_a12 = QLineEdit('0.01',self)
        self.le_a12.move(550, y)
        self.le_a12.resize(50, 20)
        y += 20
        self.le_p1  = QLineEdit('0.03',self)
        self.le_p1.move(550, y)
        self.le_p1.resize(50, 20)
        y += 20
        self.le_a21 = QLineEdit('0.03',self)
        self.le_a21.move(550, y)
        self.le_a21.resize(50, 20)
        y += 20
        self.le_a22 = QLineEdit('0.01',self)
        self.le_a22.move(550, y)
        self.le_a22.resize(50, 20)
        y += 20
        self.le_p2  = QLineEdit('0.03',self)
        self.le_p2.move(550, y)
        self.le_p2.resize(50, 20)
        y += 20
        self.le_q1  = QLineEdit('0.05',self)
        self.le_q1.move(550, y)
        self.le_q1.resize(50, 20)
        y += 20
        self.le_q2  = QLineEdit('0.05',self)
        self.le_q2.move(550, y)
        self.le_q2.resize(50, 20)
        y += 20
        self.le_m1  = QLineEdit('0.75',self)
        self.le_m1.move(550, y)
        self.le_m1.resize(50, 20)
        y += 20
        self.le_m2  = QLineEdit('1.1',self)
        self.le_m2.move(550, y)
        self.le_m2.resize(50, 20)
        y += 20
        self.le_d1  = QLineEdit('0.7',self)
        self.le_d1.move(550, y)
        self.le_d1.resize(50, 20)
        y += 20
        self.le_d2  = QLineEdit('0.5',self)
        self.le_d2.move(550, y)
        self.le_d2.resize(50, 20)
        y += 20
        self.le_c1  = QLineEdit('0.25',self)
        self.le_c1.move(550, y)
        self.le_c1.resize(50, 20)
        y += 20
        self.le_c2  = QLineEdit('0.65',self)
        self.le_c2.move(550, y)
        self.le_c2.resize(50, 20)
        y += 20
        self.le_h1  = QLineEdit('0.15',self)
        self.le_h1.move(550, y)
        self.le_h1.resize(50, 20)
        y += 20
        self.le_b1  = QLineEdit('0.67',self)
        self.le_b1.move(550, y)
        self.le_b1.resize(50, 20)
        y += 20

        
        button = QPushButton('Start', self)
        button.move(500,y)
        button.resize(50,25)
        button.clicked.connect(self.initVars)

        self.show()


class PlotCanvas(FigureCanvas):

    def e1(self,u,v):
        return a11+a12*u*v

    def e2(self,u,v):
        return a21+a22*u*v

    def f1(self,u,v):
        return u*(m1-d1)+v*d1-c1*u*u-h1*u-b1
    def f2(self,u,v):
        return v*(m2-d2)+u*d2-c2*v*v

    def Rs(self, x):
        #2 zone
        #return 0.5*np.sin(3*np.pi*x/2.)+0.5*np.sin(np.pi*x/3.)+np.sin(np.pi*x/2.)
        #return 1.5*np.sin(np.pi*x/2.)+0.5*np.sin(1*np.pi*x/2.)*np.sin(2.*np.pi*x/1.)
        #return 1.2 * np.sin(3 * np.pi * x / 2.) + 0.5 * np.sin(np.pi * x / 3.) * np.sin(np.pi * x / 2.)
        #1 zone
        #return 0.5*np.sin(3*np.pi*x/2.)-0.2*np.sin(2*np.pi*x/2.)-np.sin(3.*np.pi*x/3.)
        return 1.5*np.sin(np.pi*x/2.)-0.5*np.sin(1*np.pi*x/2.)*np.sin(2.*np.pi*x/2.)

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        

        
    def plot(self):
        self.axes.cla()
        plt = self.figure.add_subplot(111)
        global N1
        global tt
        global l
        global h
        global N2
        global t
        global hh
        global rr
        global a11
        global a12
        global p1
        global a21
        global a22
        global p2
        global q1
        global q2
        global m1
        global m2
        global d1
        global d2
        global c1
        global c2
        global h1
        global b1
        global x 
        global y 
        global v 
        global a 
        global b 
        global z 
        
        tst = time.clock()
        a[0]=0.
        b[0]=0.
        for i in range(0,N1+1):
            x[i]=i*h
            #if i*h<0.62: y[i] = 0.
            #elif i*h<1.27: y[i]=-21.30*(i*h)*(i*h)+40.26*(i*h)-16.77
            #else: y[i]=0.
            y[i] = ky1 * np.exp(ky2 * (((i * h / ky3) - ky4) ** ky5))
            #y[i] = 0.8 * np.exp(-80.0 * (((i * h / 1.99) - 0.3) ** 2))
            #if i*h<1.32: v[i] = 0.
            #elif i*h<1.96: v[i]=-21.30*(i*h)*(i*h)+69.65*(i*h)-54.69
            #else: v[i]=0.0
            #v[i] = 0.9 * np.exp(-80.0 * (((i * h / 1.8) - 0.8) ** 2))
            v[i] = kv1 * np.exp(kv2 * (((i * h / kv3) - kv4) ** kv5))

        x = np.linspace(0, l, N1+1)
        R = self.Rs(x)

        plt.axis([0.,l,0.0,2.5])
        plt.plot(x,y, 'b-',label='$u^0(x)$')
        plt.plot(x,v, 'g--',label='$v^0(x)$')
        plt.plot(x,R, 'k-.',label='$r(x)$')
        plt.legend(loc=0)
        plt.set_xlabel('$x$')
        plt.set_ylabel('$u,v,r$')
        plt.grid(True)

        pylab.ion()
        x = np.linspace(0, l, N1+1)
        for j in range(1,N2+1):
            for i in range(1,N1):
                e11=(self.e1(y[i],v[i])+self.e1(y[i+1],v[i+1]))/2.
                e12=(self.e1(y[i],v[i])+self.e1(y[i-1],v[i-1]))/2.
                aa=e12/rr
                bb=e11/rr
                cc=aa+bb+1
                r12 = p1/rr
                a[i]=bb/(cc-aa*a[i-1])
                d=t*self.f1(y[i],v[i])-r12*0.5*((y[i]+y[i+1])*(v[i+1]-v[i])-(y[i]+y[i-1])*(v[i]-v[i-1]))+y[i]- \
                   (q1/rr)*0.5*((y[i]+y[i+1])*(R[i+1]-R[i]) - (y[i]+y[i-1])*(R[i]-R[i-1]))
                b[i]=(aa*b[i-1]+d)/(cc-aa*a[i-1])
            for ii in range(1,N1+1):
                i=N1-ii
                y[i] = a[i]*y[i+1]+b[i]

            for i in range(0,N1+1):
                if y[i]<0: y[i]=0

            for i in range(1,N1):
                e21=(self.e2(y[i],v[i])+self.e2(y[i+1],v[i+1]))/2.
                e22=(self.e2(y[i],v[i])+self.e2(y[i-1],v[i-1]))/2.
                aa=e22/rr
                bb=e21/rr
                cc=aa+bb+1
                r12 = p2/rr
                a[i]=bb/(cc-aa*a[i-1])
                d=t*self.f2(y[i],v[i])-r12*0.5*((v[i]+v[i+1])*(y[i+1]-y[i])-(v[i]+v[i-1])*(y[i]-y[i-1]))+v[i]- \
                  (q2/rr)*0.5*((v[i]+v[i+1])*(R[i+1]-R[i]) - (v[i]+v[i-1])*(R[i]-R[i-1]))
                b[i]=(aa*b[i-1]+d)/(cc-aa*a[i-1])
            for ii in range(1,N1+1):
                i=N1-ii
                v[i] = a[i]*v[i+1]+b[i]

            for i in range(0,N1+1):
                if v[i]<0: v[i]=0

            pylab.clf()
            pylab.plot(x,y, 'b-')
            pylab.plot(x,v, 'g--')
            plt.plot(x, R, 'k-.')

            plt.grid(True)
            
            plt.axis([0.,l,0.0,2.5])
            pylab.draw()
            pylab.draw()
            plt.axis([0.,l,0.0,2.5])
            plt.plot(x,y, 'b-',label='$u$')
            plt.plot(x,v, 'g--',label='$v$')
            plt.plot(x, R, 'k-.', label='$r$')
            plt.legend(loc=0)
            plt.set_xlabel('$x$')
            plt.set_ylabel('$u,v,r$')

        self.draw()
        dt = time.clock() - tst
        print ("N2 = %i, N1 = %i, time solution = %1.3e, h = %1.3e" % (N2, N1, dt, h))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())


Ответы (1 шт):

Автор решения: S. Nick

В графическом интерфейсе есть цикл по умолчанию, который блокируется циклами, которые занимают слишком много времени и вызывают зависание приложения. Простой способ решить - использовать processEvents()

Глобальные переменные - это ЗЛО.

Я удалил некоторые строки, которые мне были не совсем понятны, добавите если что.

import sys
from PyQt5.Qt import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
import pylab
import time


class PlotCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        super().__init__(self.fig)

        self.p = parent                                                     # !!!
        
    def e1(self, u, v):
        return self.p.a11 + self.p.a12 * u * v

    def e2(self, u, v):
        return self.p.a21 + self.p.a22 * u * v

    def f1(self, u, v):
        return u * (self.p.m1-self.p.d1) + v * self.p.d1 - self.p.c1 * u * u - self.p.h1 * u - self.p.b1
        
    def f2(self, u, v):
        return v * (self.p.m2-self.p.d2) + u * self.p.d2 - self.p.c2 * v * v

    def Rs(self, x):
        return 1.5 * np.sin(np.pi*x/2.) - 0.5*np.sin(1*np.pi*x/2.) * np.sin(2.*np.pi*x/2.)
        
    def plot(self):
        self.axes.cla()
        plt = self.axes     
        tst = time.perf_counter()
        
        self.p.a[0] = 0.
        self.p.b[0] = 0.
        for i in range(0, self.p.N1+1):
            self.p.x[i] = i * self.p.h
            self.p.y[i] = self.p.ky1 * np.exp(self.p.ky2 * \
                          (((i * self.p.h / self.p.ky3) -self.p.ky4) ** self.p.ky5))
            self.p.v[i] = self.p.kv1 * np.exp(self.p.kv2 * \
                          (((i * self.p.h / self.p.kv3) - self.p.kv4) ** self.p.kv5))

        self.p.x = np.linspace(0, self.p.l, self.p.N1+1)
        R = self.Rs(self.p.x)
        
        plt.axis([0., self.p.l, 0.0, 2.5])
        
        plt.plot(self.p.x, self.p.y, 'b-', label='$u^0(x)$')
        plt.plot(self.p.x, self.p.v, 'g--', label='$v^0(x)$')
        plt.plot(self.p.x, R, 'k-.', label='$r(x)$')
        
        plt.legend(loc=0)
        plt.set_xlabel('$x$')
        plt.set_ylabel('$u,v,r$')
        plt.grid(True)
        
        pylab.ion()
        self.p.x = np.linspace(0, self.p.l, self.p.N1+1)

        for j in range(1, self.p.N2+1):
            for i in range(1, self.p.N1):
                e11 = (self.e1(self.p.y[i], self.p.v[i]) + self.e1(self.p.y[i+1], self.p.v[i+1])) / 2.
                e12 = (self.e1(self.p.y[i], self.p.v[i]) + self.e1(self.p.y[i-1], self.p.v[i-1])) / 2.
                aa = e12 / self.p.rr
                bb = e11 / self.p.rr
                cc = aa + bb + 1
                r12 = self.p.p1 / self.p.rr
                self.p.a[i] = bb / (cc-aa*self.p.a[i-1])
                d = self.p.t*self.f1(self.p.y[i], self.p.v[i])-r12*0.5 * \
                    ((self.p.y[i]+self.p.y[i+1])*(self.p.v[i+1]-self.p.v[i]) - \
                    (self.p.y[i]+self.p.y[i-1])*(self.p.v[i]-self.p.v[i-1]))+self.p.y[i]- \
                    (self.p.q1/self.p.rr)*0.5*((self.p.y[i]+self.p.y[i+1]) * \
                    (R[i+1]-R[i]) - (self.p.y[i]+self.p.y[i-1])*(R[i]-R[i-1]))
                self.p.b[i] = (aa*self.p.b[i-1]+d)/(cc-aa*self.p.a[i-1])
            for ii in range(1, self.p.N1+1):
                i = self.p.N1-ii
                self.p.y[i] = self.p.a[i]*self.p.y[i+1]+self.p.b[i]

            for i in range(0,self.p.N1+1):
                if self.p.y[i]<0: self.p.y[i]=0

            for i in range(1,self.p.N1):
                e21 = (self.e2(self.p.y[i],self.p.v[i])+self.e2(self.p.y[i+1],self.p.v[i+1]))/2.
                e22 = (self.e2(self.p.y[i],self.p.v[i])+self.e2(self.p.y[i-1],self.p.v[i-1]))/2.
                aa = e22 / self.p.rr
                bb = e21 / self.p.rr
                cc = aa + bb + 1
                r12 = self.p.p2 / self.p.rr
                self.p.a[i] = bb / (cc-aa*self.p.a[i-1])
                d = self.p.t*self.f2(self.p.y[i],self.p.v[i])-r12*0.5 * \
                    ((self.p.v[i]+self.p.v[i+1])*(self.p.y[i+1]-self.p.y[i]) - \
                    (self.p.v[i]+self.p.v[i-1])*(self.p.y[i]-self.p.y[i-1]))+self.p.v[i]- \
                    (self.p.q2/self.p.rr)*0.5*((self.p.v[i]+self.p.v[i+1]) * \
                    (R[i+1]-R[i]) - (self.p.v[i]+self.p.v[i-1])*(R[i]-R[i-1]))
                self.p.b[i] = (aa*self.p.b[i-1]+d)/(cc-aa*self.p.a[i-1])
            for ii in range(1,self.p.N1+1):
                i = self.p.N1 - ii
                self.p.v[i] = self.p.a[i] * self.p.v[i+1] + self.p.b[i]

            for i in range(0, self.p.N1+1):
                if self.p.v[i]<0: self.p.v[i]=0
            
            plt.plot(self.p.x, R, 'k-.')
            plt.grid(True)
            
            plt.axis([0., self.p.l, 0.0, 2.5])
            plt.axis([0., self.p.l, 0.0, 2.5])
            plt.plot(self.p.x, self.p.y, 'b-', label='$u$')
            plt.plot(self.p.x, self.p.v, 'g--', label='$v$')
            plt.plot(self.p.x, R, 'k-.', label='$r$')
             
            app.processEvents()                                              # <--- !!!
            self.draw()

            if not self.p.flag:
                break

        dt = time.perf_counter() - tst
        print ("N2 = %i, N1 = %i, time solution = %1.3e, h = %1.3e" % (self.p.N2, self.p.N1, dt, self.p.h))


class App(QWidget):    
    def __init__(self):
        super().__init__()
        
        self._global()                                                       # +++
        self.layout = QGridLayout(self)                                      # +++
        self.flag = True                                                     # +++
        self.initUI()

    def _global(self):
        self.ky1 = 0.8
        self.ky2 = -80.0
        self.ky3 = 1.99
        self.ky4 = 0.3
        self.ky5 = 2.0
        self.kv1 = 1.9
        self.kv2 = -80.0
        self.kv3 = 1.8
        self.kv4 = 0.5
        self.kv5 = 2.0

        self.N1 = 50
        self.tt = 20.
        self.l = 2.
        self.h = self.l / self.N1
        self.N2 = 50
        self.t = self.tt / self.N2
        self.hh = self.h * self.h
        self.rr = self.hh / self.t

        self.a11 = 0.03
        self.a12 = 0.01
        self.p1 = 0.03
        self.a21 = 0.03
        self.a22 = 0.01
        self.p2 = 0.03
        self.q1 = 0.05
        self.q2 = 0.05

        self.m1 = 0.75
        self.m2 = 1.1
        self.d1 = 0.7
        self.d2 = 0.5
        self.c1 = 0.25
        self.c2 = 0.65
        self.h1 = 0.15
        self.b1 = 0.67

        self.x = np.zeros((self.N1+1), 'float')
        self.y = np.zeros((self.N1+1), 'float')
        self.v = np.zeros((self.N1+1), 'float')
        self.a = np.zeros((self.N1), 'float')
        self.b = np.zeros((self.N1), 'float')
        self.z = np.zeros((self.N1+1), 'float')

    def initUI(self):
        self.m = PlotCanvas(self, width=5, height=4)
        self.layout.addWidget(self.m, 0, 0) 
        
        self.le_ky1  = QLineEdit('0.8', self)
        self.le_ky2  = QLineEdit('-80.0', self)
        self.le_ky3  = QLineEdit('1.99', self)
        self.le_ky4  = QLineEdit('0.3', self)
        self.le_ky5  = QLineEdit('2.0', self)
        self.le_kv1  = QLineEdit('1.9', self)
        self.le_kv2  = QLineEdit('-80.0', self)
        self.le_kv3  = QLineEdit('1.8', self)
        self.le_kv4  = QLineEdit('0.5', self)
        self.le_kv5  = QLineEdit('2.0', self)
        self.le_a11 = QLineEdit('0.03',self)
        self.le_a12 = QLineEdit('0.01',self)
        self.le_p1  = QLineEdit('0.03',self)
        self.le_a21 = QLineEdit('0.03',self)
        self.le_a22 = QLineEdit('0.01',self)
        self.le_p2  = QLineEdit('0.03',self)
        self.le_q1  = QLineEdit('0.05',self)
        self.le_q2  = QLineEdit('0.05',self)
        self.le_m1  = QLineEdit('0.75',self)
        self.le_m2  = QLineEdit('1.1',self)
        self.le_d1  = QLineEdit('0.7',self)
        self.le_d2  = QLineEdit('0.5',self)
        self.le_c1  = QLineEdit('0.25',self)
        self.le_c2  = QLineEdit('0.65',self)
        self.le_h1  = QLineEdit('0.15',self)
        self.le_b1  = QLineEdit('0.67',self)
        
        button = QPushButton('Start', self)
        button.clicked.connect(self.initVars)
        
        formLayout = QFormLayout()  
        formLayout.setVerticalSpacing(1)        
        formLayout.addRow('ky1:', self.le_ky1)
        formLayout.addRow('ky2:', self.le_ky2)
        formLayout.addRow('ky3:', self.le_ky3)
        formLayout.addRow('ky4:', self.le_ky4)
        formLayout.addRow('ky5:', self.le_ky5)
        formLayout.addRow('kv1:', self.le_kv1)
        formLayout.addRow('kv2:', self.le_kv2)
        formLayout.addRow('kv3:', self.le_kv3)
        formLayout.addRow('kv4:', self.le_kv4)
        formLayout.addRow('kv5:', self.le_kv5)
        formLayout.addRow('a11:', self.le_a11)
        formLayout.addRow('a12:', self.le_a12)
        formLayout.addRow('p1:', self.le_p1)
        formLayout.addRow('a21:', self.le_a21)
        formLayout.addRow('a22:', self.le_a22)
        formLayout.addRow('p2:', self.le_p2)
        formLayout.addRow('q1:', self.le_q1)
        formLayout.addRow('q2:', self.le_q2)
        formLayout.addRow('m1:', self.le_m1)
        formLayout.addRow('m2:', self.le_m2)
        formLayout.addRow('d1:', self.le_d1)
        formLayout.addRow('d2:', self.le_d2)
        formLayout.addRow('c1:', self.le_c1)
        formLayout.addRow('c2:', self.le_c2)
        formLayout.addRow('h1:', self.le_h1)
        formLayout.addRow('b1:', self.le_b1)
        formLayout.addRow('', button)
        
        self.layout.addLayout(formLayout, 0, 1)
        self.layout.setColumnStretch(0, 1)
        self.layout.setColumnStretch(1, 0)

    def initVars(self):
        self.ky1 = float(self.le_ky1.text())
        self.ky2 = float(self.le_ky2.text())
        self.ky3 = float(self.le_ky3.text())
        self.ky4 = float(self.le_ky4.text())
        self.ky5 = float(self.le_ky5.text())
        self.kv1 = float(self.le_kv1.text())
        self.kv2 = float(self.le_kv2.text())
        self.kv3 = float(self.le_kv3.text())
        self.kv4 = float(self.le_kv4.text())
        self.kv5 = float(self.le_kv5.text())

        self.a11 = float(self.le_a11.text())
        self.a12 = float(self.le_a12.text())
        self.p1  = float(self.le_p1 .text())
        self.a21 = float(self.le_a21.text())
        self.a22 = float(self.le_a22.text())
        self.p2  = float(self.le_p2 .text())
        self.q1  = float(self.le_q1 .text())
        self.q2  = float(self.le_q2 .text())
        self.m1  = float(self.le_m1 .text())
        self.m2  = float(self.le_m2 .text())
        self.d1  = float(self.le_d1 .text())
        self.d2  = float(self.le_d2 .text())
        self.c1  = float(self.le_c1 .text())
        self.c2  = float(self.le_c2 .text())
        self.h1  = float(self.le_h1 .text())
        self.b1  = float(self.le_b1 .text())

        if self.kv4 > 2 or self.kv4 < 0:
            QMessageBox.about(self, "Ошибка", "Значение kv4 должно быть от 0 до 2")
        else:
            self.h = self.l / self.N1
            self.t = self.tt / self.N2
            self.hh = self.h * self.h
            self.rr = self.hh / self.t
            self.x = np.zeros((self.N1+1), 'float')
            self.y = np.zeros((self.N1+1), 'float')
            self.v = np.zeros((self.N1+1), 'float')
            self.a = np.zeros((self.N1), 'float')
            self.b = np.zeros((self.N1), 'float')
            self.z = np.zeros((self.N1+1), 'float')
            
            self.m.plot()                                   
        
    def closeEvent(self, event):
        self.flag = False
            

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.resize(800, 600)
    ex.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка