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))
Related
So I have some python code that plots a few graphs using pyplot. Every time I run the script new plot windows are created that I have to close manually. How do I close all open pyplot windows at the start of the script? Ie. closing windows that were opened during previous executions of the script?
In MatLab this can be done simply by using closeall.
To close all open figures from a script, you can call
plt.close('all')
or you can terminate the associated Python process.
This solution won't allow you to close plots from previous runs, but will prevent you from leaving them open!
The only way I have found to close these "hanging" figures is to find the process and kill.
Plot in a non blocking manner then ask for input. This should prevent you from forgetting to properly close the plot.
plt.show(block=False)
plt.pause(0.001) # Pause for interval seconds.
input("hit[enter] to end.")
plt.close('all') # all open plots are correctly closed after each run
import matplotlib.pyplot as plt
plt.close("all")
(In case you have pyplot already imported, you obviously don't need to import it again. In that case just make sure to replace plt in plt.close("all") with whatever alias you chose for pyplot when you imported it.)
I just had the same problem. I call a function that generates multiple plot windows. Each time I call the function the popped up plot windows accumulate in number. Trying matplotlib.pyplot.close('All') at the begining of the function didn't solve the problem. I solved the problem by calling matplotlib.pyplot.close(figure), where figure is a plot figure instance (object).
I maintain a list of my plot figure objects. So, it is a good idea to maintain a list, and then call matplotlib.pyplot.close(figure) for each instance of a figure object:
import matplotlib.pyplot as plot
Add plot instance objects (figure,axis) to a list:
fig, (ax1,ax2) = plt.subplots(nrows=2)
figAxisDict = {'figure': fig, 'axis1': ax1, 'axis2':ax2}
figAxisList.append(figAxisDict)
Call the function for figure closing, and clear the list afterwards:
if len(figAxisList) !=0:
for figAxis in figAxisList:
figure=figAxis['figure']
plot.close(figure)
figAxisList[:]=[]
As there seems no absolutely trivial solution to do this automatically from the script itself: the possibly simplest way to close all existing figures in pycharm is killing the corresponding processes (as jakevdp suggested in his comment):
Menu Run\Stop... (Ctrl-F2). You'll find the windows closed with a delay of few seconds.
Honestly, the developer needs to make this a simple function like it is in MATLAB.
My temporary solution for Spyder:
first install keyboard and pynput via the Anaconda Prompt
in Spyder run "mouse.position" with your mouse over the position where your plots pane is
These coordinates are the ones you need to replace in the code below.
import keyboard
from pynput.mouse import Button, Controller
#%% Clear Old Plots
#Selects the mouse as the controller
mouse = Controller()
#Record current mouse position
recmp = mouse.position
#Set pointer position on plots pane
mouse.position = (1136,370) # <-- replace coordinates here with yours!
#Opens the plot pane
keyboard.press_and_release('ctrl+shift+g')
#Click and release left mouse button
mouse.press(Button.left)
mouse.release(Button.left)
#Runs close all in the plots pane
keyboard.press_and_release('ctrl+shift+w')
#Resets mouse position to the original location
mouse.position = recmp
On *nix you can use killall command.
killall app
closes every instance of window with app for the window name.
You can also use the same command from inside your python script.
You can use os.system("bashcommand") to run the bashcommand.
I'm plotting some graphs and then I interact with them using the canvas.mpl_connect commands. So when I show the plot, I want the window to be the active one since the beginning.
At the moment, when the script is run, the plot pops up but it's not the active window, the terminal still is (i.e. if I type a key, that is written in the Terminal, and not interpreted by the plot-window). I need to click on the plot-window to make it the active one and then I'm able to interact with the graphs. It would be way nicer if it was already active the first time it pops up.
Working on MacOSX 10.10.3 with python 2.7.5 and matplotlib 1.3.1
EDIT
I don't just need to bring the window in front, I want to be able to interact with the window without having to click on it. So if I type some keys, the graph will respond and not the terminal.
You can set the order windows are displayed in using canvas manager but it only works with some graphical backends. The following example uses the TkAgg backend which works but the same idea won't work the macosx backend.
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
from pylab import get_current_fig_manager
fig1 = plt.figure()
fig2 = plt.figure()
fig1.canvas.manager.window.attributes('-topmost', 1)
plt.show()
Figure 1 should show up on top of figure 2.
So, I've finally found a solution here https://github.com/matplotlib/matplotlib/pull/663
Apparently a work around is to import
from AppKit import NSApplication
and issuing just before show():
NSApplication.sharedApplication().activateIgnoringOtherApps_(True)
I'm not really sure what it does, and apparently it works just in non-interactive mode, but that worked perfectly for me.
You might also want to check here
https://github.com/matplotlib/matplotlib/issues/665/
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
I have noticed that when I run:
import pylab as pl
pl.ion()
# Plot something
pl.show()
pl.close()
The last statement does not fully close the Figure. The figure goes dark, and the contents go away, but the Figure stays on the screen until I exit IPython as shown below
I am using the latest stable version of matplotlib (1.3.1) using an Anaconda distribution, on Linux 64 bit, and I connect remotely using ssh -X.
The backend I am using is below:
backend : QT4Agg
backend.qt4 : PySide
you have to specify wich figure you want to close. In case you want to close all of them:
pl.close('all')
Also, there is a way to just clear but not close a figure:
pl.clf()
Also, seen below from another SO question:
Remember that plt.show() is a blocking function, so in the example code you used above, plt.close() isn't being executed until the window is closed, which makes it redundant.
You can use plt.ion() at the beginning of your code to make it non-blocking, although this has other implications.
You can also use the following lines after your plotting
#Your Plotting function
plt.waitforbuttonpress(0)
plt.close(fig)
The plt.waitforbuttonpress(0) will wait until a user input (Key press) is given. After that it will properly close the matplotlib window properly. It is very important to specify which figure to close.
At the end of the last function I call in one of my programs, I have the following code to plot a simple color plot.
plt.figure()
plt.pcolormesh(X,Y,Z)
plt.colorbar()
plt.show()
Afterwords I return to main and my program is complete. The plot displays as expected, however when I go to close it using the x button in the corner (on ubuntu), my program doesn't end. It just hangs there with a process running. How can I correct this?
your matplotlib might be running in non-interactive mode for some reason.
I am not sure how to prevent that in your local configuration but if you add either this:
plt.ion()
or this:
matplotlib.interactive(True)
somewhere at the beginning of your script, it should change the behaviour of your plots.
For interactive mode, You need this at the head of file:
import matplotlib
matplotlib.use("TkAgg")