plotlp 0.1.11__tar.gz → 0.1.12__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 (68) hide show
  1. {plotlp-0.1.11 → plotlp-0.1.12}/PKG-INFO +1 -1
  2. {plotlp-0.1.11 → plotlp-0.1.12}/pyproject.toml +1 -1
  3. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/__init__.py +3 -1
  4. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/StyledAxes.py +24 -1
  5. plotlp-0.1.12/src/plotlp/modules/StyledAxes_LP/_functions/scalebar.py +65 -0
  6. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/StyledFigure.py +65 -1
  7. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/cmap.py +6 -0
  8. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/color.py +4 -0
  9. plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP/gridsubplots.py +101 -0
  10. plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP/test_gridsubplots.py +79 -0
  11. plotlp-0.1.12/src/plotlp/modules/subplots_LP/_functions/__template__.py +19 -0
  12. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/subplots_LP/subplots.py +2 -2
  13. plotlp-0.1.12/src/plotlp/py.typed +0 -0
  14. plotlp-0.1.12/src/plotlp/routines/__init__.py +0 -0
  15. {plotlp-0.1.11 → plotlp-0.1.12}/README.md +0 -0
  16. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/__init__.py +0 -0
  17. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/_functions/__init__.py +0 -0
  18. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/_functions/__template__.py +0 -0
  19. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/test_StyledAxes.py +0 -0
  20. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/__init__.py +0 -0
  21. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/_functions/__init__.py +0 -0
  22. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/_functions/__template__.py +0 -0
  23. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/test_StyledFigure.py +0 -0
  24. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/__init__.py +0 -0
  25. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/__init__.py +0 -0
  26. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/_functions/__init__.py +0 -0
  27. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/_functions/__template__.py +0 -0
  28. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/test_cmap.py +0 -0
  29. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/__init__.py +0 -0
  30. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/_functions/__init__.py +0 -0
  31. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/_functions/__template__.py +0 -0
  32. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/test_color.py +0 -0
  33. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/__init__.py +0 -0
  34. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/_functions/__init__.py +0 -0
  35. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/_functions/__template__.py +0 -0
  36. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/figure.py +0 -0
  37. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/test_figure.py +0 -0
  38. {plotlp-0.1.11/src/plotlp/modules/imgfigure_LP → plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP}/__init__.py +0 -0
  39. {plotlp-0.1.11/src/plotlp/modules/imgfigure_LP → plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP}/_functions/__init__.py +0 -0
  40. {plotlp-0.1.11/src/plotlp/modules/imgfigure_LP → plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP}/_functions/__template__.py +0 -0
  41. {plotlp-0.1.11/src/plotlp/modules/make_animation_LP → plotlp-0.1.12/src/plotlp/modules/imgfigure_LP}/__init__.py +0 -0
  42. {plotlp-0.1.11/src/plotlp/modules/make_animation_LP → plotlp-0.1.12/src/plotlp/modules/imgfigure_LP}/_functions/__init__.py +0 -0
  43. {plotlp-0.1.11/src/plotlp/modules/make_animation_LP → plotlp-0.1.12/src/plotlp/modules/imgfigure_LP}/_functions/__template__.py +0 -0
  44. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/imgfigure_LP/imgfigure.py +0 -0
  45. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/imgfigure_LP/test_imgfigure.py +0 -0
  46. {plotlp-0.1.11/src/plotlp/modules/plt_LP → plotlp-0.1.12/src/plotlp/modules/make_animation_LP}/__init__.py +0 -0
  47. {plotlp-0.1.11/src/plotlp/modules/plt_LP → plotlp-0.1.12/src/plotlp/modules/make_animation_LP}/_functions/__init__.py +0 -0
  48. {plotlp-0.1.11/src/plotlp/modules/plt_LP → plotlp-0.1.12/src/plotlp/modules/make_animation_LP}/_functions/__template__.py +0 -0
  49. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/make_animation_LP/make_animation.py +0 -0
  50. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/make_animation_LP/test_make_animation.py +0 -0
  51. {plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/__init__.py +0 -0
  52. {plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/_functions/__init__.py +0 -0
  53. {plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/_functions/__template__.py +0 -0
  54. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/plt_LP/plt.py +0 -0
  55. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/plt_LP/test_plt.py +0 -0
  56. {plotlp-0.1.11/src/plotlp/modules/style_LP/styles → plotlp-0.1.12/src/plotlp/modules/style_LP}/__init__.py +0 -0
  57. {plotlp-0.1.11/src/plotlp/modules/subplots_LP → plotlp-0.1.12/src/plotlp/modules/style_LP/_functions}/__init__.py +0 -0
  58. {plotlp-0.1.11/src/plotlp/modules/subplots_LP → plotlp-0.1.12/src/plotlp/modules/style_LP}/_functions/__template__.py +0 -0
  59. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/style.py +0 -0
  60. {plotlp-0.1.11/src/plotlp/modules/subplots_LP/_functions → plotlp-0.1.12/src/plotlp/modules/style_LP/styles}/__init__.py +0 -0
  61. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/darkLP.py +0 -0
  62. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/default.py +0 -0
  63. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/lightLP.py +0 -0
  64. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/styleLP.py +0 -0
  65. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/test_style.py +0 -0
  66. {plotlp-0.1.11/src/plotlp/routines → plotlp-0.1.12/src/plotlp/modules/subplots_LP}/__init__.py +0 -0
  67. /plotlp-0.1.11/src/plotlp/py.typed → /plotlp-0.1.12/src/plotlp/modules/subplots_LP/_functions/__init__.py +0 -0
  68. {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/subplots_LP/test_subplots.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: plotlp
3
- Version: 0.1.11
3
+ Version: 0.1.12
4
4
  Summary: A library wrapper around matplotlib for custom plots.
5
5
  Requires-Dist: corelp
6
6
  Requires-Dist: cycler
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plotlp"
3
- version = "0.1.11"
3
+ version = "0.1.12"
4
4
  description = "A library wrapper around matplotlib for custom plots."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -18,11 +18,13 @@ sources = {
18
18
  'cmap': 'plotlp.modules.cmap_LP.cmap',
19
19
  'color': 'plotlp.modules.color_LP.color',
20
20
  'figure': 'plotlp.modules.figure_LP.figure',
21
+ 'gridsubplots': 'plotlp.modules.gridsubplots_LP.gridsubplots',
21
22
  'imgfigure': 'plotlp.modules.imgfigure_LP.imgfigure',
22
23
  'make_animation': 'plotlp.modules.make_animation_LP.make_animation',
23
24
  'plt': 'plotlp.modules.plt_LP.plt',
24
25
  'style': 'plotlp.modules.style_LP.style',
25
- 'subplots': 'plotlp.modules.subplots_LP.subplots'
26
+ 'subplots': 'plotlp.modules.subplots_LP.subplots',
27
+ 'scalebar': 'plotlp.modules.StyledAxes_LP._functions.scalebar'
26
28
  }
27
29
 
28
30
 
@@ -21,6 +21,7 @@ from corelp import prop
21
21
  import numpy as np
22
22
  from matplotlib.patches import Rectangle
23
23
  from mpl_toolkits.axes_grid1.inset_locator import inset_axes
24
+ from plotlp import scalebar as scbar
24
25
 
25
26
 
26
27
 
@@ -61,6 +62,11 @@ class StyledAxes(Axes) :
61
62
  def style(self) :
62
63
  return self.figure.style
63
64
 
65
+ # Legend
66
+ def legend(self, *args, **kwargs) :
67
+ with plt.style.context(self.style):
68
+ return super().legend(*args, **kwargs)
69
+
64
70
  # Imshow
65
71
  def imshow(self, X, *args, barname=None, coordinates=None, **kwargs) :
66
72
  with plt.style.context(self.style):
@@ -87,6 +93,12 @@ class StyledAxes(Axes) :
87
93
  cmap = plt.get_cmap(plt.rcParams['image.cmap'])
88
94
  return super().pcolormesh(*args, cmap=cmap, **kwargs)
89
95
 
96
+ # Bar
97
+ def bar(self, *args, **kwargs) :
98
+ with plt.style.context(self.style):
99
+ self.polish_grids = True
100
+ return super().bar(*args, **kwargs)
101
+
90
102
  # Implot
91
103
  def implot(self, img, x, y, w, h, zorder=3, **kwargs) :
92
104
  newaxe = inset_axes(self, [x, y, w, h], transform=self.transData, zorder=zorder, axes_class=StyledAxes)
@@ -98,6 +110,17 @@ class StyledAxes(Axes) :
98
110
  im.set_clip_path(clip_rect)
99
111
  return im
100
112
 
113
+ # Scalebar
114
+ def scalebar(self, *args, **kwargs) :
115
+ with plt.style.context(self.style):
116
+ scbar(self, *args, **kwargs)
117
+
118
+ # Facecolor
119
+ def set_facecolor(self, *args, **kwargs) :
120
+ with plt.style.context(self.style):
121
+ super().set_facecolor(*args, **kwargs)
122
+
123
+
101
124
 
102
125
  ### --- Polish functions ---
103
126
 
@@ -114,7 +137,7 @@ class StyledAxes(Axes) :
114
137
  # grids
115
138
  @prop()
116
139
  def polish_grids(self) :
117
- return len(self.lines) > 0 or len(self.collections) > 0
140
+ return len(self.lines) > 0 or len(self.collections) > 0 # no grid with patches here
118
141
  grid_major = {'linestyle':'-', 'alpha':1}
119
142
  grid_minor = {'linestyle':'--', 'alpha':0.5}
120
143
  def grids(self) :
@@ -0,0 +1,65 @@
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
+ import matplotlib.pyplot as plt
10
+ import matplotlib.patches as mpatches
11
+ import numpy as np
12
+
13
+ # Scalebar
14
+ def scalebar(self, pixel=1., unit=None, length=None, *, loc='lower right', bar_height_frac=0.015, pad_frac=0.05, color="white", fontsize=10, zorder=5, label_pad=4, **kwargs) :
15
+
16
+ ax = self
17
+
18
+ # Get image dimensions
19
+ xlim = ax.get_xlim()
20
+ ylim = ax.get_ylim()
21
+ img_w = abs(xlim[1] - xlim[0]) # width in pixels
22
+ img_h = abs(ylim[1] - ylim[0]) # height in pixels
23
+ x_min, x_max = min(xlim), max(xlim)
24
+ y_min, y_max = min(ylim), max(ylim)
25
+
26
+ # Autoselect bar width
27
+ if length is None:
28
+ target_px = img_w * 0.15
29
+ magnitude = 10 ** np.floor(np.log10(target_px * pixel))
30
+ for step in [1, 2, 5, 10]:
31
+ candidate = step * magnitude
32
+ if candidate / pixel <= target_px * 1.5:
33
+ length = candidate
34
+ break
35
+ else:
36
+ length = magnitude
37
+ bar_px = length / pixel # bar length in pixels
38
+
39
+ # Bar height
40
+ bar_h = img_h * bar_height_frac # bar thickness in pixels
41
+
42
+ # Bar padding from barder
43
+ pad = min(img_w, img_h) * pad_frac
44
+
45
+ # Anchor position
46
+ loc = loc.lower()
47
+ x0 = x_max - pad - bar_px if "right" in loc else x_min + pad
48
+ y0 = y_max - pad - bar_h if "lower" in loc else y_min + pad
49
+
50
+ # Scale bar rectangle
51
+ bar_rect = mpatches.Rectangle((x0, y0), bar_px, bar_h, linewidth=0, facecolor=color, zorder=zorder)
52
+ ax.add_patch(bar_rect)
53
+
54
+ # Label
55
+ label_x = x0 + bar_px / 2
56
+ pt_to_data = (y_max - y_min) / ax.get_window_extent().height * 72 / ax.figure.dpi
57
+ inverted = ax.yaxis_inverted()
58
+ if inverted:
59
+ label_y = y0 - label_pad * pt_to_data # above bar visually (smaller y)
60
+ va = "top"
61
+ else:
62
+ label_y = y0 + bar_h + label_pad * pt_to_data
63
+ va = "bottom"
64
+
65
+ ax.text(label_x, label_y, f"{length:g} {unit}", color=color, fontsize=fontsize, ha="center", va="bottom", zorder=zorder, fontweight="bold")
@@ -149,6 +149,54 @@ class StyledFigure(Figure) :
149
149
  def add_axes(self, *args, **kwargs):
150
150
  with plt.style.context(self.style) :
151
151
  return super().add_axes(*args, **kwargs)
152
+ def subplots(self, nrows=1, ncols=1, **kwargs):
153
+ axs = super().subplots(nrows, ncols, **kwargs)
154
+ self._axes_grid = np.asarray(axs) # remember the grid
155
+ return axs
156
+
157
+
158
+
159
+ @property
160
+ def merge(self):
161
+ return _MergeIndexer(self)
162
+
163
+ def _normalize_indices(self, idx, size):
164
+ if isinstance(idx, slice):
165
+ return list(range(*idx.indices(size)))
166
+ if isinstance(idx, (list, tuple, np.ndarray)):
167
+ return list(idx)
168
+ return [idx]
169
+
170
+ def _merge_axes(self, rows, cols):
171
+
172
+ if not hasattr(self, "_axes_grid"):
173
+ raise RuntimeError("merge only works with fig.subplots()")
174
+
175
+ grid = self._axes_grid
176
+ nrows, ncols = grid.shape
177
+ r = self._normalize_indices(rows, nrows)
178
+ c = self._normalize_indices(cols, ncols)
179
+ axes_to_merge = [grid[i, j] for i in r for j in c]
180
+
181
+ # gridspec
182
+ gs = axes_to_merge[0].get_gridspec()
183
+ rmin, rmax = min(r), max(r) + 1
184
+ cmin, cmax = min(c), max(c) + 1
185
+
186
+ # remove axes
187
+ for ax in set(axes_to_merge):
188
+ if ax in self.axes:
189
+ self.delaxes(ax)
190
+
191
+ # create merged axis
192
+ new_ax = self.add_subplot(gs[rmin:rmax, cmin:cmax])
193
+
194
+ # update stored grid
195
+ for i in r:
196
+ for j in c:
197
+ grid[i, j] = new_ax
198
+
199
+ return new_ax
152
200
 
153
201
 
154
202
 
@@ -177,7 +225,7 @@ class StyledFigure(Figure) :
177
225
  cax = divider.append_axes("right", **self.cax)
178
226
  cax.is_cbar = True
179
227
  cbar = super().colorbar(mappable=mappable, cax=cax, ax=None, **kwargs)
180
- if barname is not None :
228
+ if barname is not None and barname != '':
181
229
  cbar.ax.set_ylabel(barname, **self.barname)
182
230
  return cbar
183
231
 
@@ -287,6 +335,22 @@ class StyledFigure(Figure) :
287
335
 
288
336
 
289
337
 
338
+ class _MergeIndexer:
339
+
340
+ def __init__(self, fig):
341
+ self.fig = fig
342
+
343
+ def __getitem__(self, key):
344
+
345
+ if not isinstance(key, tuple):
346
+ key = (key, slice(None))
347
+
348
+ r, c = key
349
+
350
+ return self.fig._merge_axes(r, c)
351
+
352
+
353
+
290
354
  # %% Test function run
291
355
  if __name__ == "__main__":
292
356
  from corelp import test
@@ -107,6 +107,7 @@ class Cmap(LinearSegmentedColormap) :
107
107
  }
108
108
 
109
109
  super().__init__(self.name, cdict)
110
+ self.set_bad(self.bad)
110
111
 
111
112
 
112
113
 
@@ -171,6 +172,11 @@ class Cmap(LinearSegmentedColormap) :
171
172
  node = (erfinv(node)/self.nodebase + 1) / 2
172
173
  return (np.round(node * 1000)).astype(int)/1000
173
174
 
175
+ # Bad color
176
+ _bad = "greyLP" #bad color
177
+ @prop(variable=True)
178
+ def bad(self) -> str :
179
+ return color(auto=self._bad)
174
180
 
175
181
 
176
182
  cmaps = {
@@ -238,6 +238,10 @@ class Color(str) :
238
238
  lum = Color(k, k, k)
239
239
  return self.mix(lum, abs(fact))
240
240
 
241
+ # Return string without alpha (Not a color object anymore)
242
+ @property
243
+ def noalpha(self) :
244
+ return self[:-2]
241
245
 
242
246
 
243
247
  colors = {
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-03-11
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : gridsubplots
8
+
9
+ """
10
+ Subplots functions that creates a grid of axis (typically for images plots).
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+ import matplotlib.gridspec as gridspec
17
+ import matplotlib.ticker as ticker
18
+ import numpy as np
19
+ from plotlp import figure
20
+
21
+
22
+
23
+ # %% Function
24
+ def gridsubplots(nrows, ncols, yticks=None, xticks=None, figsize_ratio=None, **kwargs) :
25
+ '''
26
+ Subplots functions that creates a grid of axis (typically for images plots).
27
+
28
+ Parameters
29
+ ----------
30
+ nrows : int
31
+ Number of rows in grid.
32
+ ncols : int
33
+ Number of columns in grid.
34
+ yticks : list
35
+ List of string corresponding to y labels.
36
+ xticks : list
37
+ List of string corresponding to x labels.
38
+ figsize_ratio : int
39
+ (x / y) ratio to apply to default figure, if None will use (ncols / nrows).
40
+ **kwargs : dict
41
+ key-ward arguments to pass to plotlp.figure function.
42
+
43
+ Returns
44
+ -------
45
+ fig : StyledFigure
46
+ figure object.
47
+ axes : np.array(StyledAxes)
48
+ axes array.
49
+
50
+ Examples
51
+ --------
52
+ >>> from plotlp import gridsubplots
53
+ ...
54
+ >>> fig, axes = gridsubplots(2, 3, yticks=['1', '2'], xticks=['1', '2', '3'])
55
+ '''
56
+
57
+ figsize_ratio = ncols * 0.93 / nrows if figsize_ratio is None else figsize_ratio
58
+ fig = figure(figsize_ratio=figsize_ratio, **kwargs)
59
+ gs = gridspec.GridSpec(nrows, ncols, hspace=0, wspace=0) # no space between axes
60
+ axes = np.array([[fig.add_subplot(gs[i, j]) for j in range(ncols)] for i in range(nrows)])
61
+ if xticks is not None and len(xticks) != ncols : raise SyntaxError('xticks do not have the length of ncols')
62
+ if yticks is not None and len(yticks) != nrows : raise SyntaxError('yticks do not have the length of nrows')
63
+
64
+ for i in range(nrows):
65
+ for j in range(ncols):
66
+ ax = axes[i, j]
67
+ ax.polish_noborders = False
68
+
69
+ # remove ticks everywhere
70
+ ax.xaxis.set_major_locator(ticker.NullLocator())
71
+ ax.yaxis.set_major_locator(ticker.NullLocator())
72
+ ax.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
73
+
74
+ # bottom border row
75
+ if i == nrows - 1 and xticks is not None:
76
+ ax.tick_params(bottom=True, labelbottom=True)
77
+ ax.xaxis.set_major_locator(MidpointLocator())
78
+ ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos, label=str(xticks[j]): label))
79
+
80
+ # left border column
81
+ if j == 0 and yticks is not None:
82
+ ax.tick_params(left=True, labelleft=True)
83
+ ax.yaxis.set_major_locator(MidpointLocator())
84
+ ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos, label=str(yticks[i]): label))
85
+
86
+ return fig, axes
87
+
88
+
89
+
90
+ class MidpointLocator(ticker.Locator):
91
+ """Always places a single tick at the midpoint of the current axis limits."""
92
+ def __call__(self):
93
+ vmin, vmax = self.axis.get_view_interval()
94
+ return [(vmin + vmax) / 2]
95
+
96
+
97
+
98
+ # %% Test function run
99
+ if __name__ == "__main__":
100
+ from corelp import test
101
+ test(__file__)
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-03-11
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : plotLP
7
+ # Module : gridsubplots
8
+
9
+ """
10
+ This file allows to test gridsubplots
11
+
12
+ gridsubplots : Subplots functions that creates a grid of axis (typically for images plots).
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import debug
19
+ import pytest
20
+ from plotlp import gridsubplots
21
+ debug_folder = debug(__file__)
22
+
23
+
24
+
25
+ # %% Function test
26
+ def test_function() :
27
+ '''
28
+ Test gridsubplots 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 gridsubplots()
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 gridsubplots return values
57
+ '''
58
+ assert gridsubplots(*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 gridsubplots error values
70
+ '''
71
+ with pytest.raises(error, match=error_message) :
72
+ gridsubplots(*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!')
@@ -34,8 +34,8 @@ def subplots(*args, **kwargs) :
34
34
  -------
35
35
  fig : StyledFigure
36
36
  Figure.
37
- axes : tuple[StyledAxes]
38
- tuple of axes.
37
+ axes : numpy.ndarray[StyledAxes]
38
+ array of axes.
39
39
 
40
40
  Examples
41
41
  --------
File without changes
File without changes
File without changes