Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
337 views
in Technique[技术] by (71.8m points)

python - matplotlib show() doesn't work twice

I have a strange problem, with matplotlib. If I run this program, I'm able to open and close several time the same figure.

import numpy
from pylab import figure, show


X = numpy.random.rand(100, 1000)
xs = numpy.mean(X, axis=1)
ys = numpy.std(X, axis=1)

fig = figure()
ax = fig.add_subplot(111)
ax.set_title('click on point to plot time series')
line, = ax.plot(xs, ys, 'o', picker=5)  # 5 points tolerance


def onpick(event):

    figi = figure()
    ax = figi.add_subplot(111)
    ax.plot([1,2,3,4])        
    figi.show()

fig.canvas.mpl_connect('pick_event', onpick)

show()

On the contrary, if I use the same code of onpick function into my custom widget it opens the figure only the first time, into the other events it enters into the functions but doesn't display the figure:

from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar
import time

STEP = 0.000152 

class MplCanvas(FigureCanvas):

    def __init__(self):

        # initialization of the canvas
        FigureCanvas.__init__(self, Figure())

        self.queue = []
        self.I_data = np.array([])
        self.T_data = np.array([])

        self.LvsT = self.figure.add_subplot(111)
        self.LvsT.set_xlabel('Time, s')
        self.LvsT.set_ylabel('PMT Voltage, V')
        self.LvsT.set_title("Light vs Time")
        self.LvsT.grid(True)

        self.old_size = self.LvsT.bbox.width, self.LvsT.bbox.height
        self.LvsT_background = self.copy_from_bbox(self.LvsT.bbox)

        self.LvsT_plot, = self.LvsT.plot(self.T_data,self.I_data)
        #self.LvsT_plot2, = self.LvsT.plot(self.T_data2,self.I_data2) 

        self.mpl_connect('axes_enter_event', self.enter_axes)
        self.mpl_connect('button_press_event', self.onpick)
        self.count = 0
        self.draw()

    def enter_axes(self,event):

        print "dentro"

    def onpick(self,event):
        print "click"
        print 'you pressed', event.canvas

        a = np.arange(10)
        print a
        print self.count

        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot(a)    
        fig.show()



    def Start_Plot(self,q,Vmin,Vmax,ScanRate,Cycles):
        self.queue = q

        self.LvsT.clear()
        self.LvsT.set_xlim(0,abs(Vmin-Vmax)/ScanRate*Cycles)
        self.LvsT.set_ylim(-3, 3)
        self.LvsT.set_autoscale_on(False)
        self.LvsT.clear()
        self.draw()

        self.T_data = np.array([])
        self.I_data = np.array([])

        # call the update method (to speed-up visualization)
        self.timerEvent(None)
        # start timer, trigger event every 1000 millisecs (=1sec)
        self.timerLvsT = self.startTimer(3)

    def timerEvent(self, evt):

        current_size = self.LvsT.bbox.width, self.LvsT.bbox.height
        if self.old_size != current_size:
            self.old_size = current_size
            self.LvsT.clear()
            self.LvsT.grid()
            self.draw()
            self.LvsT_background = self.copy_from_bbox(self.LvsT.bbox)

        self.restore_region(self.LvsT_background, bbox=self.LvsT.bbox)

        result = self.queue.get()

        if result == 'STOP': 
            self.LvsT.draw_artist(self.LvsT_plot)
            self.killTimer(self.timerLvsT)
            print "Plot finito LvsT"

        else:
            # append new data to the datasets
            self.T_data = np.append(self.T_data,result[0:len(result)/2])
            self.I_data = np.append(self.I_data,result[len(result)/2:len(result)])

            self.LvsT_plot.set_data(self.T_data,self.I_data)#L_data
            #self.LvsT_plot2.set_data(self.T_data2,self.I_data2)#L_data

            self.LvsT.draw_artist(self.LvsT_plot)

            self.blit(self.LvsT.bbox)


class LvsT_MplWidget(QtGui.QWidget):
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)        
        self.canvas = MplCanvas()
        self.vbl = QtGui.QVBoxLayout()
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)

This widget is needed for an animation plot and when the experiment is finished if I click on the plot it should appear a figure, that appears only the first time.

Do you have any clue?

Thank you very much.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

At the start of your code, enable interactive mode via plt.ion()


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...