How to update mayavi interactively in ipython notebook? - python

I've been trying to create an interactive 3d plot in jupyter notebook.This worked great with matplotlib. Unfortunately matplotlib is very unfit to display intersecting planes. Therefore I wanted to switch to mayavi.
However mayavi shows some weird behaviour when I try to interactively change its values. Running the following Code:
%matplotlib notebook
#math
import numpy as np
#plotting
from mayavi import mlab
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from IPython import display
import time
mlab.init_notebook()
X = np.arange(-5, 5, 0.3)
Y = np.arange(-5, 5, 0.3)
X,Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
mlab.clf()
#plot setup
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
def foo(x, y):
display.clear_output()
ax.cla()
#generate plots
ax.pcolor(X,Y,R,cmap='Blues')
ax.plot(x, y, 'ro')
mlab.mesh(X + x,Y,R, colormap='Blues')
#display plots
display.display(plt.gcf())
display.display(mlab.gcf())
def op_on_click(event):
foo(event.xdata, event.ydata)
foo(3,0)
time.sleep(10)
foo(10,0)
fig.canvas.mpl_connect('button_press_event', op_on_click)
It will immediately display the mayavi plot and update it after 10 seconds (as expected). But it does not redraw when the on_click event of the matplotlib figure is triggered.
Running it without mlab.clf() shows that the meshes actually get generated, the plot just doesnt get redrawn.
Any help on how to make it react to the on_click would be very appreciated.

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))

How to animate zoom in a 3d scatterplot in matplotlib

I am a student and I am new to matplotlib animation.
I am trying to figure out how to animate zooming in towards the center of my 3d scatterplot, and I've included my code below. I am trying to get the zeroes to be at the middle of each axis so I am able to see the overall plot as a zoom in. I don't get an error whenever I run my code but when I run the animation the intervals change abruptly and don't seem to go in a certain pattern. Another thing I've noticed is that the zeroes are only sometimes in the middle of the axis, while the plot "glitches out".
Thank You.
import matplotlib.pylab as plt
import matplotlib.animation as animation
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
%matplotlib notebook
x = np.random.rand(100)*100
y = np.random.rand(100)*100
z = np.random.rand(100)*100
#setup figure
fig = plt.figure()
ax = fig.add_subplot(111, facecolor='LightCyan', projection = '3d')
#set up viewing window (in this case the 25 most recent values)
ax.set_xlim([-1, 1])
ax.set_ylim([-1,1])
ax.set_zlim([-1,1])
#sets up list of images for animation
plot = ax.scatter(x, y, z, color='b', marker= '*',)
def func(i):
x_lim = ax.set_xlim(-i,i)
y_lim = ax.set_ylim(-i, i)
z_lim = ax.set_zlim(-i, i)
return plot
ani = animation.FuncAnimation(fig, func, frames=100, interval=1000, blit=True)

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

Matplotlib does not display interactive graph in Ipython

I am trying to plot a 3D scatter plot with matplotlib from IPython. I am able to make a plot when I use the inline magic command as follows
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
y = np.arange(10)
x = np.arange(10)
z = np.arange(10)
plt.figure()
ax = plt.axes(projection='3d')
ax.scatter(x,y,z)
But because the plot is inline, it is not interactive and I can not rotate it to the viewing angle I want. When I replace the inline command with
%matplotlib
I get
<mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fb80bf40358>
as output, but no window or graph appears. If I add
plt.show()
to the end of the script, nothing happens. How do I plot an interactive graph in IPython?
You may want to use pylab to get rid of most imports and all the namespaces:
%pylab
from mpl_toolkits.mplot3d import Axes3D
y = rand(100)
x = rand(100)
z = rand(100)
ax = subplot(projection='3d')
ax.scatter(x, y, z)
See https://plot.ly/ for interactive inline plots.

Categories

Resources