I am trying to write a GUI in Python3 using PyQt4.
For data visualization, I need to isolate a specific point on a curve plotted by the function whole_plot(). To do so, I am currently using a slider that let the GUI user choose a point of interest. When the slider_value is changed, the point is selected and plotted by calling the function point_plot().
Regarding some previous answers, I am now trying to update my graph through matplotlib.animation (cf. post python matplotlib update scatter plot from a function). But for some reasons, I still got the wrong updating, can someone help me figure out what is the problem in my code?
import sys
import numpy as np
from PyQt4 import QtGui
from PyQt4 import QtCore
import matplotlib.pyplot as plt
import matplotlib.animation
#
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
#%%
# some Arbitrary data
nbr_points = 500
my_X_data = np.linspace(-10,10,nbr_points)
my_Y_data = my_X_data**3 + 100*np.cos(my_X_data*5)
class MyWidget(QtGui.QWidget):
def __init__(self):
super(MyWidget, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(600,300,1000,600)
grid = QtGui.QGridLayout()
self.setLayout(grid)
self.figure_1 = plt.figure(figsize=(15,5))
self.canvas_1 = FigureCanvas(self.figure_1)
self.toolbar = NavigationToolbar(self.canvas_1, self)
grid.addWidget(self.canvas_1, 2,0,1,2)
grid.addWidget(self.toolbar, 0,0,1,2)
# Slider
self.slider = QtGui.QSlider(QtCore.Qt.Horizontal)
self.slider.setMinimum(0)
self.slider.setMaximum(nbr_points-1)
self.slider.setTickInterval(1)
self.slider.valueChanged.connect(self.point_plot)
# Slider info box
self.label = QtGui.QLabel(self)
grid.addWidget(self.label,4,0)
# +1 / -1 buttons
btn_plus_one = QtGui.QPushButton('+1', self)
btn_plus_one.clicked.connect(self.value_plus_one)
btn_minus_one = QtGui.QPushButton('-1', self)
btn_minus_one.clicked.connect(self.value_minus_one)
hbox = QtGui.QHBoxLayout()
hbox.addWidget(btn_minus_one)
hbox.addWidget(self.slider)
hbox.addWidget(btn_plus_one)
grid.addLayout(hbox, 3,0,1,3)
self.whole_plot()
self.point_plot()
self.show()
def whole_plot(self):
ax1 = self.figure_1.add_subplot(111)
ax1.clear()
ax1.cla()
#
ax1.plot(my_X_data,my_Y_data,'b-')
#
ax1.set_xlim([-10,10])
ax1.set_ylim([-1000,1000])
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
#
self.canvas_1.draw()
def point_plot(self):
ax1 = self.figure_1.add_subplot(111)
#
X_point, Y_point = [],[]
scat = ax1.scatter(X_point,Y_point, s=100,c='k')
def animate(i):
index_slider_value = self.slider.value()
X_point = my_X_data[index_slider_value,]
Y_point = my_Y_data[index_slider_value,]
scat.set_offsets(np.c_[X_point,Y_point])
anim = matplotlib.animation.FuncAnimation(self.figure_1,animate, frames=my_X_data, interval=200, repeat=True)
self.canvas_1.draw()
def value_plus_one(self):
# slider +1
if self.slider.value() < (my_X_data.shape[0]-1):
index_slider_value = self.slider.value() + 1
self.slider.setValue(index_slider_value)
def value_minus_one(self):
# slider -1
if self.slider.value() > 0:
index_slider_value = self.slider.value() - 1
self.slider.setValue(index_slider_value)
def main():
app = QtGui.QApplication(sys.argv)
MyWidget()
sys.exit(app.exec_())
if __name__ == '__main__':
main()