Updating matplotlib plot during code execution - python

I have found that the latest update to python/matplotlib has broken a crucial feature, namely, the ability to regularly update or "refresh" a matplotlib plot during code execution. Below is a minimally (non-)working example.
import numpy as np
from matplotlib.pyplot import *
from time import sleep
x = np.array([0])
y = np.array([0])
figure()
for i in range(51):
gca().cla()
plot(x,y)
xlim([0,50])
ylim([0,2500])
draw()
show(block = False)
x = np.append(x,[x[-1]+1])
y = np.append(y,[x[-1]**2])
sleep(0.01)
If I run this program using Python 3.4.3 and matplotlib 1.4.3, I can see the plot continually update, and the curve grows as the program runs. However, using Python 3.5.1 with matplotlib 1.5.3, the matplotlib window opens but does not show the plot. Instead, it continually shows the window is "not responding" and only presents the final plot when the code finishes executing.
What can I do about this? Is there some way to achieve the functionality that I want using the latest release?
Note: I'm running this from the default IDLE environment if that makes a difference.

That is interesting. I'm used to draw interactive plots a little bit differently:
import numpy as np
import matplotlib.pyplot as plt
from time import sleep
x = np.array([0])
y = np.array([0])
plt.ion()
fig = plt.figure()
ax=fig.add_subplot(111)
ax.set_xlim([0,50])
ax.set_ylim([0,2500])
line, = ax.plot(x,y)
plt.show()
for i in range(51):
x = np.append(x,[x[-1]+1])
y = np.append(y,[x[-1]**2])
line.set_data(x,y)
plt.pause(0.01)
Can you (or anyone) check if this shows the same problems in Matplotlib 1.5?

Related

Is it possible, that the window with the python plots in vs code shows up at the same spot?

I have a python program (not a notebook, a python file) where I produce several plots that show up one after the other. The program looks something like this:
import numpy as np
import matplotlib.pyplot as plt
functions = [np.sin, np.cos, np.abs, np.square]
x = np.linspace(-np.pi, np.pi, 100)
for func in functions:
plt.plot(x, func(x))
plt.show()
When I run the program in vscode I have to close one plot before the next one opens. The windows with the plots open at different locations every time and it would be more convenient if the X button was at the same place every time so i can click through them more easily. Is there a way to do this?
I solved it like this:
import numpy as np
import matplotlib.pyplot as plt
from pylab import get_current_fig_manager
functions = [np.sin, np.cos, np.abs, np.square]
x = np.linspace(-np.pi, np.pi, 100)
for func in functions:
thismanager = get_current_fig_manager()
thismanager.window.wm_geometry("+500+0")
plt.plot(x, func(x))
plt.show()
Like on this webpage: https://pyquestions.com/how-do-you-set-the-absolute-position-of-figure-windows-with-matplotlib
or as answered here: How do you set the absolute position of figure windows with matplotlib?.
I thought it was a vscode issue but everything is done by matplotlib. If anyone knows a more permanent solution, please let me know, as setting this for every plot is quite annoying.

Plotting changing graphs with matplotlib

So I have been trying to get a plot to update every iteration through a loop. A stripped down version of my code is as follows:
1 import matplotlib.pyplot as plt
2 import numpy as np
3
4 x = np.linspace(0, 9, 10)
5 for j in range(10):
6 y = np.random.random(10)
7 plt.plot(x,y)
8 plt.show()
9 plt.pause(1)
10 plt.clf()
My issue is that I have to close each plot before the next one is created; it seems like the plot is stuck on plt.show(), whereas I expect a new plot to replace the current one every second without needing my interaction. I've consulted the following questions:
When to use cla(), clf() or close() for clearing a plot in matplotlib?
Python plt: close or clear figure does not work
Matplotlib pyplot show() doesn't work once closed
But none of the solutions seemed to work for me. Any help would be appreciated!
You should set interactive mode with plt.ion(), and use draw to update
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
fig=plt.figure()
x = np.linspace(0, 9, 10)
for j in range(10):
y = np.random.random(10)
plt.plot(x,y)
fig.canvas.draw()
plt.pause(1)
plt.clf()
link to tutorial
Note that it might not work on all platforms; I tested on Pythonista/ios, which didn't work as expected.
From
matplotlib tutorial
Note
Interactive mode works with suitable backends in ipython and in the ordinary python shell, but it does not work in the IDLE IDE. If the default backend does not support interactivity, an interactive backend can be explicitly activated using any of the methods discussed in What is a backend?.

Showing a few figures without stopping calculations in matplotlib

Hi I would like to show a few figures in matplotlib without stopping calculations. I would like the figure to show up right after the calculations that concern it are finished for example:
import numpy as np
import pylab as py
x=np.linspace(0,50,51)
y=x
fig, axs = plt.subplots(1, 1)
cs = axs.plot(x, y)
now i want to show the plot without blocking the possibility to make some other calculations
plt.show(block=False)
plt.pause(5)
I create the second plot
y1=2*x
fig1, axs1 = plt.subplots(1, 1)
cs1 = axs1.plot(x, y1)
plt.show()
This works however the first freezes (after 5 secound pause which I added) until I call plt.show() at the end. It is crucial that the first figure shows and works, then after calculations another figure is added to it.
The following code should do what you want. I did this in an IPython Notebook.
from IPython import display
import matplotlib.pyplot as plt
def stream_plot(iterable, plotlife=10.):
for I in iterable:
display.clear_output(wait=True)
output = do_calculations_on_i(I)
plt.plot(output)
display.display(plt.gca());
time.sleep(plotlife); #how long to show the plot for
the wait=True will wait to clear the old plot until it has something new to plot, or any other output is printed.
I put the sleep in there so I can observe each plot before it is wiped away. This was useful for having to observe distributions for several entities. You may or may not need it for what you want to do.

Updating a plot in python's matplotlib

I'm trying to plot streaming data in matplotlib. I can update the plot using interactive mode and the set_ydata function. It animates and everything looks good until the loop ends. Then the python kernel crashes and I get this message:
C:\Conda\lib\site-packages\matplotlib\backend_bases.py:2437:
MatplotlibDeprecationWarning: Using default event loop until function specific to
this GUI is implemented
warnings.warn(str, mplDeprecation)
Here's the code:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 10, 0.1)
y = np.sin(x)
plt.ion() #interactive mode on
ax = plt.gca()
line, = ax.plot(x,y)
ax.set_ylim([-5,5])
for i in np.arange(100):
line.set_ydata(y)
plt.draw()
y = y*1.01
plt.pause(0.1)
Can anyone tell me why this is crashing instead of just exiting the loop? I'm doing this in Jupyter with Python 3. And of course, if there's a better way to do this, I would love to hear about it. Thanks!
This code was adapted from How to update a plot in matplotlib?
It works well for me with mac_osx backend from Jupyter notebook in python 3.4.
Maybe you want to add plt.close() at the end to keep things tidy and prevent a hang up?

Live plotting on bloch sphere

I am trying to plot live data on a bloch sphere using Qutip's function bloch().
So far, the code always interrupts, when I have a b.show() in there.
I found a lot of solutions online to similar problems, but most of them make use of direct matplotlib commands like matplotlib.draw() which doesn't seem to work with the bloch class.
Then, there are other solutions which make use of for example Tk or GTKagg (e.g. https://stackoverflow.com/a/15742183/3276735 or real-time plotting in while loop with matplotlib)
Can somebody please help me how to deal with the same problem in the bloch class?
Edit:
Here's a minimal example:
Basically, I want to update my plot with one point at a time, preferably in a loop. My goal is to display live data in the plot that has to be read from a file.
import qutip as qt
import numpy as np
b = qt.Bloch()
theta = np.arange(0,np.pi,0.1)
for ii in range(len(theta)):
b.add_points([np.sin(theta[ii]),0,np.cos(theta[ii])])
b.show()
I think you are breaking your plot because you are calling show for every point. Try calling show outside the loop (in the end).
import qutip as qt
import numpy as np
b = qt.Bloch()
theta = np.arange(0,np.pi,0.1)
for ii in range(len(theta)):
b.add_points([np.sin(theta[ii]),0,np.cos(theta[ii])])
b.show() # Changed here
EDIT: Animated plot
Consider show as an absolute command to call the plot into view. It's not a draw command (or redraw). If you do want to show an image every "n" seconds or so you'll need to clear the plot before calling it again. You may try this:
import qutip as qt
import numpy as np
b = qt.Bloch()
theta = np.arange(0,np.pi,0.1)
for ii in range(len(theta)):
b.clear()
b.add_points([np.sin(theta[ii]),0,np.cos(theta[ii])])
b.show()
# wait time step and load new value from file.
, I don't have QuTip in my current distribution so I can't really test it but I'm betting its heavily based in matplotlib. My best advise however is for you to use the formulation give for animation in the QuTiP docs. By following this recipe:
from pylab import *
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
fig = figure()
ax = Axes3D(fig,azim=-40,elev=30)
sphere=Bloch(axes=ax)
def animate(i):
sphere.clear()
sphere.add_vectors([sin(theta),0,cos(theta)])
sphere.add_points([sx[:i+1],sy[:i+1],sz[:i+1]])
sphere.make_sphere()
return ax
def init():
sphere.vector_color = ['r']
return ax
ani = animation.FuncAnimation(fig, animate, np.arange(len(sx)),
init_func=init, blit=True, repeat=False)
ani.save('bloch_sphere.mp4', fps=20, clear_temp=True)
, you should be able to modify the animate function to perform all operations you need.

Categories

Resources