opening and closing plots with matplotlib.pyplot - python

I"m running into issues when trying to interactively make plots with matplotlib.pyplot.
The general sequence of events is as follows:
1) open terminal, type ipython, copy and paste commands from my sublime text into ipython, eventually typing plt.show().
2) viewing my nice pretty plot be made, but with one small issue I want to fix or build upon
3) closing the window that houses the plot
4) seeing the command line return to normal again. Typing plt.close(), just to make sure the plot really closed
5) copying and pasting commands again, again ending with plt.show().
Only, the result of #5 results in no plot this time!
This seems to be a problem that repeats itself, so if anyone has any input I'd be very grateful. I noticed that when I create the plot the first time, it creates a plot window (which I can see with Command-Tab​​ Application Switcher). When I try to close this after making the plot the first time, this window never actually disappears from the Application Switcher.
Thanks

Related

Matplot, how terminate a python script with a second script

I have a python script that runs matplotlib to plot a figure on the screen (with plt.show). I need to launch this script every hour in order to update the pie with last values collected. As matplot is blocking with the previous pie drawn on the screen, I can not draw a new pie with new values.
I need to close automatically the previous plot but only as soon as the script is run again (via cronotab). I tried with a different script to be launched before the re-launch of the plotting script and with plt.close(‘all’) but it doesn’t work.
Any suggestion?
Thanks
I found a solution valid for me. I put the plotting in a while cicle and I put, at the end:
plt.show(block=False)
time.sleep(3600)
plt.close('all')
now it work as expected. The pie is updating every hour, redrawing itself with new values. I know that block=False is deprecated but I tried other solution without success (like plt.ion()).

Spyder: refresh existing plot window instead of opening a new one

I want to show plots in a separate window. Currently I have the IPython graphics backend set to "automatic".
When I re-run the code (or plot another figure), Spyder opens a new plot window. Is it possible to refresh the figure in the window that is already opened instead of opening a new one?
The GUI window that opens when you call plt.show() is bound to a figure. You cannot change the figure inside it. (Well, to be precise, there might be an option of obtaining a handle from the operating system and manipulating its content, but I assume this is not worth the effort.)
Re-running the code actually means that you produce a new figure since the code does not know that it's been run before.
So, exchanging the figure or reusing the window to plot a different figure is not possible.
What is possible however is to use the figure and manipulate the figure while it's open. This is done via plt.ion(). After calling this command in IPython you can adapt the figure, e.g. adding new lines to it etc.
See this example:
At IN [6] the window opens and when IN [7] is executed, the figure stays open and the content changes.
Sure, it is possible with Spyder while in the same running kernel. Try the following example using num as parameter to plt.figure(), where num will always refer to the same figure and refresh it if already opened. Also works with plt.subplots().
import matplotlib.pyplot as plt
from scipy import *
t = linspace(0, 0.1,1000)
w = rand(1)*60*2*pi
fig = plt.figure(num=10, clear=True, figsize = [10,8])
plt.plot(t,cos(w*t))
plt.plot(t,cos(w*t-2*pi/3))
plt.plot(t,cos(w*t-4*pi/3))

Closing pyplot figures from previous run

I am writing a python program to do some data analysis, and while developing the code, I have notived that if I do plt.show() at the end of my code, the windows stay on forever unless I manually close each one.
I would like to be able to
1. Either close the old plot when I rerun the program, i.e. at the beginning of each execution, the program should check for any pyplot instances running and close them, or
2. Update the existing figures with the new data, although this would be the less favorable solution, since I am also changing plot types and am unsure how that will affect the replotting.
For the first choice I have tried plt.close('all') at various locations in my code but it either does nothing or immedeately closes the window after it is being shown.
I have also seen people suggesting to just kill the associated process. How would I do that from within the python program?
Any help would be appreciated

How to update existing matplotlib (python) figures with sublime text

I've been using the IEP from pyzo before trying out Sublime Text (ST).
There is an annoying behaviour with ST that IEP doesn't have.
In IEP, much like with Matlab or Octave, the editor and the interactive console talk to each other.
Typically if you compute some_stuff and plot it in a script, after execution of this script you can go to the console and check some values:
print some_stuff[0:10]
or modify your plot:
plt.whatever()
which will update your figure.
Also if you run your script several times with different parameters, the figure is simply updated.
However when you do so in ST, even with REPL, after execution of the script nothing is left, you can't access some_stuff[0:10] from REPL. Similarly, you can't modify your figure. And if you run your script several times with different parameters, a new figure is generated in a new window each time instead of updating the existing figure.
Is there an easy work around this? Thanks!
How about saving your figure to a file with plt.savefig("fig.png")? If you open that file with your image viewer it will be updated after running your program.

reliably show matplotlib (0.99 to 1.3.1) figures without blocking

Is there any way to show a pyplot figure in Python 2.65, Matplotlib 0.99, without locking everything else?
I have a program with a Pmw GUI running on Python 2.75 with Matplotlib 1.3.1. on Windows (64-bit Winpython).
Everytime a figure is drawn (or everytime something is added to an existing one), the routine calls plt.show().
It is possible to show pyplot figures while allowing the user to keep using the GUI and manipulate the figures, nothing blocks anything, as I want it to be since I need the user to look at the plots when deciding what to do next in the GUI, and to have several plots next to each other for comparison.
Now, I need to make all of this work on a system with Python 2.65 and Matplotlib 0.99. The behaviour now seems to be that nothing is visible unless plt.show() is called, and then it will block everything until the plot window is closed.
I tried using plt.draw() instead but then the figure does not even show up.
Worse: Some routines who draw into existing figures never get a chance because they can't execute while the figure is being shown, and when they can, the figure is gone already. I cannot wait until the last drawing operation because the graphs are meant to build up incremental, adding information to existing graphs which the user needs to be able to see.
I am not allowed to update matplotlib. I am allowed to use non-binary parts of libraries if I make them part of "my" software package.
Ideally, I am looking for code that will work in both environments I'm working in, but at this point I am willing to make compromises...
Update:
I have found some code running in the same environment that is able to do all of these things, where I can remove the plt.show() calls, even run it in IDLE (which according to matplotlib docs has problems in these regards), and it "just works" -- I haven't been able to find any difference in how the two codes handle the task: Both define a figure.axes object, pass it to routines that draw into them (using plt.plot()) and store it for future use.
I've also found that my current code will change its behaviour on the current set of libraries, depending on how I run it: In a "regular" console in Spyder or a system console, all's fine, but on a dedicated console in Spyder, the first plot will lock up the interface
=> I'm beginning to think this isn't about the matplotlib version after all, but have no idea where else to look --is there anything else that changes matplotlib's behaviour, based on how it's launched?
It looks like you are looking for:
plt.show(block=False)
or plt.ion:
plt.ion()
plt.show()
# update figure, calc stuff
plt.pause()
Not really sure if they are available in 0.99.
elyase's answer sent me into the right direction:
import matplotlib
matplotlib.interactive(True)
This at the beginning of a script is what it takes to make sure that matplotlib will always and in all environments create plots in a way that allows scripts to continue running, while allowing the user to manipulate the figure and the code to keep drawing into it.
Matplotlib has two modes of operating: The interactive and the non-interactive, and my script going into the latter mode was the problem.
I have still no idea why this is the default behaviour in some cases and not in others (had believed it was one standard setting per matplotlib installation). Since other scripts are able to run without the above. and there must be something that my script inadvertently does to land in non-interactive mode, but the above code is what will override the setting, come what may; at least in all scenarios I've tried so far: python 2.75, matplotlib 1.3.1 using Spyder's regular and dedicated shells and system shells, and Py 2.65, matplotlib 0.99, using system shells and IDLE.
P.S.:
This does not seem to help on Linux. I tried to run the same skript (Tkinter GUI that opens plots, is able to draw into existing plots) on SuSE 13.1 (current version of python 2.7 and all libraries) and no single plot window pops up until the GUI is closed, and then they all jump at me ... it seems that it's not trivial to make matplotlib behave the same everywhere.

Categories