diplotocus 0.6.0__tar.gz → 0.6.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. {diplotocus-0.6.0 → diplotocus-0.6.3}/PKG-INFO +1 -1
  2. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/GUI.ipynb +1 -1
  3. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/animations.ipynb +93 -3
  4. diplotocus-0.6.3/src/diplotocus/_version.py +1 -0
  5. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/animations.py +124 -86
  6. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus.egg-info/PKG-INFO +1 -1
  7. diplotocus-0.6.0/src/diplotocus/_version.py +0 -1
  8. {diplotocus-0.6.0 → diplotocus-0.6.3}/.gitattributes +0 -0
  9. {diplotocus-0.6.0 → diplotocus-0.6.3}/.gitignore +0 -0
  10. {diplotocus-0.6.0 → diplotocus-0.6.3}/.readthedocs.yaml +0 -0
  11. {diplotocus-0.6.0 → diplotocus-0.6.3}/LICENSE +0 -0
  12. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/Makefile +0 -0
  13. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/_static/force-light.css +0 -0
  14. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/_static/force-light.js +0 -0
  15. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/make.bat +0 -0
  16. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/requirements.txt +0 -0
  17. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/Web_GUI.png +0 -0
  18. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/button.svg +0 -0
  19. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/demo.mp4 +0 -0
  20. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/favicon.ico +0 -0
  21. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/force-light.css +0 -0
  22. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/force-light.js +0 -0
  23. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/logo.mp4 +0 -0
  24. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/_static/logo.svg +0 -0
  25. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/api/core.rst +0 -0
  26. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/api/index.rst +0 -0
  27. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/conf.py +0 -0
  28. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/index.rst +0 -0
  29. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/easings.ipynb +0 -0
  30. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/index.ipynb +0 -0
  31. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/installation.ipynb +0 -0
  32. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/plot_objects.ipynb +0 -0
  33. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/quick-start.ipynb +0 -0
  34. {diplotocus-0.6.0 → diplotocus-0.6.3}/docs/source/notebooks/timeline.ipynb +0 -0
  35. {diplotocus-0.6.0 → diplotocus-0.6.3}/logo.png +0 -0
  36. {diplotocus-0.6.0 → diplotocus-0.6.3}/pyproject.toml +0 -0
  37. {diplotocus-0.6.0 → diplotocus-0.6.3}/readme.md +0 -0
  38. {diplotocus-0.6.0 → diplotocus-0.6.3}/setup.cfg +0 -0
  39. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/GUI.html +0 -0
  40. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/__init__.py +0 -0
  41. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/app.js +0 -0
  42. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/server.py +0 -0
  43. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/bg.png +0 -0
  44. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Draw.png +0 -0
  45. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Morph.png +0 -0
  46. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Rotate.png +0 -0
  47. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Scale.png +0 -0
  48. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Sequence.png +0 -0
  49. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Translate.png +0 -0
  50. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_Tween.png +0 -0
  51. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/btn/btn_bg_default.png +0 -0
  52. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/favicon.ico +0 -0
  53. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/src/logo_bg.png +0 -0
  54. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/GUI/style.css +0 -0
  55. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/__init__.py +0 -0
  56. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/core.py +0 -0
  57. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus/easings.py +0 -0
  58. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus.egg-info/SOURCES.txt +0 -0
  59. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus.egg-info/dependency_links.txt +0 -0
  60. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus.egg-info/requires.txt +0 -0
  61. {diplotocus-0.6.0 → diplotocus-0.6.3}/src/diplotocus.egg-info/top_level.txt +0 -0
  62. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test.py +0 -0
  63. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test10.py +0 -0
  64. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test2.py +0 -0
  65. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test3.py +0 -0
  66. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test4.py +0 -0
  67. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test5.py +0 -0
  68. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test6.py +0 -0
  69. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test7.py +0 -0
  70. {diplotocus-0.6.0 → diplotocus-0.6.3}/tests/test8.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diplotocus
3
- Version: 0.6.0
3
+ Version: 0.6.3
4
4
  Summary: A python package to generate animations of matplotlib objects.
5
5
  Author-email: Tristan Boin <tristan.boin@obspm.fr>
6
6
  License-Expression: MIT
@@ -13,7 +13,7 @@
13
13
  "\n",
14
14
  "```{warning}\n",
15
15
  "\n",
16
- "The GUI might not be as stable as the python interface. Feel free to report any issues you encounters.\n",
16
+ "The GUI might not be as stable as the python interface and is currently lacking recently added features. Feel free to report any issues you encounter or features you want to see be added in priority.\n",
17
17
  "```\n",
18
18
  "\n",
19
19
  "When running diplotocus through this mode, you will make edit your animation through a local web page in your browser. This page communicates with a python server, which links the GUI and diplotocus objects in the background. Hence, everything you can do through python, you can do through the GUI, and vice versa.\n",
@@ -39,14 +39,14 @@
39
39
  },
40
40
  {
41
41
  "cell_type": "code",
42
- "execution_count": null,
42
+ "execution_count": 2,
43
43
  "id": "8292940a",
44
44
  "metadata": {},
45
45
  "outputs": [
46
46
  {
47
47
  "data": {
48
48
  "application/vnd.jupyter.widget-view+json": {
49
- "model_id": "e81b7a3356ae4f16a27fae17363df670",
49
+ "model_id": "2eaf909a7fe44442baed97f7da7c03ed",
50
50
  "version_major": 2,
51
51
  "version_minor": 0
52
52
  },
@@ -74,7 +74,7 @@
74
74
  "text/html": [
75
75
  "\n",
76
76
  " <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
77
- " <source src=\"../_static/animations/anim_translate.mp4?randId=449\" type=\"video/mp4\">\n",
77
+ " <source src=\"../_static/animations/anim_translate.mp4?randId=322\" type=\"video/mp4\">\n",
78
78
  " </video>\n",
79
79
  " "
80
80
  ],
@@ -503,6 +503,84 @@
503
503
  "tl.save_video('../_static/animations/anim_morph.mp4')"
504
504
  ]
505
505
  },
506
+ {
507
+ "cell_type": "markdown",
508
+ "id": "543e2a0d",
509
+ "metadata": {},
510
+ "source": [
511
+ "### Subdraw\n",
512
+ "\n",
513
+ "```{eval-rst}\n",
514
+ ".. automethod:: diplotocus.animations.plotObject.subdraw\n",
515
+ " :noindex:\n",
516
+ "```"
517
+ ]
518
+ },
519
+ {
520
+ "cell_type": "code",
521
+ "execution_count": 1,
522
+ "id": "46a8632c",
523
+ "metadata": {},
524
+ "outputs": [
525
+ {
526
+ "data": {
527
+ "application/vnd.jupyter.widget-view+json": {
528
+ "model_id": "9bfc289f510045839c333aefaa210fdc",
529
+ "version_major": 2,
530
+ "version_minor": 0
531
+ },
532
+ "text/plain": [
533
+ " 0%| | 0/60 [00:00<?, ?it/s]"
534
+ ]
535
+ },
536
+ "metadata": {},
537
+ "output_type": "display_data"
538
+ },
539
+ {
540
+ "data": {
541
+ "text/markdown": [
542
+ "Saved video ../_static/animations/anim_subdraw.mp4"
543
+ ],
544
+ "text/plain": [
545
+ "<IPython.core.display.Markdown object>"
546
+ ]
547
+ },
548
+ "metadata": {},
549
+ "output_type": "display_data"
550
+ },
551
+ {
552
+ "data": {
553
+ "text/html": [
554
+ "\n",
555
+ " <video width=\"640\" height=\"360\" autoplay loop muted playsinline>\n",
556
+ " <source src=\"../_static/animations/anim_subdraw.mp4?randId=2913\" type=\"video/mp4\">\n",
557
+ " </video>\n",
558
+ " "
559
+ ],
560
+ "text/plain": [
561
+ "<IPython.core.display.HTML object>"
562
+ ]
563
+ },
564
+ "metadata": {},
565
+ "output_type": "display_data"
566
+ }
567
+ ],
568
+ "source": [
569
+ "import diplotocus as dpl\n",
570
+ "import numpy as np\n",
571
+ "\n",
572
+ "x = np.linspace(0,2*np.pi,60)\n",
573
+ "y = np.cos(x)\n",
574
+ "\n",
575
+ "tl = dpl.Timeline(xlim=(-1,7),ylim=(-2,2))\n",
576
+ "\n",
577
+ "p = dpl.plot(x=x,y=y)\n",
578
+ "p.subdraw(start_index=0,end_index=5,duration=60)\n",
579
+ "\n",
580
+ "tl.animate(p)\n",
581
+ "tl.save_video('../_static/animations/anim_subdraw.mp4')"
582
+ ]
583
+ },
506
584
  {
507
585
  "cell_type": "markdown",
508
586
  "id": "7d3c9b15",
@@ -513,6 +591,12 @@
513
591
  "```{eval-rst}\n",
514
592
  ".. automethod:: diplotocus.animations.plotObject.draw\n",
515
593
  " :noindex:\n",
594
+ "```\n",
595
+ "\n",
596
+ "```{note}\n",
597
+ "\n",
598
+ "`draw()` is a shorthand animation that subdraws every datapoint from 0 to the current_frame (or reversed if `reverse=True`). It is equivalent to `subdraw('start',0)`.\n",
599
+ "\n",
516
600
  "```"
517
601
  ]
518
602
  },
@@ -591,6 +675,12 @@
591
675
  "```{eval-rst}\n",
592
676
  ".. automethod:: diplotocus.animations.plotObject.sequence\n",
593
677
  " :noindex:\n",
678
+ "```\n",
679
+ "\n",
680
+ "```{note}\n",
681
+ "\n",
682
+ "`sequence()` is a shorthand animation that only subdraws the datapoint at the current frame index (or reversed if `reverse=True`). It is equivalent to `subdraw(0,0)`.\n",
683
+ "\n",
594
684
  "```"
595
685
  ]
596
686
  },
@@ -0,0 +1 @@
1
+ __version__ = "0.6.3"
@@ -155,56 +155,33 @@ class plotObject:
155
155
  data_x = to_np_array(self.x)
156
156
  data_y = to_np_array(self.y)
157
157
 
158
- #First pass to get frame if sequencing
159
- for anim in self.anims:
160
- if anim['name'] != 'sequence':
161
- continue
162
- if self.x is None:
163
- continue
164
- if x < anim['delay'] or x > anim['delay'] + anim['duration']:
165
- continue
166
- t = self.get_t_from_x(anim,x)
158
+ i_min,i_max = -1,-1
167
159
 
168
- if len(data_x.shape) == 1:
169
- data_x = data_x.reshape((-1,1))
170
- data_y = data_y.reshape((-1,1))
171
-
172
- _i = max(min(round(t*len(data_x)),len(data_x)-1),0)
173
- data_x = data_x[_i]
174
- data_y = data_y[_i]
175
- kwargs = self.resize_kwargs(kwargs,_i)
160
+ if 'alpha' in kwargs:
161
+ alpha = to_np_array(kwargs['alpha'])
162
+ if np.sum(alpha) == 0:
163
+ kwargs['alpha'] = 1
176
164
 
177
- #Second pass to cut points if drawing or erasing
178
- i_max = -1
179
165
  for anim in self.anims:
180
- if anim['name'] != 'draw':
166
+ if anim['name'] != 'sample':
181
167
  continue
182
168
  if self.x is None:
183
169
  continue
184
170
  if x < anim['delay'] or x > anim['delay'] + anim['duration']:
185
171
  continue
186
- t = self.get_t_from_x(anim,x)
187
172
 
188
- if 'alpha' in kwargs:
189
- alpha = to_np_array(kwargs['alpha'])
190
- if np.sum(alpha) == 0:
191
- kwargs['alpha'] = 1
173
+ #if len(data_x.shape) == 1:
174
+ #data_x = data_x.reshape((-1,1))
175
+ #data_y = data_y.reshape((-1,1))
192
176
 
193
- if anim['reverse']:
194
- i_max = max(round((1-t)*len(data_x)),0)
195
- else:
196
- i_max = min(round(t*len(data_x)),len(data_x))
177
+ i_min,i_max = self.get_i_min_i_max_sample(anim,x,len(data_x))
197
178
  break
198
179
 
199
- if i_max > 0:
200
- data_x = data_x[:i_max]
180
+ if i_min >= 0 and i_max >= 0:
181
+ data_x = data_x[i_min:i_max]
201
182
  if data_y is not None:
202
- data_y = data_y[:i_max]
203
- kwargs = self.resize_kwargs(kwargs,list(range(i_max)))
204
- elif i_max == 0:
205
- data_x = []
206
- data_y = []
207
- kwargs = self.resize_kwargs(kwargs,None)
183
+ data_y = data_y[i_min:i_max]
184
+ kwargs = self.resize_kwargs(kwargs,list(range(i_min,i_max)))
208
185
 
209
186
  #Third pass to morph
210
187
  for anim in self.anims:
@@ -287,6 +264,26 @@ class plotObject:
287
264
  if self.function is not None:
288
265
  self.function(data_x,data_y,x,kwargs)
289
266
 
267
+ def get_i_min_i_max_sample(self,anim,x,len_data):
268
+ if anim['reverse']:
269
+ _x = anim['duration'] - (x - anim['delay'])
270
+ else:
271
+ _x = x - anim['delay']
272
+ if type(anim['min']) == str and anim['min'] == 'start':
273
+ i_min = 0
274
+ else:
275
+ i_min = int((_x + anim['min'])/anim['duration']*len_data)
276
+ i_min = max(i_min,0)
277
+ if type(anim['max']) == str and anim['max'] == 'end':
278
+ i_max = len_data - 1
279
+ else:
280
+ if anim['max'] == anim['min']:
281
+ i_max = i_min + 1
282
+ else:
283
+ i_max = int((_x + anim['max'])/anim['duration']*len_data)
284
+ i_max = min(i_max,len_data-1)
285
+ return i_min,i_max
286
+
290
287
  def get_sequential_t(self,i,x,size,anim):
291
288
  delay = anim['delay'] + i/size*anim['duration']*(1-anim['subduration'])
292
289
  duration = anim['duration']*anim['subduration']
@@ -568,28 +565,7 @@ class plotObject:
568
565
  persistent : bool, default=True
569
566
  if True, the plot object will continue to be plotted after its last animation has played.
570
567
  """
571
- if sort is not None:
572
- if sort[-1] == 'x':
573
- idx = np.argsort(self.x)
574
- else:
575
- idx = np.argsort(self.y)
576
- if sort[0] == '-':
577
- idx = idx[::-1]
578
- self.x = self.x[idx]
579
- self.y = self.y[idx]
580
- self.kwargs = self.resize_kwargs(self.kwargs,idx)
581
-
582
- self.anims.append({
583
- 'name':'draw',
584
- 'duration':duration,
585
- 'delay':delay,
586
- 'easing':easing,
587
- 'reverse':reverse,
588
- 'persistent':persistent,
589
- 'played':False
590
- })
591
- self.compute_timings()
592
- return self
568
+ return self.subdraw('start',0,duration,reverse,sort,delay,easing,persistent)
593
569
 
594
570
  def scale(self,start_scale,end_scale,duration,center=None,delay=0,easing=None,persistent=True):
595
571
  """Scale a plot object from one size to another.
@@ -820,13 +796,17 @@ class plotObject:
820
796
  self.compute_timings()
821
797
  return self
822
798
 
823
- def sequence(self,duration,delay=0,easing=None,persistent=True):
799
+ def sequence(self,duration,reverse=False,sort=None,delay=0,easing=None,persistent=True):
824
800
  """Plot one datapoint or row of the dataset per frame.
825
801
 
826
802
  Parameters
827
803
  ----------
828
804
  duration : float
829
805
  the number of frames the animation runs from.
806
+ reverse : bool, default=False
807
+ if True, removes points sequentially instead of adding points.
808
+ sort : str, default=None
809
+ sorts the data to draw it in order. Can be 'x','-x','y','-y' to sort in ascending or descending order.
830
810
  delay : float, default=0
831
811
  the number of frames after what the animation starts playing.
832
812
  easing : callable, optional
@@ -836,11 +816,44 @@ class plotObject:
836
816
 
837
817
  If the dataset is 1-dimensional, this plots a single datapoint per frame, if 2D, it will plot one row per frame. This animation can be used if you have a predefined list of datapoints you want to animate frame-by-frame.
838
818
  """
819
+ return self.subdraw(0,0,duration,reverse,sort,delay,easing,persistent)
820
+
821
+ def subdraw(self,start_index,end_index,duration,reverse=False,sort=None,delay=0,easing=None,persistent=True):
822
+ """Plot multiple datapoints or rows of the dataset per frame, in the range
823
+ [current_frame_index - start_index;current_frame_index + end_index]
824
+
825
+ Parameters
826
+ ----------
827
+ start_index : int or str
828
+ start index around the current frame index for the datapoints to plot. If str, can be 'start' to force
829
+ the range to start at 0 or 'end' to force it to end at the last datapoint.
830
+ end_index : int or str
831
+ end index around the current frame index for the datapoints to plot. If str, can be 'start' to force
832
+ the range to start at 0 or 'end' to force it to end at the last datapoint.
833
+ duration : float
834
+ the number of frames the animation runs from.
835
+ reverse : bool, default=False
836
+ if True, removes points sequentially instead of adding points.
837
+ sort : str, default=None
838
+ sorts the data to draw it in order. Can be 'x','-x','y','-y' to sort in ascending or descending order.
839
+ delay : float, default=0
840
+ the number of frames after what the animation starts playing.
841
+ easing : callable, optional
842
+ the easing used for this animation. If None, a linear easing is applied.
843
+ persistent : bool, default=True
844
+ if True, the plot object will continue to be plotted after its last animation has played.
845
+ """
846
+ if sort is not None:
847
+ self.sort_data(sort)
848
+
839
849
  self.anims.append({
840
- 'name':'sequence',
850
+ 'name':'sample',
851
+ 'min':start_index,
852
+ 'max':end_index,
841
853
  'duration':duration,
842
854
  'delay':delay,
843
855
  'easing':easing,
856
+ 'reverse':reverse,
844
857
  'persistent':persistent,
845
858
  'played':False
846
859
  })
@@ -851,6 +864,8 @@ class plotObject:
851
864
  if self.obj is not None and self.base_color is None:
852
865
  if isinstance(self.obj,(list,np.ndarray)):
853
866
  self.base_color = self.obj[0].get_color()
867
+ elif isinstance(self.obj,mpl.patches.Polygon):
868
+ self.base_color = self.obj.get_fc()
854
869
  elif isinstance(self.obj,mpl.container.BarContainer):
855
870
  self.base_color = self.obj[0].get_fc()
856
871
  elif hasattr(self.obj,'get_color'):
@@ -933,23 +948,8 @@ class plotObject:
933
948
  bbox = mpl.transforms.Bbox.union(bboxes)
934
949
  cx = (bbox.x0 + bbox.x1) / 2
935
950
  cy = (bbox.y0 + bbox.y1) / 2
936
- elif self.mpl_obj_type == mpl.collections.Collection:
937
- offsets = self.obj.get_offsets()
938
- if len(offsets) == 0:
939
- cx,cy = 0,0
940
- else:
941
- cx = np.mean(offsets[:, 0])
942
- cy = np.mean(offsets[:, 1])
943
- elif self.mpl_obj_type == mpl.collections.QuadMesh:
944
- coords = self.obj.get_coordinates()
945
- x0 = np.nanmin(coords[..., 0])
946
- x1 = np.nanmax(coords[..., 0])
947
- y0 = np.nanmin(coords[..., 1])
948
- y1 = np.nanmax(coords[..., 1])
949
-
950
- cx = 0.5 * (x0 + x1)
951
- cy = 0.5 * (y0 + y1)
952
- elif self.mpl_obj_type == mpl.patches.Rectangle:
951
+ elif self.mpl_obj_type == mpl.patches.Rectangle and \
952
+ (self.mpl_plot_type == plt.hist or self.mpl_plot_type == plt.bar):
953
953
  rects = self.obj.patches
954
954
  if isinstance(rects, list) and len(rects) > 0:
955
955
  centers_x = []
@@ -966,15 +966,51 @@ class plotObject:
966
966
  bbox = self.obj.get_bbox()
967
967
  cx = (bbox.x0 + bbox.x1) / 2
968
968
  cy = (bbox.y0 + bbox.y1) / 2
969
+ elif self.mpl_obj_type == mpl.patches.Polygon or \
970
+ self.mpl_obj_type == mpl.patches.Arrow or \
971
+ self.mpl_obj_type == mpl.patches.Rectangle or \
972
+ self.mpl_obj_type == mpl.patches.RegularPolygon or \
973
+ self.mpl_obj_type == mpl.patches.Wedge or \
974
+ self.mpl_obj_type == mpl.patches.FancyArrow:
975
+ bbox = self.obj.get_extents()
976
+ cx = (bbox.x0 + bbox.x1) / 2
977
+ cy = (bbox.y0 + bbox.y1) / 2
978
+ elif self.mpl_obj_type == mpl.collections.Collection:
979
+ offsets = self.obj.get_offsets()
980
+ if len(offsets) == 0:
981
+ cx,cy = 0,0
982
+ else:
983
+ cx = np.mean(offsets[:, 0])
984
+ cy = np.mean(offsets[:, 1])
985
+ elif self.mpl_obj_type == mpl.collections.QuadMesh:
986
+ coords = self.obj.get_coordinates()
987
+ x0 = np.nanmin(coords[..., 0])
988
+ x1 = np.nanmax(coords[..., 0])
989
+ y0 = np.nanmin(coords[..., 1])
990
+ y1 = np.nanmax(coords[..., 1])
991
+
992
+ cx = 0.5 * (x0 + x1)
993
+ cy = 0.5 * (y0 + y1)
969
994
  elif self.mpl_obj_type == mpl.collections.FillBetweenPolyCollection:
970
995
  bboxes = [p.get_extents() for p in self.obj.get_paths() if p.vertices.size]
971
996
  bbox = mpl.transforms.Bbox.union(bboxes)
972
997
  cx = 0.5 * (bbox.x0 + bbox.x1)
973
998
  cy = 0.5 * (bbox.y0 + bbox.y1)
974
- elif self.mpl_obj_type == mpl.patches.Circle:
999
+ elif self.mpl_obj_type == mpl.patches.Circle or self.mpl_obj_type == mpl.patches.Ellipse:
975
1000
  cx,cy = self.obj.get_center()
976
1001
  return (cx,cy)
977
1002
 
1003
+ def sort_data(self,sort):
1004
+ if sort[-1] == 'x':
1005
+ idx = np.argsort(self.x)
1006
+ else:
1007
+ idx = np.argsort(self.y)
1008
+ if sort[0] == '-':
1009
+ idx = idx[::-1]
1010
+ self.x = self.x[idx]
1011
+ self.y = self.y[idx]
1012
+ self.kwargs = self.resize_kwargs(self.kwargs,idx)
1013
+
978
1014
  class axis_zoom(plotObject):
979
1015
  """
980
1016
  Zooms into the axis given a zoom value.
@@ -4298,7 +4334,7 @@ class Arrow(plotObject):
4298
4334
  properties.
4299
4335
  """
4300
4336
  def __init__(self,x,y,dx,dy,width=1.0,easing=None,axis=None, *args, **kwargs):
4301
- self.mpl_obj_type = mpl.patches.Circle
4337
+ self.mpl_obj_type = mpl.patches.Arrow
4302
4338
  kwargs['x'] = x
4303
4339
  kwargs['y'] = y
4304
4340
  kwargs['dx'] = dx
@@ -4331,7 +4367,7 @@ class Ellipse(plotObject):
4331
4367
  Rotation in degrees anti-clockwise.
4332
4368
  """
4333
4369
  def __init__(self,xy,width,height,angle=0,easing=None,axis=None, *args, **kwargs):
4334
- self.mpl_obj_type = mpl.patches.Circle
4370
+ self.mpl_obj_type = mpl.patches.Ellipse
4335
4371
  kwargs['xy'] = xy
4336
4372
  kwargs['width'] = width
4337
4373
  kwargs['height'] = height
@@ -4386,7 +4422,7 @@ class FancyArrow(plotObject):
4386
4422
  length_includes_head=False,head_width=None,head_length=None,
4387
4423
  shape='full',overhang=0,head_starts_at_zero=False,
4388
4424
  easing=None,axis=None, *args, **kwargs):
4389
- self.mpl_obj_type = mpl.patches.Circle
4425
+ self.mpl_obj_type = mpl.patches.FancyArrow
4390
4426
  kwargs['x'] = x
4391
4427
  kwargs['y'] = y
4392
4428
  kwargs['dx'] = dx
@@ -4429,7 +4465,7 @@ class Polygon(plotObject):
4429
4465
  points).
4430
4466
  """
4431
4467
  def __init__(self,xy,closed=True,easing=None,axis=None, *args, **kwargs):
4432
- self.mpl_obj_type = mpl.patches.Circle
4468
+ self.mpl_obj_type = mpl.patches.Polygon
4433
4469
  kwargs['xy'] = xy
4434
4470
  kwargs['closed'] = closed
4435
4471
  super().__init__(easing=easing,axis=axis,*args, **kwargs)
@@ -4477,7 +4513,7 @@ class Rectangle(plotObject):
4477
4513
  coordinate.
4478
4514
  """
4479
4515
  def __init__(self,xy,width,height,angle=0.0,rotation_point='xy',easing=None,axis=None, *args, **kwargs):
4480
- self.mpl_obj_type = mpl.patches.Circle
4516
+ self.mpl_obj_type = mpl.patches.Rectangle
4481
4517
  kwargs['xy'] = xy
4482
4518
  kwargs['width'] = width
4483
4519
  kwargs['height'] = height
@@ -4518,7 +4554,7 @@ class RegularPolygon(plotObject):
4518
4554
  The polygon rotation angle (in radians).
4519
4555
  """
4520
4556
  def __init__(self,xy,numVertices,radius=5,orientation=0,easing=None,axis=None, *args, **kwargs):
4521
- self.mpl_obj_type = mpl.patches.Circle
4557
+ self.mpl_obj_type = mpl.patches.RegularPolygon
4522
4558
  kwargs['xy'] = xy
4523
4559
  kwargs['numVertices'] = numVertices
4524
4560
  kwargs['radius'] = radius
@@ -4548,7 +4584,7 @@ class Wedge(plotObject):
4548
4584
  to outer radius *r*.
4549
4585
  """
4550
4586
  def __init__(self,center,r,theta1,theta2,width=None,easing=None,axis=None, *args, **kwargs):
4551
- self.mpl_obj_type = mpl.patches.Circle
4587
+ self.mpl_obj_type = mpl.patches.Wedge
4552
4588
  kwargs['center'] = center
4553
4589
  kwargs['r'] = r
4554
4590
  kwargs['theta1'] = theta1
@@ -4757,5 +4793,7 @@ class bar(plotObject):
4757
4793
  if len(data_x) == 0:
4758
4794
  data_x = [0]
4759
4795
  data_y = [0]
4796
+ kwargs['width'] = [0]
4797
+ kwargs['bottom'] = [0]
4760
4798
  obj = self.axis.bar(data_x,data_y,**kwargs)
4761
4799
  self.obj = obj
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diplotocus
3
- Version: 0.6.0
3
+ Version: 0.6.3
4
4
  Summary: A python package to generate animations of matplotlib objects.
5
5
  Author-email: Tristan Boin <tristan.boin@obspm.fr>
6
6
  License-Expression: MIT
@@ -1 +0,0 @@
1
- __version__ = "0.6.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes