I'm new to Python and now studying matplotlib
to use animation function.
I'm following qutip
tutorial because of my study.
But when I copied and pasted example code of qutip
tutorial, it didn't work
Error message was Axes3D object is not iterable
.
So, I want to check the code I created but don't know whether the problem is my code of is other thing.
I don't know what to do and want to know why the example code doesn't work.
This is the example code from the tutorial:
from qutip import *
from scipy import *
def qubit_integrate(w, theta, gamma1, gamma2, psi0, tlist):
sx = sigmax(); sy = sigmay(); sz = sigmaz(); sm = sigmam()
H = w * (cos(theta) * sz + sin(theta) * sx)
c_op_list = []
n_th = 0.5 # temperature
rate = gamma1 * (n_th + 1)
if rate > 0.0: c_op_list.append(sqrt(rate) * sm)
rate = gamma1 * n_th
if rate > 0.0: c_op_list.append(sqrt(rate) * sm.dag())
rate = gamma2
if rate > 0.0: c_op_list.append(sqrt(rate) * sz)
output = mesolve(H, psi0, tlist, c_op_list, [sx, sy, sz])
return output.expect[0], output.expect[1], output.expect[2]
w = 1.0 * 2 * pi # qubit angular frequency
theta = 0.2 * pi # qubit angle from sigma_z axis (toward sigma_x axis)
gamma1 = 0.5 # qubit relaxation rate
gamma2 = 0.2 # qubit dephasing rate
a = 1.0
psi0 = (a* basis(2,0) + (1-a)*basis(2,1))/(sqrt(a**2 + (1-a)**2))
tlist = linspace(0,4,250)
sx, sy, sz = qubit_integrate(w, theta, gamma1, gamma2, psi0, tlist)
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([np.sin(theta),0,np.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)
And this is my own code:
import numpy as np
import qutip as q
import scipy as sp
up=q.basis(2,0)
sx=q.sigmax()
sy=q.sigmay()
sz=q.sigmaz()
bz=0.
by=0.
bx=15.
w=np.pi/20
H=w*(sx*bx+sy*by+sz*bz)
def state(t):
states=[q.Qobj.expm(-(0+1j)*H*t)*up]
return states
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from mpl_toolkits.mplot3d import Axes3D
fig=plt.figure()
ax=Axes3D(fig,azim=-40,elev=30)
sphere=q.Bloch(axes=ax)
sphere.add_states(up)
def ini():
sphere.vector_color=("r")
return ax
t=np.linspace(0,1,256)
def animate(i):
sphere.clear()
sphere.add_states(state[i])
return ax
ani.FuncAnimation(fig,animate,frames=len(t),init_func=ini,blit=True,repeat=False)
plt.show()
Remove the blit
argument to make the tutorial work:
ani = animation.FuncAnimation(fig, animate, np.arange(len(sx)),
init_func=init, repeat=False)
plt.show()
ani.save('bloch_sphere.mp4', fps=20)
frames
must be iterable.
Change:
frames=len(t)
into:
frames=t
I.e., this line:
ani.FuncAnimation(fig, animate, frames=len(t), init_func=ini, blit=True, repeat=False)
should become this:
ani.FuncAnimation(fig, animate, frames=t, init_func=ini, blit=True, repeat=False)
A few more changes.
state(i)
not with square brackets state[i]
ani = ani.FuncAnimation
Full code:
def animate(i):
sphere.clear()
sphere.add_states(state(i))
sphere.make_sphere()
return ax
ani = ani.FuncAnimation(fig, animate, frames=t, init_func=ini, repeat=False)
plt.show()
This is the end state of the animation:
In addition to removing the blit=True
argument, I also had to change the writer string value to "ffmpeg" (and of course installing the ffmpeg package, also installed the opencv package via pip but not sure it was required).
anim.save(name + '.mp4', fps=10, writer="ffmpeg", codec=codec)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With