babelplot 2025.8__tar.gz → 2025.10__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.8 → babelplot-2025.10}/PKG-INFO +1 -1
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/__init__.py +1 -1
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/backend/catalog/bokeh_.py +60 -27
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/backend/catalog/matplotlib_.py +47 -47
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/backend/catalog/plotly_.py +35 -35
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/backend/catalog/vedo_.py +18 -14
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/backend/helper/validation.py +53 -1
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/constant/path.py +1 -1
- babelplot-2025.10/package/babelplot/task/color.py +112 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/task/help.py +6 -2
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/task/instantiation.py +2 -1
- babelplot-2025.10/package/babelplot/task/plotting.py +85 -0
- babelplot-2025.10/package/babelplot/task/showing.py +172 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/backend.py +23 -40
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/ffp_base.py +3 -3
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/figure.py +2 -21
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/frame.py +2 -1
- babelplot-2025.8/package/babelplot/type/translator.py → babelplot-2025.10/package/babelplot/type/plot_function.py +6 -4
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/plot_type.py +3 -60
- babelplot-2025.10/package/babelplot/type/translator.py +70 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/version.py +1 -1
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot.egg-info/PKG-INFO +1 -1
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot.egg-info/SOURCES.txt +3 -1
- babelplot-2025.8/package/babelplot/runtime/figure.py +0 -55
- babelplot-2025.8/package/babelplot/task/showing.py +0 -137
- {babelplot-2025.8 → babelplot-2025.10}/MANIFEST.in +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/README-COPYRIGHT-utf8.txt +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/README-LICENCE-utf8.txt +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/README.rst +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/documentation/wiki/description.asciidoc +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/api/backend.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/api/definition.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/api/help.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/backend/helper/creation.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/constant/backend.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/constant/project.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/extension/enum_.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/extension/function.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/runtime/backends.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/dimension.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot/type/plot.py +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot.egg-info/dependency_links.txt +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot.egg-info/requires.txt +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/package/babelplot.egg-info/top_level.txt +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/pyproject.toml +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/requirements.txt +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/setup.cfg +0 -0
- {babelplot-2025.8 → babelplot-2025.10}/setup.py +0 -0
|
@@ -18,7 +18,7 @@ else:
|
|
|
18
18
|
beartype_this_package()
|
|
19
19
|
|
|
20
20
|
from babelplot.task.instantiation import NewFigure, NewPlot
|
|
21
|
-
from babelplot.task.showing import
|
|
21
|
+
from babelplot.task.showing import ShowFigures
|
|
22
22
|
from babelplot.type.dimension import dim_e
|
|
23
23
|
from babelplot.type.plot_type import plot_e
|
|
24
24
|
from babelplot.version import __version__
|
|
@@ -9,24 +9,26 @@ import gzip
|
|
|
9
9
|
import typing as h
|
|
10
10
|
from multiprocessing import Process as process_t
|
|
11
11
|
|
|
12
|
-
from babelplot.task.
|
|
12
|
+
from babelplot.task.plotting import NewPlotFunctionsTemplate, SetDefaultPlotFunction
|
|
13
|
+
from babelplot.task.showing import ShowHTMLPlotWithPyQt
|
|
13
14
|
from babelplot.type.dimension import dim_e
|
|
14
15
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
15
16
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
16
17
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
17
|
-
from babelplot.type.
|
|
18
|
+
from babelplot.type.plot_function import plot_function_h
|
|
19
|
+
from babelplot.type.plot_type import plot_e
|
|
18
20
|
from bokeh.embed import file_html as HTMLofBackendContent # noqa
|
|
19
21
|
from bokeh.layouts import column as NewBackendColLayout # noqa
|
|
20
22
|
from bokeh.layouts import grid as NewBackendGridLayout # noqa
|
|
21
23
|
from bokeh.layouts import row as NewBackendRowLayout # noqa
|
|
22
24
|
from bokeh.models.renderers import GlyphRenderer as backend_plot_t # noqa
|
|
23
|
-
from bokeh.plotting import figure as
|
|
25
|
+
from bokeh.plotting import figure as backend_frame_t # noqa
|
|
24
26
|
from bokeh.resources import INLINE # noqa
|
|
25
27
|
|
|
26
28
|
NAME = "bokeh"
|
|
27
29
|
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
class backend_figure_t: ...
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
@d.dataclass(slots=True, repr=False, eq=False)
|
|
@@ -44,24 +46,22 @@ class frame_t(base_frame_t):
|
|
|
44
46
|
**kwargs,
|
|
45
47
|
) -> plot_t:
|
|
46
48
|
""""""
|
|
47
|
-
|
|
49
|
+
return plot_t(
|
|
48
50
|
title=title,
|
|
49
51
|
property=kwargs.copy(),
|
|
50
52
|
backend_name=self.backend_name,
|
|
53
|
+
raw=plot_function(self.raw, *args, **kwargs),
|
|
51
54
|
)
|
|
52
55
|
|
|
53
|
-
output.raw = plot_function(self.raw, *args, **kwargs)
|
|
54
|
-
|
|
55
|
-
return output
|
|
56
|
-
|
|
57
56
|
|
|
58
57
|
@d.dataclass(slots=True, repr=False, eq=False)
|
|
59
58
|
class figure_t(base_figure_t):
|
|
60
|
-
|
|
59
|
+
|
|
60
|
+
layout: h.Any = d.field(init=False, default=None)
|
|
61
61
|
|
|
62
62
|
def _NewBackendFigure(self, *args, **kwargs) -> backend_figure_t:
|
|
63
63
|
""""""
|
|
64
|
-
return backend_figure_t(
|
|
64
|
+
return backend_figure_t() # self.raw is never used.
|
|
65
65
|
|
|
66
66
|
def _NewFrame(
|
|
67
67
|
self,
|
|
@@ -73,26 +73,31 @@ class figure_t(base_figure_t):
|
|
|
73
73
|
**kwargs,
|
|
74
74
|
) -> frame_t:
|
|
75
75
|
""""""
|
|
76
|
-
|
|
76
|
+
return frame_t(
|
|
77
77
|
title=title,
|
|
78
78
|
dim=dim,
|
|
79
79
|
backend_name=self.backend_name,
|
|
80
|
+
raw=backend_frame_t(title=title, **kwargs),
|
|
80
81
|
)
|
|
81
82
|
|
|
82
|
-
output.raw = backend_frame_t(title=title, **kwargs)
|
|
83
|
-
|
|
84
|
-
return output
|
|
85
|
-
|
|
86
83
|
def AdjustLayout(self) -> None:
|
|
87
84
|
""""""
|
|
88
|
-
# from bokeh.layouts import LayoutDOM as backend_content_t # noqa
|
|
89
|
-
|
|
90
85
|
# arranged_frames must be composed of list since Bokeh does not support tuples
|
|
91
86
|
# here!
|
|
92
87
|
n_rows, n_cols = self.shape
|
|
93
88
|
arranged_frames = [n_cols * [None] for _ in range(n_rows)]
|
|
94
89
|
for frame, (row, col) in zip(self.frames, self.locations):
|
|
95
|
-
|
|
90
|
+
raw = frame.raw
|
|
91
|
+
if raw.renderers.__len__() == 0:
|
|
92
|
+
_ = backend_frame_t.text(
|
|
93
|
+
raw,
|
|
94
|
+
x=(0,),
|
|
95
|
+
y=(0,),
|
|
96
|
+
text=("Empty Frame",),
|
|
97
|
+
text_font_size="30px",
|
|
98
|
+
text_color="#FF0000",
|
|
99
|
+
)
|
|
100
|
+
arranged_frames[row][col] = raw
|
|
96
101
|
|
|
97
102
|
# Bokeh does not support inserting None as an indicator of empty space. As a
|
|
98
103
|
# workaround, the frames are currently flattened (and None_s are filtered out).
|
|
@@ -123,6 +128,7 @@ class figure_t(base_figure_t):
|
|
|
123
128
|
""""""
|
|
124
129
|
try:
|
|
125
130
|
html = HTMLofBackendContent(self.layout, INLINE)
|
|
131
|
+
html = gzip.compress(html.encode())
|
|
126
132
|
except ValueError as exception:
|
|
127
133
|
html = f"""
|
|
128
134
|
<!DOCTYPE html>
|
|
@@ -133,24 +139,51 @@ class figure_t(base_figure_t):
|
|
|
133
139
|
</body>
|
|
134
140
|
</html>
|
|
135
141
|
"""
|
|
136
|
-
|
|
142
|
+
|
|
143
|
+
process = process_t(target=ShowHTMLPlotWithPyQt, args=(html,))
|
|
144
|
+
process.start()
|
|
145
|
+
|
|
137
146
|
if modal:
|
|
138
|
-
|
|
139
|
-
self.AcknowledgeClosure()
|
|
147
|
+
process.join()
|
|
140
148
|
else:
|
|
141
|
-
html = gzip.compress(html.encode())
|
|
142
|
-
process = process_t(target=lambda: ShowHTMLWithPyQt(html, uid))
|
|
143
|
-
process.start()
|
|
144
149
|
self.showing_process = process
|
|
145
150
|
|
|
146
151
|
|
|
147
|
-
|
|
148
|
-
|
|
152
|
+
def _DefaultFunction(type_: plot_e, frame_dim: int, /) -> plot_function_h:
|
|
153
|
+
""""""
|
|
154
|
+
|
|
155
|
+
def Actual(frame: backend_frame_t, *args, **kwargs) -> backend_plot_t:
|
|
156
|
+
""""""
|
|
157
|
+
args = ", ".join(map(lambda _: type(_).__name__, args))
|
|
158
|
+
kwargs = ", ".join(
|
|
159
|
+
f"{_key}={type(_vle).__name__}" for _key, _vle in kwargs.items()
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return backend_frame_t.text(
|
|
163
|
+
frame,
|
|
164
|
+
x=(0,),
|
|
165
|
+
y=(0,),
|
|
166
|
+
text=(
|
|
167
|
+
f"Unhandled Plot Request\n{type_.name}.{frame_dim}\nargs: {args}\nkwargs: {kwargs}",
|
|
168
|
+
),
|
|
169
|
+
text_font_size="30px",
|
|
170
|
+
text_align="center",
|
|
171
|
+
text_color="#FF0000",
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
return Actual
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
PLOTS = NewPlotFunctionsTemplate()
|
|
178
|
+
PLOTS[plot_e.SCATTER][0] = backend_frame_t.scatter
|
|
179
|
+
SetDefaultPlotFunction(PLOTS, _DefaultFunction)
|
|
149
180
|
|
|
150
181
|
|
|
151
182
|
TRANSLATIONS = {
|
|
152
183
|
"color_face": "fill_color",
|
|
153
184
|
"opacity": "alpha",
|
|
185
|
+
("AddFrame", "azimuth"): None,
|
|
186
|
+
("AddFrame", "elevation"): None,
|
|
154
187
|
}
|
|
155
188
|
|
|
156
189
|
|
|
@@ -10,12 +10,15 @@ 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.task.color import NewConvertedColor
|
|
14
|
+
from babelplot.task.plotting import NewPlotFunctionsTemplate
|
|
13
15
|
from babelplot.type.dimension import dim_e
|
|
14
16
|
from babelplot.type.ffp_base import backend_element_h
|
|
15
17
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
16
18
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
17
19
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
18
|
-
from babelplot.type.
|
|
20
|
+
from babelplot.type.plot_function import plot_function_h
|
|
21
|
+
from babelplot.type.plot_type import plot_e, plot_type_h
|
|
19
22
|
from logger_36 import L
|
|
20
23
|
from matplotlib.artist import Artist as backend_plot_t # noqa
|
|
21
24
|
from matplotlib.container import Container as backend_plots_t # noqa
|
|
@@ -27,7 +30,7 @@ from matplotlib.pyplot import Figure as backend_figure_t # noqa
|
|
|
27
30
|
from matplotlib.pyplot import figure as NewBackendFigure # noqa
|
|
28
31
|
from mpl_toolkits.mplot3d import Axes3D as backend_frame_3d_t # noqa
|
|
29
32
|
|
|
30
|
-
import matplotlib as
|
|
33
|
+
import matplotlib as mtpl # noqa
|
|
31
34
|
|
|
32
35
|
NAME = "matplotlib"
|
|
33
36
|
|
|
@@ -39,7 +42,7 @@ backend_frame_h = backend_frame_2d_t | backend_frame_3d_t
|
|
|
39
42
|
def _DefaultProperties(type_: type[plot_type_h], /) -> dict[str, h.Any]:
|
|
40
43
|
""""""
|
|
41
44
|
name = type_.__name__
|
|
42
|
-
properties =
|
|
45
|
+
properties = mtpl.rcParams.find_all(f"^{name}\\.")
|
|
43
46
|
|
|
44
47
|
return {_key.replace(f"{name}.", ""): _vle for _key, _vle in properties.items()}
|
|
45
48
|
|
|
@@ -108,16 +111,13 @@ class frame_t(base_frame_t):
|
|
|
108
111
|
**kwargs,
|
|
109
112
|
) -> plot_t:
|
|
110
113
|
""""""
|
|
111
|
-
|
|
114
|
+
return plot_t(
|
|
112
115
|
title=title,
|
|
113
116
|
property=kwargs.copy(),
|
|
114
117
|
backend_name=self.backend_name,
|
|
118
|
+
raw=plot_function(self.raw, *args, **kwargs),
|
|
115
119
|
)
|
|
116
120
|
|
|
117
|
-
output.raw = plot_function(self.raw, *args, **kwargs)
|
|
118
|
-
|
|
119
|
-
return output
|
|
120
|
-
|
|
121
121
|
|
|
122
122
|
@d.dataclass(slots=True, repr=False, eq=False)
|
|
123
123
|
class figure_t(base_figure_t):
|
|
@@ -126,11 +126,7 @@ class figure_t(base_figure_t):
|
|
|
126
126
|
|
|
127
127
|
def _NewBackendFigure(self, *args, **kwargs) -> backend_figure_t:
|
|
128
128
|
""""""
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
output.canvas.mpl_connect("close_event", lambda *_, **__: _OnCloseEvent(self))
|
|
132
|
-
|
|
133
|
-
return output
|
|
129
|
+
return NewBackendFigure(*args, num=None, **kwargs)
|
|
134
130
|
|
|
135
131
|
def _NewFrame(
|
|
136
132
|
self,
|
|
@@ -204,25 +200,29 @@ class figure_t(base_figure_t):
|
|
|
204
200
|
|
|
205
201
|
def _BackendShow(self, modal: bool, /) -> None:
|
|
206
202
|
""""""
|
|
207
|
-
|
|
208
|
-
raw.show()
|
|
203
|
+
self.raw.show()
|
|
209
204
|
|
|
210
205
|
if modal:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
title = f"{title} [MASTER FIGURE]"
|
|
214
|
-
else:
|
|
215
|
-
title = "MASTER FIGURE"
|
|
216
|
-
raw.suptitle(title)
|
|
206
|
+
if "qt" in mtpl.get_backend().lower():
|
|
207
|
+
from matplotlib.backends.qt_compat import QtWidgets # noqa
|
|
217
208
|
|
|
218
|
-
|
|
209
|
+
application = QtWidgets.QApplication.instance()
|
|
210
|
+
application.exec()
|
|
211
|
+
else:
|
|
212
|
+
event_manager = self.raw.canvas
|
|
213
|
+
event_manager.mpl_connect("close_event", _OnCloseEvent)
|
|
214
|
+
event_manager.start_event_loop()
|
|
219
215
|
|
|
220
216
|
|
|
221
|
-
def _OnCloseEvent(
|
|
217
|
+
def _OnCloseEvent(event: h.Any, /) -> None:
|
|
222
218
|
""""""
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
figure.
|
|
219
|
+
event.canvas.stop_event_loop()
|
|
220
|
+
|
|
221
|
+
figures = tuple(map(pypl.figure, pypl.get_fignums()))
|
|
222
|
+
if figures.__len__() > 0:
|
|
223
|
+
event_manager = figures[0].canvas
|
|
224
|
+
event_manager.mpl_connect("close_event", _OnCloseEvent)
|
|
225
|
+
event_manager.start_event_loop()
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
def _Arrows2(frame: backend_frame_2d_t, *args, **kwargs) -> backend_plot_t:
|
|
@@ -390,26 +390,26 @@ def _Text3(frame: backend_frame_2d_t, text, x, y, z, *_, **kwargs) -> backend_pl
|
|
|
390
390
|
return frame.text(x, y, z, text, **kwargs)
|
|
391
391
|
|
|
392
392
|
|
|
393
|
-
PLOTS =
|
|
394
|
-
|
|
395
|
-
PLOTS[plot_e.ARROWS][
|
|
396
|
-
PLOTS[plot_e.ARROWS][
|
|
397
|
-
PLOTS[plot_e.BAR3][
|
|
398
|
-
PLOTS[plot_e.BARH][
|
|
399
|
-
PLOTS[plot_e.BARV][
|
|
400
|
-
PLOTS[plot_e.ELEVATION][
|
|
401
|
-
PLOTS[plot_e.IMAGE][
|
|
402
|
-
PLOTS[plot_e.ISOSET][
|
|
403
|
-
PLOTS[plot_e.ISOSET][
|
|
404
|
-
PLOTS[plot_e.MESH][
|
|
405
|
-
PLOTS[plot_e.PIE][
|
|
406
|
-
PLOTS[plot_e.POLYGON][
|
|
407
|
-
PLOTS[plot_e.POLYLINE][
|
|
408
|
-
PLOTS[plot_e.POLYLINE][
|
|
409
|
-
PLOTS[plot_e.SCATTER][
|
|
410
|
-
PLOTS[plot_e.SCATTER][
|
|
411
|
-
PLOTS[plot_e.TEXT][
|
|
412
|
-
PLOTS[plot_e.TEXT][
|
|
393
|
+
PLOTS = NewPlotFunctionsTemplate()
|
|
394
|
+
|
|
395
|
+
PLOTS[plot_e.ARROWS][0] = _Arrows2
|
|
396
|
+
PLOTS[plot_e.ARROWS][1] = _Arrows3
|
|
397
|
+
PLOTS[plot_e.BAR3][1] = _Bar3
|
|
398
|
+
PLOTS[plot_e.BARH][0] = _BarH
|
|
399
|
+
PLOTS[plot_e.BARV][0] = _BarV
|
|
400
|
+
PLOTS[plot_e.ELEVATION][1] = _ElevationSurface
|
|
401
|
+
PLOTS[plot_e.IMAGE][0] = backend_frame_2d_t.matshow
|
|
402
|
+
PLOTS[plot_e.ISOSET][0] = _IsoContour
|
|
403
|
+
PLOTS[plot_e.ISOSET][1] = _IsoSurface
|
|
404
|
+
PLOTS[plot_e.MESH][1] = _Mesh
|
|
405
|
+
PLOTS[plot_e.PIE][0] = backend_frame_2d_t.pie
|
|
406
|
+
PLOTS[plot_e.POLYGON][0] = _Polygon
|
|
407
|
+
PLOTS[plot_e.POLYLINE][0] = backend_frame_2d_t.plot
|
|
408
|
+
PLOTS[plot_e.POLYLINE][1] = backend_frame_3d_t.plot
|
|
409
|
+
PLOTS[plot_e.SCATTER][0] = backend_frame_2d_t.scatter
|
|
410
|
+
PLOTS[plot_e.SCATTER][1] = backend_frame_3d_t.scatter
|
|
411
|
+
PLOTS[plot_e.TEXT][0] = _Text2
|
|
412
|
+
PLOTS[plot_e.TEXT][1] = _Text3
|
|
413
413
|
|
|
414
414
|
|
|
415
415
|
TRANSLATIONS = {
|
|
@@ -437,7 +437,7 @@ TRANSLATIONS = {
|
|
|
437
437
|
(_ElevationSurface, "color_face"): "color",
|
|
438
438
|
(_IsoContour, "color"): "colors",
|
|
439
439
|
(_IsoSurface, "color_face"): "color",
|
|
440
|
-
(_Mesh, "color_face"): "color",
|
|
440
|
+
(_Mesh, "color_face"): ("color", lambda _: NewConvertedColor(_, "hex", 0)),
|
|
441
441
|
(_Polygon, "color_edge"): "edgecolor",
|
|
442
442
|
(_Polygon, "color_face"): "facecolor",
|
|
443
443
|
(backend_frame_2d_t.pie, "color"): "colors",
|
|
@@ -13,12 +13,14 @@ from pathlib import Path as path_t
|
|
|
13
13
|
import numpy as nmpy
|
|
14
14
|
import plotly.figure_factory as fcry # noqa
|
|
15
15
|
import plotly.graph_objects as plly # noqa
|
|
16
|
-
from babelplot.task.
|
|
16
|
+
from babelplot.task.plotting import NewPlotFunctionsTemplate
|
|
17
|
+
from babelplot.task.showing import ShowHTMLPlotWithPyQt
|
|
17
18
|
from babelplot.type.dimension import dim_e
|
|
18
19
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
19
20
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
20
21
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
21
|
-
from babelplot.type.
|
|
22
|
+
from babelplot.type.plot_function import plot_function_h
|
|
23
|
+
from babelplot.type.plot_type import plot_e
|
|
22
24
|
from plotly.basedatatypes import BasePlotlyType as backend_plot_t # noqa
|
|
23
25
|
from plotly.graph_objects import Figure as backend_figure_t # noqa
|
|
24
26
|
from plotly.subplots import make_subplots as NewMultiAxesFigure # noqa
|
|
@@ -54,16 +56,13 @@ class frame_t(base_frame_t):
|
|
|
54
56
|
**kwargs,
|
|
55
57
|
) -> plot_t:
|
|
56
58
|
""""""
|
|
57
|
-
|
|
59
|
+
return plot_t(
|
|
58
60
|
title=title,
|
|
59
61
|
property=kwargs.copy(),
|
|
60
62
|
backend_name=self.backend_name,
|
|
63
|
+
raw=plot_function(*args, **kwargs),
|
|
61
64
|
)
|
|
62
65
|
|
|
63
|
-
output.raw = plot_function(*args, **kwargs)
|
|
64
|
-
|
|
65
|
-
return output
|
|
66
|
-
|
|
67
66
|
|
|
68
67
|
@d.dataclass(slots=True, repr=False, eq=False)
|
|
69
68
|
class figure_t(base_figure_t):
|
|
@@ -138,18 +137,19 @@ class figure_t(base_figure_t):
|
|
|
138
137
|
Note on include_plotlyjs:
|
|
139
138
|
- "cdn": works but must be online.
|
|
140
139
|
- True => blank figure if using
|
|
141
|
-
PySide6.QtWebEngineWidgets.QWebEngineView.setHtml because of html size
|
|
142
|
-
|
|
140
|
+
PySide6.QtWebEngineWidgets.QWebEngineView.setHtml because of html size
|
|
141
|
+
limit.
|
|
142
|
+
See note in babelplot.task.html.Show.
|
|
143
143
|
"""
|
|
144
144
|
html = self.raw.to_html(include_plotlyjs=True, config=_FIGURE_CONFIG)
|
|
145
|
-
|
|
145
|
+
html = gzip.compress(html.encode())
|
|
146
|
+
|
|
147
|
+
process = process_t(target=ShowHTMLPlotWithPyQt, args=(html,))
|
|
148
|
+
process.start()
|
|
149
|
+
|
|
146
150
|
if modal:
|
|
147
|
-
|
|
148
|
-
self.AcknowledgeClosure()
|
|
151
|
+
process.join()
|
|
149
152
|
else:
|
|
150
|
-
html = gzip.compress(html.encode())
|
|
151
|
-
process = process_t(target=lambda: ShowHTMLWithPyQt(html, uid))
|
|
152
|
-
process.start()
|
|
153
153
|
self.showing_process = process
|
|
154
154
|
|
|
155
155
|
|
|
@@ -456,26 +456,26 @@ def _Text3(text: str, x: float, y: float, z: float, *_, **kwargs) -> backend_plo
|
|
|
456
456
|
)
|
|
457
457
|
|
|
458
458
|
|
|
459
|
-
PLOTS =
|
|
460
|
-
|
|
461
|
-
PLOTS[plot_e.ARROWS][
|
|
462
|
-
PLOTS[plot_e.ARROWS][
|
|
463
|
-
PLOTS[plot_e.BAR3][
|
|
464
|
-
PLOTS[plot_e.BARH][
|
|
465
|
-
PLOTS[plot_e.BARV][
|
|
466
|
-
PLOTS[plot_e.ELEVATION][
|
|
467
|
-
PLOTS[plot_e.IMAGE][
|
|
468
|
-
PLOTS[plot_e.ISOSET][
|
|
469
|
-
PLOTS[plot_e.ISOSET][
|
|
470
|
-
PLOTS[plot_e.MESH][
|
|
471
|
-
PLOTS[plot_e.PIE][
|
|
472
|
-
PLOTS[plot_e.POLYGON][
|
|
473
|
-
PLOTS[plot_e.POLYLINE][
|
|
474
|
-
PLOTS[plot_e.POLYLINE][
|
|
475
|
-
PLOTS[plot_e.SCATTER][
|
|
476
|
-
PLOTS[plot_e.SCATTER][
|
|
477
|
-
PLOTS[plot_e.TEXT][
|
|
478
|
-
PLOTS[plot_e.TEXT][
|
|
459
|
+
PLOTS = NewPlotFunctionsTemplate()
|
|
460
|
+
|
|
461
|
+
PLOTS[plot_e.ARROWS][0] = _Arrows2
|
|
462
|
+
PLOTS[plot_e.ARROWS][1] = _Arrows3
|
|
463
|
+
PLOTS[plot_e.BAR3][1] = _Bar3
|
|
464
|
+
PLOTS[plot_e.BARH][0] = _BarH
|
|
465
|
+
PLOTS[plot_e.BARV][0] = _BarV
|
|
466
|
+
PLOTS[plot_e.ELEVATION][1] = _ElevationSurface
|
|
467
|
+
PLOTS[plot_e.IMAGE][0] = _Image
|
|
468
|
+
PLOTS[plot_e.ISOSET][0] = _IsoContour
|
|
469
|
+
PLOTS[plot_e.ISOSET][1] = _IsoSurface
|
|
470
|
+
PLOTS[plot_e.MESH][1] = _Mesh
|
|
471
|
+
PLOTS[plot_e.PIE][0] = _Pie
|
|
472
|
+
PLOTS[plot_e.POLYGON][0] = _Polygon
|
|
473
|
+
PLOTS[plot_e.POLYLINE][0] = _Polyline2
|
|
474
|
+
PLOTS[plot_e.POLYLINE][1] = _Polyline3
|
|
475
|
+
PLOTS[plot_e.SCATTER][0] = _Scatter2
|
|
476
|
+
PLOTS[plot_e.SCATTER][1] = _Scatter3
|
|
477
|
+
PLOTS[plot_e.TEXT][0] = _Text2
|
|
478
|
+
PLOTS[plot_e.TEXT][1] = _Text3
|
|
479
479
|
|
|
480
480
|
|
|
481
481
|
def _ApplyGlobalTranslation(
|
|
@@ -7,12 +7,14 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
7
7
|
import dataclasses as d
|
|
8
8
|
from multiprocessing import Process as process_t
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
from babelplot.task.color import NewConvertedColor
|
|
11
|
+
from babelplot.task.plotting import NewPlotFunctionsTemplate
|
|
11
12
|
from babelplot.type.dimension import dim_e
|
|
12
13
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
13
14
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
14
15
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
15
|
-
from babelplot.type.
|
|
16
|
+
from babelplot.type.plot_function import plot_function_h
|
|
17
|
+
from babelplot.type.plot_type import plot_e
|
|
16
18
|
from numpy import ndarray as array_t
|
|
17
19
|
from vedo import Mesh as backend_plot_t # noqa
|
|
18
20
|
from vedo import Plotter as backend_figure_t # noqa
|
|
@@ -40,13 +42,11 @@ class frame_t(base_frame_t):
|
|
|
40
42
|
title=title,
|
|
41
43
|
property=kwargs.copy(),
|
|
42
44
|
backend_name=self.backend_name,
|
|
45
|
+
raw=plot_function(*args, **kwargs),
|
|
43
46
|
)
|
|
44
47
|
|
|
45
|
-
raw
|
|
46
|
-
|
|
47
|
-
self.raw.__iadd__(raw)
|
|
48
|
-
|
|
49
|
-
output.raw = raw
|
|
48
|
+
if output.raw is not None:
|
|
49
|
+
self.raw.__iadd__(output.raw)
|
|
50
50
|
|
|
51
51
|
return output
|
|
52
52
|
|
|
@@ -80,12 +80,15 @@ class figure_t(base_figure_t):
|
|
|
80
80
|
|
|
81
81
|
def _BackendShow(self, modal: bool, /) -> None:
|
|
82
82
|
""""""
|
|
83
|
+
# Passing self.raw.show().close shows the figures one by one.
|
|
84
|
+
BackendShow = lambda: self.raw.show().close()
|
|
85
|
+
|
|
86
|
+
process = process_t(target=BackendShow)
|
|
87
|
+
process.start()
|
|
88
|
+
|
|
83
89
|
if modal:
|
|
84
|
-
|
|
85
|
-
self.AcknowledgeClosure()
|
|
90
|
+
process.join()
|
|
86
91
|
else:
|
|
87
|
-
process = process_t(target=lambda: self.raw.show().close())
|
|
88
|
-
process.start()
|
|
89
92
|
self.showing_process = process
|
|
90
93
|
|
|
91
94
|
|
|
@@ -108,9 +111,9 @@ def _Mesh(triangles: array_t, vertices: array_t, *_, **kwargs) -> backend_plot_t
|
|
|
108
111
|
return output
|
|
109
112
|
|
|
110
113
|
|
|
111
|
-
PLOTS =
|
|
112
|
-
PLOTS[plot_e.ISOSET][
|
|
113
|
-
PLOTS[plot_e.MESH][
|
|
114
|
+
PLOTS = NewPlotFunctionsTemplate()
|
|
115
|
+
PLOTS[plot_e.ISOSET][1] = _IsoSurface
|
|
116
|
+
PLOTS[plot_e.MESH][1] = _Mesh
|
|
114
117
|
|
|
115
118
|
|
|
116
119
|
TRANSLATIONS = {
|
|
@@ -118,6 +121,7 @@ TRANSLATIONS = {
|
|
|
118
121
|
(_IsoSurface, "color_face"): None,
|
|
119
122
|
(_IsoSurface, "step_size"): None,
|
|
120
123
|
(_IsoSurface, "width_edge"): None,
|
|
124
|
+
(_Mesh, "color_face"): ("color_face", lambda _: NewConvertedColor(_, "hex", 0)),
|
|
121
125
|
}
|
|
122
126
|
|
|
123
127
|
|
|
@@ -7,9 +7,11 @@ SEE COPYRIGHT NOTICE BELOW
|
|
|
7
7
|
import importlib as mprt
|
|
8
8
|
import importlib.util as mput
|
|
9
9
|
import sys as s
|
|
10
|
+
import typing as h
|
|
10
11
|
from pathlib import Path as path_t
|
|
11
12
|
|
|
12
13
|
from babelplot.runtime.backends import BACKENDS
|
|
14
|
+
from babelplot.type.plot_function import plot_functions_h
|
|
13
15
|
from babelplot.type.plot_type import plot_e
|
|
14
16
|
|
|
15
17
|
|
|
@@ -36,7 +38,7 @@ def CheckBackend(backend: str | path_t, /) -> None:
|
|
|
36
38
|
if hasattr(module, "PLOTS"):
|
|
37
39
|
defined = getattr(module, "PLOTS")
|
|
38
40
|
if isinstance(defined, dict):
|
|
39
|
-
issues =
|
|
41
|
+
issues = _PlotFunctionsIssues(defined)
|
|
40
42
|
if issues is not None:
|
|
41
43
|
print(f"--- PLOTS:\n ", "\n ".join(issues), sep="")
|
|
42
44
|
else:
|
|
@@ -49,6 +51,56 @@ def CheckBackend(backend: str | path_t, /) -> None:
|
|
|
49
51
|
# TODO: Check that translations respect the format (to be documented by the way).
|
|
50
52
|
|
|
51
53
|
|
|
54
|
+
def _PlotFunctionsIssues(plots: plot_functions_h, /) -> h.Sequence[str] | None:
|
|
55
|
+
""""""
|
|
56
|
+
issues = []
|
|
57
|
+
|
|
58
|
+
for key, value in plots.items():
|
|
59
|
+
if not isinstance(key, plot_e):
|
|
60
|
+
issues.append(
|
|
61
|
+
f"{key}/{type(key).__name__}: Invalid plot type. "
|
|
62
|
+
f"Expected={plot_e.__name__}."
|
|
63
|
+
)
|
|
64
|
+
continue
|
|
65
|
+
|
|
66
|
+
if not isinstance(value, list | tuple):
|
|
67
|
+
issues.append(
|
|
68
|
+
f"{key}/{type(value).__name__}: Invalid plot record type. "
|
|
69
|
+
f"Expected=list or tuple."
|
|
70
|
+
)
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
value = tuple(filter(lambda _: _ is not None, value))
|
|
74
|
+
|
|
75
|
+
how_defined = key.value
|
|
76
|
+
if (n_dimensions := value.__len__()) != (
|
|
77
|
+
n_required := how_defined[2].__len__()
|
|
78
|
+
):
|
|
79
|
+
issues.append(
|
|
80
|
+
f"{key}: Invalid number of possible dimensions {n_dimensions}. "
|
|
81
|
+
f"Expected={n_required}."
|
|
82
|
+
)
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
for d_idx, for_dim in enumerate(value):
|
|
86
|
+
if not callable(for_dim):
|
|
87
|
+
issues.append(
|
|
88
|
+
f"{key}/{for_dim}: Invalid plot function "
|
|
89
|
+
f"for dim {how_defined[2][d_idx]}. "
|
|
90
|
+
f"Expected=Callable."
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
missing = set(plot_e.__members__.values()).difference(plots.keys())
|
|
94
|
+
if missing.__len__() > 0:
|
|
95
|
+
missing = str(sorted(_elm.name for _elm in missing))[1:-1].replace("'", "")
|
|
96
|
+
issues.append(f"Missing plot type(s): {missing}")
|
|
97
|
+
|
|
98
|
+
if issues.__len__() > 0:
|
|
99
|
+
return issues
|
|
100
|
+
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
|
|
52
104
|
"""
|
|
53
105
|
COPYRIGHT NOTICE
|
|
54
106
|
|