Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate points with labels with matplotlib

I've got an animation with lines and now I want to label the points. I tried plt.annotate() and I tried plt.text() but the labes don't move. This is my example code:

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

Can you help me please?

My next step is: I have vectors with origin in these Points. These vectors change their length and their direction in each animation step. How can I animate these?

Without animation this works:

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)

First thanks a lot for your fast and very helpful answer!

My Vector animation problem I have solved with this:

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="->"))

and in the 'update-function' I write:

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

to change the start and end position of the vectors (arrows).

But what is, wehn I have 100 vectors or more? It is not practicable to write:

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

I tried with a list:

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

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

and got this error: AttributeError: 'list' object has no attribute 'axes'

What can I do? Have you any idea?

like image 382
Christiane Homann Avatar asked Aug 21 '13 08:08

Christiane Homann


People also ask

How do you plot a moving point in Python?

Practical Data Science using PythonCreate a figure and a set of subplots. Create x and y data points using numpy. Plot x and y data points using plot() method. Make an animation by repeatedly calling a function *animate* that moves the X-axis during real-time plot.


1 Answers

I'm coming here from this question, where an annotation should be updated that uses both xy and xytext. It appears that, in order to update the annotation correctly, one needs to set the attribute .xy of the annotation to set the position of the annotated point and to use the .set_position() method of the annotation to set the position of the annotation. Setting the .xytext attribute has no effect -- somewhat confusing in my opinion. Below a complete example:

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

The result looks something like this:

result of the above code

In case that versions matter, this code has been tested on Python 2.7 and 3.6 with matplotlib version 2.1.1, and in both cases setting .xytext had no effect, while .set_position() and .xy worked as expected.

like image 193
Thomas Kühn Avatar answered Oct 31 '22 03:10

Thomas Kühn