How can I open two different pylab figures from the same button from a wxpython gui?

喜欢而已 提交于 2019-12-24 00:33:23

问题


I am new to python and I have a serious problem that I cannot overcome. I have created a gui using wxpython that has two text fields and a button. When this button is pressed I call a function that call another function which creates a pie figure according to the input in text boxes. The problem is that if the user do not close the figure and enter new values to the textboxes and press again the button, the program crash instead of showing a second figure. I tried to create different threads when the button is pressed the result is the same.

More specifically:

this are the functions that are called when the button is clicked:

def statistics_button(self,event):

   t=threading.Thread(target=self.m_button21OnButtonClick,args=(event,))
    t.start()
    print t    

def m_button21OnButtonClick( self, event ):

    '''some code here'''


    fig=statistics.mmr_dist(mmr1,mmr2) 

    show()

the statistics_button is called first and then this calls the m_button21OnButtonClick. the statistics.mmr_dist function is the following:

'''some code'''
fig=pylab.figure(tit,figsize=(8,8),frameon=False)

ax=pylab.axes([0.1, 0.1, 0.8, 0.8])
pita=pylab.pie(db.values(), labels=tuple(db.keys()), autopct='%1.1f%%', shadow=True)
ti="%s-%s\n Maximum Distance = %s m\n Minimum Distance = %s m" % (ddf1.label,ddf2.label,maxdist,mindist)
title(ti, bbox={'facecolor':'0.8', 'pad':5}) 


'''some code'''

return fig

So far I have understood that the show() command blocks the function m_button21OnButtonClick from finishing so it cannot be called again when the button is clicked unless the figure is closed. But this is the reason I implemented different threads. Though it doesn't seem to work.


回答1:


See this page for advice on getting pylab to work with wxPython--which you probably shouldn't really try (see next paragraph). The problem is that pylab uses Tkinter which is incompatible with a running copy of wxPython.

Ultimately, you should just embed your plots in wxPython. That works very well and is a better user experience anyway.




回答2:


Try issuing the command pylab.ion() after you import pylab, and see if that lets you show multiple plots. That has always been my approach when needing to repeatedly show updating plots without closing the window.

Note that you'll need to create new figure and axes objects for each different plot window, otherwise plots will overwrite old plots.

For example, the following code works to produce two windows with different plots for me:

 import pylab
 pylab.ion()

 fig1 = pylab.figure()
 fig1.add_subplot(111).plot([1,2],[3,4])
 pylab.draw()

 fig2 = pylab.figure()
 fig2.add_subplot(111).plot([5,6],[10,9])
 pylab.draw()

Added

Given your follow-up comments, here is a new script that does use show(), but which displays the different plots each time pylab.draw() is called, and which leaves the plot windows showing indefinitely. It uses simple input logic to decide when to close the figures (because using show() means pylab won't process clicks on the windows x button), but that should be simple to add to your gui as another button or as a text field.

import numpy as np
import pylab
pylab.ion()

def get_fig(fig_num, some_data, some_labels):

    fig = pylab.figure(fig_num,figsize=(8,8),frameon=False)
    ax = fig.add_subplot(111)
    ax.set_ylim([0.1,0.8]); ax.set_xlim([0.1, 0.8]);
    ax.set_title("Quarterly Stapler Thefts")
    ax.pie(some_data, labels=some_labels, autopct='%1.1f%%', shadow=True);
    return fig

my_labels = ("You", "Me", "Some guy", "Bob")

# To ensure first plot is always made.
do_plot = 1; num_plots = 0;

while do_plot:
    num_plots = num_plots + 1;
    data = np.random.rand(1,4).tolist()[0]

    fig = get_fig(num_plots,data,my_labels)
    fig.canvas.draw()
    pylab.draw()

    print "Close any of the previous plots? If yes, enter its number, otherwise enter 0..."
    close_plot = raw_input()

    if int(close_plot) > 0:
        pylab.close(int(close_plot))

    print "Create another random plot? 1 for yes; 0 for no."
    do_plot = raw_input();

    # Don't allow plots to go over 10.
    if num_plots > 10:
        do_plot = 0

pylab.show()



回答3:


If you want to create pie charts or other types of graphs in wxPython, then you should use PyPlot (included in wx) or matplotlib, which can be embedded in wxPython. The wxPython demo has an example of PyPlot. For matplot see here or here.



来源:https://stackoverflow.com/questions/9814861/how-can-i-open-two-different-pylab-figures-from-the-same-button-from-a-wxpython

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!