plotlp 0.1.2__tar.gz → 0.1.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 (44) hide show
  1. {plotlp-0.1.2 → plotlp-0.1.3}/PKG-INFO +3 -8
  2. {plotlp-0.1.2 → plotlp-0.1.3}/pyproject.toml +7 -2
  3. plotlp-0.1.3/src/plotlp/modules/StyledAxes_LP/StyledAxes.py +206 -0
  4. plotlp-0.1.3/src/plotlp/modules/StyledAxes_LP/test_StyledAxes.py +27 -0
  5. plotlp-0.1.3/src/plotlp/modules/StyledFigure_LP/StyledFigure.py +293 -0
  6. plotlp-0.1.3/src/plotlp/modules/StyledFigure_LP/test_StyledFigure.py +27 -0
  7. plotlp-0.1.3/src/plotlp/modules/cmap_LP/cmap.py +210 -0
  8. plotlp-0.1.3/src/plotlp/modules/cmap_LP/test_cmap.py +64 -0
  9. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/color_LP/color.py +86 -93
  10. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/color_LP/test_color.py +1 -1
  11. plotlp-0.1.3/src/plotlp/modules/figure_LP/figure.py +56 -0
  12. plotlp-0.1.3/src/plotlp/modules/figure_LP/test_figure.py +62 -0
  13. plotlp-0.1.3/src/plotlp/modules/imgfigure_LP/imgfigure.py +62 -0
  14. plotlp-0.1.3/src/plotlp/modules/imgfigure_LP/test_imgfigure.py +39 -0
  15. plotlp-0.1.3/src/plotlp/modules/plt_LP/__init__.py +0 -0
  16. plotlp-0.1.3/src/plotlp/modules/plt_LP/plt.py +24 -0
  17. plotlp-0.1.3/src/plotlp/modules/plt_LP/test_plt.py +27 -0
  18. plotlp-0.1.3/src/plotlp/modules/style_LP/__init__.py +0 -0
  19. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/style_LP/style.py +2 -9
  20. plotlp-0.1.3/src/plotlp/modules/style_LP/styles/__init__.py +0 -0
  21. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/style_LP/styles/darkLP.py +1 -1
  22. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/style_LP/styles/lightLP.py +1 -1
  23. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/style_LP/styles/styleLP.py +1 -1
  24. plotlp-0.1.3/src/plotlp/modules/subplots_LP/__init__.py +0 -0
  25. plotlp-0.1.3/src/plotlp/modules/subplots_LP/subplots.py +54 -0
  26. plotlp-0.1.3/src/plotlp/modules/subplots_LP/test_subplots.py +54 -0
  27. plotlp-0.1.3/src/plotlp/modules.json +56 -0
  28. plotlp-0.1.3/src/plotlp/py.typed +0 -0
  29. plotlp-0.1.3/src/plotlp/scripts/__init__.py +0 -0
  30. plotlp-0.1.2/src/plotlp/modules/cmap_LP/cmap.py +0 -132
  31. plotlp-0.1.2/src/plotlp/modules/cmap_LP/test_cmap.py +0 -79
  32. plotlp-0.1.2/src/plotlp/modules.json +0 -20
  33. {plotlp-0.1.2 → plotlp-0.1.3}/README.md +0 -0
  34. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/__init__.py +0 -0
  35. {plotlp-0.1.2/src/plotlp/modules → plotlp-0.1.3/src/plotlp/modules/StyledAxes_LP}/__init__.py +0 -0
  36. {plotlp-0.1.2/src/plotlp/modules/cmap_LP → plotlp-0.1.3/src/plotlp/modules/StyledFigure_LP}/__init__.py +0 -0
  37. {plotlp-0.1.2/src/plotlp/modules/color_LP → plotlp-0.1.3/src/plotlp/modules}/__init__.py +0 -0
  38. {plotlp-0.1.2/src/plotlp/modules/style_LP → plotlp-0.1.3/src/plotlp/modules/cmap_LP}/__init__.py +0 -0
  39. {plotlp-0.1.2/src/plotlp/modules/style_LP/styles → plotlp-0.1.3/src/plotlp/modules/color_LP}/__init__.py +0 -0
  40. {plotlp-0.1.2/src/plotlp/scripts → plotlp-0.1.3/src/plotlp/modules/figure_LP}/__init__.py +0 -0
  41. /plotlp-0.1.2/src/plotlp/py.typed → /plotlp-0.1.3/src/plotlp/modules/imgfigure_LP/__init__.py +0 -0
  42. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/style_LP/styles/default.py +0 -0
  43. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/modules/style_LP/test_style.py +0 -0
  44. {plotlp-0.1.2 → plotlp-0.1.3}/src/plotlp/scripts.json +0 -0
@@ -1,17 +1,12 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: plotlp
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: A library wrapper around matplotlib for custom plots.
5
5
  Requires-Dist: corelp
6
6
  Requires-Dist: cycler
7
- Requires-Dist: ipykernel
8
7
  Requires-Dist: matplotlib
9
- Requires-Dist: pytest
10
- Requires-Dist: sphinx
11
- Requires-Dist: sphinx-design
12
- Requires-Dist: sphinx-rtd-theme
13
- Requires-Dist: spyder-kernels
14
- Requires-Dist: toml
8
+ Requires-Dist: numpy
9
+ Requires-Dist: pillow
15
10
  Requires-Python: >=3.12
16
11
  Description-Content-Type: text/markdown
17
12
 
@@ -1,15 +1,20 @@
1
1
  [project]
2
2
  name = "plotlp"
3
- version = "0.1.2"
3
+ version = "0.1.3"
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", "ipykernel", "matplotlib", "pytest", "sphinx", "sphinx-design", "sphinx-rtd-theme", "spyder-kernels", "toml",]
7
+ dependencies = [ "corelp", "cycler", "matplotlib", "numpy", "pillow",]
8
8
 
9
9
  [build-system]
10
10
  requires = [ "uv_build>=0.8.8,<0.9.0",]
11
11
  build-backend = "uv_build"
12
12
 
13
+ [dependency-groups]
14
+ dev = [ "pytest",]
15
+ docs = [ "sphinx", "sphinx-design", "sphinx-rtd-theme", "toml",]
16
+ anaconda = [ "ipykernel", "spyder-kernels",]
17
+
13
18
  [tool.uv]
14
19
  required-environments = [ "sys_platform == 'linux' and platform_machine == 'x86_64'", "sys_platform == 'win32' and (platform_machine == 'AMD64' or platform_machine == 'x86_64')",]
15
20
 
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-12-11
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : StyledAxes
8
+
9
+ """
10
+ A class using stored styles inside.
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+ from matplotlib.axes import Axes
17
+ from matplotlib import pyplot as plt
18
+ import matplotlib.projections as projections
19
+ import inspect
20
+ from corelp import prop
21
+ import numpy as np
22
+ from matplotlib.patches import Rectangle
23
+ from mpl_toolkits.axes_grid1.inset_locator import inset_axes
24
+
25
+
26
+
27
+ # %% Class
28
+ class StyledAxes(Axes) :
29
+ f'''
30
+ A class using stored styles inside.
31
+
32
+ Attributes
33
+ ----------
34
+ style : dict
35
+ associated figure style.
36
+ polish_imscale : bool
37
+ True to polish automatically imscale
38
+ polish_grids : bool
39
+ True to polish automatically grids
40
+ polish_noborder : bool
41
+ True to polish automatically no boders
42
+ polish_equiscale : bool
43
+ True to polish automatically equiscale
44
+
45
+ Examples
46
+ --------
47
+ >>> from plotlp import subplots
48
+ ...
49
+ >>> fig, axes = subplots(nrows=2, ncols=2) # StyledFigure, StyledAxes
50
+ >>> axis = fig.axis # StyledAxes, current axis of fig
51
+ >>> axis.polish() # applies all the polish methods for all the "polish_attr" attributes
52
+ >>> axis.grids() # applies the polish grids, adds major and minor grids
53
+ >>> axis.imscale() # applies the polish imscale, sets x and y limits to images borders
54
+ >>> axis.noborder() # applies the polish no border, removes axis borders
55
+ >>> axis.equiscale() # applies the polish equiscale, x and y unit have same size on plot
56
+ >>> axis.implot(image, x, y, w, h) # plots an image to the coordinates, deformes to fit the box defined
57
+ '''
58
+
59
+ name = "styled"
60
+ @property
61
+ def style(self) :
62
+ return self.figure.style
63
+
64
+ # Imshow
65
+ def imshow(self, X, *args, barname=None, coordinates=None, **kwargs) :
66
+ with plt.style.context(self.style):
67
+ if coordinates is not None :
68
+ x, y = coordinates
69
+ dx, dy = (x[-1]-x[0]) / (len(x)-1) / 2, (y[-1]-y[0]) / (len(y)-1) / 2
70
+ extent = [x[0]-dx, x[-1]+dx, y[0]-dy, y[-1]+dy]
71
+ kwargs.update(dict(extent=extent, aspect='auto', origin='lower'))
72
+ im = super().imshow(X, *args, **kwargs)
73
+ if coordinates is not None :
74
+ self.invert_yaxis()
75
+ Ny, Nx = X.shape
76
+ self.set_box_aspect(Ny / Nx)
77
+ self.polish_axis = False
78
+ if barname is not None :
79
+ self.figure.colorbar(im, barname=barname)
80
+
81
+ return im
82
+
83
+ # Pcolormesh
84
+ def pcolormesh(self, *args, cmap=None, **kwargs):
85
+ with plt.style.context(self.style):
86
+ if cmap is None:
87
+ cmap = plt.get_cmap(plt.rcParams['image.cmap'])
88
+ return super().pcolormesh(*args, cmap=cmap, **kwargs)
89
+
90
+ # Implot
91
+ def implot(self, img, x, y, w, h, zorder=3, **kwargs) :
92
+ newaxe = inset_axes(self, [x, y, w, h], transform=self.transData, zorder=zorder, axes_class=StyledAxes)
93
+ newaxe.set_axis_off()
94
+ kw = {'aspect':'auto','extent':[x, x+w, y, y+h],'origin':'lower'}
95
+ kw.update(kwargs)
96
+ im = newaxe.imshow(img, **kw)
97
+ clip_rect = Rectangle((0, 0), 1, 1, transform=self.transAxes, facecolor="none")
98
+ im.set_clip_path(clip_rect)
99
+ return im
100
+
101
+
102
+ ### --- Polish functions ---
103
+
104
+
105
+
106
+ polish_axis = True
107
+ def polish(self) :
108
+ if not self.polish_axis : return
109
+ if self.polish_grids : self.grids()
110
+ if self.polish_imscale : self.imscale()
111
+ if self.polish_noborders : self.noborders()
112
+ if self.polish_equiscale : self.equiscale()
113
+
114
+ # grids
115
+ @prop()
116
+ def polish_grids(self) :
117
+ return len(self.lines) > 0 or len(self.collections) > 0
118
+ grid_major = {'linestyle':'-', 'alpha':1}
119
+ grid_minor = {'linestyle':'--', 'alpha':0.5}
120
+ def grids(self) :
121
+ with plt.style.context(self.style) :
122
+ if self.grid_major is not None and len(self.grid_major) > 0 :
123
+ self.grid(which='major',**self.grid_major)
124
+ if self.grid_minor is not None and len(self.grid_minor) > 0 :
125
+ self.minorticks_on() # force enabling minor ticks
126
+ self.grid(which='minor',**self.grid_minor)
127
+
128
+ # imscale
129
+ @prop()
130
+ def polish_imscale(self) :
131
+ return len(self.get_images()) > 0
132
+ def imscale(self) :
133
+ with plt.style.context(self.style) :
134
+ xmax, ymax = 0, 0
135
+ for image in self.get_images() : # Get maximum image coordinates
136
+ y, x = np.shape(image.get_array())[0:2]
137
+ ymax, xmax = max(y, ymax), max(x, xmax)
138
+ if self.get_autoscalex_on() :
139
+ self.set_xlim(-0.5, xmax - 0.5)
140
+ if self.get_autoscaley_on() :
141
+ self.set_ylim(ymax - 0.5, -0.5)
142
+
143
+ # noborders
144
+ @prop()
145
+ def polish_noborders(self) :
146
+ return not self.polish_grids
147
+ def noborders(self) :
148
+ with plt.style.context(self.style) :
149
+ self.set_axis_off()
150
+
151
+ # equiscale
152
+ @prop()
153
+ def polish_equiscale(self) :
154
+ return False
155
+ def equiscale(self) :
156
+ with plt.style.context(self.style) :
157
+ self.set_aspect(aspect='equal', adjustable='box')
158
+
159
+
160
+
161
+ ### --- Regenerate parent class methods in the given style ---
162
+
163
+
164
+
165
+ def is_plottable(method_name, method_obj):
166
+ """
167
+ Returns True if this method should be wrapped automatically.
168
+ """
169
+ if hasattr(StyledAxes, method_name): # Already overriden
170
+ return False
171
+ if method_name.startswith("_"): # private
172
+ return False # handled separately
173
+ if not callable(method_obj):
174
+ return False
175
+ if not inspect.ismethoddescriptor(method_obj) and not inspect.isfunction(method_obj):
176
+ return False
177
+ # Heuristic: methods returning artists / sequences of artists
178
+ # Usually are plotting methods; we accept them all here
179
+ return True
180
+
181
+ def wrap_method(method_name):
182
+ """
183
+ Returns a wrapper method that applies the style context
184
+ then calls the parent Axes method.
185
+ """
186
+ def wrapper(self, *args, **kwargs):
187
+ with plt.style.context(self.style):
188
+ method = getattr(super(StyledAxes, self), method_name)
189
+ return method(*args, **kwargs)
190
+ wrapper.__name__ = method_name
191
+ return wrapper
192
+
193
+ # Dynamically inject each wrapper method into StyledAxes
194
+ for name, obj in Axes.__dict__.items():
195
+ if is_plottable(name, obj):
196
+ setattr(StyledAxes, name, wrap_method(name))
197
+
198
+ # Finally register projection
199
+ projections.register_projection(StyledAxes)
200
+
201
+
202
+
203
+ # %% Test function run
204
+ if __name__ == "__main__":
205
+ from corelp import test
206
+ test(__file__)
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-12-11
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : StyledAxes
8
+
9
+ """
10
+ This file allows to test StyledAxes
11
+
12
+ StyledAxes : A class using stored styles inside.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import print, debug
19
+ from plotlp import StyledAxes
20
+ debug_folder = debug(__file__)
21
+
22
+
23
+
24
+ # %% Test function run
25
+ if __name__ == "__main__":
26
+ from corelp import test
27
+ test(__file__)
@@ -0,0 +1,293 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-12-11
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : StyledFigure
8
+
9
+ """
10
+ A class defining figures with custom styles included inside.
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+ from matplotlib.figure import Figure
17
+ from matplotlib import pyplot as plt
18
+ import numpy as np
19
+ from plotlp import style as get_style
20
+ from plotlp import StyledAxes # do not remove even if unused
21
+ from mpl_toolkits.axes_grid1 import make_axes_locatable
22
+ from corelp import selfkwargs, prop
23
+ import gc
24
+ from io import BytesIO
25
+ from pathlib import Path
26
+ from PIL import Image
27
+ import string
28
+
29
+
30
+
31
+ # %% Class
32
+ class StyledFigure(Figure) :
33
+ f'''
34
+ A class defining figures with custom styles included inside.
35
+
36
+ Parameters
37
+ ----------
38
+ figsize : tuple
39
+ figure size [inch] (x, y).
40
+ dpi : int
41
+ Dots Per Inch resolution.
42
+ style : str or dict
43
+ Name of style or corresponding dict.
44
+ lightmode : bool
45
+ True to use lightLP style.
46
+ darkmode : bool
47
+ True to use darkLP style.
48
+ kwargs : dict
49
+ Keyword arguments corresponding to attributes to change.
50
+
51
+ Attributes
52
+ ----------
53
+ axis : property
54
+ set as an index, when gotten returns corresponding axis.
55
+ plot_axes : list
56
+ list of plotting axes.
57
+ naxes : int
58
+ Number of plotting axes.
59
+ figsize_default : tuple
60
+ Default figure size (x, y) in inch.
61
+ figsize_ratio : float
62
+ x/y figure size ratio, while keeping the same area as default figsize.
63
+ figsize_fact : tuple
64
+ (x, y) figure size growing factors.
65
+ title : property
66
+ suptitle applied and to apply when set.
67
+ tight : bool
68
+ True to apply tight layout when polishing.
69
+
70
+ Examples
71
+ --------
72
+ >>> from plotlp import figure, plt
73
+ ...
74
+ >>> fig = figure() # Savefigure output
75
+ >>> plt.imshow(image, barname='My colorbar') # Apply barname to auto createe colorbar
76
+ >>> fig.polish() # Applies StyledAxes automatic polishing on each axis
77
+ >>> fig.arrayfig(close=False) # Saves figure into an numpy array (calls fig.savefig, close=False to not close figure)
78
+ >>> plt.savefig(png_path=png_path, close=False, **savefig_kwargs) # saving png only
79
+ >>> plt.savefig(pdf_path=pdf_path, close=False, **savefig_kwargs) # saving pdf only
80
+ >>> plt.savefig(path, **savefig_kwargs) # saving png and pdf automatically, close=True by default so no more figure after
81
+ '''
82
+
83
+ def __init__(self, figsize=None, dpi=None, *, style=None, darkmode=False, lightmode=False, **kwargs):
84
+
85
+ # Style
86
+ if style is not None :
87
+ self.style = style
88
+ elif lightmode : self.lightmode()
89
+ elif darkmode : self.darkmode()
90
+ else :
91
+ self.style
92
+
93
+ # Init
94
+ with plt.style.context(self.style) :
95
+ super().__init__(figsize, dpi)
96
+ selfkwargs(self, kwargs)
97
+ self.figresize()
98
+
99
+
100
+
101
+ #Style
102
+ style_name = 'lightLP'
103
+ _style = None #style dict
104
+ style_kwargs = {}
105
+ @property
106
+ def style(self) :
107
+ if self._style is None :
108
+ self.style = self.style_name
109
+ return self._style
110
+ @style.setter
111
+ def style(self,value) :
112
+ if isinstance(value,str) :
113
+ self.style_name = value
114
+ self._style = get_style(value)
115
+ else :
116
+ self.style_name = None
117
+ self._style = value
118
+ self._style.update(self.style_kwargs)
119
+ def lightmode(self) : #to auto call lightmode
120
+ self.style = 'lightLP'
121
+ def darkmode(self) : #to auto call darkmode
122
+ self.style = 'darkLP'
123
+
124
+
125
+
126
+ #Axe
127
+ axis_num = 0 #index of axes
128
+
129
+ @property
130
+ def axis(self) :
131
+ return self.plot_axes[self.axis_num]
132
+ @axis.setter
133
+ def axis(self,value) :
134
+ self.axis_num = value
135
+ plt.sca(self.plot_axes[self.axis_num])
136
+
137
+ @property
138
+ def naxes(self) :
139
+ return len(self.plot_axes)
140
+
141
+ @property
142
+ def plot_axes(self) :
143
+ return [ax for ax in self.axes if not getattr(ax, "is_cbar", False)]
144
+
145
+ def add_subplot(self, *args, **kwargs):
146
+ with plt.style.context(self.style) :
147
+ kwargs["projection"] = "styled" # force the Axes type
148
+ return super().add_subplot(*args, **kwargs)
149
+ def add_axes(self, *args, **kwargs):
150
+ with plt.style.context(self.style) :
151
+ return super().add_axes(*args, **kwargs)
152
+
153
+
154
+
155
+ # Paper index
156
+ paper_index_kwargs = {'size': 20, 'weight': 'bold'}
157
+ def paper_index(self, axes=None, **kwargs) :
158
+ with plt.style.context(self.style) :
159
+ if axes is None :
160
+ axes = self.plot_axes
161
+ kw = self.paper_index_kwargs.copy()
162
+ kw.update(kwargs)
163
+ for n, ax in enumerate(axes):
164
+ ax.text(-0.1, 1.1, string.ascii_lowercase[n], transform=ax.transAxes, **kw)
165
+
166
+
167
+
168
+ # Colorbar
169
+ barname = {'rotation':270,'labelpad':10}
170
+ cax = {'size':"5%", 'pad':0.05}
171
+ def colorbar(self, mappable, cax=None, ax=None, barname=None, **kwargs) :
172
+ with plt.style.context(self.style) :
173
+ if cax is None :
174
+ if ax is None :
175
+ ax = mappable.axes
176
+ divider = make_axes_locatable(ax)
177
+ cax = divider.append_axes("right", **self.cax)
178
+ cax.is_cbar = True
179
+ cbar = super().colorbar(mappable=mappable, cax=cax, ax=None, **kwargs)
180
+ if barname is not None :
181
+ cbar.ax.set_ylabel(barname, **self.barname)
182
+ return cbar
183
+
184
+
185
+
186
+ #figure size parameter
187
+ @prop()
188
+ def figsize_default(self) :
189
+ return self.get_size_inches()
190
+
191
+ @prop()
192
+ def figsize_ratio(self) :
193
+ x, y = self.figsize_default
194
+ return x / y
195
+
196
+ @prop()
197
+ def figsize_fact(self) :
198
+ return 1., 1.
199
+
200
+ def figresize(self) :
201
+ default = self.figsize_default
202
+ ratio = self.figsize_ratio
203
+ fact = self.figsize_fact
204
+ area = default[0] * default[1]
205
+ y = np.sqrt(area/ratio)
206
+ x = ratio * y
207
+ self.set_size_inches(x * fact[0], y * fact[1])
208
+ self._figsize_default = None
209
+ self._figsize_ratio = None
210
+ self._figsize_fact = None
211
+
212
+
213
+
214
+ # Title
215
+ @property
216
+ def title(self) :
217
+ if getattr(self, '_title', None) is None :
218
+ return None
219
+ return self._title.get_text()
220
+ @title.setter
221
+ def title(self, value) :
222
+ with plt.style.context(self.style) :
223
+ self._title = self.suptitle(value)
224
+
225
+
226
+
227
+ # Polish
228
+ tight = True
229
+ polish_figure = True
230
+ def polish(self) :
231
+ with plt.style.context(self.style) :
232
+ for axis_num in range(self.naxes) :
233
+ self.axis = axis_num
234
+ self.axis.polish()
235
+ if self.tight :
236
+ self.tight_layout()
237
+
238
+
239
+
240
+ # Savefig
241
+ def savefig(self, path=None, *, polish=None, path_png=None, path_pdf=None, close=True, **kwargs) :
242
+ if polish is True or polish is None and self.polish_figure :
243
+ self.polish()
244
+
245
+ with plt.style.context(self.style) :
246
+
247
+ # Saving in array
248
+ if isinstance(path, BytesIO) :
249
+ super().savefig(path, **kwargs)
250
+
251
+ # Saving in file
252
+ else :
253
+ path_png = Path(path_png) if path_png is not None else Path(path) if path is not None and path.suffix != '.pdf' else None
254
+ path_pdf = Path(path_pdf) if path_pdf is not None else Path(path) if path is not None and path.suffix != '.png' else None
255
+
256
+ if path_png is not None :
257
+ super().savefig(path_png.with_suffix('.png'), **kwargs)
258
+ if path_pdf is not None :
259
+ super().savefig(path_pdf.with_suffix('.pdf'), **kwargs)
260
+
261
+ # Close figure
262
+ if close :
263
+ plt.close(self)
264
+ gc.collect()
265
+
266
+
267
+
268
+ #Arrayfig
269
+ def arrayfig(self, *args, **kwargs) :
270
+ '''
271
+ Converts figure into a numpy array
272
+ '''
273
+ with plt.style.context(self.style) :
274
+ with BytesIO() as buf:
275
+ self.savefig(buf, *args, **kwargs)
276
+ buf.seek(0)
277
+ image = Image.open(buf)
278
+ image_np = np.array(image)
279
+ return image_np
280
+
281
+
282
+
283
+ #Show
284
+ def show(self, *args, **kwargs) :
285
+ with plt.style.context(self.style) :
286
+ super().show(*args,**kwargs)
287
+
288
+
289
+
290
+ # %% Test function run
291
+ if __name__ == "__main__":
292
+ from corelp import test
293
+ test(__file__)
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-12-11
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : StyledFigure
8
+
9
+ """
10
+ This file allows to test StyledFigure
11
+
12
+ StyledFigure : A class defining figures with custom styles included inside.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import print, debug
19
+ from plotlp import StyledFigure
20
+ debug_folder = debug(__file__)
21
+
22
+
23
+
24
+ # %% Test function run
25
+ if __name__ == "__main__":
26
+ from corelp import test
27
+ test(__file__)