Animate List In The Middle Of Annotate Arrow Props
I am aiming to animate a df in the middle of an annotate function. I can get the arrow to animate and the first value of the df to appear but not animate with the updated coordinat
Solution 1:
Although you could use plt.text
to display the label, you don't need it. ax.annotate
can generate the label as well as the arrow. You can specify the label string as the first argument to ax.annotate
,
arrow = ax.annotate(Number[0], xy=(a_data[0][0], b_data[0][0]), ...
and you can change the label by calling arrow.set_text
:
arrow.set_text(Number[i])
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import random
from functools import partial
import pandas as pd
one_sample = partial(random.sample, range(100), 10)
a_data = [one_sample() for _ inrange(1000)]
b_data = [one_sample() for _ inrange(1000)]
df = pd.DataFrame(np.random.randint(0, 100, size=(100, 1)), columns=list('A'))
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 100)
ax.set_ylim(0, 100)
Number = df['A']
arrow = ax.annotate(Number[0], xy=(a_data[0][0], b_data[0][0]),
xytext=(a_data[0][1], b_data[0][1]),
arrowprops={'arrowstyle': "<->", 'color': 'black'}, ha='center')
defanimate(i):
arrow_start = (a_data[0 + i][0], b_data[0 + i][0])
arrow_end = (a_data[0 + i][1], b_data[0 + i][1])
arrow.set_position(arrow_start)
arrow.xy = arrow_end
arrow.set_text(Number[i])
return [arrow]
ani = animation.FuncAnimation(fig, animate, interval=500, blit=True)
plt.show()
To place the label in the middle of the arrow, I believe you would need to use plt.text
(or a second call to ax.annotate
). To move the label generated by plt.text
, call label.set_position
:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import random
import math
from functools import partial
import pandas as pd
one_sample = partial(random.sample, range(100), 10)
a_data = [one_sample() for _ inrange(1000)]
b_data = [one_sample() for _ inrange(1000)]
df = pd.DataFrame(np.random.randint(0, 100, size=(100, 1)), columns=list('A'))
Number = df['A']
data = np.stack([a_data, b_data], axis=2)
# a_data and b_data contain more data than we are actually using, # so let's crop `data` to make the following code simpler:
data = data[:, :2, :]
middle = data.mean(axis=1)
# find the direction perpendicular to the arrow
perp_dir = (data[:, 0] - data[:, 1]).astype('float')
perp_dir = np.array((-perp_dir[:, 1], perp_dir[:, 0]))
perp_dir /= np.sqrt((perp_dir**2).sum(axis=0))
perp_dir = perp_dir.T
# shift middle by a little bit in the perpendicular direction
offset = 3.0
middle += offset * perp_dir
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 100)
ax.set_ylim(0, 100)
arrow = ax.annotate('', xy=data[0, 0],
xytext=data[0, 1],
arrowprops={'arrowstyle': "<->", 'color': 'black'},
ha='center')
label = plt.text(middle[0, 0], middle[0, 1], Number[0], fontsize = 8,
ha = 'center')
defanimate(i):
arrow_start = data[i, 0]
arrow_end = data[i, 1]
arrow.set_position(arrow_start)
arrow.xy = arrow_end
label.set_text(Number[i])
label.set_position(middle[i])
return [arrow, label]
ani = animation.FuncAnimation(fig, animate, interval=500, blit=True)
plt.show()
Post a Comment for "Animate List In The Middle Of Annotate Arrow Props"