如何在此代码中更新每个框架中的文本?

时间:2019-03-06 13:57:09

标签: python-3.x matplotlib animation

我已经在Python上编写了一个代码,用于将Cicle上的“ Stereographic Projection”动画化为Real行。我定义了三个函数,分别为update_plot()update_texts()create_animation()。(如下面的代码所示)。现在出于动画目的,我必须在animation.FuncAnimation()中传递前两个函数。因此,我尝试创建并清空名为anim = []append()两个动画对象的列表。现在,与功能update_plot()对应的动画是可以的,但是update_texts()并没有按我预期的那样工作。实际上,我想更新每一帧中的点(R_x, R_y)(根据update_text的定义)的坐标。

我不明白如何解决此问题。请帮忙。谢谢。

我还附上了下面代码输出的瞬间图片。

我的代码:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation

W = 3
H = 1.2


mpl.rc('text', usetex=True)
mpl.rc('font', family='serif')

plt.style.use(['ggplot', 'dark_background'])


def create_circle(x, y):
    circle = plt.Circle((x, y), radius=1, fill=False,
                        edgecolor='skyblue', lw=2)
    return circle


def stereo_project(p):
    x = p[0]
    y = p[1]

    # transformation
    x1 = x / (1 - y)
    y1 = 0

    return x1, y1


def rotate(p, angle):
    vec = np.array([p[0], p[1]]).reshape(2, 1)

    theta = angle
    R = np.array([[np.cos(theta), -np.sin(theta)],
                  [np.sin(theta), np.cos(theta)]])

    point = R.dot(vec)

    return point[0][0], point[1][0]


def update_plot(angle, plot, plot1, plot2, plot3):
    p = (0, 1)
    R_x, R_y = rotate(p, angle)
    SR_x, SR_y = stereo_project((R_x, R_y))
    x = [p[0], R_x]
    y = [p[1], R_y]
    x1 = [R_x, SR_x]
    y1 = [R_y, SR_y]
    plot.set_data(x, y)
    plot1.set_data(x1, y1)
    plot2.set_data([R_x], [R_y])
    plot3.set_data([SR_x], [SR_y])

    return plot, plot1


def update_texts(angle):
    p = (0, 1)
    R_x, R_y = rotate(p, angle)
    plt.text(R_x, R_y, '$({0:.2f}, {1:.2f})$'.format(R_x, R_y),
             horizontalalignment='right',
             verticalalignment='center', fontsize=15, color='orange')



def create_animation():

    fig = plt.figure()
    ax = plt.axes(xlim=(-W, W), ylim=(-H, H))

    plot = plt.plot([], [], '-o', markersize=5, color='c')[0]
    plot1 = plt.plot([], [], '-o', markersize=5, color='c')[0]
    plot2 = plt.plot([], [], '-o', markersize=5, color='m')[0]
    plot3 = plt.plot([], [], '-o', markersize=5, color='lime')[0]


    ax.set_aspect('equal')
    circle = create_circle(0, 0)
    ax.add_patch(circle)

    l1 = [-3, 3]
    l2 = [0, 0]
    plt.plot(l1, l2)

    title = 'Stereographic Projection: $\mathbf{S^{1}} \setminus \{(0, 1)\}$ ' \
            'to $\mathbf{R}$'
    plt.title(title, color='orange', y=1.09)
    plt.grid(False)
    plt.gca().spines['left'].set_visible(False)
    plt.gca().spines['top'].set_visible(False)
    plt.gca().spines['right'].set_visible(False)
    plt.gca().spines['bottom'].set_visible(False)
    plt.gca().set_xticks([])
    plt.gca().set_yticks([])

    anim = []
    anim.append(animation.FuncAnimation(fig, update_plot,
                                        fargs=(plot, plot1, plot2, plot3),
                                        frames=np.arange(0, 2 * np.pi, 0.01),
                                        interval=50, repeat=True))

    anim.append(animation.FuncAnimation(fig, update_texts,
                                        frames=np.arange(0, 2 * np.pi, 0.01),
                                        interval=50, repeat=True))



    plt.show()


if __name__ == '__main__':

    create_animation()

输出。 Output

1 个答案:

答案 0 :(得分:1)

文本是artist,因此您可以像其他任何artist一样对其进行动画处理。

因此,就像您在代码中获得Line2D返回的plt.plot对象的句柄,然后用set_data更新行一样,您也可以获取{{由text创建的实例1}},并使用plt.texttext.set_text更新其位置和文本。

我还更改了您的代码,以在单个函数中处理文本和行的更新。

有了这个我

text.set_position