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.
- {plotlp-0.1.11 → plotlp-0.1.12}/PKG-INFO +1 -1
- {plotlp-0.1.11 → plotlp-0.1.12}/pyproject.toml +1 -1
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/__init__.py +3 -1
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/StyledAxes.py +24 -1
- plotlp-0.1.12/src/plotlp/modules/StyledAxes_LP/_functions/scalebar.py +65 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/StyledFigure.py +65 -1
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/cmap.py +6 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/color.py +4 -0
- plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP/gridsubplots.py +101 -0
- plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP/test_gridsubplots.py +79 -0
- plotlp-0.1.12/src/plotlp/modules/subplots_LP/_functions/__template__.py +19 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/subplots_LP/subplots.py +2 -2
- plotlp-0.1.12/src/plotlp/py.typed +0 -0
- plotlp-0.1.12/src/plotlp/routines/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/README.md +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/_functions/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledAxes_LP/test_StyledAxes.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/_functions/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/test_StyledFigure.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/_functions/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/cmap_LP/test_cmap.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/_functions/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/color_LP/test_color.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/_functions/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/figure.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/figure_LP/test_figure.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/imgfigure_LP → plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP}/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/imgfigure_LP → plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP}/_functions/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/imgfigure_LP → plotlp-0.1.12/src/plotlp/modules/gridsubplots_LP}/_functions/__template__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/make_animation_LP → plotlp-0.1.12/src/plotlp/modules/imgfigure_LP}/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/make_animation_LP → plotlp-0.1.12/src/plotlp/modules/imgfigure_LP}/_functions/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/make_animation_LP → plotlp-0.1.12/src/plotlp/modules/imgfigure_LP}/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/imgfigure_LP/imgfigure.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/imgfigure_LP/test_imgfigure.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/plt_LP → plotlp-0.1.12/src/plotlp/modules/make_animation_LP}/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/plt_LP → plotlp-0.1.12/src/plotlp/modules/make_animation_LP}/_functions/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/plt_LP → plotlp-0.1.12/src/plotlp/modules/make_animation_LP}/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/make_animation_LP/make_animation.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/make_animation_LP/test_make_animation.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/_functions/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/plt_LP/plt.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/plt_LP/test_plt.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/style_LP/styles → plotlp-0.1.12/src/plotlp/modules/style_LP}/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/subplots_LP → plotlp-0.1.12/src/plotlp/modules/style_LP/_functions}/__init__.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/subplots_LP → plotlp-0.1.12/src/plotlp/modules/style_LP}/_functions/__template__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/style.py +0 -0
- {plotlp-0.1.11/src/plotlp/modules/subplots_LP/_functions → plotlp-0.1.12/src/plotlp/modules/style_LP/styles}/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/darkLP.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/default.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/lightLP.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/styles/styleLP.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/style_LP/test_style.py +0 -0
- {plotlp-0.1.11/src/plotlp/routines → plotlp-0.1.12/src/plotlp/modules/subplots_LP}/__init__.py +0 -0
- /plotlp-0.1.11/src/plotlp/py.typed → /plotlp-0.1.12/src/plotlp/modules/subplots_LP/_functions/__init__.py +0 -0
- {plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/subplots_LP/test_subplots.py +0 -0
|
@@ -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 = {
|
|
@@ -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!')
|
|
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
|
{plotlp-0.1.11 → plotlp-0.1.12}/src/plotlp/modules/StyledFigure_LP/_functions/__template__.py
RENAMED
|
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
|
|
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
|
{plotlp-0.1.11/src/plotlp/modules/style_LP → plotlp-0.1.12/src/plotlp/modules/plt_LP}/__init__.py
RENAMED
|
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
|
{plotlp-0.1.11/src/plotlp/routines → plotlp-0.1.12/src/plotlp/modules/subplots_LP}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|