[PYTHON] matplotlib를 사용하여 레이블로 포인트 애니메이트하기
PYTHONmatplotlib를 사용하여 레이블로 포인트 애니메이트하기
선이있는 애니메이션이 생겼으니 점에 레이블을 붙이고 싶습니다. 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.업데이트 기능에서 변경된 모든 객체가 반환됩니다. 따라서 주석이 위치를 변경했기 때문에 반환해야합니다.
업데이트 기능에서 변경된 모든 객체가 반환됩니다. 따라서 주석이 위치를 변경했기 때문에 반환해야합니다.
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.여기서 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.목록을 통해 여러 주석을 애니메이션화하는 방법을 생각했습니다. 먼저 주석 목록을 만듭니다.
목록을 통해 여러 주석을 애니메이션화하는 방법을 생각했습니다. 먼저 주석 목록을 만듭니다.
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는 작업 속도를 늦출 수 있음을 지적하는 것이 좋습니다. 하지만 안타깝게도 목록에서 주석을 애니메이션으로 작업 할 수있는 유일한 방법은 ...
from https://stackoverflow.com/questions/18351932/animate-points-with-labels-with-matplotlib by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 절단 (truncation)이 가능한 파일을 열거 나 (읽기 / 쓰기) 작성하는 방법은 무엇입니까? (0) | 2018.11.19 |
---|---|
[PYTHON] Javascript에서 파이썬의 dir과 같습니다. (0) | 2018.11.19 |
[PYTHON] 클래스 이름을 동적으로 설정하는 방법은 무엇입니까? (0) | 2018.11.19 |
[PYTHON] 여러 범위의 파이썬 공용체 (0) | 2018.11.19 |
[PYTHON] 파이썬에서 큰 따옴표 셸 명령을 subprocess.Popen ()에 전달 하시겠습니까? (0) | 2018.11.19 |