Modify line / plot in IPython notebook "interact" - python

Is there a way to modify the plot inside IPython "interact" function rather than replotting it?
In case when the plot contains a lot of heavy graphics (or some parts require heavy calculations) it would be much faster than doing the plot from the scratch.
I'm trying the following code, but it does not work: after changing the slider the whole plot becomes blank.
%matplotlib inline
import matplotlib.pyplot as plt
from IPython.html.widgets import interact
import numpy as np
x = np.arange(0,11.)
y1 = x / 10.
y2 = np.random.rand(len(x))
plt.plot(x,y1)
plt.plot(x,y2)
plt.ylim([0,1])
ax = plt.gca()
def replot_it(a):
ax.lines.pop(1)
y = (x/10.)**a
ax.plot(x,y)
interact(replot_it, a=(0.,5.))
I would appreciate any suggestions.

If you have IPython > 3.0 and mpl > 1.4: run this is one cell:
%matplotlib notebook
import matplotlib.pyplot as plt
from IPython.html.widgets import interact
import numpy as np
x = np.arange(0,11.)
y1 = x / 10.
y2 = np.random.rand(len(x))
fig, ax = plt.subplots()
ln1, = ax.plot(x,y1)
ln2, = ax.plot(x,y2)
ax.set_ylim([0,1])
def replot_it(a):
y = (x/10.)**a
ln2.set_ydata(y)
ax.figure.canvas.draw()
and
interact(replot_it, a=(0.,5.))
in the cell below it.

Related

How to solve Axes3D error when plotting a function?

I have a code to graph mi function f(x,y)=(x^4 + y^4). I already imported all the necessary libraries, but when i run it, the "MatplotlibDeprecationWarning: Axes3D(fig) adding itself to the figure is deprecated since 3.4. Pass the keyword argument auto_add_to_figure=False and use fig.add_axes(ax) to suppress this warning. The default value of auto_add_to_figure will change to False in mpl3.5 and True values will no longer work in 3.6. This is consistent with other Axes classes." error shows.
This is my code:
`
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
figura = plt.figure()
ejes = Axes3D(figura)
plt.show()
def f(x,y):
return ((x**4)+(y**4))
x = np.linspace(-2,2,40)
y = np.linspace(-2,2,40)
x,y = np.meshgrid(x,y)
z= f(x,y)
ejes.plot_wireframe(x,y,z)
`
On my environment it actually works. Anyway you can obtain the same plot using the "3d" projection of pyplot:
import numpy as np
import matplotlib.pyplot as plt
figura = plt.figure(figsize=(7,7))
ejes = plt.subplot(111, projection="3d")
def f(x,y):
return ((x**4)+(y**4))
x = np.linspace(-2,2,40)
y = np.linspace(-2,2,40)
x,y = np.meshgrid(x,y)
z= f(x,y)
ejes.plot_wireframe(x,y,z)
plt.show()

How to draw 3D dynamic curve with python

I continue to output three-dimensional coordinates, and use these coordinates to output three-dimensional dynamic curves. Here is my code, but there is nothing in the figure.
plt.ion()
x = [0]
y = [0]
z = [0]
x_now = 0
fig = plt.figure()
ax1 = plt.axes(projection='3d')
for i in range(50):
plt.clf()
x_now = i * 1
x.append(x_now)
y.append(x_now)
z.append(x_now)
ax1.scatter3D(x, y, z)
plt.show()
plt.pause(0.1)
plt.clf() will clear the figure.
import matplotlib.pyplot as plt
x = [0]
y = [0]
z = [0]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
for i in range(5):
x_now = i * 1
x.append(x_now)
y.append(x_now)
z.append(x_now)
ax.scatter(x, y, z)
plt.pause(0.1)
plt.show()
Where do you launch this script? If it is jupyter-notebook, add this line on top:
%matplotlib inline
If you are using jupyter-console, it will be
%matplotlib <backend>
where <backend> is one of ('osx', 'qt4', 'qt5', 'gtk3', 'notebook', 'wx', 'qt', 'nbagg).
If it is a regular script, first you should do:
import matplotlib
matplotlib.use('<backend>') #in quotes
where <backend> is:
- interactive backends:
GTK3Agg, GTK3Cairo, MacOSX, nbAgg,
Qt4Agg, Qt4Cairo, Qt5Agg, Qt5Cairo,
TkAgg, TkCairo, WebAgg, WX, WXAgg, WXCairo
- non-interactive backends:
agg, cairo, pdf, pgf, ps, svg, template
Then you are importing:
import matplotlib.pyplot as plt
and go on with your script.

Plotly plot_trisurf isn't working with arange arrays

I've basically just copied the example code found on the Matplotlib website, but I replaced their radii and angles with simple arange arrays.
I've tried different array functions and I can't seem to figure out anything.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from Equation import Expression
x = np.arange(0,100,0.01)
y = np.arange(0,100,0.01)
x2 = np.append(0,x.flatten())
y2 = np.append(0,y.flatten())
z = x2 + y2
print(z)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(x, y, z, linewidth=0.2, antialiased=True)
plt.show()
I'm just trying to make a graph of z = x + y but I'm getting a confusing error.
"RuntimeError: Error in qhull Delaunay triangulation calculation: singular input data (exitcode=2); use python verbose option (-v) to see original qhull error."
Edit: I've also tried it without calling flatten() but I get the same result though.
The error you are getting is because your z is not a surface but a line. You need to use at least 3 points that would define a plane. One option could be to use np.meshgrid to create your surface for plotting and then flatten everything to insert into the function. Try going back to some example code here. Note you may also want to change your resolution depending on the detail of your surface.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0,100,1)
y = np.arange(0,100,1)
x2 = np.append(0,x.flatten())
y2 = np.append(0,y.flatten())
x2,y2 = np.meshgrid(x2,y2) #This is what you were missing
z = x2 + y2
fig = plt.figure(figsize=(12,12))
ax = fig.gca(projection='3d')
ax.plot_trisurf(x2.flatten(), y2.flatten(), z.flatten(), linewidth=0.2, antialiased=True) #flatten all the arrays here
plt.show()

Contourf animation

I am using a for loop to calculate values at every node of 20x20 matrix and storing data in
MM = []
I want to animate the results and my code looks like this:
ax = plt.subplot(111)
for i in range(60):
x = MM[i]
ax.contourf(X,Y,x, cmap = cm.hot)
plt.draw()
plt.show()
The problem is that it shows only MM[-1].
I have looked over the examples given here, but can't figure out how to make it work.
Thank you.
Your problem is likely due how you are running Matplotlib and what graphical backend you are using. The following example works in IPython. Note that I call ion() to set the interactive mode to on.
from matplotlib import pyplot as plt
import numpy as np
x = y = np.arange(-3.0, 3.01, 0.025)
X, Y = np.meshgrid(x, y)
plt.ion()
ax = plt.subplot(111)
for i in range(1,20):
Z1 = plt.mlab.bivariate_normal(X, Y, 0.5+i*0.1, 0.5, 1, 1)
ax.contourf(x,y,Z1, cmap = plt.cm.hot)
plt.draw()
plt.show()
The information here should help you get your animation running.

Strange behavior of matplotlib's griddata

I have a .txt file with values
x1 y1 z1
x2 y2 z2
etc.
With my previous little experience I was trying to draw a contourf, with this code
import numpy as np
import matplotlib
from matplotlib import rc
import matplotlib.mlab as ml
from pylab import *
rc('font', family='serif')
rc('font', serif='Times New Roman')
rc('font', size='9')
rc('text', usetex=True)
from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
import numpy.ma as ma
from numpy.random import uniform
from matplotlib.colors import LogNorm
matplotlib.use('pgf')
fig = plt.figure()
data = np.genfromtxt('Velocidad.txt')
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
rc('text', usetex=True)
rc('font', family='serif')
x = data[:,0]
y = data[:,1]
z = data[:,2]
xi = np.linspace(0,3000.0, 400)
yi = np.linspace(0,4.0, 200)
zi = griddata(x,y,z,xi,yi,interp='nn')
CS = plt.contourf(xi,yi,zi,200,cmap=plt.cm.jet,rasterized=True)
plt.colorbar()
plt.xlim(0,3000)
plt.ylim(0,4.0)
plt.ylabel(r'$t$')
plt.xlabel(r'$x$')
plt.title(r' Contour de $v(x,t)$')
plt.savefig("CampoVel.png", dpi=100)
plt.show()
the problem is the output:
When I see this picture and I look at the data (which is here, in this link) and I don't understand those discontinuities in x=750 and x=1875. And those strange vertical lines all over the plot. Looking at the data I would expect something smooth, at least in those positions, but the output obviously isn't. Is this a problem of griddata()? How can I solve it?
I have been told that as my data is regularly spaced on X and Y, I shouldn't use griddata(), but I have looked examples and I can't get the code to work.
If you simply reshape your data after loading it and skip the griddata thing, doing this:
data = data.reshape(81, 201, 3)
x = data[...,0]
y = data[...,1]
z = data[...,2]
CS = plt.contourf(x,y,z,200,cmap=plt.cm.jet,rasterized=True)
plt.colorbar()
plt.show()
You get this:

Categories