babelplot 2025.5__tar.gz → 2025.6__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.
- {babelplot-2025.5 → babelplot-2025.6}/PKG-INFO +1 -1
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/__init__.py +2 -2
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/api/definition.py +1 -1
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/api/help.py +1 -1
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/backend/catalog/bokeh_.py +5 -15
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/backend/catalog/matplotlib_.py +20 -28
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/backend/catalog/plotly_.py +108 -21
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/backend/catalog/vedo_.py +3 -15
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/backend/helper/validation.py +1 -1
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/extension/enum_.py +3 -3
- babelplot-2025.6/package/babelplot/runtime/figure.py +55 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/task/help.py +4 -4
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/task/instantiation.py +9 -22
- babelplot-2025.5/package/babelplot/task/show_pyqt6.py → babelplot-2025.6/package/babelplot/task/showing.py +32 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/type/backend.py +105 -16
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/type/dimension.py +24 -50
- babelplot-2025.5/package/babelplot/type/base.py → babelplot-2025.6/package/babelplot/type/ffp_base.py +13 -14
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/type/figure.py +50 -53
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/type/frame.py +12 -41
- babelplot-2025.6/package/babelplot/type/plot.py +61 -0
- babelplot-2025.5/package/babelplot/type/plot_definition.py → babelplot-2025.6/package/babelplot/type/plot_type.py +164 -251
- babelplot-2025.6/package/babelplot/type/translator.py +60 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/version.py +1 -1
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot.egg-info/PKG-INFO +1 -1
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot.egg-info/SOURCES.txt +5 -3
- babelplot-2025.5/package/babelplot/type/plot.py +0 -126
- {babelplot-2025.5 → babelplot-2025.6}/MANIFEST.in +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/README-COPYRIGHT-utf8.txt +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/README-LICENCE-utf8.txt +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/README.rst +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/documentation/wiki/description.asciidoc +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/api/backend.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/backend/helper/creation.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/constant/backend.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/constant/path.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/constant/project.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/extension/function.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot/runtime/backends.py +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot.egg-info/dependency_links.txt +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot.egg-info/requires.txt +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/package/babelplot.egg-info/top_level.txt +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/pyproject.toml +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/requirements.txt +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/setup.cfg +0 -0
- {babelplot-2025.5 → babelplot-2025.6}/setup.py +0 -0
|
@@ -18,9 +18,9 @@ else:
|
|
|
18
18
|
beartype_this_package()
|
|
19
19
|
|
|
20
20
|
from babelplot.task.instantiation import NewFigure, NewPlot
|
|
21
|
+
from babelplot.task.showing import ShowAllFigures
|
|
21
22
|
from babelplot.type.dimension import dim_e
|
|
22
|
-
from babelplot.type.
|
|
23
|
-
from babelplot.type.plot_definition import plot_e
|
|
23
|
+
from babelplot.type.plot_type import plot_e
|
|
24
24
|
from babelplot.version import __version__
|
|
25
25
|
|
|
26
26
|
"""
|
|
@@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2022
|
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from babelplot.task.help import
|
|
7
|
+
from babelplot.task.help import PrintHelp # noqa
|
|
8
8
|
from babelplot.task.help import PrintUsage # noqa
|
|
9
9
|
|
|
10
10
|
"""
|
|
@@ -7,12 +7,12 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
7
7
|
import dataclasses as d
|
|
8
8
|
import typing as h
|
|
9
9
|
|
|
10
|
-
from babelplot.task.
|
|
10
|
+
from babelplot.task.showing import Show
|
|
11
11
|
from babelplot.type.dimension import dim_e
|
|
12
12
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
13
13
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
14
14
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
15
|
-
from babelplot.type.
|
|
15
|
+
from babelplot.type.plot_type import plot_e, plot_function_h
|
|
16
16
|
from bokeh.embed import file_html as HTMLofBackendContent # noqa
|
|
17
17
|
from bokeh.layouts import column as NewBackendColLayout # noqa
|
|
18
18
|
from bokeh.layouts import grid as NewBackendGridLayout # noqa
|
|
@@ -38,10 +38,7 @@ class frame_t(base_frame_t):
|
|
|
38
38
|
|
|
39
39
|
def _NewPlot(
|
|
40
40
|
self,
|
|
41
|
-
|
|
42
|
-
plot_function: (
|
|
43
|
-
type[backend_plot_t] | h.Callable[..., backend_plot_t | h.Any] | None
|
|
44
|
-
),
|
|
41
|
+
plot_function: plot_function_h,
|
|
45
42
|
*args,
|
|
46
43
|
title: str | None = None, # If _, then it is swallowed by kwargs!
|
|
47
44
|
**kwargs,
|
|
@@ -53,13 +50,6 @@ class frame_t(base_frame_t):
|
|
|
53
50
|
backend_name=self.backend_name,
|
|
54
51
|
)
|
|
55
52
|
|
|
56
|
-
if plot_function is None:
|
|
57
|
-
if hasattr(backend_frame_t, type_):
|
|
58
|
-
plot_function = getattr(backend_frame_t, type_)
|
|
59
|
-
else:
|
|
60
|
-
raise ValueError(f"{type_}: Unknown {NAME} graph object.")
|
|
61
|
-
|
|
62
|
-
output.backend_type = plot_function
|
|
63
53
|
output.raw = plot_function(self.raw, *args, **kwargs)
|
|
64
54
|
|
|
65
55
|
return output
|
|
@@ -78,7 +68,7 @@ class figure_t(base_figure_t):
|
|
|
78
68
|
col: int,
|
|
79
69
|
*args,
|
|
80
70
|
title: str | None = None,
|
|
81
|
-
dim: dim_e = dim_e.XY,
|
|
71
|
+
dim: dim_e = dim_e.XY,
|
|
82
72
|
**kwargs,
|
|
83
73
|
) -> frame_t:
|
|
84
74
|
""""""
|
|
@@ -116,7 +106,7 @@ class figure_t(base_figure_t):
|
|
|
116
106
|
return HTMLofBackendContent(self.layout, INLINE)
|
|
117
107
|
|
|
118
108
|
|
|
119
|
-
PLOTS =
|
|
109
|
+
PLOTS = plot_e.NewPlotsTemplate()
|
|
120
110
|
PLOTS[plot_e.SCATTER][1] = backend_frame_t.scatter
|
|
121
111
|
|
|
122
112
|
|
|
@@ -10,12 +10,12 @@ import typing as h
|
|
|
10
10
|
import matplotlib.pyplot as pypl # noqa
|
|
11
11
|
import numpy as nmpy
|
|
12
12
|
import skimage.measure as msre
|
|
13
|
-
from babelplot.type.base import backend_element_h
|
|
14
13
|
from babelplot.type.dimension import dim_e
|
|
14
|
+
from babelplot.type.ffp_base import backend_element_h
|
|
15
15
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
16
16
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
17
17
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
18
|
-
from babelplot.type.
|
|
18
|
+
from babelplot.type.plot_type import plot_e, plot_function_h, plot_type_h
|
|
19
19
|
from logger_36 import L
|
|
20
20
|
from matplotlib.artist import Artist as backend_plot_t # noqa
|
|
21
21
|
from matplotlib.container import Container as backend_plots_t # noqa
|
|
@@ -36,7 +36,7 @@ array_t = nmpy.ndarray
|
|
|
36
36
|
backend_frame_h = backend_frame_2d_t | backend_frame_3d_t
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def _DefaultProperties(type_:
|
|
39
|
+
def _DefaultProperties(type_: type[plot_type_h], /) -> dict[str, h.Any]:
|
|
40
40
|
""""""
|
|
41
41
|
name = type_.__name__
|
|
42
42
|
properties = mlpl.rcParams.find_all(f"^{name}\\.")
|
|
@@ -102,10 +102,7 @@ class frame_t(base_frame_t):
|
|
|
102
102
|
|
|
103
103
|
def _NewPlot(
|
|
104
104
|
self,
|
|
105
|
-
|
|
106
|
-
plot_function: (
|
|
107
|
-
type[backend_plot_t] | h.Callable[..., backend_plot_t | h.Any] | None
|
|
108
|
-
),
|
|
105
|
+
plot_function: plot_function_h,
|
|
109
106
|
*args,
|
|
110
107
|
title: str | None = None, # /!\ If _, then it is swallowed by kwargs!
|
|
111
108
|
**kwargs,
|
|
@@ -117,18 +114,6 @@ class frame_t(base_frame_t):
|
|
|
117
114
|
backend_name=self.backend_name,
|
|
118
115
|
)
|
|
119
116
|
|
|
120
|
-
if plot_function is None:
|
|
121
|
-
# Next, priority is given to 2-D plots... which might be a problem if a 2-D and
|
|
122
|
-
# 3-D frame have plot types with the same name. For example, scatter in 2-D and
|
|
123
|
-
# 3-D.
|
|
124
|
-
if hasattr(backend_frame_2d_t, type_):
|
|
125
|
-
plot_function = getattr(backend_frame_2d_t, type_)
|
|
126
|
-
elif hasattr(backend_frame_3d_t, type_):
|
|
127
|
-
plot_function = getattr(backend_frame_3d_t, type_)
|
|
128
|
-
else:
|
|
129
|
-
raise ValueError(f"{type_}: Unknown {NAME} graph object.")
|
|
130
|
-
|
|
131
|
-
output.backend_type = plot_function
|
|
132
117
|
output.raw = plot_function(self.raw, *args, **kwargs)
|
|
133
118
|
|
|
134
119
|
return output
|
|
@@ -169,9 +154,7 @@ class figure_t(base_figure_t):
|
|
|
169
154
|
)
|
|
170
155
|
self.raw.add_axes(raw)
|
|
171
156
|
else:
|
|
172
|
-
raise NotImplementedError(
|
|
173
|
-
f"{dim}: Dimension management not implemented yet"
|
|
174
|
-
)
|
|
157
|
+
raise NotImplementedError(f"Frame dimension {dim} not implemented.")
|
|
175
158
|
if title is not None:
|
|
176
159
|
raw.set_title(title)
|
|
177
160
|
|
|
@@ -181,22 +164,31 @@ class figure_t(base_figure_t):
|
|
|
181
164
|
|
|
182
165
|
def AdjustLayout(self) -> None:
|
|
183
166
|
""""""
|
|
184
|
-
|
|
167
|
+
figure_raw = self.raw
|
|
185
168
|
|
|
186
169
|
if self.title is not None:
|
|
187
|
-
|
|
170
|
+
figure_raw.suptitle(self.title)
|
|
188
171
|
for frame in self.frames:
|
|
189
172
|
if frame.title is not None:
|
|
190
173
|
frame.raw.set_title(frame.title)
|
|
191
174
|
for plot in frame.plots:
|
|
192
175
|
if plot.title is not None:
|
|
193
|
-
plot.raw
|
|
176
|
+
plot_raw = plot.raw
|
|
177
|
+
if isinstance(plot_raw, h.Sequence):
|
|
178
|
+
plot_raw_s = plot_raw
|
|
179
|
+
else:
|
|
180
|
+
plot_raw_s = (plot_raw,)
|
|
181
|
+
for plot_raw in plot_raw_s:
|
|
182
|
+
if (
|
|
183
|
+
SetLabel := getattr(plot_raw, "set_label", None)
|
|
184
|
+
) is not None:
|
|
185
|
+
SetLabel(plot.title)
|
|
194
186
|
|
|
195
187
|
if self.frames.__len__() < 2:
|
|
196
188
|
return
|
|
197
189
|
|
|
198
|
-
grid_spec = grid_spec_t(*self.shape, figure=
|
|
199
|
-
bottoms, tops, lefts, rights = grid_spec.get_grid_positions(
|
|
190
|
+
grid_spec = grid_spec_t(*self.shape, figure=figure_raw)
|
|
191
|
+
bottoms, tops, lefts, rights = grid_spec.get_grid_positions(figure_raw)
|
|
200
192
|
|
|
201
193
|
for frame, (row, col) in zip(self.frames, self.locations):
|
|
202
194
|
left, bottom, width, height = (
|
|
@@ -385,7 +377,7 @@ def _Text3(frame: backend_frame_2d_t, text, x, y, z, *_, **kwargs) -> backend_pl
|
|
|
385
377
|
return frame.text(x, y, z, text, **kwargs)
|
|
386
378
|
|
|
387
379
|
|
|
388
|
-
PLOTS =
|
|
380
|
+
PLOTS = plot_e.NewPlotsTemplate()
|
|
389
381
|
|
|
390
382
|
PLOTS[plot_e.SCATTER][1] = backend_frame_2d_t.scatter
|
|
391
383
|
PLOTS[plot_e.POLYLINE][1] = backend_frame_2d_t.plot
|
|
@@ -5,23 +5,17 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import dataclasses as d
|
|
8
|
-
import typing as h
|
|
9
8
|
from pathlib import Path as path_t
|
|
10
9
|
|
|
11
10
|
import numpy as nmpy
|
|
12
11
|
import plotly.figure_factory as fcry # noqa
|
|
13
12
|
import plotly.graph_objects as plly # noqa
|
|
14
|
-
from babelplot.task.
|
|
13
|
+
from babelplot.task.showing import Show
|
|
15
14
|
from babelplot.type.dimension import dim_e
|
|
16
15
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
17
16
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
18
17
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
19
|
-
from babelplot.type.
|
|
20
|
-
UNDEFINED_PARAMETER,
|
|
21
|
-
PlotsFromTemplate,
|
|
22
|
-
plot_e,
|
|
23
|
-
plot_type_h,
|
|
24
|
-
)
|
|
18
|
+
from babelplot.type.plot_type import plot_e, plot_function_h
|
|
25
19
|
from plotly.basedatatypes import BasePlotlyType as backend_plot_t # noqa
|
|
26
20
|
from plotly.graph_objects import Figure as backend_figure_t # noqa
|
|
27
21
|
from plotly.subplots import make_subplots as NewMultiAxesFigure # noqa
|
|
@@ -51,10 +45,7 @@ class frame_t(base_frame_t):
|
|
|
51
45
|
|
|
52
46
|
def _NewPlot(
|
|
53
47
|
self,
|
|
54
|
-
|
|
55
|
-
plot_function: (
|
|
56
|
-
type[backend_plot_t] | h.Callable[..., backend_plot_t | h.Any] | None
|
|
57
|
-
),
|
|
48
|
+
plot_function: plot_function_h,
|
|
58
49
|
*args,
|
|
59
50
|
title: str | None = None, # If _, then it is swallowed by kwargs!
|
|
60
51
|
**kwargs,
|
|
@@ -66,13 +57,6 @@ class frame_t(base_frame_t):
|
|
|
66
57
|
backend_name=self.backend_name,
|
|
67
58
|
)
|
|
68
59
|
|
|
69
|
-
if plot_function is None:
|
|
70
|
-
if hasattr(plly, type_):
|
|
71
|
-
plot_function = getattr(plly, type_)
|
|
72
|
-
else:
|
|
73
|
-
raise ValueError(f"{type_}: Unknown {NAME} graph object.")
|
|
74
|
-
|
|
75
|
-
output.backend_type = plot_function
|
|
76
60
|
output.raw = plot_function(*args, **kwargs)
|
|
77
61
|
|
|
78
62
|
return output
|
|
@@ -320,6 +304,108 @@ def _BarV(*args, **kwargs) -> backend_plot_t:
|
|
|
320
304
|
return plly.Bar(x=positions, y=counts, **kwargs)
|
|
321
305
|
|
|
322
306
|
|
|
307
|
+
def _Bar3(*args, **kwargs) -> backend_plot_t:
|
|
308
|
+
""""""
|
|
309
|
+
if args.__len__() == 1:
|
|
310
|
+
counts = nmpy.asarray(args[0])
|
|
311
|
+
x, y = counts.shape
|
|
312
|
+
else:
|
|
313
|
+
x, y, counts = args
|
|
314
|
+
counts = nmpy.asarray(counts)
|
|
315
|
+
|
|
316
|
+
if counts.ndim == 2:
|
|
317
|
+
counts = counts.ravel()
|
|
318
|
+
|
|
319
|
+
if isinstance(x, int):
|
|
320
|
+
x, y = nmpy.meshgrid(range(x), range(y), indexing="ij")
|
|
321
|
+
if x.ndim == 2:
|
|
322
|
+
x = x.ravel()
|
|
323
|
+
y = y.ravel()
|
|
324
|
+
|
|
325
|
+
x = x.astype(nmpy.float64)
|
|
326
|
+
y = y.astype(nmpy.float64)
|
|
327
|
+
|
|
328
|
+
differences = nmpy.diff(x)
|
|
329
|
+
thickness_x = min(differences[differences > 0.0])
|
|
330
|
+
differences = nmpy.diff(y)
|
|
331
|
+
thickness_y = min(differences[differences > 0.0])
|
|
332
|
+
thickness_x *= 0.4
|
|
333
|
+
thickness_y *= 0.4
|
|
334
|
+
|
|
335
|
+
vertices_x = []
|
|
336
|
+
vertices_y = []
|
|
337
|
+
vertices_z = []
|
|
338
|
+
for x_, y_, count in zip(x, y, counts):
|
|
339
|
+
x_min, y_min = x_ - thickness_x, y_ - thickness_y
|
|
340
|
+
x_max, y_max = x_ + thickness_x, y_ + thickness_y
|
|
341
|
+
|
|
342
|
+
vertices_x.extend((x_min, x_min, x_max, x_max, x_min, x_min, x_max, x_max))
|
|
343
|
+
vertices_y.extend((y_min, y_max, y_max, y_min, y_min, y_max, y_max, y_min))
|
|
344
|
+
vertices_z.extend((0, 0, 0, 0, count, count, count, count))
|
|
345
|
+
|
|
346
|
+
bottom = (
|
|
347
|
+
nmpy.array((0, 0), dtype=nmpy.int64),
|
|
348
|
+
nmpy.array((1, 2), dtype=nmpy.int64),
|
|
349
|
+
nmpy.array((2, 3), dtype=nmpy.int64),
|
|
350
|
+
)
|
|
351
|
+
top = tuple(_ + 4 for _ in bottom)
|
|
352
|
+
left = (
|
|
353
|
+
nmpy.array((0, 1), dtype=nmpy.int64),
|
|
354
|
+
nmpy.array((1, 5), dtype=nmpy.int64),
|
|
355
|
+
nmpy.array((4, 4), dtype=nmpy.int64),
|
|
356
|
+
)
|
|
357
|
+
right = (
|
|
358
|
+
nmpy.array((3, 2), dtype=nmpy.int64),
|
|
359
|
+
nmpy.array((2, 6), dtype=nmpy.int64),
|
|
360
|
+
nmpy.array((7, 7), dtype=nmpy.int64),
|
|
361
|
+
)
|
|
362
|
+
front = (
|
|
363
|
+
nmpy.array((0, 0), dtype=nmpy.int64),
|
|
364
|
+
nmpy.array((3, 7), dtype=nmpy.int64),
|
|
365
|
+
nmpy.array((7, 4), dtype=nmpy.int64),
|
|
366
|
+
)
|
|
367
|
+
back = (
|
|
368
|
+
nmpy.array((1, 1), dtype=nmpy.int64),
|
|
369
|
+
nmpy.array((2, 6), dtype=nmpy.int64),
|
|
370
|
+
nmpy.array((6, 5), dtype=nmpy.int64),
|
|
371
|
+
)
|
|
372
|
+
triangles_i = []
|
|
373
|
+
triangles_j = []
|
|
374
|
+
triangles_k = []
|
|
375
|
+
v_idx = 0
|
|
376
|
+
for _ in range(counts.size):
|
|
377
|
+
for face in (bottom, top, left, right, front, back):
|
|
378
|
+
triangles_i.extend(face[0] + v_idx)
|
|
379
|
+
triangles_j.extend(face[1] + v_idx)
|
|
380
|
+
triangles_k.extend(face[2] + v_idx)
|
|
381
|
+
v_idx += 8
|
|
382
|
+
|
|
383
|
+
if "color" in kwargs:
|
|
384
|
+
colors = kwargs["color"]
|
|
385
|
+
del kwargs["color"]
|
|
386
|
+
else:
|
|
387
|
+
colors = nmpy.random.random(size=(counts.size, 3))
|
|
388
|
+
colors = colors[
|
|
389
|
+
tuple(
|
|
390
|
+
(nmpy.fromiter(range(12 * counts.size), nmpy.float64) / 12.0).astype(
|
|
391
|
+
nmpy.int64
|
|
392
|
+
)
|
|
393
|
+
),
|
|
394
|
+
:,
|
|
395
|
+
]
|
|
396
|
+
|
|
397
|
+
return plly.Mesh3d(
|
|
398
|
+
x=vertices_x,
|
|
399
|
+
y=vertices_y,
|
|
400
|
+
z=vertices_z,
|
|
401
|
+
i=triangles_i,
|
|
402
|
+
j=triangles_j,
|
|
403
|
+
k=triangles_k,
|
|
404
|
+
facecolor=colors,
|
|
405
|
+
**kwargs,
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
|
|
323
409
|
def _Pie(values: array_t, *_, **kwargs) -> backend_plot_t:
|
|
324
410
|
""""""
|
|
325
411
|
return plly.Pie(values=values, **kwargs)
|
|
@@ -356,7 +442,7 @@ def _Text3(text: str, x: float, y: float, z: float, *_, **kwargs) -> backend_plo
|
|
|
356
442
|
)
|
|
357
443
|
|
|
358
444
|
|
|
359
|
-
PLOTS =
|
|
445
|
+
PLOTS = plot_e.NewPlotsTemplate()
|
|
360
446
|
|
|
361
447
|
PLOTS[plot_e.SCATTER][1] = _Scatter2
|
|
362
448
|
PLOTS[plot_e.POLYLINE][1] = _Polyline2
|
|
@@ -375,13 +461,14 @@ PLOTS[plot_e.ARROWS][2] = _Arrows3
|
|
|
375
461
|
PLOTS[plot_e.ELEVATION][2] = _ElevationSurface
|
|
376
462
|
PLOTS[plot_e.ISOSET][2] = _IsoSurface
|
|
377
463
|
PLOTS[plot_e.MESH][2] = _Mesh
|
|
464
|
+
PLOTS[plot_e.BAR3][2] = _Bar3
|
|
378
465
|
PLOTS[plot_e.TEXT][2] = _Text3
|
|
379
466
|
|
|
380
467
|
|
|
381
468
|
TRANSLATIONS = {
|
|
382
469
|
"alpha": "opacity",
|
|
383
470
|
"color_face": "surfacecolor",
|
|
384
|
-
(_IsoSurface, "color_face"):
|
|
471
|
+
(_IsoSurface, "color_face"): None,
|
|
385
472
|
(_Mesh, "color_face"): "facecolor",
|
|
386
473
|
}
|
|
387
474
|
|
|
@@ -5,15 +5,13 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import dataclasses as d
|
|
8
|
-
import typing as h
|
|
9
8
|
|
|
10
9
|
import vedo # noqa
|
|
11
|
-
from babelplot.type.base import backend_plot_h
|
|
12
10
|
from babelplot.type.dimension import dim_e
|
|
13
11
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
14
12
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
15
13
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
16
|
-
from babelplot.type.
|
|
14
|
+
from babelplot.type.plot_type import plot_e, plot_function_h
|
|
17
15
|
from numpy import ndarray as array_t
|
|
18
16
|
from vedo import Mesh as backend_plot_t # noqa
|
|
19
17
|
from vedo import Plotter as backend_figure_t # noqa
|
|
@@ -31,10 +29,7 @@ class frame_t(base_frame_t):
|
|
|
31
29
|
|
|
32
30
|
def _NewPlot(
|
|
33
31
|
self,
|
|
34
|
-
|
|
35
|
-
plot_function: (
|
|
36
|
-
type[backend_plot_h] | h.Callable[..., backend_plot_h | h.Any] | None
|
|
37
|
-
),
|
|
32
|
+
plot_function: plot_function_h,
|
|
38
33
|
*args,
|
|
39
34
|
title: str | None = None, # If _, then it is swallowed by kwargs!
|
|
40
35
|
**kwargs,
|
|
@@ -46,16 +41,9 @@ class frame_t(base_frame_t):
|
|
|
46
41
|
backend_name=self.backend_name,
|
|
47
42
|
)
|
|
48
43
|
|
|
49
|
-
if plot_function is None:
|
|
50
|
-
if hasattr(vedo, type_):
|
|
51
|
-
plot_function = getattr(vedo, type_)
|
|
52
|
-
else:
|
|
53
|
-
raise ValueError(f"{type_}: Unknown {NAME} graph object.")
|
|
54
|
-
|
|
55
44
|
raw = plot_function(*args, **kwargs)
|
|
56
45
|
self.raw.__iadd__(raw)
|
|
57
46
|
|
|
58
|
-
output.backend_type = plot_function
|
|
59
47
|
output.raw = raw
|
|
60
48
|
|
|
61
49
|
return output
|
|
@@ -95,7 +83,7 @@ def _IsoSurface(volume: array_t, iso_value: float, *_, **kwargs) -> backend_plot
|
|
|
95
83
|
return volume_t(volume).isosurface(value=[iso_value], **kwargs)
|
|
96
84
|
|
|
97
85
|
|
|
98
|
-
PLOTS =
|
|
86
|
+
PLOTS = plot_e.NewPlotsTemplate()
|
|
99
87
|
PLOTS[plot_e.ISOSET][2] = _IsoSurface
|
|
100
88
|
|
|
101
89
|
|
|
@@ -10,7 +10,7 @@ import sys as s
|
|
|
10
10
|
from pathlib import Path as path_t
|
|
11
11
|
|
|
12
12
|
from babelplot.runtime.backends import BACKENDS
|
|
13
|
-
from babelplot.type.
|
|
13
|
+
from babelplot.type.plot_type import plot_e
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def CheckBackend(backend: str | path_t, /) -> None:
|
|
@@ -9,17 +9,17 @@ from enum import Enum as enum_t
|
|
|
9
9
|
|
|
10
10
|
def EnumMembers(enum: type[enum_t], /) -> tuple[str, ...]:
|
|
11
11
|
""""""
|
|
12
|
-
return tuple(sorted(str(
|
|
12
|
+
return tuple(sorted(str(_) for _ in enum.__members__.values()))
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def EnumNames(enum: type[enum_t], /) -> tuple[str, ...]:
|
|
16
16
|
""""""
|
|
17
|
-
return tuple(sorted(
|
|
17
|
+
return tuple(sorted(_.name for _ in enum.__members__.values()))
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def EnumValues(enum: type[enum_t], /) -> tuple[str, ...]:
|
|
21
21
|
""""""
|
|
22
|
-
return tuple(sorted(
|
|
22
|
+
return tuple(sorted(_.value for _ in enum.__members__.values()))
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
"""
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright CNRS/Inria/UniCA
|
|
3
|
+
Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2022
|
|
4
|
+
SEE COPYRIGHT NOTICE BELOW
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
UN_SHOWN_FIGURES = []
|
|
8
|
+
SHOWN_FIGURES = []
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
COPYRIGHT NOTICE
|
|
13
|
+
|
|
14
|
+
This software is governed by the CeCILL license under French law and
|
|
15
|
+
abiding by the rules of distribution of free software. You can use,
|
|
16
|
+
modify and/ or redistribute the software under the terms of the CeCILL
|
|
17
|
+
license as circulated by CEA, CNRS and INRIA at the following URL
|
|
18
|
+
"http://www.cecill.info".
|
|
19
|
+
|
|
20
|
+
As a counterpart to the access to the source code and rights to copy,
|
|
21
|
+
modify and redistribute granted by the license, users are provided only
|
|
22
|
+
with a limited warranty and the software's author, the holder of the
|
|
23
|
+
economic rights, and the successive licensors have only limited
|
|
24
|
+
liability.
|
|
25
|
+
|
|
26
|
+
In this respect, the user's attention is drawn to the risks associated
|
|
27
|
+
with loading, using, modifying and/or developing or reproducing the
|
|
28
|
+
software by the user in light of its specific status of free software,
|
|
29
|
+
that may mean that it is complicated to manipulate, and that also
|
|
30
|
+
therefore means that it is reserved for developers and experienced
|
|
31
|
+
professionals having in-depth computer knowledge. Users are therefore
|
|
32
|
+
encouraged to load and test the software's suitability as regards their
|
|
33
|
+
requirements in conditions enabling the security of their systems and/or
|
|
34
|
+
data to be ensured and, more generally, to use and operate it in the
|
|
35
|
+
same conditions as regards security.
|
|
36
|
+
|
|
37
|
+
The fact that you are presently reading this means that you have had
|
|
38
|
+
knowledge of the CeCILL license and that you accept its terms.
|
|
39
|
+
|
|
40
|
+
SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
|
|
41
|
+
|
|
42
|
+
This software is being developed by Eric Debreuve, a CNRS employee and
|
|
43
|
+
member of team Morpheme.
|
|
44
|
+
Team Morpheme is a joint team between Inria, CNRS, and UniCA.
|
|
45
|
+
It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
|
|
46
|
+
I3S, and Laboratory iBV.
|
|
47
|
+
|
|
48
|
+
CNRS: https://www.cnrs.fr/index.php/en
|
|
49
|
+
Inria: https://www.inria.fr/en/
|
|
50
|
+
UniCA: https://univ-cotedazur.eu/
|
|
51
|
+
Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
|
|
52
|
+
I3S: https://www.i3s.unice.fr/en/
|
|
53
|
+
iBV: http://ibv.unice.fr/
|
|
54
|
+
Team Morpheme: https://team.inria.fr/morpheme/
|
|
55
|
+
"""
|
|
@@ -9,7 +9,7 @@ import sys as s
|
|
|
9
9
|
|
|
10
10
|
from babelplot.constant.path import BACKEND_CATALOG_PY_PATH
|
|
11
11
|
from babelplot.runtime.backends import BACKENDS
|
|
12
|
-
from babelplot.type.
|
|
12
|
+
from babelplot.type.plot_type import plot_e
|
|
13
13
|
from logger_36 import L
|
|
14
14
|
from logger_36.api.handler import AddConsoleHandler
|
|
15
15
|
|
|
@@ -31,7 +31,7 @@ def PrintUsage() -> None:
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def
|
|
34
|
+
def PrintHelp() -> None:
|
|
35
35
|
""""""
|
|
36
36
|
if (n_arguments := s.argv.__len__()) == 1:
|
|
37
37
|
PrintUsage()
|
|
@@ -42,7 +42,7 @@ def Main() -> None:
|
|
|
42
42
|
backends = "\n".join(backends)
|
|
43
43
|
print(f"Available Backends:\n{backends}")
|
|
44
44
|
elif s.argv[1] == "plots":
|
|
45
|
-
plots = plot_e.
|
|
45
|
+
plots = plot_e.Formatted().splitlines()
|
|
46
46
|
plots = (f" {_lne}" for _lne in plots)
|
|
47
47
|
plots = "\n".join(plots)
|
|
48
48
|
print(f"Defined BabelPlot Plots:\n{plots}")
|
|
@@ -66,7 +66,7 @@ def Main() -> None:
|
|
|
66
66
|
for key, value in backend.PLOTS.items():
|
|
67
67
|
functions = []
|
|
68
68
|
for dim, function in enumerate(value, start=1):
|
|
69
|
-
if function is not
|
|
69
|
+
if function is not None:
|
|
70
70
|
functions.append(f"Dim.{dim}: {function.__name__}")
|
|
71
71
|
functions = ", ".join(functions)
|
|
72
72
|
plots.append(f"{key}: {functions}")
|
|
@@ -8,12 +8,11 @@ import typing as h
|
|
|
8
8
|
from pathlib import Path as path_t
|
|
9
9
|
|
|
10
10
|
from babelplot.runtime.backends import BACKENDS
|
|
11
|
-
from babelplot.type.base import backend_plot_h
|
|
12
11
|
from babelplot.type.dimension import dim_e
|
|
13
12
|
from babelplot.type.figure import figure_t
|
|
14
13
|
from babelplot.type.frame import frame_t
|
|
15
14
|
from babelplot.type.plot import plot_t
|
|
16
|
-
from babelplot.type.
|
|
15
|
+
from babelplot.type.plot_type import plot_function_h, plot_type_h
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
def NewFigure(
|
|
@@ -28,24 +27,17 @@ def NewFigure(
|
|
|
28
27
|
if backend_name is None:
|
|
29
28
|
return None
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
return actual_figure_t.New(
|
|
31
|
+
backend_name,
|
|
32
|
+
*args,
|
|
32
33
|
title=title,
|
|
33
34
|
offline_version=offline_version,
|
|
34
|
-
|
|
35
|
+
**kwargs,
|
|
35
36
|
)
|
|
36
37
|
|
|
37
|
-
args, kwargs = TranslatedArguments(
|
|
38
|
-
"_NewBackendFigure", args, kwargs, BACKENDS[backend_name].arguments_translations
|
|
39
|
-
)
|
|
40
|
-
raw = output._NewBackendFigure(*args, **kwargs)
|
|
41
|
-
|
|
42
|
-
output.raw = raw
|
|
43
|
-
|
|
44
|
-
return output
|
|
45
|
-
|
|
46
38
|
|
|
47
39
|
def NewPlot(
|
|
48
|
-
type_: plot_type_h |
|
|
40
|
+
type_: plot_type_h | plot_function_h,
|
|
49
41
|
*plt_args,
|
|
50
42
|
fig_args=(),
|
|
51
43
|
frm_args=(),
|
|
@@ -74,6 +66,9 @@ def NewPlot(
|
|
|
74
66
|
backend=backend,
|
|
75
67
|
**fig_kwargs,
|
|
76
68
|
)
|
|
69
|
+
if figure is None:
|
|
70
|
+
return None
|
|
71
|
+
|
|
77
72
|
frame = figure.AddFrame(
|
|
78
73
|
*frm_args,
|
|
79
74
|
title=frm_title,
|
|
@@ -96,14 +91,6 @@ def NewPlot(
|
|
|
96
91
|
return figure, frame, plot
|
|
97
92
|
|
|
98
93
|
|
|
99
|
-
# def CloseFigure(figure: figure_t, /)->None:
|
|
100
|
-
# """"""
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# def CloseAllFigures()->None:
|
|
104
|
-
# """"""
|
|
105
|
-
|
|
106
|
-
|
|
107
94
|
"""
|
|
108
95
|
COPYRIGHT NOTICE
|
|
109
96
|
|
|
@@ -9,6 +9,7 @@ import sys as s
|
|
|
9
9
|
import tempfile as tmpf
|
|
10
10
|
|
|
11
11
|
from babelplot.constant.project import NAME
|
|
12
|
+
from babelplot.runtime.figure import SHOWN_FIGURES, UN_SHOWN_FIGURES
|
|
12
13
|
from babelplot.type.figure import figure_t
|
|
13
14
|
from PyQt6.QtCore import QUrl as url_t
|
|
14
15
|
from PyQt6.QtWebEngineWidgets import QWebEngineView as widget_t
|
|
@@ -33,6 +34,37 @@ def Show(figure: figure_t, /) -> None:
|
|
|
33
34
|
application.exec()
|
|
34
35
|
|
|
35
36
|
|
|
37
|
+
def ShowAllFigures(
|
|
38
|
+
*,
|
|
39
|
+
modal: bool = True,
|
|
40
|
+
) -> None:
|
|
41
|
+
""""""
|
|
42
|
+
# TODO: Is this related to backend thread support (see associated constant)?
|
|
43
|
+
if all(_.backend_name == "matplotlib" for _ in UN_SHOWN_FIGURES):
|
|
44
|
+
for figure in UN_SHOWN_FIGURES:
|
|
45
|
+
figure.AdjustLayout()
|
|
46
|
+
|
|
47
|
+
SHOWN_FIGURES.extend(UN_SHOWN_FIGURES) # /!\ Must be removed when closed.
|
|
48
|
+
UN_SHOWN_FIGURES.clear()
|
|
49
|
+
|
|
50
|
+
import matplotlib.pyplot as pypl # noqa
|
|
51
|
+
|
|
52
|
+
pypl.show()
|
|
53
|
+
else:
|
|
54
|
+
while UN_SHOWN_FIGURES.__len__() > 1:
|
|
55
|
+
UN_SHOWN_FIGURES[0].Show(modal=False)
|
|
56
|
+
if UN_SHOWN_FIGURES.__len__() > 0:
|
|
57
|
+
UN_SHOWN_FIGURES[0].Show(modal=modal)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# def CloseFigure(figure: figure_t, /)->None:
|
|
61
|
+
# """"""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# def CloseAllFigures()->None:
|
|
65
|
+
# """"""
|
|
66
|
+
|
|
67
|
+
|
|
36
68
|
def _SetHTMLFromFile(success: bool, widget: widget_t, html: str, /) -> None:
|
|
37
69
|
"""
|
|
38
70
|
From: https://doc.qt.io/qtforpython-6/PySide6/QtWebEngineWidgets/QWebEngineView.html#PySide6.QtWebEngineWidgets.PySide6.QtWebEngineWidgets.QWebEngineView.setHtml
|