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.
Files changed (44) hide show
  1. {babelplot-2025.7 → babelplot-2025.8}/PKG-INFO +1 -1
  2. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/bokeh_.py +44 -8
  3. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/plotly_.py +1 -1
  4. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/vedo_.py +33 -5
  5. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/backend.py +23 -3
  6. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/figure.py +1 -1
  7. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/version.py +1 -1
  8. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/PKG-INFO +1 -1
  9. {babelplot-2025.7 → babelplot-2025.8}/MANIFEST.in +0 -0
  10. {babelplot-2025.7 → babelplot-2025.8}/README-COPYRIGHT-utf8.txt +0 -0
  11. {babelplot-2025.7 → babelplot-2025.8}/README-LICENCE-utf8.txt +0 -0
  12. {babelplot-2025.7 → babelplot-2025.8}/README.rst +0 -0
  13. {babelplot-2025.7 → babelplot-2025.8}/documentation/wiki/description.asciidoc +0 -0
  14. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/__init__.py +0 -0
  15. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/api/backend.py +0 -0
  16. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/api/definition.py +0 -0
  17. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/api/help.py +0 -0
  18. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/catalog/matplotlib_.py +0 -0
  19. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/helper/creation.py +0 -0
  20. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/backend/helper/validation.py +0 -0
  21. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/constant/backend.py +0 -0
  22. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/constant/path.py +0 -0
  23. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/constant/project.py +0 -0
  24. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/extension/enum_.py +0 -0
  25. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/extension/function.py +0 -0
  26. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/runtime/backends.py +0 -0
  27. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/runtime/figure.py +0 -0
  28. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/task/help.py +0 -0
  29. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/task/instantiation.py +0 -0
  30. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/task/showing.py +0 -0
  31. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/dimension.py +0 -0
  32. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/ffp_base.py +0 -0
  33. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/frame.py +0 -0
  34. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/plot.py +0 -0
  35. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/plot_type.py +0 -0
  36. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot/type/translator.py +0 -0
  37. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/SOURCES.txt +0 -0
  38. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/dependency_links.txt +0 -0
  39. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/requires.txt +0 -0
  40. {babelplot-2025.7 → babelplot-2025.8}/package/babelplot.egg-info/top_level.txt +0 -0
  41. {babelplot-2025.7 → babelplot-2025.8}/pyproject.toml +0 -0
  42. {babelplot-2025.7 → babelplot-2025.8}/requirements.txt +0 -0
  43. {babelplot-2025.7 → babelplot-2025.8}/setup.cfg +0 -0
  44. {babelplot-2025.7 → babelplot-2025.8}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: babelplot
3
- Version: 2025.7
3
+ Version: 2025.8
4
4
  Summary: A Meta Plotting Library That Speaks Several Backends
5
5
  Home-page: https://src.koda.cnrs.fr/eric.debreuve/babelplot/
6
6
  Author: Eric Debreuve
@@ -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(*args, title=title, **kwargs)
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
- arranged_frames: list[list[backend_frame_t]]
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 AsHTML(self) -> str:
122
+ def _BackendShow(self, modal: bool, /) -> None:
108
123
  """"""
109
- return HTMLofBackendContent(self.layout, INLINE)
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: Does not work: no PNG export produced
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
- self.raw.__iadd__(raw)
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 _Show(self) -> None:
81
+ def _BackendShow(self, modal: bool, /) -> None:
80
82
  """"""
81
- self.raw.show().close()
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
- raise ValueError(f"Unknown plot {type_}.")
50
+ L.error(f"Unknown plot {type_}.")
51
+ return _FakePlotFunction(type_, frame_dim)
51
52
 
52
53
  if output.__len__() <= frame_dim - 1:
53
- raise ValueError(f"Unknown plot {type_} for dimension {frame_dim}.")
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
- raise ValueError(f"Unknown plot {type_} for dimension {frame_dim}.")
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 shown.")
203
+ L.warning(f"Figure {self.title} empty; Not showing.")
204
204
  else:
205
205
  self.AdjustLayout()
206
206
 
@@ -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
- __version__ = "2025.7"
7
+ __version__ = "2025.8"
8
8
 
9
9
  """
10
10
  COPYRIGHT NOTICE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: babelplot
3
- Version: 2025.7
3
+ Version: 2025.8
4
4
  Summary: A Meta Plotting Library That Speaks Several Backends
5
5
  Home-page: https://src.koda.cnrs.fr/eric.debreuve/babelplot/
6
6
  Author: Eric Debreuve
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes