I'm writing an app that allows you to drag and drop datafiles unto a gui which then plots it. However using plt.show() causes the interface to become non-interactive, that means I need to first close the plot before dragging and dropping another file. I wanted to avoid doing this.
I've tried using plt.ion() but doing that causes the plot gui from updating when you resize it or try to manually close it.
Related
With a single script, I have to produce dozens of figures with matplotlib using spyder. I would like spyder to create figures while I can work with other browsers or windows without interruption. Here were the methods I tried. Let us say that there are 40 plots to be created. Each plot contains multiple subplots
(1) From How do I get interactive plots again in Spyder/IPython/matplotlib?. I used %matplotlib inline. The plots will be created inline at the end of the program. However, the usage of computation memory keeps accumulating. At some point, python will show an error message due to lack of memory and then crash. The message is like: "More than 20 figures have been opened. Figures created through the pyplot interface (matplotlib.pyplot.figure) are retained until explicitly closed and may consume too much memory."
(2) Then, I use plt.close() to close each figure after saving it. The memory issue is resolved. However, even if the figure is not shown, every time python close a figure and open another one, all other browsers and windows will be affected. If I am typing on a window, after the interruption, I have to click the window again in order to continue typing.
Previously, when I used MATLAB, I could simply specify h=figure and then set(h,'visible','off') to avoid this issue. I wonder if I can do similar things with python.
Thank you for the help!
I wrote an app to plot a graph from an input file when you drag and drop the file onto a gui interface. However after the execution of plt.show() in the program, the gui interface becomes inactve.
Using plt.draw() instead of plt.show() or using plt.ion() solves this issue, but then the python graph stop updating, ie. resizing/ closing the graph doesn't work until the next time a file is dragged and dropped.
Try to make two different files and put the plt.show() in the other one, to see if it works.
I have spent over an hour searching, just to figure this simple thing. So, before considering this a duplicate question, please compare my question to any question out there.
This is my code:
import pandas
import matplotlib.pyplot as plt
dataset = pandas.read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=1)
print dataset, type(dataset)
plt.plot(dataset)
plt.show()
plt.close()
Firstly, plt.show() to my understanding is a blocking function. So what is the way to close the figure. There is no point in writing plt.close() after it. So where is the right way to put it.
Secondly, how can I make sure all the windows are closed when I execute a new process of the same python code. For example in MATLAB, one could easily say close all in the beginning of their file and it closes all the opened plots which were the result of previous MATLAB code execution. plt.close('all') is not working either.
I am using PyCharm. The results I found for the first situation, might work on IDLE but not in the PyCharm. How can I do it PyCharm.
plt.show(block=False) will do the trick- This is the way you can make this function non-blocking (both in run & debug mode). The main dis-advantage is that if the code ends, the figure is automatically closes...
I had the same problem.
I fix it making the python file in Pycharm to run in only one console. Go to: run---Edit configuration-- check that "single instance only" is activated
There are two ways to run matplotlib, non-interactive and interactive. In non-interactive mode, the default, you are right that plt.show() is blocking. In this case, calling plt.close() is pointless, the code won't stop as long as the figure is open. In interactive mode, however (which can be triggers by plt.ion()), this code will open then immediately close the figure. You would need to put something to wait for user input if you run code like this in a script. Interactive mode, as the name implies, is designed more for running interactively rather than in a script.
As for closing figures from multiple runs of a python script, this isn't possible. If you open multiple instances of MATLAB, close all in one instance won't close the figures in another instance. Running multiple processes of the same python code is the same as opening multiple instances of MATLAB, one run has no knowledge of the others.
I'm following a book by Wes McKinney and in the section introducing pandas, he's given a simple example of plotting a pandas Data Frame. Here're the lines I wrote:
tz_counts = frame['tz'].value_counts() # frame is a Data Frame
tz_counts[:10] # works fine till here. I can see the key-value I wanted
tz_counts[:10].plot(kind='barh', rot=0)
It just prints a line on screen that says
<matplotlib.axes.AxesSubplot object at 0x3d14ed0>
rather than displaying a plot window as I'd expect with matplotlib's plot function. What's wrong here? How can I make it work?
Matplotlib doesn't show the plot until you tell it to, unless you're in "interactive" mode.
Short Answer: Call plt.show() when you're ready to display the plot.
This starts the gui mainloop of whatever backend you're using, so it is blocking. (i.e. execution will stop until you close the window)
If you want it to show up automatically without stopping execution, you can turn on interactive mode either with plt.ion() or by using ipython --pylab.
However, using --pylab mode in ipython will import all of numpy, matplotlib.pyplot, and a few other things into the global namespace. This is convenient for interactive use, but teaches very bad habits and overwrites functions in the standard library (e.g. min, max, etc).
You can still use matplotlib's interactive mode in ipython without using "pylab" mode to avoid the global import. Just call plt.ion()
Matplotlib's default TkAgg backend will work in interactive mode with any python shell (not just ipython). However, other backends can't avoid blocking further execution without the gui mainloop being run in a separate thread. If you're using a different backend, then you'll need to tell ipython this with the --gui=<backend> option.
Try using:
%matplotlib
tz_counts = frame['tz'].value_counts()
tz_counts[:10].plot(kind='barh', rot=0)
Using % matplotlib prevents importing * from pylab and numpy which in turn prevents variable clobbering.
I would like to save my figures to disk without rendering them on the screen and without having to change my rendering backend.
I tried the instructions in here, namely avoiding calling fig.show() nor fig.draw() and just calling fig.savefig, but I noticed that the mere statement fig = plt.figure() already opens a figure on the screen.
How can I save a figure to disk without having to render it, and without having to change my backend?
pyplot has an interactive functionality which will automatically call draw() after most plt.* calls for you.
draw is not automatically called if you don't go through the state machine interface (ex gca().plot(...) would not automatically redraw, but plt.plot(...) would).
See the code, the important function in draw_if_interactive.
This can be turn off via plt.ioff() or by not calling plt.ion() (ipython --pylab automatically turns it on for you).
doc