plotlp 0.1.9__tar.gz → 0.1.11__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 (62) hide show
  1. {plotlp-0.1.9 → plotlp-0.1.11}/PKG-INFO +4 -1
  2. {plotlp-0.1.9 → plotlp-0.1.11}/pyproject.toml +2 -2
  3. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/__init__.py +1 -0
  4. plotlp-0.1.11/src/plotlp/modules/make_animation_LP/make_animation.py +176 -0
  5. plotlp-0.1.11/src/plotlp/modules/make_animation_LP/test_make_animation.py +79 -0
  6. plotlp-0.1.11/src/plotlp/modules/subplots_LP/_functions/__template__.py +19 -0
  7. plotlp-0.1.11/src/plotlp/py.typed +0 -0
  8. plotlp-0.1.11/src/plotlp/routines/__init__.py +0 -0
  9. {plotlp-0.1.9 → plotlp-0.1.11}/README.md +0 -0
  10. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledAxes_LP/StyledAxes.py +0 -0
  11. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledAxes_LP/__init__.py +0 -0
  12. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledAxes_LP/_functions/__init__.py +0 -0
  13. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledAxes_LP/_functions/__template__.py +0 -0
  14. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledAxes_LP/test_StyledAxes.py +0 -0
  15. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledFigure_LP/StyledFigure.py +0 -0
  16. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledFigure_LP/__init__.py +0 -0
  17. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledFigure_LP/_functions/__init__.py +0 -0
  18. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledFigure_LP/_functions/__template__.py +0 -0
  19. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/StyledFigure_LP/test_StyledFigure.py +0 -0
  20. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/__init__.py +0 -0
  21. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/cmap_LP/__init__.py +0 -0
  22. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/cmap_LP/_functions/__init__.py +0 -0
  23. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/cmap_LP/_functions/__template__.py +0 -0
  24. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/cmap_LP/cmap.py +0 -0
  25. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/cmap_LP/test_cmap.py +0 -0
  26. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/color_LP/__init__.py +0 -0
  27. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/color_LP/_functions/__init__.py +0 -0
  28. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/color_LP/_functions/__template__.py +0 -0
  29. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/color_LP/color.py +0 -0
  30. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/color_LP/test_color.py +0 -0
  31. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/figure_LP/__init__.py +0 -0
  32. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/figure_LP/_functions/__init__.py +0 -0
  33. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/figure_LP/_functions/__template__.py +0 -0
  34. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/figure_LP/figure.py +0 -0
  35. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/figure_LP/test_figure.py +0 -0
  36. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/imgfigure_LP/__init__.py +0 -0
  37. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/imgfigure_LP/_functions/__init__.py +0 -0
  38. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/imgfigure_LP/_functions/__template__.py +0 -0
  39. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/imgfigure_LP/imgfigure.py +0 -0
  40. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/imgfigure_LP/test_imgfigure.py +0 -0
  41. {plotlp-0.1.9/src/plotlp/modules/plt_LP → plotlp-0.1.11/src/plotlp/modules/make_animation_LP}/__init__.py +0 -0
  42. {plotlp-0.1.9/src/plotlp/modules/plt_LP → plotlp-0.1.11/src/plotlp/modules/make_animation_LP}/_functions/__init__.py +0 -0
  43. {plotlp-0.1.9/src/plotlp/modules/plt_LP → plotlp-0.1.11/src/plotlp/modules/make_animation_LP}/_functions/__template__.py +0 -0
  44. {plotlp-0.1.9/src/plotlp/modules/style_LP → plotlp-0.1.11/src/plotlp/modules/plt_LP}/__init__.py +0 -0
  45. {plotlp-0.1.9/src/plotlp/modules/style_LP → plotlp-0.1.11/src/plotlp/modules/plt_LP}/_functions/__init__.py +0 -0
  46. {plotlp-0.1.9/src/plotlp/modules/style_LP → plotlp-0.1.11/src/plotlp/modules/plt_LP}/_functions/__template__.py +0 -0
  47. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/plt_LP/plt.py +0 -0
  48. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/plt_LP/test_plt.py +0 -0
  49. {plotlp-0.1.9/src/plotlp/modules/style_LP/styles → plotlp-0.1.11/src/plotlp/modules/style_LP}/__init__.py +0 -0
  50. {plotlp-0.1.9/src/plotlp/modules/subplots_LP → plotlp-0.1.11/src/plotlp/modules/style_LP/_functions}/__init__.py +0 -0
  51. {plotlp-0.1.9/src/plotlp/modules/subplots_LP → plotlp-0.1.11/src/plotlp/modules/style_LP}/_functions/__template__.py +0 -0
  52. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/style_LP/style.py +0 -0
  53. {plotlp-0.1.9/src/plotlp/modules/subplots_LP/_functions → plotlp-0.1.11/src/plotlp/modules/style_LP/styles}/__init__.py +0 -0
  54. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/style_LP/styles/darkLP.py +0 -0
  55. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/style_LP/styles/default.py +0 -0
  56. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/style_LP/styles/lightLP.py +0 -0
  57. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/style_LP/styles/styleLP.py +0 -0
  58. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/style_LP/test_style.py +0 -0
  59. {plotlp-0.1.9/src/plotlp/routines → plotlp-0.1.11/src/plotlp/modules/subplots_LP}/__init__.py +0 -0
  60. /plotlp-0.1.9/src/plotlp/py.typed → /plotlp-0.1.11/src/plotlp/modules/subplots_LP/_functions/__init__.py +0 -0
  61. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/subplots_LP/subplots.py +0 -0
  62. {plotlp-0.1.9 → plotlp-0.1.11}/src/plotlp/modules/subplots_LP/test_subplots.py +0 -0
@@ -1,12 +1,15 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: plotlp
3
- Version: 0.1.9
3
+ Version: 0.1.11
4
4
  Summary: A library wrapper around matplotlib for custom plots.
5
5
  Requires-Dist: corelp
6
6
  Requires-Dist: cycler
7
+ Requires-Dist: imageio
8
+ Requires-Dist: imageio-ffmpeg
7
9
  Requires-Dist: matplotlib
8
10
  Requires-Dist: numpy
9
11
  Requires-Dist: pillow
12
+ Requires-Dist: tifffile
10
13
  Requires-Python: >=3.12
11
14
  Description-Content-Type: text/markdown
12
15
 
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "plotlp"
3
- version = "0.1.9"
3
+ version = "0.1.11"
4
4
  description = "A library wrapper around matplotlib for custom plots."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
7
- dependencies = [ "corelp", "cycler", "matplotlib", "numpy", "pillow",]
7
+ dependencies = [ "corelp", "cycler", "imageio", "imageio-ffmpeg", "matplotlib", "numpy", "pillow", "tifffile",]
8
8
 
9
9
  [build-system]
10
10
  requires = [ "uv_build",]
@@ -19,6 +19,7 @@ sources = {
19
19
  'color': 'plotlp.modules.color_LP.color',
20
20
  'figure': 'plotlp.modules.figure_LP.figure',
21
21
  'imgfigure': 'plotlp.modules.imgfigure_LP.imgfigure',
22
+ 'make_animation': 'plotlp.modules.make_animation_LP.make_animation',
22
23
  'plt': 'plotlp.modules.plt_LP.plt',
23
24
  'style': 'plotlp.modules.style_LP.style',
24
25
  'subplots': 'plotlp.modules.subplots_LP.subplots'
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-02-08
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : make_animation
8
+
9
+ """
10
+ This module allows to create animations from plots
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+ from corelp import Path
17
+ from matplotlib import pyplot as plt
18
+ import imageio
19
+ import io
20
+ import numpy as np
21
+ import tifffile as tiff
22
+
23
+
24
+
25
+ # %% Function
26
+ def make_animation(export_path:str, name=None, fps:float=24., loop:bool=True, pingpong:bool=False, extension:str='.gif', iterator=range, *, extension2animate='.png', array2animate=None, tif2animate=None, key2animate=None, function2animate=None, parameter2animate=None, value2animate=None, dpi:int=300, **kwargs) :
27
+ '''
28
+ This module allows to create animations from plots, chose from animating images from a folder or through live generation with a function
29
+
30
+ Parameters
31
+ ----------
32
+ export_path : str or pathlib.Path
33
+ Path where to save animation.
34
+ name : str
35
+ name of animation file.
36
+ fps : float
37
+ Animation Frames Per Second.
38
+ loop : bool
39
+ True to loop animation.
40
+ pingpong : bool
41
+ True to make animation back and forth.
42
+ extension2animate : str
43
+ Extension of animated function in folder.
44
+ array2animate : function
45
+ Array to animate.
46
+ tif2animate : function
47
+ Array to tif2animate.
48
+ key2animate : function
49
+ Keys of tif to animate.
50
+ function2animate : function
51
+ Function to animate.
52
+ parameter2animate : str
53
+ Name of parameter to animate.
54
+ **kwargs : dict
55
+ Other fixed parameter for function, the animated parameter will be ignored.
56
+
57
+ Examples
58
+ --------
59
+ >>> from plotlp import make_animation
60
+ ...
61
+ >>> make_animation(saving_path, "myanimation", function2animate=myplottingfunction, parameter2animate=""myparameter", value2animate=np.linspace(mini,maxi,1000), **kwargs) # from function
62
+ >>> make_animation(saving_path, "myanimation", extension2animate='.tif') # from folder
63
+ '''
64
+
65
+ # Path
66
+ export_path = Path(export_path)
67
+ if name is not None : export_path = export_path / name
68
+ export_path = export_path.with_suffix(extension)
69
+ fps = float(fps)
70
+
71
+ # Animation modalities
72
+ if function2animate is not None :
73
+ function_animation(export_path, fps, loop, pingpong, function2animate, parameter2animate, value2animate, dpi, iterator, **kwargs)
74
+ elif array2animate is not None :
75
+ array_animation(export_path, fps, loop, pingpong, array2animate, iterator)
76
+ elif tif2animate is not None :
77
+ tif_animation(export_path, fps, loop, pingpong, tif2animate, key2animate, iterator)
78
+ else :
79
+ folder_animation(export_path, fps, loop, pingpong, extension2animate, iterator)
80
+
81
+
82
+
83
+ def folder_animation(export_path, fps, loop, pingpong, extension2animate, iterator) :
84
+ folder_path = export_path.with_suffix('')
85
+
86
+ # List and naturally sort all PNG files
87
+ image_files = [img for img in folder_path.iterdir() if img.suffix == extension2animate]
88
+ if not image_files:
89
+ raise ValueError("No PNG images found in the folder.")
90
+ image_files.sort()
91
+ if pingpong:
92
+ image_files = image_files + image_files[-2:0:-1]
93
+
94
+ # Stream images one at a time and save to GIF
95
+ with get_writer(export_path, fps, loop) as writer :
96
+ for file in iterator(image_files):
97
+ frame = imageio.imread(file)
98
+ writer.append_data(frame)
99
+
100
+
101
+
102
+ def array_animation(export_path, fps, loop, pingpong, array2animate, iterator) :
103
+ array2animate = np.asarray(array2animate)
104
+ if pingpong:
105
+ array2animate = np.concatenate(
106
+ (array2animate, array2animate[-2:0:-1]),
107
+ axis=0
108
+ )
109
+
110
+ # Write frames directly
111
+ with get_writer(export_path, fps, loop) as writer:
112
+ for frame in iterator(array2animate):
113
+ frame = np.clip(frame / frame.max() * 255, 0, 255).astype(np.uint8)
114
+ writer.append_data(frame)
115
+
116
+
117
+
118
+ def tif_animation(export_path, fps, loop, pingpong, tif2animate, key2animate, iterator) :
119
+ tif2animate = (export_path.parent / tif2animate).with_suffix('.tif')
120
+ if key2animate is None :
121
+ with tiff.TiffFile(tif2animate) as tif:
122
+ num_pages = len(tif.pages)
123
+ key2animate = np.arange(num_pages)
124
+ if pingpong:
125
+ key2animate = np.concatenate(
126
+ (key2animate, key2animate[-2:0:-1]),
127
+ axis=0
128
+ )
129
+
130
+ # Write frames directly
131
+ with get_writer(export_path, fps, loop) as writer:
132
+ for i in iterator(key2animate):
133
+ frame = tiff.imread(tif2animate, key=i)
134
+ frame = np.clip(frame / frame.max() * 255, 0, 255).astype(np.uint8)
135
+ writer.append_data(frame)
136
+
137
+
138
+
139
+ def function_animation(export_path, fps, loop, pingpong, function2animate, parameter2animate, value2animate, dpi, iterator, **kwargs) :
140
+
141
+ # List of parameter
142
+ if parameter2animate is None:
143
+ raise ValueError("parameter2animate must be provided when function2animate is used")
144
+ if pingpong:
145
+ value2animate = np.hstack((value2animate, value2animate[-2:0:-1]))
146
+
147
+ # Stream images one at a time and save to GIF
148
+ with get_writer(export_path, fps, loop) as writer :
149
+ for value in iterator(value2animate):
150
+ kwargs[parameter2animate] = value
151
+ fig = function2animate(**kwargs)
152
+ fig.set_dpi(dpi)
153
+ buf = io.BytesIO()
154
+ fig.savefig(buf, format="png", dpi=dpi)
155
+ buf.seek(0)
156
+ frame = imageio.imread(buf)
157
+ writer.append_data(frame)
158
+ plt.close(fig)
159
+
160
+
161
+
162
+ def get_writer(export_path, fps, loop) :
163
+ match export_path.suffix :
164
+ case '.mp4' :
165
+ return imageio.get_writer(export_path, fps=fps, codec='libx264', quality=8, format='ffmpeg')
166
+ case '.gif' :
167
+ return imageio.get_writer(export_path, mode='I', fps=fps, loop=0 if loop else 1)
168
+ case _ :
169
+ raise SyntaxError(f'Animation extension not recognized: -->{export_path.suffix}<--')
170
+
171
+
172
+
173
+ # %% Test function run
174
+ if __name__ == "__main__":
175
+ from corelp import test
176
+ test(__file__)
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-02-08
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : template_[library]
7
+ # Module : make_animation
8
+
9
+ """
10
+ This file allows to test make_animation
11
+
12
+ make_animation : This module allows to create animations from plots
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import print, debug
19
+ import pytest
20
+ from template_[lowerlib] import make_animation
21
+ debug_folder = debug(__file__)
22
+
23
+
24
+
25
+ # %% Function test
26
+ def test_function() :
27
+ '''
28
+ Test make_animation function
29
+ '''
30
+ print('Hello world!')
31
+
32
+
33
+
34
+ # %% Instance fixture
35
+ @pytest.fixture()
36
+ def instance() :
37
+ '''
38
+ Create a new instance at each test function
39
+ '''
40
+ return make_animation()
41
+
42
+ def test_instance(instance) :
43
+ '''
44
+ Test on fixture
45
+ '''
46
+ pass
47
+
48
+
49
+ # %% Returns test
50
+ @pytest.mark.parametrize("args, kwargs, expected, message", [
51
+ #([], {}, None, ""),
52
+ ([], {}, None, ""),
53
+ ])
54
+ def test_returns(args, kwargs, expected, message) :
55
+ '''
56
+ Test make_animation return values
57
+ '''
58
+ assert make_animation(*args, **kwargs) == expected, message
59
+
60
+
61
+
62
+ # %% Error test
63
+ @pytest.mark.parametrize("args, kwargs, error, error_message", [
64
+ #([], {}, None, ""),
65
+ ([], {}, None, ""),
66
+ ])
67
+ def test_errors(args, kwargs, error, error_message) :
68
+ '''
69
+ Test make_animation error values
70
+ '''
71
+ with pytest.raises(error, match=error_message) :
72
+ make_animation(*args, **kwargs)
73
+
74
+
75
+
76
+ # %% Test function run
77
+ if __name__ == "__main__":
78
+ from corelp import test
79
+ test(__file__)
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Author : Lancelot PINCET
4
+ # GitHub : https://github.com/LancelotPincet
5
+
6
+
7
+
8
+ # %% Libraries
9
+
10
+
11
+
12
+
13
+ # %% Function
14
+ def temp(**kwargs) :
15
+ '''
16
+ TODO
17
+ '''
18
+
19
+ print('Hello world!')
File without changes
File without changes
File without changes