Matplotlib: getting a figure to show without plt.show()
Peter Otten
__peter__ at web.de
Wed Oct 22 06:38:02 EDT 2014
Peter Pearson wrote:
> I'm using Matplotlib to present a "control" window with clickable
> buttons, and to plot things in another window when you click buttons,
> in the style of the code below. I'm ashamed of the stinky way I
> use "first" to call plt.show the first time data are plotted but then
> to call fig.canvas.draw for subsequent data plots.
> def callback(event):
> global n, first
> fig = plt.figure(2)
> fig.clear()
> plt.plot([0,1],[0,n])
> n += 1 # (Pretending something changes from one plot to the next.)
> if first:
> first = False
> plt.show()
> else:
> fig.canvas.draw()
> Can someone tell me the right way?
I don't see what's wrong with doing something different the first time
around.
> If I call plt.show every time, then after about 40 plots I get
> "RuntimeError: maximum recursion depth exceeded while calling a Python
> object", which makes sense because I'm getting one layer deeper in
> callbacks with every plot (plt.show doesn't return). But if I call
> fig.canvas.draw every time, the window for the data plot never appears
> on my screen.
If your backend uses tkinter, then the problem may be that plt.show() starts
a new mainloop. Over here this causes the script to hang on termination.
Through try-and-error I came up with
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
def callback(event):
global n, fig2
if fig2 is None:
fig2 = plt.figure(2)
fig2.clear()
fig2.gca().plot([0, .5, 1], [0, 1/n, 1])
fig2.show()
n += 1
n = 1
fig2 = None
plt.figure(1)
quit_button = Button(plt.axes([.1, .3, .4, .2]), "Quit")
quit_button.on_clicked(lambda x: plt.close("all"))
plot_button = Button(plt.axes([.1, .1, .4, .2]), "Plot")
plot_button.on_clicked(callback)
plt.show()
If you don't mind that the second window shows up immediately you can modify
that to
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
def callback(event):
global n
fig2.clear()
fig2.gca().plot([0, .5, 1], [0, 1/n, 1])
fig2.show()
n += 1
n = 1
plt.figure(1)
quit_button = Button(plt.axes([.1, .3, .4, .2]), "Quit")
quit_button.on_clicked(lambda x: plt.close("all"))
plot_button = Button(plt.axes([.1, .1, .4, .2]), "Plot")
plot_button.on_clicked(callback)
fig2 = plt.figure(2)
plt.show()
and thus avoid the special case.
As I'm not an expert for matplotlib you might also post your question on the
matplotlib mailing list.
More information about the Python-list
mailing list