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/
Related
I want to save a plot created using matplotlib to a file but I do not want it to show as inline plot in Spyder IDE. My code:
import matplotlib.pyplot as plt
from math import sin,pi
import numpy as np
x = np.linspace(0,2*pi,100)
y = np.sin(x)
plt.plot(x,y)
plt.savefig('sin.png')
When I run this code, the plot keep showing in IPython console as inline plot whereas I just want to save it to a file. How can I fix this problem?
add plt.close() after plt.savefig().
This behaviour is steered by some of the settings in spyder.
First, you may of course opt not to use IPython at all. Instead if the script is executed in a new python console, it will not pop up at all without you specifying plt.show() at the end.
If however you want to use IPython, but not get any graphical output, you may deactivate the graphical output for the IPython console. I.e. no checkmark at "Activate support". This will then also require you to call plt.show() to actually show the figure in a new window.
Note that changing those settings will require to restart Spyder.
Those are the general settings. If you want this behaviour only for a single script, use plt.close() at the end of a cell/script.
I am trying to follow some of the guides for generating real-time plots such as: real-time plotting in while loop with matplotlib and http://thread.gmane.org/gmane.comp.python.matplotlib.general/35705
However, I believe the sample code was compiled with python 2.7. When I try to compile mine I do not see a real-time plot being updated. Is this because python 3 doesn't support it? Or am I missing a library or something? Only when I stop the while loop I see the last value that was plotted. I am using Rodeo as my IDE; would this be preventing me from viewing the real-time plot?
import serial
import numpy as np
import matplotlib.pyplot as plt
def plotlive():
plt.plot(ard_dat,'o')
plt.xlabel('count', fontsize=12)
plt.ylabel('reading', fontsize=12)
plt.legend(loc='upper right')
ard_dat=[]
plt.ion()
cnt=0
arduinoSerialData = serial.Serial('com5',9600)
while True:
while (arduinoSerialData.inWaiting()==0):
pass
srdata = arduinoSerialData.readline()
try:
intstrdata = int(srdata)
except ValueError:
pass
ard_dat.append(intstrdata)
drawnow(plotlive)
plt.pause(.00001)
cnt+=1
if (cnt>50):
ard_dat.pop(0)
There is no specific python 2 or 3 command in the code so you can leave that out of the equation.
I would not recommend to use drawnow. Call plotlive() directly instead. This is however just a recommendation because drawnow is a pretty useless package, but it would not prevent the code from running.
Assuming that the serial works fine, the code from the question should produce an updating plot when being run as script.
The main point is this: Rodeo is not capable of producing animations. See this issue: https://github.com/yhat/rodeo/issues/488
The reason is that it uses a notebook-like output mechanism. While in Jupyter notebook you would actually be able to set the backend to interactive mode (%matplotlib tk or %matplotlib notebook), this is apparently not possible in Rodeo.
Rodeo also does not seem to have the option to run some code as python script outside of its IDE. Therefore the idea would be to either use a different IDE or to at least run animations outside of Rodeo.
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))
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.
Whenever I call show() in matplotlib the plot window appears behind all other windows and I have to minimize everything to see it. Is there any way I can prevent this or programmatically bring it to the front. On OSX Lion. Python 2.7
Well. This answer is presented in the comments to the accepted answer but I think it deserves to have a place as a separate one as it solves the issue nicely. Besides the author's problem I additionally had the problem that matplotlib window wasn't in the tray of active windows so I couldn't switch to it by <Alt>+<Tab>.
Changing of the matplotlib's default backend macosx solved everything. You can try immediately in your code like this:
import matplotlib
matplotlib.use("Qt5agg")
Qt5agg might not be presented in your system then please pick the one that is. You can find them:
import matplotlib.rcsetup as rcsetup
print(rcsetup.all_backends)
If it helped then you might want to change your backend in the configuration. For that locate it first:
import matplotlib
matplotlib.matplotlib_fname()
Then change backend: value:
backend : macosx
to your backend. I used in the end:
backend : TkAgg
Not exactly an answer to your question, but I'm using ipython instead of the default python console. When launched it with ipython --pylab I can plot e.g. by typing
>> plot([1,3,2])
and have the plot pop up in front. It also has some other very nice features ;)
Matplotlib developer's seem to be aware of this issue. But looking into https://github.com/matplotlib/matplotlib/issues/596 it looks like it's going to be a while until getting a solution, apparently because some people find it annoying that figure.show() "steals" screen space.
It may be OS-specific, but using interactive plotting (which plots as soon as you instruct) causes figures to come up in the foreground as soon as they're made on Ubuntu:
import pylab as P
P.ion()
P.figure(1)
P.plot([1,2,3],[1,4,9])
I have the same set-up as nickponline. What works for me is:
from pylab import get_current_fig_manager()
get_current_fig_manager().window.raise_()
If you have multiple figures, this only raises the currently active one. For that case, I found that the following works:
fig1=figure(1)
cfm1=get_current_fig_manager().window
fig2=figure(2)
cfm2=get_current_fig_manager().window
...
cfm1.activateWindow()
cfm1._raise()
pause(.1) # or something else that uses up some time
cfm2.activateWindow()
cfm2.raise_()