When starting with python test.py , the following works for me:
import matplotlib.pyplot as plt import Tkinter, tkFileDialog root = Tkinter.Tk() root.withdraw() file_path = tkFileDialog.askopenfilename() root.destroy() print file_path x = range(10) plt.plot(x) plt.show()
I think this works because the Tk instance for the file dialog is destroyed before matplotlib starts its work. Interestingly, this also works for me when you run from
ipython --pylab=tk
where I would expect problems starting the event loop twice. The canonical solution in this case would be to check if Tk is working before starting it (again).
I am on MacOSX 10.7.5, custom matplotlib (doesn't matter).
The only thing I noticed is that after experimenting with this, the touchpad gestures on my Mac no longer work ... Peering into this.
Edit
Here is a breakdown of the Tk commands executed by tkFileDialog.askopenfilename() :
# breakdown of tkFileDialog.askopenfilename() import Tkinter as Tk window = Tk.Tk() window.withdraw() w = Tk.Frame(window) s = w.tk.call('tk_getOpenFile', *w._options({})) print s w.destroy() window.destroy()
When I run this (with python test.py ), I get a file open dialog where I can select the file. After "OK", it prints the file name and exits. This works every time on my system. However, sometimes three finger gestures on my touchpad stop working during the launch of this program! And they do not return after the program! Even after I killed the terminal, the program started !!!
The only way I found to return them is to add the following matplotlib code to test.py :
import matplotlib matplotlib.use('tkagg') import matplotlib.pyplot as plt plt.figure()
and then click on the title bar "Figure 1". This instantly returns 3-finger gestures. I suspect this is just a bug in Tkinter . (By the way, I'm on Tcl / Tk 8.5)
I cannot reproduce the behavior that the file open dialog is constantly overwritten on my system.
Could you describe what happens on your system if you run test.py without any matplotlib commands?
Alternatively, since Tkinter is deprecated and apparently faulty, can I suggest using Qt instead? Not only does it look much nicer, it is also more sleepy, and I had no problems with errors.
Edit 2
I broke the Tk actions matplotlib performs when executing the above commands in a non-interactive environment (i.e. with python test.py , not iPython). These are the main backend calls:
import matplotlib.backends.backend_tkagg as backend figManager = backend.new_figure_manager(1) figManager.show() backend.show.mainloop()
They are still independent of the backend. Ie, for a Qt figure, just use:
import matplotlib.backends.backend_qt4agg as backend
If we break it down to a specific level, we have:
import matplotlib.backends.backend_tkagg as backend import Tkinter as Tk window = Tk.Tk() window.withdraw()
First, run tkFileDialog with comments and check if the matplotlib shape is displayed and behaves correctly. Then uncomment the tkFileDialog calls and see if you finally get the expected behavior.
If not, you need to continue the breakdown of FigureCanvasTkAgg and FigureManagerTkAgg to understand what is happening ...
Edit 3
OK, as the problem persists, let him smash matplotlib Tk again. The following code completely isolates all the matplotlib Tk actions that I consider to be significant (so you no longer need to import anything from matplotlib!). Note that I refused to create a toolbar and assigned many callbacks and keypress events. If the code below works, then the problem lies in them. If this does not work, we can conclude that this is purely a Tk problem and most likely an error that should be reported. Here is the code:
import Tkinter as Tk window = Tk.Tk() window.withdraw()
Please play around with the comments of some lines and see if you can work properly. If not, I would conclude that this is a bug in Tkinter , which should be reported.