Automatically updated graph in jupyter notebook using qt5 - python

how to do this in jupyter notebook:
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
m = 100
n = 100
matrix = np.random.normal(0,1,m*n).reshape(m,n)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
fig.show()
fig.canvas.draw()
for i in range(0,100):
#ax.clear()
plt.plot(matrix[i,:])
fig.canvas.draw()
but using "%matplotlib qt5" instead of "notebook"?
When I try it it show the figure only after the loop is ended. I would like to see it updating every plot.

In principle you can do the following in interactive mode:
%matplotlib qt4
import numpy as np
import matplotlib.pyplot as plt
m = 100
n = 100
matrix = np.random.normal(0,1,m*n).reshape(m,n)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
plt.draw()
for i in range(0,30):
#ax.clear()
plt.plot(matrix[i,:])
plt.draw()
plt.pause(0.1)
plt.ioff()
plt.show()
However, it might crash in jupyter after finishing the loop, due to Qt being used.
It should however work, when using the tk backend, %matplotlib tk.
You might want to consider using a FuncAnimation instead of interactive mode. While this would suffer from the same limitations with Qt in Jupyter I find it more intuitive to use a function for updating the plot and there is no need to redraw the canvas manually.
%matplotlib tk
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation
m = 100
n = 100
matrix = np.random.normal(0,1,m*n).reshape(m,n)
fig = plt.figure()
ax = fig.add_subplot(111)
def update(i):
#ax.clear()
plt.plot(matrix[i,:])
ani = matplotlib.animation.FuncAnimation(fig, update, frames=30, repeat=False)
plt.show()
I asked a new question on why this would no work with the qt backend.

Related

VS Code jupyter notebook matplotlib plot directly in plot viewer?

Is it possible to have a matplotlib plot directly displayed in the plot viewer? I am currently working in VS Code on a juptyer notebook, both recently installed/updated. By default, the plot would open inline, like any other result of a cell, and I can open that in the plot viewer by clicking the icon in the top-left corner. Is it possible to have it displayed directly in the plot viewer, without the need to open it manually? I am just trying with something basic, like:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
ax.plot(x, y)
Thank you!
Add %matplotlib qt to your code before creating the figure/axes instances
import matplotlib.pyplot as plt
import numpy as np
%matplotlib qt
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
ax.plot(x, y)

Matplotlib figure is not updating with ipywidgets slider

I have the following code to generate a simple graph.
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, np.sin(x))
def update(w = 1.0):
line.set_ydata(np.sin(w * x))
plt.show()
interact(update)
The code generates the plot just fine -
output
But when I drag the slider, the figure will not update. Any ideas on why this is?
Note: Your code actually works for me out of the box, so it may be worth updating your dependencies and see if that fixes it.
However, the main thing you want to change is to call fig.canvas.draw() instead of plt.show()
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, np.sin(x))
def update(w = 1.0):
line.set_ydata(np.sin(w * x))
fig.canvas.draw()
interact(update)
Using Ipympl
There is also a widget based notebook backend (that will also work in jupyterlab): ipympl which you can install with pip install ipympl and use with %matplotlib ipympl
In general the ipympl backend will work better with other widgets than the notebook backend.
using interactive with matplotlib
One unfortunate consequence of interactive is that it assumes the output will be fully regenerated every time the slider value changes. This doesn't always play super nicely with the set_data methods you are using. So you are likely better off manually generating and connecting the sliders. I'll also note that I've written a package that automates using the set_data command to connect widgets to updating matplotlib plots: https://mpl-interactions.readthedocs.io/en/stable/. With that package your code would be
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import mpl_interactions.ipyplot as iplt
x = np.linspace(0, 2 * np.pi, 1000)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
def f(x, w):
return np.sin(w * x)
controls = iplt.plot(x, f, w=(1, 10))
This would do a job.
# load the interactive tool
from ipywidgets import interact, interactive, widgets, fixed
try:
from ipywidgets import Layout
except:
pass
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
def fta(freq = 50.0):
"showing sine frequency"
y = np.sin(freq*x)
f, ax1 = plt.subplots(nrows=1,figsize=(8,6))
ax1.plot(x[0:100], y[0:100],'b')
ax1.set_ylim(ymin=-1.1, ymax=1.1)
ax1.grid();
# then use it interactively,
interactive( fta, freq=(0.0,100.0))

Most efficient way to generate many figures with matplotlib

I need to generate and save thousands of scatter plots which are essentially the same except the only thing that changes is the "y" variable. What is the fastest way to do this?
I thought about creating the Figure and Axes instance and simply clearing then between plots like this:
import matplotlib.pyplot as plt
import numpy as np
data = np.random.random((100, 1000))
x = list(range(100))
fig = plt.figure()
ax = fig.add_subplot(111)
for i in range(data.shape[1]):
ax.scatter(x, data[:,i])
fig.savefig("%d.png" % i, dpi=100)
ax.cla()
This still takes an decent amount of time, so is a better/faster way to do this? Each image in this example is about 15kb so I'm assuming writing to disk is not limiting the speed too much.
One option is to use multiple processes.
import matplotlib.pyplot as plt
import numpy as np
import multiprocessing
data = np.random.random((100, 1000))
x = list(range(100))
fig = plt.figure()
ax = fig.add_subplot(111)
def save_plot(i):
ax.scatter(x, data[:,i])
fig.savefig("%d.png" % i, dpi=100)
ax.cla()
p = multiprocessing.Pool(4)
p.map(save_plot, range(data.shape[1]))
Try creating your figures without the GUI. I find that much faster when creating and saving many figures.
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
fig = plt.Figure()
ax = fig.add_subplot(111)
ax.plot(range(5))
canvas = FigureCanvas(fig)
canvas.print_figure('sample.png')
Something similar can be found at http://www.dalkescientific.com/writings/diary/archive/2005/04/23/matplotlib_without_gui.html

Plots that varies over the time on Python Matplotlib with Jupyter

In the following lines I report a code that generates a plot changing over the time with Python on Anaconda Spyder
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-3, 3, 0.01)
N = 1
fig = plt.figure()
ax = fig.add_subplot(111)
for N in range(8):
y = np.sin(np.pi*x*N)
line, = ax.plot(x, y)
plt.draw()
plt.pause(0.5)
line.remove()
I would like to do the some with Jupyter, but it is not possible. Particularly it seems that the Matplotlib method .pause() does not exist on Jupyter.
Is there anyone who can explain me this difference and can help me building up a code for plots variating over the time with Python on Jupyter, please?
It works for me if I select an interactive backend using the magic command %matplotlib; it is likely that your Jupyter notebook settings are set to display plots inline.
import matplotlib.pyplot as plt
import numpy as np
%matplotlib
x = np.arange(-3, 3, 0.01)
N = 1
fig = plt.figure()
ax = fig.add_subplot(111)
for N in range(8):
y = np.sin(np.pi*x*N)
line, = ax.plot(x, y)
plt.draw()
plt.pause(0.5)
line.remove()
To restore your setings, use the magic %matplotlib inline

Is it possible to speed up interactive IPython Notebook plots by not generating new figures every time?

Every example I've seen of using widgets for interactive matplotlib plots in the notebook do something like this (adapted from here):
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from IPython.html.widgets import interact
from IPython.display import display
def sigmoid_demo(a=5,b=1):
x = np.linspace(0,10,256)
s = 1/(1+np.exp(-(x-a)/(b+0.1))) # +0.1 to avoid dividing by 0
sn = 100.0*(s-min(s))/(max(s)-min(s)) # normalize sigmoid to 0-100
# Does this have to be in this function?
fig, ax = plt.subplots(figsize=(24,6))
ax.set_xticks([])
ax.set_yticks([])
plt.plot(x,sn,lw=2,color='black')
plt.xlim(x.min(), x.max())
w=interact(sigmoid_demo,a=5,b=1)
I suspect that the responsiveness of the plot could be sped up hugely if you didn't have to create a brand new figure with plt.subplots() or plt.figure() each time a widget was adjusted.
I've tried a few things to move figure creation outside of the function being called by interact() but nothing has worked.
Some setup:
%matplotlib notebook
import matplotlib.pyplot as plt
from IPython.html.widgets import interactive
from IPython.display import display
import numpy as np
Create your objects:
fig, ax = plt.subplots()
ax.set_xlim(0, .25)
ax.set_ylim(-2.5, 2.5)
ax.set_title('beat frequencies')
lnA, = ax.plot([], [], color='r', label='A')
lnB, = ax.plot([], [], color='purple', label='B')
lnsum, = ax.plot([], [], color='k', label='signal')
ax.legend()
max_time = 3
rate = 8000
times = np.linspace(0,max_time,rate*max_time)
def beat_freq(f1=220.0, f2=224.0):
A = np.sin(2*np.pi*f1*times)
B = np.sin(2*np.pi*f2*times)
sig = A + B
lnA.set_data(times, A)
lnB.set_data(times, B)
lnsum.set_data(times, sig)
plt.draw()
beat_freq(0, 0)
and the interactive (which I think needs to go in it's own cell)
interactive(beat_freq, f1=(200.0,300.0), f2=(200.0,300.0))
You can also poke at the objects from a different cell:
ax.set_xlim(0, .05)
ax.set_ylim(-2, 2)
plt.draw()
or
lnB.set_color('g')
ax.legend()
plt.draw()

Categories

Resources