python - Making a plot in a second window using data from main window -
i'm trying make program in have main window , second window. second window should opened checking check-box in main window , closed unchecking it.
the following minimal example works fine (thanks importanceofbeingernest !), want spin arrow (the one, bent when run example) changing spinbox in main window.
solution: see 5th comment in first answer!
import sys pyqt4 import qtgui, qtcore matplotlib import pyplot plt mpl_toolkits.mplot3d import axes3d matplotlib.backends.backend_qt4agg import figurecanvasqtagg figurecanvas matplotlib import animation import numpy np class newsphere(qtgui.qmainwindow): def __init__(self): super(newsphere, self).__init__() self.mainbox = qtgui.qwidget() self.mainbox.setlayout(qtgui.qhboxlayout()) self.setcentralwidget(self.mainbox) self.spin = qtgui.qspinbox() self.spin.setvalue(20) self.spin.setmaximum(100) self.spin.setminimum(-100) self.checkplot = qtgui.qcheckbox("check") self.mainbox.layout().addwidget(self.spin) self.mainbox.layout().addwidget(self.checkplot) self.plot = none self.checkplot.clicked.connect(self.showplot) def showplot(self): if self.plot == none: self.plot = plot(self.kinematic()) self.plot.show() # register signal closure self.plot.signalclose.connect(self.uncheck) # register signal spin value changed self.spin.valuechanged.connect(self.kinematic) else: self.plot.close() self.plot = none def kinematic(self): x = self.spin.value() / 100 v = np.matrix([[1.,x,0.],[0.,1.,0.],[0.,0.,1.]]) 0 = np.matrix([[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]]) pos = np.hstack([v, zero]) return pos def uncheck(self): self.checkplot.setchecked(false) self.plot = none class plot(qtgui.qwidget): signalclose = qtcore.pyqtsignal() def __init__(self, pos=none): super(plot, self).__init__() self.setlayout(qtgui.qhboxlayout()) self.fig = plt.figure() self.ax = self.fig.add_subplot(111,projection = '3d') self.fig.tight_layout() self.ax.view_init(40, 225) ''' dashed coordinate system ''' self.ax.plot([0,1], [0,0], [0,0], label='$x_0$', linestyle="dashed", color="red") self.ax.plot([0,0], [0,-10], [0,0], label='$y_0$', linestyle="dashed", color="green") self.ax.plot([0,0], [0,0], [0,1], label='$z_0$', linestyle="dashed", color="blue") self.ax.set_xlim3d(-3,3) self.ax.set_ylim3d(-3,3) self.ax.set_zlim3d(-3,3) self.canvas = figurecanvas(self.fig) self.layout().addwidget(self.canvas) self.pos = pos self.setup_plot() self.ani = animation.funcanimation(self.fig, self.update_plot, init_func=self.setup_plot, blit=true) def setup_plot(self): self.ax.legend(loc='best') self.position = self.ax.quiver(0, 0, 0, 0, 0, 0, pivot="tail", color="black") return self.position, def update_plot(self, i): x_zero = self.pos[:,3] y_zero = self.pos[:,4] z_zero = self.pos[:,5] v_x = self.pos[0,0:3] v_y = self.pos[1,0:3] v_z = self.pos[2,0:3] self.position = self.ax.quiver(-x_zero, -y_zero, z_zero, -v_x[0,:], v_y[0,:], v_z[0,:], pivot="tail", color="black") self.canvas.draw() return self.position, # need make sure animation stops, when window closed def closeevent(self, event): self.signalclose.emit() self.close() super(plot, self).closeevent(event) def close(self): self.ani.event_source.stop() super(plot, self).close() if __name__ == '__main__': app = qtgui.qapplication(sys.argv) main = newsphere() main.show() sys.exit(app.exec_())
here working example of think trying achieve.
main window has spin box , check box. once checkbox clicked, new window plot show , animation start. current value , array given plot window. if change spin box value while animation running, updated. when plot window closed or when checkbox unchecked, animation stop (and deleted).
import sys pyqt4 import qtgui, qtcore matplotlib import pyplot plt mpl_toolkits.mplot3d import axes3d matplotlib.backends.backend_qt4agg import figurecanvasqtagg figurecanvas matplotlib import animation import numpy np class newsphere(qtgui.qmainwindow): def __init__(self): super(newsphere, self).__init__() self.mainbox = qtgui.qwidget() self.mainbox.setlayout(qtgui.qhboxlayout()) self.setcentralwidget(self.mainbox) self.spin = qtgui.qspinbox() self.spin.setvalue(5) self.spin.setmaximum(10) self.spin.setminimum(1) self.checkplot = qtgui.qcheckbox("check") self.mainbox.layout().addwidget(self.spin) self.mainbox.layout().addwidget(self.checkplot) self.plot = none self.checkplot.clicked.connect(self.showplot) def showplot(self): if self.plot == none: self.plot = plot(self.kinematic(), self.spin.value()) self.plot.show() # register signal closure self.plot.signalclose.connect(self.uncheck) # register signal spin value changed self.spin.valuechanged.connect(self.plot.update_factor) else: self.plot.close() self.plot = none def kinematic(self): v = np.array([[1.,2.,3.],[2.,1.,3.],[3.,2.,1.]]) return v def uncheck(self): self.checkplot.setchecked(false) self.plot = none class plot(qtgui.qwidget): signalclose = qtcore.pyqtsignal() def __init__(self, v=none, factor=1): super(plot, self).__init__() self.setlayout(qtgui.qhboxlayout()) self.fig = plt.figure() self.ax = self.fig.add_subplot(111,projection = '3d') self.ax.set_aspect('equal') self.fig.tight_layout() self.ax.view_init(40, 225) self.ax.set_xlim3d(0,3) self.ax.set_ylim3d(0,3) self.ax.set_zlim3d(0,4) self.canvas = figurecanvas(self.fig) self.layout().addwidget(self.canvas) self.pos = v self.setup_plot() self.update_factor(factor) self.ani = animation.funcanimation(self.fig, self.update_plot, blit=false) def setup_plot(self): xpos, ypos = np.meshgrid(np.arange(self.pos.shape[0]),np.arange(self.pos.shape[1]) ) self.xpos = xpos.flatten('f') self.ypos = ypos.flatten('f') self.zpos = np.zeros_like(self.xpos) self.bar = none def update_factor(self, factor): self.factor = factor self.dx = np.ones_like(self.xpos)*np.min(np.abs(self.factor/10.), 0.1) self.dy = self.dx.copy() def update_plot(self, i): if self.bar != none: self.bar.remove() del self.bar pos = self.pos+np.sin(i/8.) dz = pos.flatten() self.bar = self.ax.bar3d(self.xpos, self.ypos, self.zpos, self.dx, self.dy, dz, color=(1.-self.factor/10.,0,self.factor/10.), zsort='average', linewidth=0) self.canvas.draw() # need make sure animation stops, when window closed def closeevent(self, event): self.signalclose.emit() self.close() super(plot, self).closeevent(event) def close(self): self.ani.event_source.stop() super(plot, self).close() if __name__ == '__main__': app = qtgui.qapplication(sys.argv) main = newsphere() main.show() sys.exit(app.exec_())
since wasn't sure want animate, changed plot barplot, can change whatever need. hope helps.
Comments
Post a Comment