My Project
animationTools.py
Go to the documentation of this file.
1 from matplotlib import pyplot as plt, animation, artist
2 import numpy as np
3 
4 from animationSupportClasses import SingleLine, SinglePlot, bcolors
5 
6 class BKAnimation():
7  def __init__(
8  self,
9  single_plots,
10  frame_interval = 10,
11  movement_per_frame = 10,
12  n_frames = 10,
13  fps = 10,
14  sleep_amount = 1,
15  max_lim_change = 0.1
16  ):
17  self.single_plots = single_plots
18 
19  self.frame_interval = frame_interval
20  self.movement_per_frame = movement_per_frame
21  self.n_frames = n_frames
22  self.fps = fps
23  self.sleep_amount = sleep_amount
24  self.max_lim_change = max_lim_change
25 
26 
27 
28  def init_live_plot(
29  self,
30  positions,
31  figure_shape,
32  titles,
33  show_plot = True,
34  suptitle = ""
35  ):
36  #plt.ion()
37  self.fig = plt.figure(figsize=figure_shape)
38  self.axs = [self.fig.add_subplot(pos, title = title) for pos, title in zip(positions, titles)]
39  self.fig.suptitle(suptitle, fontsize=12)
40 
41  self.init_subplots()
42  #self.fig.canvas.manager.full_screen_toggle()
43  if(show_plot):
44  self.fig.show()
45  self.fig.canvas.draw()
46 
47  def init_subplots(
48  self
49  ):
50  for single_plot in self.single_plots:
51  print("printing plot: " + str(single_plot.ax_number) + ", length: " + str(len(single_plot.single_line_list)) + ", plot type: " + single_plot.plot_type)
52  self.init_specified_subplot(single_plot)
53  self.init_lims(single_plot)
54  self.init_labels(single_plot)
55 
56  #quit()
57 
59  self,
60  single_plot
61  ):
62  for single_line in single_plot.single_line_list:
63  print("printing line: ax_number: " + str(single_line.ax_number) + ", line_number: " + str(single_line.line_number))
64  if(single_plot.plot_type == 'bar'):
65  self.init_bar_plot(single_line, single_plot.ax_number)
66  elif(single_plot.plot_type == 'spring'):
67  self.init_spring_plot(single_line, single_plot.ax_number)
68  else:
69  self.init_line_plot(single_line, single_plot.ax_number)
70 
71  def init_line_plot(
72  self,
73  single_line,
74  ax_number
75  ):
76  self.axs[ax_number].plot(\
77  single_line.x_values[single_line.x_i[0]:(single_line.x_i[1])] + single_line.starting_position["x"],\
78  single_line.y_values[single_line.y_i[0]:(single_line.y_i[1])] + single_line.starting_position["y"],\
79  marker = single_line.marker,
80  markersize = single_line.marker_size
81  )
82 
83  def init_spring_plot(
84  self,
85  single_line,
86  ax_number
87  ):
88  single_line.print_all()
89  self.axs[ax_number].plot(\
90  single_line.x_values[single_line.x_i[0]:(single_line.x_i[1] + 1)] + single_line.starting_position["x"],\
91  single_line.y_values[single_line.y_i[0]:(single_line.y_i[1] + 1)] + single_line.starting_position["y"],\
92  marker = single_line.marker,
93  markersize = single_line.marker_size,
94  linewidth = single_line.line_width,
95  color = single_line.color
96  )
97 
98  def init_bar_plot(
99  self,
100  single_line,
101  ax_number
102  ):
103  self.axs[ax_number].bar(single_line.x_values[single_line.x_i], single_line.y_values[single_line.y_i])
104 
105  def init_lims(
106  self,
107  single_plot
108  ):
109  self.update_live_x_lim(single_plot)
110  self.update_live_y_lim(single_plot)
111 
112  def init_labels(
113  self,
114  single_plot
115  ):
116  self.axs[single_plot.ax_number].set_xlabel(single_plot.x_label)
117  self.axs[single_plot.ax_number].set_ylabel(single_plot.y_label)
118 
119 
120 
121 
122 
123  def update_subplots(
124  self,
125  update_lims = False
126  ):
127  for single_plot in self.single_plots:
128  self.update_specified_subplot(single_plot)
129  if(update_lims):
130  self.update_live_x_lim(single_plot)
131  self.update_live_y_lim(single_plot)
132  self.fig.canvas.draw()
133 
135  self,
136  single_plot
137  ):
138  print("ax: " + str(single_plot.ax_number))
139  for single_line in single_plot.single_line_list:
140  self.update_live_x_values(single_line, single_plot.plot_type)
141  self.update_live_y_values(single_line, single_plot.plot_type)
142 
144  self,
145  single_line,
146  plot_type
147  ):
148  if(plot_type == 'spring'):
149  self.axs[single_line.ax_number].lines[single_line.line_number].set_xdata(single_line.x_values[single_line.x_i[0]:(single_line.x_i[1] + 1)] + single_line.starting_position["x"])
150  elif(self.axs[single_line.ax_number].lines):
151  # if(single_line.ax_number == 0):
152  # print("x indexes: ", single_line.x_i)
153  # print(len(single_line.x_values[single_line.x_i[0]:single_line.x_i[1]] + single_line.starting_position["x"]))
154  # print(len(single_line.x_values))
155  # print(len(single_line.y_values[single_line.x_i[0]:single_line.x_i[1]] + single_line.starting_position["x"]))
156  # print(len(single_line.y_values))
157  # print("y_indexes: ", single_line.y_i)
158  self.axs[single_line.ax_number].lines[single_line.line_number].set_xdata(single_line.x_values[single_line.x_i[0]:single_line.x_i[1]] + single_line.starting_position["x"])
159  elif(plot_type == 'bar'):
160  print("bar")
161  else:
162  print("Please initiate ax plot before updating.")
163  quit()
164 
166  self,
167  single_line,
168  plot_type
169  ):
170  if(plot_type == 'spring'):
171  return
172  elif(self.axs[single_line.ax_number].lines):
173  self.axs[single_line.ax_number].lines[single_line.line_number].set_ydata(single_line.y_values[single_line.y_i[0]:single_line.y_i[1]] + single_line.starting_position["y"])
174  elif(plot_type == 'bar'):
175  for rect, h in zip(self.axs[single_line.ax_number].patches, single_line.get_y_values()):
176  rect.set_height(h)
177  else:
178  print("Please initiate ax plot before updating.")
179  quit()
180 
181 
182 
183  def update_live_x_lim(
184  self,
185  single_plot
186  ):
187  if(self.axs[single_plot.ax_number].lines or single_plot.plot_type == 'bar'):
188  self.axs[single_plot.ax_number].set_xlim(single_plot.x_lim['min'], single_plot.x_lim['max'])
189  else:
190  print("Please initiate ax plot before updating.")
191  quit()
192 
193  def update_live_y_lim(
194  self,
195  single_plot
196  ):
197  if(self.axs[single_plot.ax_number].lines or single_plot.plot_type == 'bar'):
198  self.axs[single_plot.ax_number].set_ylim(single_plot.y_lim['min'], single_plot.y_lim['max'])
199  else:
200  print("Please initiate ax plot before updating.")
201  quit()
202 
204  self,
205  ax_number,
206  index_first_spring,
207  block_line_index = 0
208  ):
209  block_spring_plot = self.single_plots[ax_number].single_line_list[block_line_index]
210  block_line_x_values = block_spring_plot.get_x_values()
211  block_line_start_positions = block_spring_plot.get_starting_position()['x']
212  pad_shift = self.single_plots[ax_number].get_last_plotted_x_value(2)
213  if(index_first_spring > 1):
214  block_line_x_values += pad_shift
215  for i, upper_spring in enumerate(self.single_plots[ax_number].single_line_list[index_first_spring:]):
216  upper_spring_x_values = upper_spring.get_x_values()
217  upper_spring_x_values[0] = block_line_x_values[i] + block_line_start_positions[i]
218  if(index_first_spring > 1):
219  upper_spring_x_values[1] = block_line_start_positions[i] + pad_shift
220 
221  self.single_plots[ax_number].change_x(i+index_first_spring, upper_spring_x_values)
222 
223  def update_suptitle(
224  self,
225  suptitle
226  ):
227  self.fig.suptitle(suptitle)
228 
229  def check_lims(
230  self,
231  ax_number,
232  axis_checked,
233  reduce_extra_lim_amount = 3
234  ):
235  ax = self.axs[ax_number]
236  if(axis_checked == 'y'):
237  current_lims = self.single_plots[ax_number].y_lim
238  elif(axis_checked == 'x'):
239  current_lims = self.single_plots[ax_number].x_lim
240  compared_lims = {'min': None, 'max': None}
241  for line in ax.lines:
242  if(axis_checked == 'y'):
243  data = line.get_ydata()
244  elif(axis_checked == 'x'):
245  data = line.get_xdata()
246  else:
247  print(bcolors.WARNING + "Warning: tried to update non-existing axis \"" + axis_checked + "\"" + bcolors.ENDC)
248  break
249  max = np.max(data)
250  min = np.min(data)
251 
252  if(compared_lims['max'] == None or compared_lims['max'] < max):
253  compared_lims['max'] = max
254  if(compared_lims['min'] == None or compared_lims['min'] > min):
255  compared_lims['min'] = min
256 
257  new_max = current_lims['max']
258  new_min = current_lims['min']
259 
260  max_lim_diff = (compared_lims["max"] - compared_lims["min"])*self.max_lim_change
261  if(compared_lims['max'] > current_lims['max'] or (current_lims['max'] - compared_lims['max']) > max_lim_diff):
262  new_max = compared_lims['max'] + max_lim_diff / reduce_extra_lim_amount
263  new_min = compared_lims['min'] - max_lim_diff / reduce_extra_lim_amount
264  elif(compared_lims['min'] < current_lims['min'] or (compared_lims['min'] - current_lims['min']) > max_lim_diff):
265  new_max = compared_lims['max'] + max_lim_diff / reduce_extra_lim_amount
266  new_min = compared_lims['min'] - max_lim_diff / reduce_extra_lim_amount
267  if(axis_checked == 'y'):
268  ax.set_ylim(new_max, new_min)
269  elif(axis_checked == 'x'):
270  ax.set_xlim(new_max, new_min)
271 
272 
273 
274 
275 
276  def change_xy_lim(
277  self,
278  ax_number,
279  lim_min_add,
280  lim_max_add
281  ):
282  self.change_x_lim(ax_number, lim_min_add, lim_max_add)
283  self.change_y_lim(ax_number, lim_min_add, lim_max_add)
284 
285  def change_x_lim(
286  self,
287  ax_number,
288  x_lim_min_add,
289  x_lim_max_add
290  ):
291  self.single_plots[ax_number].change_x_lim(x_lim_min_add, x_lim_max_add)
292 
293  def change_y_lim(
294  self,
295  ax_number,
296  y_lim_min_add,
297  y_lim_max_add
298  ):
299  self.single_plots[ax_number].change_y_lim(y_lim_min_add, y_lim_max_add)
300 
301  def shift_xy_indexes(
302  self,
303  ax_number,
304  line_number,
305  shift_amount,
306  only_shift_first = False
307  ):
308  self.shift_x_indexes(ax_number, line_number, shift_amount, only_shift_first = only_shift_first)
309  self.shift_y_indexes(ax_number, line_number, shift_amount, only_shift_first = only_shift_first)
310 
311  def shift_x_indexes(
312  self,
313  ax_number,
314  line_number,
315  shift_amount,
316  only_shift_first = False
317  ):
318  self.single_plots[ax_number].shift_x_indexes(line_number, shift_amount, only_shift_first = only_shift_first)
319 
320  def shift_y_indexes(
321  self,
322  ax_number,
323  line_number,
324  shift_amount,
325  only_shift_first = False
326  ):
327  self.single_plots[ax_number].shift_y_indexes(line_number, shift_amount, only_shift_first = only_shift_first)
328 
329  def change_x(
330  self,
331  ax_number,
332  line_number,
333  get_axis = "x"
334  ):
335  if(get_axis == "x"):
336  new_height = self.get_last_plotted_x_value(ax_number, line_number)
337  elif(get_axis == "y"):
338  new_height = self.get_last_plotted_y_value(ax_number, line_number)
339  new_height = np.array(new_height)
340  self.single_plots[ax_number].change_x(line_number, new_height)
341 
342  def change_y(
343  self,
344  ax_number,
345  line_number,
346  get_axis = "y"
347  ):
348  if(get_axis == "x"):
349  new_height = self.get_last_plotted_x_value(ax_number, line_number)
350  elif(get_axis == "y"):
351  new_height = self.get_last_plotted_y_value(ax_number, line_number)
352  self.single_plots[ax_number].change_y(line_number, new_height)
353 
354 
355 
356 
358  self,
359  ax_number,
360  line_number
361  ):
362  line_dependencies = self.single_plots[ax_number].single_line_list[line_number].line_dependencies
363  if(line_dependencies):
364  x_values = []
365  for i, ax_number in enumerate(line_dependencies['ax_numbers']):
366  for line_dependency in line_dependencies['line_numbers'][i]:
367  x_values.append(self.single_plots[ax_number].get_last_plotted_x_value(line_dependency))
368  return x_values
369  return self.single_plots[ax_number].get_last_plotted_x_value(line_number)
370 
372  self,
373  ax_number,
374  line_number
375  ):
376  line_dependencies = self.single_plots[ax_number].single_line_list[line_number].line_dependencies
377  if(line_dependencies):
378  y_values = []
379  for i, ax_number in enumerate(line_dependencies['ax_numbers']):
380  for line_dependency in line_dependencies['line_numbers'][i]:
381  y_values.append(self.single_plots[ax_number].get_last_plotted_y_value(line_dependency))
382  return y_values
383  return self.single_plots[ax_number].get_last_plotted_y_value(line_number)
384 
385  def get_frame_interval(
386  self
387  ):
388  return self.frame_interval
389 
390  def set_frame_interval(
391  self,
392  new_value
393  ):
394  self.frame_interval = new_value
395 
397  self
398  ):
399  return self.movement_per_frame
400 
402  self,
403  new_value
404  ):
405  self.movement_per_frame = new_value
406 
407  def get_n_frames(
408  self
409  ):
410  return self.n_frames
411 
412  def set_n_frames(
413  self,
414  new_value
415  ):
416  self.n_frames = new_value
417 
418  def get_fps(
419  self
420  ):
421  return self.fps
422 
423  def set_fps(
424  self,
425  new_value
426  ):
427  self.fps = new_value
428 
429  def get_sleep_amount(
430  selfSinglePlot
431  ):
432  return self.sleep_amount
433 
434  def set_sleep_amount(
435  self,
436  new_value
437  ):
438  self.sleep_amount = new_value
439 
440 
def init_bar_plot(self, single_line, ax_number)
def set_frame_interval(self, new_value)
def init_spring_plot(self, single_line, ax_number)
def get_last_plotted_y_value(self, ax_number, line_number)
def init_live_plot(self, positions, figure_shape, titles, show_plot=True, suptitle="")
START: INITIALIZE ##.
def change_y_lim(self, ax_number, y_lim_min_add, y_lim_max_add)
def shift_xy_indexes(self, ax_number, line_number, shift_amount, only_shift_first=False)
def update_suptitle(self, suptitle)
def update_subplots(self, update_lims=False)
END: INITIALIZE ##.
def shift_x_indexes(self, ax_number, line_number, shift_amount, only_shift_first=False)
def update_live_x_values(self, single_line, plot_type)
def change_x_lim(self, ax_number, x_lim_min_add, x_lim_max_add)
def init_line_plot(self, single_line, ax_number)
def __init__(self, single_plots, frame_interval=10, movement_per_frame=10, n_frames=10, fps=10, sleep_amount=1, max_lim_change=0.1)
def change_y(self, ax_number, line_number, get_axis="y")
def shift_y_indexes(self, ax_number, line_number, shift_amount, only_shift_first=False)
def update_specified_subplot(self, single_plot)
def init_labels(self, single_plot)
def update_live_x_lim(self, single_plot)
def change_xy_lim(self, ax_number, lim_min_add, lim_max_add)
END: UPDATE ##.
def set_sleep_amount(self, new_value)
def update_live_y_lim(self, single_plot)
def init_lims(self, single_plot)
def get_sleep_amount(selfSinglePlot)
def init_specified_subplot(self, single_plot)
def set_n_frames(self, new_value)
def check_lims(self, ax_number, axis_checked, reduce_extra_lim_amount=3)
def change_x(self, ax_number, line_number, get_axis="x")
def set_fps(self, new_value)
def update_upper_springs(self, ax_number, index_first_spring, block_line_index=0)
def set_movement_per_frame(self, new_value)
def update_live_y_values(self, single_line, plot_type)
def get_last_plotted_x_value(self, ax_number, line_number)
END: HELP FUNCTIONS ##.