I am learning Python and PyQt at the moment. I'm having a problem understanding something. My program calculates the solusion of Newton's Cooling Law using Euler's Method. For now all the parameters are constant but user will be able to change them later.
I would like to make it this way that after button "Plot" is pressed, the signal is sent to function Plot with new data(not the old one). So that if I change any parameter the result after pressing "Plot" will be different.
For example here in main.py i am calculating data at the beginning and parsing it using Window's constructor because function "Plot" is inside Window class. So after pressing "Plot" the data passed to the Window object will be plotted. After that I calculate data once again but with different parameters. I would like to make a new plot with this data after pressing "Plot" once again. How to do it? What is the best approach to this? Here's my code. Thank you in advance
main.py:
from mechanical_system import Mechanical_system
from calculus import Calculus
from window import Window
from PyQt4 import QtGui
import sys
if __name__ == "__main__":
system1 = Mechanical_system(200, 300, 100, 10, 40, 50)
data = Calculus.euler(system1.ODE, 100, 0, 100, 2)
print system1.get_params()
app = QtGui.QApplication(sys.argv)
main = Window(data)
main.show()
data = Calculus.euler(system1.ODE, 200, 0, 50, 0.5)
sys.exit(app.exec_())
calculus.py:
import matplotlib.pyplot as plt
import numpy as np
class Calculus:
def __init__(self):
print "object created"
@staticmethod
def euler(f,y0,a,b,h):
"""y0 - initial temp, a-time = 0 , b-end of time gap, h - step"""
t,y = a,y0
time = [t]
value = [y]
while t <= b:
print "%6.3f %6.3f" % (t,y)
t += h
y += h * f(t,y)
time.append(t)
value.append(y)
data = {'time' : time, 'value' : value}
return data
@staticmethod
def draw_chart(time, value):
"""time dicionary contains moments for which each value was calculated"""
plt.axhline(20, 0, 100, color='r')
plt.plot(time, value, 'bo')
plt.axis([0, 100, 0, 100])
plt.xlabel("czas")
plt.ylabel("temperatura")
plt.show()
mechanical_system.py
class Mechanical_system:
#public variable holding system's parameters
system_parameters = {}
#Constructor
def __init__(self, momentum1, momentum2, n1, n2, w1, w2):
Mechanical_system.system_parameters = {'momentum1': momentum1, 'momentum2': momentum2, 'N1': n1, 'N2' : n2, 'w1' : w1, 'w2' : w2};
def get_params(self):
"""returns a dictionary that contains all the system parameters"""
return Mechanical_system.system_parameters
def set_param(self, param_name, value):
"""
sets a new value for specified parameter
available parameters: momentum1, momentum2, N1, N2, w1, w2
"""
Mechanical_system.system_parameters[param_name] = value
def ODE(self, time, temp):
"""ODE - ordinary differential equation describing our system"""
return -0.07 * (temp - 20)
window.py
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
class Window(QtGui.QDialog):
def __init__(self, data, parent = None):
super(Window, self).__init__(parent)
# a figure instance to plot on
self.figure = plt.figure()
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init__
self.canvas = FigureCanvas(self.figure)
# this is the Navigation widget
# it takes the Canvas widget and a parent
self.toolbar = NavigationToolbar(self.canvas, self)
# Just some button connected to `plot` method
self.button = QtGui.QPushButton('Plot')
self.button.clicked.connect(lambda: self.plot(data['time'], data['value']))
self.lineEdit = QtGui.QLineEdit()
self.lineEdit.resize(200, 30)
self.lineEdit.setInputMethodHints((QtCore.Qt.ImhFormattedNumbersOnly))
# set the layout
layout = QtGui.QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
layout.addWidget(self.lineEdit)
self.setLayout(layout)
def plot(self, time, value):
"""time dicionary contains moments for which each value was calculated"""
# create an axis
ax = self.figure.add_subplot(111)
# discards the old graph
ax.hold(False)
plt.axhline(20, 0, 100, color='r')
plt.axis([0, 100, 0, 100])
plt.xlabel("czas")
plt.ylabel("temperatura")
# plot data
plt.plot(time, value, '*-')
# refresh canvas
self.canvas.draw()