babelplot 2025.7__tar.gz → 2025.8__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.7 → babelplot-2025.8}/PKG-INFO +1 -1
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/bokeh_.py +44 -8
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/plotly_.py +1 -1
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/vedo_.py +33 -5
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/backend.py +23 -3
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/figure.py +1 -1
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/version.py +1 -1
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/PKG-INFO +1 -1
- {babelplot-2025.7 → babelplot-2025.8}/MANIFEST.in +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/README-COPYRIGHT-utf8.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/README-LICENCE-utf8.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/README.rst +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/documentation/wiki/description.asciidoc +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/__init__.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/api/backend.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/api/definition.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/api/help.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/matplotlib_.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/helper/creation.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/helper/validation.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/constant/backend.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/constant/path.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/constant/project.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/extension/enum_.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/extension/function.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/runtime/backends.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/runtime/figure.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/task/help.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/task/instantiation.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/task/showing.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/dimension.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/ffp_base.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/frame.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/plot.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/plot_type.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/translator.py +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/SOURCES.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/dependency_links.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/requires.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/top_level.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/pyproject.toml +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/requirements.txt +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/setup.cfg +0 -0
- {babelplot-2025.7 → babelplot-2025.8}/setup.py +0 -0
|
@@ -5,7 +5,9 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import dataclasses as d
|
|
8
|
+
import gzip
|
|
8
9
|
import typing as h
|
|
10
|
+
from multiprocessing import Process as process_t
|
|
9
11
|
|
|
10
12
|
from babelplot.task.showing import ShowHTMLWithPyQt
|
|
11
13
|
from babelplot.type.dimension import dim_e
|
|
@@ -21,8 +23,6 @@ from bokeh.models.renderers import GlyphRenderer as backend_plot_t # noqa
|
|
|
21
23
|
from bokeh.plotting import figure as backend_figure_t # noqa
|
|
22
24
|
from bokeh.resources import INLINE # noqa
|
|
23
25
|
|
|
24
|
-
# from bokeh.layouts import LayoutDOM as backend_content_t # noqa
|
|
25
|
-
|
|
26
26
|
NAME = "bokeh"
|
|
27
27
|
|
|
28
28
|
|
|
@@ -59,8 +59,6 @@ class frame_t(base_frame_t):
|
|
|
59
59
|
class figure_t(base_figure_t):
|
|
60
60
|
layout: h.Any = None
|
|
61
61
|
|
|
62
|
-
_BackendShow = ShowHTMLWithPyQt
|
|
63
|
-
|
|
64
62
|
def _NewBackendFigure(self, *args, **kwargs) -> backend_figure_t:
|
|
65
63
|
""""""
|
|
66
64
|
return backend_figure_t(*args, **kwargs)
|
|
@@ -81,17 +79,34 @@ class figure_t(base_figure_t):
|
|
|
81
79
|
backend_name=self.backend_name,
|
|
82
80
|
)
|
|
83
81
|
|
|
84
|
-
output.raw = backend_frame_t(
|
|
82
|
+
output.raw = backend_frame_t(title=title, **kwargs)
|
|
85
83
|
|
|
86
84
|
return output
|
|
87
85
|
|
|
88
86
|
def AdjustLayout(self) -> None:
|
|
89
87
|
""""""
|
|
88
|
+
# from bokeh.layouts import LayoutDOM as backend_content_t # noqa
|
|
89
|
+
|
|
90
|
+
# arranged_frames must be composed of list since Bokeh does not support tuples
|
|
91
|
+
# here!
|
|
90
92
|
n_rows, n_cols = self.shape
|
|
91
93
|
arranged_frames = [n_cols * [None] for _ in range(n_rows)]
|
|
92
94
|
for frame, (row, col) in zip(self.frames, self.locations):
|
|
93
95
|
arranged_frames[row][col] = frame.raw
|
|
94
|
-
|
|
96
|
+
|
|
97
|
+
# Bokeh does not support inserting None as an indicator of empty space. As a
|
|
98
|
+
# workaround, the frames are currently flattened (and None_s are filtered out).
|
|
99
|
+
should_be_filtered = False
|
|
100
|
+
for one_row in arranged_frames:
|
|
101
|
+
if any(_ is None for _ in one_row):
|
|
102
|
+
should_be_filtered = True
|
|
103
|
+
break
|
|
104
|
+
if should_be_filtered:
|
|
105
|
+
arranged_frames = [_ for one_row in arranged_frames for _ in one_row]
|
|
106
|
+
arranged_frames = list(filter(lambda _: _ is not None, arranged_frames))
|
|
107
|
+
arranged_frames = [arranged_frames]
|
|
108
|
+
n_rows = 1
|
|
109
|
+
n_cols = arranged_frames[0].__len__()
|
|
95
110
|
|
|
96
111
|
if n_rows > 1:
|
|
97
112
|
if n_cols > 1:
|
|
@@ -104,9 +119,29 @@ class figure_t(base_figure_t):
|
|
|
104
119
|
|
|
105
120
|
self.layout = layout
|
|
106
121
|
|
|
107
|
-
def
|
|
122
|
+
def _BackendShow(self, modal: bool, /) -> None:
|
|
108
123
|
""""""
|
|
109
|
-
|
|
124
|
+
try:
|
|
125
|
+
html = HTMLofBackendContent(self.layout, INLINE)
|
|
126
|
+
except ValueError as exception:
|
|
127
|
+
html = f"""
|
|
128
|
+
<!DOCTYPE html>
|
|
129
|
+
<html>
|
|
130
|
+
<body>
|
|
131
|
+
<h1>Figure cannot be shown</h1>
|
|
132
|
+
<p>{str(exception)}</p>
|
|
133
|
+
</body>
|
|
134
|
+
</html>
|
|
135
|
+
"""
|
|
136
|
+
uid = id(self)
|
|
137
|
+
if modal:
|
|
138
|
+
ShowHTMLWithPyQt(html, uid)
|
|
139
|
+
self.AcknowledgeClosure()
|
|
140
|
+
else:
|
|
141
|
+
html = gzip.compress(html.encode())
|
|
142
|
+
process = process_t(target=lambda: ShowHTMLWithPyQt(html, uid))
|
|
143
|
+
process.start()
|
|
144
|
+
self.showing_process = process
|
|
110
145
|
|
|
111
146
|
|
|
112
147
|
PLOTS = plot_e.NewPlotsTemplate()
|
|
@@ -115,6 +150,7 @@ PLOTS[plot_e.SCATTER][1] = backend_frame_t.scatter
|
|
|
115
150
|
|
|
116
151
|
TRANSLATIONS = {
|
|
117
152
|
"color_face": "fill_color",
|
|
153
|
+
"opacity": "alpha",
|
|
118
154
|
}
|
|
119
155
|
|
|
120
156
|
|
|
@@ -30,7 +30,7 @@ array_t = nmpy.ndarray
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
_FIGURE_CONFIG = {
|
|
33
|
-
"toImageButtonOptions": { # TODO:
|
|
33
|
+
"toImageButtonOptions": { # TODO: No PNG export produced actually.
|
|
34
34
|
"filename": str(path_t.home() / "plotly_figure"),
|
|
35
35
|
"height": None,
|
|
36
36
|
"width": None,
|
|
@@ -5,6 +5,7 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import dataclasses as d
|
|
8
|
+
from multiprocessing import Process as process_t
|
|
8
9
|
|
|
9
10
|
import vedo # noqa
|
|
10
11
|
from babelplot.type.dimension import dim_e
|
|
@@ -42,7 +43,8 @@ class frame_t(base_frame_t):
|
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
raw = plot_function(*args, **kwargs)
|
|
45
|
-
|
|
46
|
+
if raw is not None:
|
|
47
|
+
self.raw.__iadd__(raw)
|
|
46
48
|
|
|
47
49
|
output.raw = raw
|
|
48
50
|
|
|
@@ -72,13 +74,19 @@ class figure_t(base_figure_t):
|
|
|
72
74
|
backend_name=self.backend_name,
|
|
73
75
|
)
|
|
74
76
|
|
|
75
|
-
output.raw = self
|
|
77
|
+
output.raw = self.raw
|
|
76
78
|
|
|
77
79
|
return output
|
|
78
80
|
|
|
79
|
-
def
|
|
81
|
+
def _BackendShow(self, modal: bool, /) -> None:
|
|
80
82
|
""""""
|
|
81
|
-
|
|
83
|
+
if modal:
|
|
84
|
+
self.raw.show().close()
|
|
85
|
+
self.AcknowledgeClosure()
|
|
86
|
+
else:
|
|
87
|
+
process = process_t(target=lambda: self.raw.show().close())
|
|
88
|
+
process.start()
|
|
89
|
+
self.showing_process = process
|
|
82
90
|
|
|
83
91
|
|
|
84
92
|
def _IsoSurface(volume: array_t, iso_value: float, *_, **kwargs) -> backend_plot_t:
|
|
@@ -86,11 +94,31 @@ def _IsoSurface(volume: array_t, iso_value: float, *_, **kwargs) -> backend_plot
|
|
|
86
94
|
return volume_t(volume).isosurface(value=[iso_value], **kwargs)
|
|
87
95
|
|
|
88
96
|
|
|
97
|
+
def _Mesh(triangles: array_t, vertices: array_t, *_, **kwargs) -> backend_plot_t:
|
|
98
|
+
""""""
|
|
99
|
+
output = backend_plot_t((vertices, triangles))
|
|
100
|
+
|
|
101
|
+
if "width_edge" in kwargs:
|
|
102
|
+
output.linewidth(kwargs["width_edge"])
|
|
103
|
+
if "color_edge" in kwargs:
|
|
104
|
+
output.linecolor(kwargs["color_edge"])
|
|
105
|
+
if "color_face" in kwargs:
|
|
106
|
+
output.color(c=kwargs["color_face"])
|
|
107
|
+
|
|
108
|
+
return output
|
|
109
|
+
|
|
110
|
+
|
|
89
111
|
PLOTS = plot_e.NewPlotsTemplate()
|
|
90
112
|
PLOTS[plot_e.ISOSET][2] = _IsoSurface
|
|
113
|
+
PLOTS[plot_e.MESH][2] = _Mesh
|
|
91
114
|
|
|
92
115
|
|
|
93
|
-
TRANSLATIONS = {
|
|
116
|
+
TRANSLATIONS = {
|
|
117
|
+
(_IsoSurface, "color_edge"): None,
|
|
118
|
+
(_IsoSurface, "color_face"): None,
|
|
119
|
+
(_IsoSurface, "step_size"): None,
|
|
120
|
+
(_IsoSurface, "width_edge"): None,
|
|
121
|
+
}
|
|
94
122
|
|
|
95
123
|
|
|
96
124
|
"""
|
|
@@ -47,14 +47,17 @@ class backend_t:
|
|
|
47
47
|
) -> plot_function_h:
|
|
48
48
|
""""""
|
|
49
49
|
if (output := self.plot_functions.get(type_)) is None:
|
|
50
|
-
|
|
50
|
+
L.error(f"Unknown plot {type_}.")
|
|
51
|
+
return _FakePlotFunction(type_, frame_dim)
|
|
51
52
|
|
|
52
53
|
if output.__len__() <= frame_dim - 1:
|
|
53
|
-
|
|
54
|
+
L.error(f"Unknown plot {type_} for dimension {frame_dim}.")
|
|
55
|
+
return _FakePlotFunction(type_, frame_dim)
|
|
54
56
|
|
|
55
57
|
output = output[frame_dim - 1]
|
|
56
58
|
if output is None:
|
|
57
|
-
|
|
59
|
+
L.error(f"Unknown plot {type_} for dimension {frame_dim}.")
|
|
60
|
+
return _FakePlotFunction(type_, frame_dim)
|
|
58
61
|
|
|
59
62
|
return output
|
|
60
63
|
|
|
@@ -73,6 +76,9 @@ class backend_t:
|
|
|
73
76
|
out_args = []
|
|
74
77
|
out_kwargs = {}
|
|
75
78
|
|
|
79
|
+
# TODO: Add the possibility to transform the arguments by letting "translation"
|
|
80
|
+
# being either a translation command or a tuple of a translation command and
|
|
81
|
+
# a conversion function. Useful for color format adaptation.
|
|
76
82
|
for idx, value in enumerate(args):
|
|
77
83
|
if (translation := translations.get((who_s_asking, idx), -1)) == -1:
|
|
78
84
|
# No translation needed; Keeping the passed arg.
|
|
@@ -249,6 +255,20 @@ class backends_t(dict[str, backend_t]):
|
|
|
249
255
|
return "\n".join(output)
|
|
250
256
|
|
|
251
257
|
|
|
258
|
+
def _FakePlotFunction(type_: plot_e, frame_dim: int, /) -> h.Callable[..., None]:
|
|
259
|
+
""""""
|
|
260
|
+
|
|
261
|
+
def Actual(*args, **kwargs) -> None:
|
|
262
|
+
#
|
|
263
|
+
args = ", ".join(map(lambda _: type(_).__name__, args))
|
|
264
|
+
kwargs = ", ".join(
|
|
265
|
+
f"{_key}={type(_vle).__name__}" for _key, _vle in kwargs.items()
|
|
266
|
+
)
|
|
267
|
+
L.warning(f"Unhandled plot request: {type_.name}.{frame_dim}: {args}, {kwargs}")
|
|
268
|
+
|
|
269
|
+
return Actual
|
|
270
|
+
|
|
271
|
+
|
|
252
272
|
"""
|
|
253
273
|
COPYRIGHT NOTICE
|
|
254
274
|
|
|
@@ -200,7 +200,7 @@ class figure_t(base_t):
|
|
|
200
200
|
raise RuntimeError(f"Figure {self.title} already shown.")
|
|
201
201
|
|
|
202
202
|
if self.frames.__len__() == 0:
|
|
203
|
-
L.warning(f"Figure {self.title} empty; Not
|
|
203
|
+
L.warning(f"Figure {self.title} empty; Not showing.")
|
|
204
204
|
else:
|
|
205
205
|
self.AdjustLayout()
|
|
206
206
|
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|