【问题标题】:python animation.FuncAnimation error : object is not iterablepython animation.FuncAnimation 错误:对象不可迭代
【发布时间】:2017-06-29 22:36:48
【问题描述】:

我是 Python 新手,现在正在学习 matplotlib 以使用动画功能。 由于我的学习,我正在关注qutip 教程。 但是当我复制并粘贴qutip教程的示例代码时,它不起作用 错误消息是 Axes3D object is not iterable
所以,我想检查我创建的代码,但不知道问题是否出在我的代码上。 我不知道该怎么办,想知道为什么示例代码不起作用。

这是教程中的示例代码:

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)

这是我自己的代码:

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

【问题讨论】:

  • 您能否首先在动画调用中设置blit=False,如果这解决了问题,请报告回来?!在报告错误时,重要的是包含完整的回溯,以便人们知道错误来自哪里。您可以edit您的问题将其包含在内。

标签: python python-2.7 matplotlib qutip


【解决方案1】:

修复教程

删除 blit 参数以使教程正常工作:

ani = animation.FuncAnimation(fig, animate, np.arange(len(sx)),
                               init_func=init,  repeat=False)
plt.show()
ani.save('bloch_sphere.mp4', fps=20)

修正你的例子

frames 必须是可迭代的。

变化:

frames=len(t)

进入:

frames=t

即这一行:

ani.FuncAnimation(fig, animate, frames=len(t), init_func=ini, blit=True, repeat=False)

应该变成这样:

ani.FuncAnimation(fig, animate, frames=t, init_func=ini, blit=True, repeat=False)

还有一些变化。

  1. 用副合成state(i)而不是方括号state[i]调用你的函数
  2. 保留对动画ani = ani.FuncAnimation的引用

完整代码:

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

这是动画的结束状态:

【讨论】:

  • 很好的答案,但是这里的 blit 语句有什么问题?为什么会导致错误?
  • 在回答为什么 blit=True 不起作用时,return ax 应该是一个元组,只需添加一个 , 它就会起作用:return ax, 它会快一个数量级。 ...
猜你喜欢
  • 2013-07-02
  • 2017-06-22
  • 2014-10-09
  • 2017-03-22
  • 2020-03-08
  • 2013-06-03
  • 2020-04-18
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多