I am trying to animate annotations from a list of xy coordinates. The code below animates the annotation
line but I cannot get the arrow
function to animate using the same code.
The example dataset is a representation of the data I'm using. It is horizontally formatted. With this, I make a list from all the X-Coordinates and all the Y-Coordiantes from each subject. I then make a list pertaining to each time point, which is each row of data. From that I can plot a scatter and annotations.
However, when trying to plot an arrow between two separate coordinates I run into the error as stated by @ImportanceOfBeingErnest. The function should be a tuple of two elements but I'm having trouble with the arrow animation function as I think I need to provide 4 elements. The X and Y coordinate for the first point and X and Y coordinate for the second point.
Will I have to re-format that data or is there a way to animate the arrow function were 4 tuples are required?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x_data = np.random.randint(80, size=(400, 4))
y_data = np.random.randint(80, size=(400, 4))
lists = [[],[]]
lists[0] = x_data
lists[1] = y_data
fig, ax = plt.subplots(figsize = (8,6))
ax.set_xlim(0,80)
ax.set_ylim(0,80)
scatter = ax.scatter(lists[0][0], lists[1][0], zorder = 5) #Scatter plot
annotation = ax.annotate(' Subject 1', xy=(lists[0][0][2],lists[1][0][2]))
arrow = ax.annotate('', xy = (lists[0][0][0], lists[1][0][0]), xytext = (lists[0][0][1],lists[1][0][1]), arrowprops = {'arrowstyle': "<->"})
def animate(i) :
scatter.set_offsets([[[[[lists[0][0+i][0], lists[1][0+i][0]], [lists[0][0+i][1], lists[1][0+i][1]], [lists[0][0+i][2], lists[1][0+i][2]], [lists[0][0+i][3], lists[1][0+i][3]]]]]])
Subject_x = lists[0][0+i][2]
Subject_y = lists[1][0+i][2]
annotation.set_position((Subject_x, Subject_y))
annotation.xy = (Subject_x, Subject_y)
Arrow1 = (lists[0][0+i][0], lists[1][0+i][0]) #Code for arrow animation doesn't work. Produces a blank screen after the 1st frame
Arrow2 = (lists[0][0+i][1], lists[1][0+i][1])
arrow.set_position((Arrow1, Arrow2))
arrow.xy = (Arrow1, Arrow2)
ani = animation.FuncAnimation(fig, animate,
interval = 50, blit = False)
plt.show()
The solution to this is still given in this question: Animate points with labels with mathplotlib
As said several times in the comments, each position is determined by a tuple of two values
(x,y)
. Hence you cannot provide a tuple of tuples to those positions. Also the start and end of the arrow should of course be at different positions.