This page talks about the usage of ipython for interactive plotting: http://matplotlib.org/users/shell.html
According to that page, by default the %run command that is used to run scripts in ipython shuts down interactive mode. Is there an option to run the script in interactive mode as well?
I want the plotting commands in a script to take effect in the plotting figure as soon as they are run as if they are entered from the console interactively.
For example, consider the very simple script below:
# try.py:
# run in ipython that is started with
# ipython --pylab
# using
# %run -i try.py
from numpy import *
from time import sleep
ion()
x = randn(10000)
hist(x,100)
show()
sleep(5)
xlabel('labalu')
When run from ipython as indicated in the comment, this script waits 5 seconds, than shows everything. What I want is this: When run from ipython as indicated in the comment, the script should show the histogram immediately, wait 5 seconds, than update the figure to show the x label.
Moving ion() so it is after show() does what I think you want. Why it doesn't in the higher position, I do not know offhand.
If wx is used as the backend, following works:
#run in ipython that is started with ipython --pylab=wx
from numpy import *
import matplotlib
matplotlib.use('WX')
import wx
from time import sleep
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
x = np.random.uniform(0,1,100)
plt.plot(x)
plt.show()
wx.Yield()
for i in reversed(range(5)):
print(i)
sleep(1)
plt.xlabel('labl')
wx.Yield()
So, wx.Yield() lets interaction with the figure window. This also works when the script is run with normal python, but the figure is closed at the end of the script automatically.
Any cross-backends solutions (or solutions for qt/tk ) are still well come.
And below is a solution that works with both the wx and qt backends. gcf().canvas.flush_events() does the trick.
# try.py:
# run in ipython that is started with
# ipython --pylab
# using
# %run -i try.py
from numpy import *
import matplotlib
from time import sleep
x = randn(10000)
hist(x,100)
show()
ion()
gcf().canvas.flush_events()
sleep(5)
xlabel('labalu')
show()
Related
I initiated the VS Code window through a WSL Ubuntu terminal such as
/mnt/d/github/python/python_for_data_science$ code .
And test a plot
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 5, 11)
y = x**2
# functional
plt.plot(x, y)
plt.show()
By Run Python File in Terminal, it shows
/mnt/d/github/python/python_for_data_science$ /usr/bin/python /mnt/d/github/python/python_for_data_science/section_8_matplotlib.py
But I didn't see a plot. Have I missed something?
WSL might not have the ability to show UI. Alternatively you can run the code in the Python Interactive window in order to see the output. Try right-click and select Run Current File in Python Interactive window.
Whenever i try to plot something and close the plot window after that, I do not return into my Ipython shell. The shell freezes. The only thing I can do is close the shell and start all over again.
from sympy import *
x = symbols('x')
expr = 2 * x
plot(expr)
Gives a nice plot.
But when I close the plot window, the Ipython shell keeps waiting, apparently in a loop.
After searching AGAIN for some time I did find a workaround for this problem with interactive mode:
from matplotlib import interactive
interactive(True)
Thanks to joaquin who explains it here:
https://stackoverflow.com/a/8575569/9154139
I have a programme which creates an interactive matplotlib (well, pylab) figure, then waits for a raw_input while letting the user manipulate the plot to manually find the best data.
import pylab as p
p.ion()
p.figure(1)
p.plot(x,y,'.')
cen=float(raw_input('Type centre:'))
dur=float(raw_input('Type duration:'))
depth=float(raw_input('Type depth:'))
If I run this on linux (matplotlib 1.4.3), it works as expected. Running this on my Mac (matplotlib 1.5.0) freezes the pylab window at it's first draw and doesn't let the interactive features work. After something is entered into the raw_input, however, it draws all the preceding interactive clicks. Any ideas?
ion() and raw_input() do not work well together. This is a known problem. In interactive mode pyplot.ion() is using an event handler to wait for keypresses. This breaks when raw_input takes over the input.
You can make it a bit better by adding draw() or show():
import pylab as p
p.ion()
p.figure(1)
p.plot(x,y,'.')
p.show()
cen=float(raw_input('Type centre:'))
dur=float(raw_input('Type duration:'))
depth=float(raw_input('Type depth:'))
In the past I was able to do simple animations with matplotlib with a for loop, but this hasn't worked for some time now.
The standard answer is that you have to turn interactive mode on and/or force a redraw with matplotlib.pyplot.draw(). Here is my minimal working example:
import numpy as np
import matplotlib
matplotlib.use('Qt4Agg')
import matplotlib.pyplot as mplot
mplot.ion()
fig = mplot.figure(1)
ax = fig.add_subplot(111)
for ii in np.arange(0,10):
x = 200*np.random.rand(30)
ax.plot(x)
mplot.draw()
filename = ("img_%d.png" % ii)
mplot.savefig(filename)
When I run this in Interactive Python Editor, I get one figure at the very end with all the plots in it (this also happens with mplot.show())
When I run this in IPython 3.1 (with Python 3.3.5) from the command line, I get nothing at all.
The mplot.savefig(filename) line does seem to work, as the images are generated.
(It's possible this is a bug in the Qt4 backend.)
Try deleting the line matplotlib.use('Qt4Agg'). Works for me. Also works with matplotlib.use('TkAgg'). So it is a backend problem. There is another way to do animations.
I've got a script which creates a graph, but the script keeps running in the background until the window is closed. I'd like it to quit as soon as the window is created, so that Ctrl-C in the shell won't kill the window, and so that the user can leave the window open and continue working in the shell without bg-ing it manually. I've seen some solutions with daemons, but I'd like to avoid splitting this into two scripts. Is multiprocessing the easiest solution, or is there something shorter?
The relevant show() command is the last thing that is executed by the script, so I don't need to keep a reference to the window in any way.
Edit: I don't want to save the figure as a file, I want to be able to use the interactive window. Essentially the same as running mian ... & in bash
Just discovered this argument in plt.show(). setting block=False will pop up the figure window, continue following code, and keep you in the interpreter when the script has finished (if you are running in interactive mode -i).
plt.show(block=False)
This works for Unix:
import pylab
import numpy as np
import multiprocessing as mp
import os
def display():
os.setsid()
pylab.show()
mu, sigma = 2, 0.5
v = np.random.normal(mu,sigma,10000)
(n, bins) = np.histogram(v, bins=50, normed=True)
pylab.plot(bins[:-1], n)
p=mp.Process(target=display)
p.start()
When you run this script (from a terminal) the pylab plot is displayed. Pressing Ctrl-C kills the main script, but the plot remains.
I would suggest using os.fork() as the simplest solution. It is the trick that is used in daemons, but it doesn't require two scripts, and it's quite simple. For example:
import os
proc_num = os.fork()
if proc_num != 0:
#This is the parent process, that should quit immediately to return to the
#shell.
print "You can kill the graph with the command \"kill %d\"." % proc_num
import sys
sys.exit()
#If we've made it to here, we're the child process, that doesn't have to quit.
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,5,6])
plt.show()