Matplotlib show/draw works only once

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Daniel M
    New Member
    • Feb 2012
    • 7

    Matplotlib show/draw works only once

    I am writing a GUI program in Tkinter which allows the user to enter in different parameters specifying an ellipse segment. Then, he/she presses a button and the ellipse segment is plotted, using matplotlib. Here is the code (inside a class, but logically stands alone) that does this:

    Code:
    aa = DataArray(self.file0)  #Retrieve data sets
    bb = DataArray(self.file1)  #Not used right now
    cc = DataArray(self.file2)  #Not used right now
    curr = DataArray(self.file3)#Not used right now
                
    x = aa.x                 #Get the abcissa values from the initial data set
                
    ideal = IdealEllipse(float(self.r.get()) , float(self.r.get()), float(self.r.get()),xall)
    
    plt1 = plt.plot(x,ideal)
    
    plt.draw()

    It works the first time, but if the user closes the window and then tries to plot it again, only a blank graph shows up. I have tried using pyplot.show(), and I get the same result. Even if I insert pyplot.close() at the top, to close all figures, it still does not change this. Using the figure manager and interactive mode also do not change this result. I have searched through the documentation and message boards all over the place but cannot find an explanation for this. I have the most up-to-date version of matplotlib (for Python 2.6). Why is this happening?

    Thanks in advance for any help
  • dwblas
    Recognized Expert Contributor
    • May 2008
    • 626

    #2
    What is self.r.get() and why do you call the function 3 times instead of calling it once and storing the value?
    It works the first time, but if the user closes the window and then tries to plot it again, only a blank graph shows up
    I'm guessing that r.get() doesn't exist once the window is closed but we can't tell from the code you posted. Storing r.get() in a variable would make the value persistent when the variable still exists after the window is closed.

    Comment

    • Daniel M
      New Member
      • Feb 2012
      • 7

      #3
      This is all inside the command function for a button. I don't close the GUI, I just close the plot window. And then when I try to bring it back up by pressing the button, I get a blank graph. The repeated r.get() calls is a mistake. The whole function (as I am currently testing it) is:

      Code:
      def ParOpt(self):
              Ready = (self.r.get() != '') and (self.rp.get() != '') and (self.th.get() != '')
              Ready = Ready and (self.Chg1.get()!= '') and (self.Chg2.get()!= '')
              Ready = Ready and (self.Name0.get() != '') and (self.Name1.get() != '')
              Ready = Ready and (self.Name2.get() != '') and (self.Name3.get() != '')
              
              if Ready == 1:
      
                  plt.ion()
                  aa = DataArray(self.file0)  #Retrieve data sets
                  bb = DataArray(self.file1)
                  cc = DataArray(self.file2)
                  curr = DataArray(self.file3)            
      
                  d1 = float32(self.Chg1.get())
                  d2 = float32(self.Chg2.get())
                  
                  xall = aa.x                 #Get the abcissa values from the initial data set
                  
                  ideal = IdealEllipse(float(self.r.get()) , float(self.rp.get()), float(self.th.get()),xall)
      
                  Solution = Optimize(ideal,aa.s,bb.s,cc.s,d1,d2,curr.s)
      
                  s1 = str( SigFig(sqrt(Solution.disp[0,0]),sqrt(Solution.disp[0,0])) )
                  s2 = str( SigFig(sqrt(Solution.disp[1,1]),sqrt(Solution.disp[1,1])) )
      
                  # See if answer is already open
                  try:
                      answer
                  except NameError:
                      answer = None
      
                  # Test whether variable is defined to be None
                  if answer is not None:
                      answer.destroy()
                      
                  answer = Toplevel()
                  answer.title("Optimal Parameter Settings")
                  
                  aL = Label(answer, text = "Change Bender #1 by "+str(SigFig(Solution.sol[0],float(s1)))+" (+/-"+s1+")",width = 50)
                  aL.pack()
                  
                  aL = Label(answer, text = "Change Bender #2 by "+str(SigFig(Solution.sol[1],float(s2)))+" (+/-"+s2+")",width = 50)
                  aL.pack()
      
                  nd = [self.r.get()+'\t'+self.rp.get()+'\t'+self.th.get()+'\t'+str(d1)+'\t'+str(d2)+'\t'+'END\n']
                  nd.append(self.Name0.get()+'\t\n')
                  nd.append(self.Name1.get()+'\t\n')
                  nd.append(self.Name2.get()+'\t\n')
                  nd.append(self.Name3.get()+'\t\n')
                             
                  newDefaults = open('C:\Documents and Settings\dmerthe\Desktop\Merthe Ellipse Adjust Test Files\defaultvalues.txt','w')
                  newDefaults.writelines(nd)
      
                  newDefaults.close()
      
                  DiffInit = curr.s - ideal - mean(curr.s - ideal)
                  DiffFin = Solution.pred - ideal - mean(Solution.pred - ideal)
      
                  cf1 = (bb.s - aa.s)/d1
                  cf2 = (cc.s - bb.s)/d2
      
                  plt1 = plt.plot(xall,DiffInit,'b',xall,DiffFin,'r--')
      
                  xRange = max(xall) - min(xall)
                  ymin1 = min(DiffInit)
                  ymax1 = max(DiffInit)
                  ymin2 = min(DiffFin)
                  ymax2 = max(DiffFin)
                  ymax = max([ymax1,ymax2])
                  yrange = max([ymax1,ymax2]) - min([ymin1,ymin2])
      
                  sInit = SigFig(std(DiffInit),std(DiffInit)*1.0E-2)
                  sFin = SigFig(std(DiffFin),std(DiffFin)*1.0E-2)
      
                  txt1 = plt.text(min(xall)+0.1*xRange, ymax, 'Current State, $\sigma = $'+str(sInit*1.0E6)+ ' $\mu$rad', color = 'blue', fontsize = 14)
                  txt2 = plt.text(min(xall)+0.1*xRange, ymax - 0.1*yrange, 'Predicted Final State, $\sigma = $'+str(sFin*1.0E6)+ ' $\mu$rad', color = 'red', fontsize = 14)
      
                  plt.draw()
                  plt.ioff()

      Comment

      • dwblas
        Recognized Expert Contributor
        • May 2008
        • 626

        #4
        This code accepts a number and plots that number of ellipsis. When the plot window is closed it goes back to the Tkinter entry box to get another number, which you can then plot. Note that you can only do one thing at a time, so when the plot window is open the Tkinter window is not responsive.
        Code:
        try:
            import Tkinter as tk     ## Python 2.x
        except ImportError:
            import tkinter as tk     ## Python 3.x
        
        from pylab import figure, show, rand
        from matplotlib.patches import Ellipse
        
        class MatPlotTest():
            def __init__(self):
                self.num=1
                self.root = tk.Tk()
                self.create_entry()
                self.root.mainloop()
        
            def create_entry(self):
                tk.Label(self.root, text="number to create").grid()
                self.entry=tk.Entry(self.root)
                self.entry.grid(row=0, column=1)
                self.entry.focus_set()
        
                tk.Button(self.root, text="draw ellipsesiess", command=self.plot_it, 
                          bg="lightblue").grid(row=2, column=0)
                tk.Button(self.root, text="Exit", command=self.root.quit, 
                          bg="red").grid(row=2, column=1, sticky="WE")
        
            def plot_it(self):
                self.num=int(self.entry.get())
                ells = [Ellipse(xy=rand(2)*10, width=rand(), height=rand(), angle=rand()*360)
                        for ctr in xrange(self.num)]
        
                fig = figure()
                self.ax = fig.add_subplot(111, aspect='equal')
                for e in ells:
                    self.ax.add_artist(e)
                    e.set_clip_box(self.ax.bbox)
                    e.set_alpha(rand())
                    e.set_facecolor(rand(3))
        
                self.ax.set_xlim(0, 10)
                self.ax.set_ylim(0, 10)
        
                show()
        
        MP=MatPlotTest()

        Comment

        Working...