Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
337 views
in Technique[技术] by (71.8m points)

Using Python's Matplotlib how can I align annotation updates for specific points to my data set as it is graphed using FuncAnimation?

I have the following code that functions perfectly with the exception that the timing of placing my point annotations and updating the legend does not align to when the point appears on the graph. How do I get them to align?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import style
import matplotlib.patches as mpatches

style.use('ggplot')

x_data = [1,5,7,9,11,12,14,15,27,29,37,39,45,47,52,53,57,58,61,62,66,80,82,83,84,85,90,91,93,96,98,105,109,110,111,113,114,116,117,120,122,123,127,134,136,138,140,141,144,160,161,162,165,174,176,179,183,184,185,186,190,191,192,193,194,195,199,200,204]
y_data = [50,55,40,30,31,20,21,18,25,21,15,18,20,24,27,30,32,35,37,38,30,11,13,10,10,14,16,18,19,17,14,9,9,4,5,5,6,5,7,3,6,8,10,13,15,12,10,13,8,4,3,5,4,5,7,6,4,8,10,12,10,12,12,12,12,15,17,18,18]
annotations = ['','','Pasted Value','Cut Value','','Pasted Cut Value','','Abnormal Pause','','Abnormal Pause','Out of Order Field Interaction','','','','','','','','','','Window Exit','Window Entry','','Pasted Value','Out of Order Field Interaction','','','Irregular Typing Cadence','','Irregular Typing Cadence','Abnormal Pause','Irregular Typing Cadence','Out of Order Field Interaction','Value Manipulation','','Out of Order Field Interaction','','Value Manipulation','','Value Manipulation','','','','','','','','','Window Exit','Window Entry','Pasted Value','','Value Manipulation','','','Value Manipulation','Value Manipulation','','','','Copied Value','','Frustration - Repeat Paste','Frustration - Repeat Paste','Frustration - Repeat Paste','','','','']
print(len(x_data))
print(len(y_data))
print(len(annotations))

fig, ax = plt.subplots()
ax.set_xlim(0,205)
ax.set_ylim(0,100)
line, = ax.plot(0,50)

def init():
  line.set_data([], [])
  return line,

def animate(n):
  line, = plt.plot(x_data[:n], y_data[:n], color='b', marker='o')
  ax.annotate(annotations[n],(x_data[n],y_data[n]))
  updated_score = mpatches.Patch(color='b', label=y_data[n])
  plt.legend(handles=[updated_score])
  return line,

animation = FuncAnimation(fig, animate, frames=len(x_data), interval=500)

plt.title('A Cool Title')
plt.xlabel('Time in Seconds')
plt.ylabel('Value')

plt.show()

Here is a working replit

question from:https://stackoverflow.com/questions/65841482/using-pythons-matplotlib-how-can-i-align-annotation-updates-for-specific-points

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Remember that when slicing Pandas doesn't include the last value, therefore in this line plt.plot(x_data[:n+1], y_data[:n+1]) you should add +1 to include the n-th value. I think that solve the lack of timming.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import style
import matplotlib.patches as mpatches

style.use('ggplot')

x_data = [1,5,7,9,11,12,14,15,27,29,37,39,45,47,52,53,57,58,61,62,66,80,82,83,84,85,90,91,93,96,98,105,109,110,111,113,114,116,117,120,122,123,127,134,136,138,140,141,144,160,161,162,165,174,176,179,183,184,185,186,190,191,192,193,194,195,199,200,204]
y_data = [50,55,40,30,31,20,21,18,25,21,15,18,20,24,27,30,32,35,37,38,30,11,13,10,10,14,16,18,19,17,14,9,9,4,5,5,6,5,7,3,6,8,10,13,15,12,10,13,8,4,3,5,4,5,7,6,4,8,10,12,10,12,12,12,12,15,17,18,18]
annotations = ['','','Pasted Value','Cut Value','','Pasted Cut Value','','Abnormal Pause','','Abnormal Pause','Out of Order Field Interaction','','','','','','','','','','Window Exit','Window Entry','','Pasted Value','Out of Order Field Interaction','','','Irregular Typing Cadence','','Irregular Typing Cadence','Abnormal Pause','Irregular Typing Cadence','Out of Order Field Interaction','Value Manipulation','','Out of Order Field Interaction','','Value Manipulation','','Value Manipulation','','','','','','','','','Window Exit','Window Entry','Pasted Value','','Value Manipulation','','','Value Manipulation','Value Manipulation','','','','Copied Value','','Frustration - Repeat Paste','Frustration - Repeat Paste','Frustration - Repeat Paste','','','','']
print(len(x_data))
print(len(y_data))
print(len(annotations))

fig, ax = plt.subplots()
ax.set_xlim(0,205)
ax.set_ylim(0,100)
line, = ax.plot(0,50)

def init():
  line.set_data([], [])
  return line,

def animate(n):
  line, = plt.plot(x_data[:n+1], y_data[:n+1], color='b', marker='o')
  ax.annotate(annotations[n],(x_data[n],y_data[n]))
  updated_score = mpatches.Patch(color='b', label=y_data[n])
  ax.legend(handles=[updated_score])
  return line,

animation = FuncAnimation(fig, animate, frames=len(x_data), interval=500)

plt.title('A Cool Title')
plt.xlabel('Time in Seconds')
plt.ylabel('Value')

plt.show()

Check here the result: https://repl.it/@JuanJavier1/A-Cool-Title


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...