복붙노트

[PYTHON] matplotlib를 사용하여 레이블로 포인트 애니메이트하기

PYTHON

matplotlib를 사용하여 레이블로 포인트 애니메이트하기

선이있는 애니메이션이 생겼으니 점에 레이블을 붙이고 싶습니다. plt.annotate () 시도하고 plt.text () 시도했지만 labes 이동하지 마십시오. 이것은 나의 예제 코드이다 :

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

def update_line(num, data, line):
    newData = np.array([[1+num,2+num/2,3,4-num/4,5+num],[7,4,9+num/3,2,3]])
    line.set_data(newData)
    plt.annotate('A0', xy=(newData[0][0],newData[1][0]))
    return line,


fig1 = plt.figure()

data = np.array([[1,2,3,4,5],[7,4,9,2,3]])
l, = plt.plot([], [], 'r-')
plt.xlim(0, 20)
plt.ylim(0, 20)
plt.annotate('A0', xy=(data[0][0], data[1][0]))
# plt.text( data[0][0], data[1][0], 'A0')

line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
    interval=200, blit=True)
plt.show()

도와 줄수있으세요?

다음 단계는 다음과 같습니다. 나는이 점에 기원을 둔 벡터를 가지고있다. 이 벡터들은 각 애니메이션 단계에서 길이와 방향을 변경합니다. 어떻게 이들을 움직일 수 있습니까?

애니메이션이 없으면 다음과 같이 작동합니다.

soa =np.array( [ [data[0][0],data[1][0],F_A0[i][0][0],F_A0[i][1][0]],
               [data[0][1],data[1][1],F_B0[i][0][0],F_B0[i][1][0]],
               [data[0][2],data[1][2],F_D[i][0][0],F_D[i][1][0]] ])
X,Y,U,V = zip(*soa)
ax = plt.gca()
ax.quiver(X,Y,U,V,angles='xy',scale_units='xy',scale=1)

귀하의 빠르고 매우 유용한 답변에 많은 감사를드립니다!

내 벡터 애니메이션 문제 이것으로 해결했습니다 :

annotation = ax.annotate("C0", xy=(data[0][2], data[1][2]), xycoords='data',
    xytext=(data[0][2]+1, data[1][2]+1), textcoords='data',
    arrowprops=dict(arrowstyle="->"))

그리고 'update-function'에서 나는 다음과 같이 씁니다 :

annotation.xytext = (newData[0][2], newData[1][2])
annotation.xy = (data[0][2]+num, data[1][2]+num)

벡터의 시작과 끝 위치를 변경합니다 (화살표).

하지만 내가 100 개 이상의 벡터를 가지고있을 때 무엇입니까? 다음을 작성하는 것은 현실적이지 않습니다.

annotation1 = ...
annotation2 = ...
    .
    :
annotation100 = ...

나는 목록으로 시험했다 :

...
annotation = [annotation1, annotation2, ... , annotation100]
...

def update(num):
    ...
    return line, annotation

이 오류가 발생했습니다. AttributeError : 'list'객체에 'axes'속성이 없습니다.

내가 무엇을 할 수 있을지? 무슨 생각해?

해결법

  1. ==============================

    1.업데이트 기능에서 변경된 모든 객체가 반환됩니다. 따라서 주석이 위치를 변경했기 때문에 반환해야합니다.

    업데이트 기능에서 변경된 모든 객체가 반환됩니다. 따라서 주석이 위치를 변경했기 때문에 반환해야합니다.

    line.set_data(newData)
    annotation = plt.annotate('A0', xy=(newData[0][0],newData[1][0]))
    return line, annotation
    

    이 튜토리얼에서는 matplotlib 애니메이션에 대해 더 많이 읽을 수 있습니다.

    FuncAnimation이 첫 번째 업데이트에서 다시 그리기 할 때 플롯에서 제거 할 요소를 알고 있도록 init 함수를 지정해야합니다. 그래서 전체 예제는 다음과 같습니다.

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    # Create initial data
    data = np.array([[1,2,3,4,5], [7,4,9,2,3]])
    
    # Create figure and axes
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 20), ylim=(0, 20))
    
    # Create initial objects
    line, = ax.plot([], [], 'r-')
    annotation = ax.annotate('A0', xy=(data[0][0], data[1][0]))
    annotation.set_animated(True)
    
    # Create the init function that returns the objects
    # that will change during the animation process
    def init():
        return line, annotation
    
    # Create the update function that returns all the
    # objects that have changed
    def update(num):
        newData = np.array([[1 + num, 2 + num / 2, 3, 4 - num / 4, 5 + num],
                            [7, 4, 9 + num / 3, 2, 3]])
        line.set_data(newData)
        # This is not working i 1.2.1
        # annotation.set_position((newData[0][0], newData[1][0]))
        annotation.xytext = (newData[0][0], newData[1][0])
        return line, annotation
    
    anim = animation.FuncAnimation(fig, update, frames=25, init_func=init,
                                   interval=200, blit=True)
    plt.show()
    
  2. ==============================

    2.여기서 xy와 xytext를 모두 사용하는 주석을 업데이트해야하는이 질문에서 온 것입니다. 주석을 올바르게 업데이트하려면 주석의 위치를 ​​설정하고 주석의 .set_position () 메소드를 사용하여 주석의 위치를 ​​설정하기 위해 주석의 속성 .xy를 설정해야합니다. . .xytext 속성을 설정하는 것은 아무 효과가 없습니다. 제 생각에는 약간 혼란 스럽습니다. 완전한 예를 들면 다음과 같습니다.

    여기서 xy와 xytext를 모두 사용하는 주석을 업데이트해야하는이 질문에서 온 것입니다. 주석을 올바르게 업데이트하려면 주석의 위치를 ​​설정하고 주석의 .set_position () 메소드를 사용하여 주석의 위치를 ​​설정하기 위해 주석의 속성 .xy를 설정해야합니다. . .xytext 속성을 설정하는 것은 아무 효과가 없습니다. 제 생각에는 약간 혼란 스럽습니다. 완전한 예를 들면 다음과 같습니다.

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.animation as animation
    
    fig, ax = plt.subplots()
    
    ax.set_xlim([-1,1])
    ax.set_ylim([-1,1])
    
    L = 50
    theta = np.linspace(0,2*np.pi,L)
    r = np.ones_like(theta)
    
    x = r*np.cos(theta)
    y = r*np.sin(theta)
    
    line, = ax.plot(1,0, 'ro')
    
    annotation = ax.annotate(
        'annotation', xy=(1,0), xytext=(-1,0),
        arrowprops = {'arrowstyle': "->"}
    )
    
    def update(i):
    
        new_x = x[i%L]
        new_y = y[i%L]
        line.set_data(new_x,new_y)
    
        ##annotation.xytext = (-new_x,-new_y) <-- does not work
        annotation.set_position((-new_x,-new_y))
        annotation.xy = (new_x,new_y)
    
        return line, annotation
    
    ani = animation.FuncAnimation(
        fig, update, interval = 500, blit = False
    )
    
    plt.show()
    

    결과는 다음과 같습니다.

    버전이 중요한 경우,이 코드는 Python 2.7 및 3.6에서 matplotlib 버전 2.1.1로 테스트되었으며, .settarget () 및 .xy가 예상대로 작동하는 동안 .xytext를 설정하면 아무 효과가 없습니다.

  3. ==============================

    3.목록을 통해 여러 주석을 애니메이션화하는 방법을 생각했습니다. 먼저 주석 목록을 만듭니다.

    목록을 통해 여러 주석을 애니메이션화하는 방법을 생각했습니다. 먼저 주석 목록을 만듭니다.

    for i in range(0,len(someMatrix)):
         annotations.append(ax.annotate(str(i), xy=(someMatrix.item(0,i), someMatrix.item(1,i))))
    

    그런 다음 "애니메이션"기능에서 이미 작성한대로 수행하십시오.

    for num, annot in enumerate(annotations):
        annot.set_position((someMatrix.item((time,num)), someMatrix.item((time,num))))
    

    (열거 방식이 마음에 들지 않으면 루프 용으로 전통적인 방식으로 작성할 수 있습니다.) return 문에 전체 주석 목록을 반환하는 것을 잊지 마십시오.

    그런 다음 중요한 것은 FuncAnimation에 "blit = False"를 설정하는 것입니다.

    animation.FuncAnimation(fig, animate, frames="yourframecount",
                              interval="yourpreferredinterval", blit=False, init_func=init)
    

    blit = False는 작업 속도를 늦출 수 있음을 지적하는 것이 좋습니다. 하지만 안타깝게도 목록에서 주석을 애니메이션으로 작업 할 수있는 유일한 방법은 ...

  4. from https://stackoverflow.com/questions/18351932/animate-points-with-labels-with-matplotlib by cc-by-sa and MIT license