【问题标题】:Matplotlib FuncAnimation not displaying any frames until animation is completeMatplotlib FuncAnimation 在动画完成之前不显示任何帧
【发布时间】:2020-10-04 11:38:48
【问题描述】:

我正在尝试使用 matplotlib 的 FuncAnimation 为绘图设置动画,但是在动画到达最后一帧之前,动画的帧是不可见的。如果我设置repeat = True,则不会显示任何内容。当我第一次运行代码时,出现一个 matplotlib 图标 但当我点击它时什么都没有显示,直到它显示最后一帧:

如果我保存动画,我会正确看到动画显示,因此这让我认为我的代码大部分是正确的,所以我希望这是一个我只是缺少的简单修复。

抱歉,如果我倾倒了太多代码,但我不确定是否有任何东西不需要最小可重现示例。

这是主要代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from quantum_custom.constants import spin_down, spin_up, H00, H11, H
import quantum_custom.walk as walk

class QuantumState:
    def __init__(self, state):
        self.state = state

#"coin flips"
max_N = 100 #this will be the final number of coin flips
positions = 2*max_N + 1

#initial conditions
initial_spin = spin_down
initial_position = np.zeros(positions)
initial_position[max_N] = 1
initial_state = np.kron(np.matmul(H, initial_spin), initial_position) #initial state is Hadamard acting on intial state, tensor product with the initial position
quantum_state = QuantumState(initial_state)

#plot the graph
fig, ax = plt.subplots()
plt.title("N = 0")
x = np.arange(positions)
line, = ax.plot([],[])

loc = range(0, positions, positions // 10)
plt.xticks(loc)
plt.xlim(0, positions)
plt.ylim((0, 1))

ax.set_xticklabels(range(-max_N, max_N + 1, positions // 10))
ax.set_xlabel("x")
ax.set_ylabel("Probability")

def init():
    line.set_data([],[])
    return line,

def update(N):
    next_state = walk.flip_once(quantum_state.state, max_N)
    probs = walk.get_prob(next_state, max_N)
    quantum_state.state = next_state
    start_index = N % 2 + 1
    cleaned_probs = probs[start_index::2]
    cleaned_x = x[start_index::2]
    line.set_data(cleaned_x, cleaned_probs)
    if cleaned_probs.max() != 0:
        plt.ylim((0, cleaned_probs.max()))
    plt.title(f"N = {N}")
    return line,


anim = animation.FuncAnimation(
    fig, 
    update,
    frames = max_N + 1,
    init_func = init,
    interval = 20,
    repeat = False,
    blit = True,
    )

anim.save("animated.gif", writer = "ffmpeg", fps = 15)

plt.show()

这是我的quantum_custom.constants 模块。

#define spin up and spin down vectors as standard basis
spin_up = np.array([1,0])
spin_down = np.array([0,1])

#define our Hadamard operator, H, in terms of ith, jth entries, Hij
H00 = np.outer(spin_up, spin_up)
H01 = np.outer(spin_up, spin_down)
H10 = np.outer(spin_down, spin_up)
H11 = np.outer(spin_down, spin_down)
H = (H00 + H01 + H10 - H11)/np.sqrt(2.0) #matrix representation of Hadamard gate in standard basis

这是我的quantum_custom.walk 模块。

import numpy as np
from quantum_custom.constants import H00, H11, H

#define walk operators

def walk_operator(max_N):
    position_count = 2 * max_N + 1
    shift_plus = np.roll(np.eye(position_count), 1, axis = 0)
    shift_minus = np.roll(np.eye(position_count), -1, axis = 0)
    step_operator = np.kron(H00, shift_plus) + np.kron(H11, shift_minus)
    return step_operator.dot(np.kron(H, np.eye(position_count)))


def flip_once(state, max_N):
    """
    Flips the Hadamard coin once and acts on the given state appropriately.
    Returns the state after the Hadamard coin flip.
    """
    walk_op = walk_operator(max_N)
    next_state = walk_op.dot(state)
    return next_state

def get_prob(state, max_N):
    """
    For the given state, calculates the probability of being in any possible position.
    Returns an array of probabilities.
    """
    position_count = 2 * max_N + 1
    prob = np.empty(position_count)
    for k in range(position_count):
        posn = np.zeros(position_count)
        posn[k] = 1
        posn_outer = np.outer(posn, posn)
        alt_measurement_k = eye_kron(2, posn_outer)
        proj = alt_measurement_k.dot(state)
        prob[k] = proj.dot(proj.conjugate()).real       
    return prob

def eye_kron(eye_dim, mat):
    """
    Speeds up the calculation of the tensor product of an identity matrix of dimension eye_dim with a given matrix.
    This exploits the fact that majority of values in the resulting matrix will be zeroes apart from on the leading diagonal where we simply have copies of the given matrix.
    Returns a matrix.
    """
    mat_dim = len(mat)
    result_dim = eye_dim * mat_dim #dimension of the resulting matrix
    result = np.zeros((result_dim, result_dim))
    result[0:mat_dim, 0:mat_dim] = mat
    result[mat_dim:result_dim, mat_dim:result_dim] = mat
    return result

我知道保存动画是一种解决方案,但我真的很想通过运行代码来显示绘图,而不是必须保存它。谢谢!

【问题讨论】:

  • this 简单示例的动画是否立即开始?如果是,请尝试添加功能以查看其中断的位置。前段时间我遇到了同样的行为,从来没有发现我做了什么来解决这个问题,也许是一个新的环境
  • 是的,它确实会立即开始。我会按照你的建议继续添加。我的 Windows 是双启动的,所以我也会尝试在它上面运行它,看看这是否会影响任何东西。谢谢你的建议:)
  • 尝试SO中讨论的其他后端
  • 感谢 Sameeresque!使用“TkAgg”作为我的后端解决了我的问题。

标签: python matplotlib animation


【解决方案1】:

根据 Sameeresque 的建议,我尝试为 matplot lib 使用不同的后端。这是通过如下改变 by import 语句来完成的。

import matplotlib
matplotlib.use("tkagg")
import matplotlib.pyplot as plt

请注意,在import matplotlib.pyplot as pltimport matplotlib.pyplot as plt之前添加另外两行很重要,否则它不会做任何事情。

【讨论】:

    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2018-07-14
    • 2013-09-15
    相关资源
    最近更新 更多