babelplot 2025.4__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.4 → babelplot-2025.6}/PKG-INFO +1 -1
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/__init__.py +3 -1
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/api/backend.py +0 -1
- babelplot-2025.6/package/babelplot/api/definition.py +54 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/api/help.py +1 -1
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/backend/catalog/bokeh_.py +84 -94
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/backend/catalog/matplotlib_.py +156 -166
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/backend/catalog/plotly_.py +201 -110
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/backend/catalog/vedo_.py +57 -74
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/backend/helper/creation.py +7 -5
- babelplot-2025.4/package/babelplot/constant/backend.py → babelplot-2025.6/package/babelplot/backend/helper/validation.py +38 -40
- babelplot-2025.4/package/babelplot/api/definition.py → babelplot-2025.6/package/babelplot/constant/backend.py +13 -3
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/extension/enum_.py +3 -3
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/extension/function.py +0 -51
- babelplot-2025.6/package/babelplot/runtime/backends.py +55 -0
- babelplot-2025.6/package/babelplot/runtime/figure.py +55 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/task/help.py +12 -10
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/task/instantiation.py +19 -58
- babelplot-2025.4/package/babelplot/task/show_pyqt6.py → babelplot-2025.6/package/babelplot/task/showing.py +32 -0
- babelplot-2025.6/package/babelplot/type/backend.py +279 -0
- {babelplot-2025.4/package/babelplot/definition → babelplot-2025.6/package/babelplot/type}/dimension.py +24 -50
- babelplot-2025.4/package/babelplot/type/base.py → babelplot-2025.6/package/babelplot/type/ffp_base.py +30 -35
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/type/figure.py +99 -108
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/type/frame.py +39 -73
- babelplot-2025.6/package/babelplot/type/plot.py +61 -0
- babelplot-2025.4/package/babelplot/definition/plot.py → babelplot-2025.6/package/babelplot/type/plot_type.py +164 -251
- babelplot-2025.6/package/babelplot/type/translator.py +60 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/version.py +1 -1
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot.egg-info/PKG-INFO +1 -1
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot.egg-info/SOURCES.txt +9 -8
- babelplot-2025.4/package/babelplot/backend/definition/backend.py +0 -113
- babelplot-2025.4/package/babelplot/backend/definition/runtime.py +0 -77
- babelplot-2025.4/package/babelplot/backend/helper/validation.py +0 -130
- babelplot-2025.4/package/babelplot/extension/ast_.py +0 -155
- babelplot-2025.4/package/babelplot/type/plot.py +0 -119
- {babelplot-2025.4 → babelplot-2025.6}/MANIFEST.in +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/README-COPYRIGHT-utf8.txt +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/README-LICENCE-utf8.txt +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/README.rst +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/documentation/wiki/description.asciidoc +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/constant/path.py +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot/constant/project.py +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot.egg-info/dependency_links.txt +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot.egg-info/requires.txt +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/package/babelplot.egg-info/top_level.txt +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/pyproject.toml +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/requirements.txt +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/setup.cfg +0 -0
- {babelplot-2025.4 → babelplot-2025.6}/setup.py +0 -0
|
@@ -18,7 +18,9 @@ else:
|
|
|
18
18
|
beartype_this_package()
|
|
19
19
|
|
|
20
20
|
from babelplot.task.instantiation import NewFigure, NewPlot
|
|
21
|
-
from babelplot.
|
|
21
|
+
from babelplot.task.showing import ShowAllFigures
|
|
22
|
+
from babelplot.type.dimension import dim_e
|
|
23
|
+
from babelplot.type.plot_type import plot_e
|
|
22
24
|
from babelplot.version import __version__
|
|
23
25
|
|
|
24
26
|
"""
|
|
@@ -4,7 +4,6 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2022
|
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from babelplot.backend.definition.runtime import AddBackendSpecification # noqa
|
|
8
7
|
from babelplot.backend.helper.creation import PrintBackendDraft # noqa
|
|
9
8
|
from babelplot.backend.helper.validation import CheckBackend # noqa
|
|
10
9
|
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
from babelplot.type.dimension import dim_e # noqa
|
|
8
|
+
from babelplot.type.plot_type import plot_e # noqa
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
COPYRIGHT NOTICE
|
|
12
|
+
|
|
13
|
+
This software is governed by the CeCILL license under French law and
|
|
14
|
+
abiding by the rules of distribution of free software. You can use,
|
|
15
|
+
modify and/ or redistribute the software under the terms of the CeCILL
|
|
16
|
+
license as circulated by CEA, CNRS and INRIA at the following URL
|
|
17
|
+
"http://www.cecill.info".
|
|
18
|
+
|
|
19
|
+
As a counterpart to the access to the source code and rights to copy,
|
|
20
|
+
modify and redistribute granted by the license, users are provided only
|
|
21
|
+
with a limited warranty and the software's author, the holder of the
|
|
22
|
+
economic rights, and the successive licensors have only limited
|
|
23
|
+
liability.
|
|
24
|
+
|
|
25
|
+
In this respect, the user's attention is drawn to the risks associated
|
|
26
|
+
with loading, using, modifying and/or developing or reproducing the
|
|
27
|
+
software by the user in light of its specific status of free software,
|
|
28
|
+
that may mean that it is complicated to manipulate, and that also
|
|
29
|
+
therefore means that it is reserved for developers and experienced
|
|
30
|
+
professionals having in-depth computer knowledge. Users are therefore
|
|
31
|
+
encouraged to load and test the software's suitability as regards their
|
|
32
|
+
requirements in conditions enabling the security of their systems and/or
|
|
33
|
+
data to be ensured and, more generally, to use and operate it in the
|
|
34
|
+
same conditions as regards security.
|
|
35
|
+
|
|
36
|
+
The fact that you are presently reading this means that you have had
|
|
37
|
+
knowledge of the CeCILL license and that you accept its terms.
|
|
38
|
+
|
|
39
|
+
SEE LICENCE NOTICE: file README-LICENCE-utf8.txt at project source root.
|
|
40
|
+
|
|
41
|
+
This software is being developed by Eric Debreuve, a CNRS employee and
|
|
42
|
+
member of team Morpheme.
|
|
43
|
+
Team Morpheme is a joint team between Inria, CNRS, and UniCA.
|
|
44
|
+
It is hosted by the Centre Inria d'Université Côte d'Azur, Laboratory
|
|
45
|
+
I3S, and Laboratory iBV.
|
|
46
|
+
|
|
47
|
+
CNRS: https://www.cnrs.fr/index.php/en
|
|
48
|
+
Inria: https://www.inria.fr/en/
|
|
49
|
+
UniCA: https://univ-cotedazur.eu/
|
|
50
|
+
Centre Inria d'Université Côte d'Azur: https://www.inria.fr/en/centre/sophia/
|
|
51
|
+
I3S: https://www.i3s.unice.fr/en/
|
|
52
|
+
iBV: http://ibv.unice.fr/
|
|
53
|
+
Team Morpheme: https://team.inria.fr/morpheme/
|
|
54
|
+
"""
|
|
@@ -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
|
"""
|
|
@@ -4,19 +4,16 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2022
|
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import dataclasses as d
|
|
9
8
|
import typing as h
|
|
10
9
|
|
|
11
|
-
from babelplot.
|
|
12
|
-
from babelplot.
|
|
13
|
-
from babelplot.definition.plot import PlotsFromTemplate, plot_e, plot_type_h
|
|
14
|
-
from babelplot.task.show_pyqt6 import Show
|
|
10
|
+
from babelplot.task.showing import Show
|
|
11
|
+
from babelplot.type.dimension import dim_e
|
|
15
12
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
16
13
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
17
14
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
15
|
+
from babelplot.type.plot_type import plot_e, plot_function_h
|
|
18
16
|
from bokeh.embed import file_html as HTMLofBackendContent # noqa
|
|
19
|
-
from bokeh.layouts import LayoutDOM as backend_content_t # noqa
|
|
20
17
|
from bokeh.layouts import column as NewBackendColLayout # noqa
|
|
21
18
|
from bokeh.layouts import grid as NewBackendGridLayout # noqa
|
|
22
19
|
from bokeh.layouts import row as NewBackendRowLayout # noqa
|
|
@@ -24,99 +21,92 @@ from bokeh.models.renderers import GlyphRenderer as backend_plot_t # noqa
|
|
|
24
21
|
from bokeh.plotting import figure as backend_figure_t # noqa
|
|
25
22
|
from bokeh.resources import INLINE # noqa
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
# from bokeh.layouts import LayoutDOM as backend_content_t # noqa
|
|
25
|
+
|
|
26
|
+
NAME = "bokeh"
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
backend_frame_t = backend_figure_t
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
32
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
|
33
|
+
class plot_t(base_plot_t): ...
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
|
37
|
+
class frame_t(base_frame_t):
|
|
38
|
+
|
|
39
|
+
def _NewPlot(
|
|
40
|
+
self,
|
|
41
|
+
plot_function: plot_function_h,
|
|
42
|
+
*args,
|
|
43
|
+
title: str | None = None, # If _, then it is swallowed by kwargs!
|
|
44
|
+
**kwargs,
|
|
45
|
+
) -> plot_t:
|
|
46
|
+
""""""
|
|
47
|
+
output = plot_t(
|
|
48
|
+
title=title,
|
|
49
|
+
property=kwargs.copy(),
|
|
50
|
+
backend_name=self.backend_name,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
output.raw = plot_function(self.raw, *args, **kwargs)
|
|
54
|
+
|
|
55
|
+
return output
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
|
59
|
+
class figure_t(base_figure_t):
|
|
60
|
+
layout: h.Any = None
|
|
61
|
+
|
|
62
|
+
_NewBackendFigure = backend_figure_t
|
|
63
|
+
_BackendShow = Show
|
|
64
|
+
|
|
65
|
+
def _NewFrame(
|
|
66
|
+
self,
|
|
67
|
+
row: int,
|
|
68
|
+
col: int,
|
|
69
|
+
*args,
|
|
70
|
+
title: str | None = None,
|
|
71
|
+
dim: dim_e = dim_e.XY,
|
|
72
|
+
**kwargs,
|
|
73
|
+
) -> frame_t:
|
|
74
|
+
""""""
|
|
75
|
+
output = frame_t(
|
|
76
|
+
title=title,
|
|
77
|
+
dim=dim,
|
|
78
|
+
backend_name=self.backend_name,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
output.raw = backend_frame_t(*args, title=title, **kwargs)
|
|
82
|
+
|
|
83
|
+
return output
|
|
84
|
+
|
|
85
|
+
def AdjustLayout(self) -> None:
|
|
86
|
+
""""""
|
|
87
|
+
n_rows, n_cols = self.shape
|
|
88
|
+
arranged_frames = [n_cols * [None] for _ in range(n_rows)]
|
|
89
|
+
for frame, (row, col) in zip(self.frames, self.locations):
|
|
90
|
+
arranged_frames[row][col] = frame.raw
|
|
91
|
+
arranged_frames: list[list[backend_frame_t]]
|
|
92
|
+
|
|
93
|
+
if n_rows > 1:
|
|
94
|
+
if n_cols > 1:
|
|
95
|
+
layout = NewBackendGridLayout(arranged_frames)
|
|
96
|
+
else:
|
|
97
|
+
column = [_row[0] for _row in arranged_frames]
|
|
98
|
+
layout = NewBackendColLayout(column)
|
|
50
99
|
else:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
title: str | None = None,
|
|
62
|
-
dim: dim_e = dim_e.XY, # If _, then it is swallowed by kwargs!
|
|
63
|
-
**kwargs,
|
|
64
|
-
) -> backend_frame_t:
|
|
65
|
-
""""""
|
|
66
|
-
return backend_frame_t(*args, title=title, **kwargs)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def _AdjustLayout(figure: figure_t, /) -> None:
|
|
70
|
-
""""""
|
|
71
|
-
n_rows, n_cols = figure.shape
|
|
72
|
-
arranged_frames = [n_cols * [None] for _ in range(n_rows)]
|
|
73
|
-
for frame, (row, col) in zip(figure.frames, figure.locations):
|
|
74
|
-
arranged_frames[row][col] = frame.backend
|
|
75
|
-
arranged_frames: list[list[backend_frame_t]]
|
|
76
|
-
|
|
77
|
-
if n_rows > 1:
|
|
78
|
-
if n_cols > 1:
|
|
79
|
-
layout = NewBackendGridLayout(arranged_frames)
|
|
80
|
-
else:
|
|
81
|
-
column = [_row[0] for _row in arranged_frames]
|
|
82
|
-
layout = NewBackendColLayout(column)
|
|
83
|
-
else:
|
|
84
|
-
layout = NewBackendRowLayout(arranged_frames[0])
|
|
85
|
-
|
|
86
|
-
figure.layout = layout
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def _AsHTML(figure: figure_t, /) -> str:
|
|
90
|
-
""""""
|
|
91
|
-
|
|
92
|
-
return HTMLofBackendContent(figure.layout, INLINE)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# noinspection PyTypeChecker
|
|
96
|
-
plot_t: type[base_plot_t] = type("plot_t", (base_plot_t,), {})
|
|
97
|
-
# noinspection PyTypeChecker
|
|
98
|
-
frame_t: type[base_frame_t] = type(
|
|
99
|
-
"frame_t",
|
|
100
|
-
(base_frame_t,),
|
|
101
|
-
{"plot_class": plot_t, "NewBackendPlot": staticmethod(_NewPlot)},
|
|
102
|
-
)
|
|
103
|
-
# noinspection PyTypeChecker
|
|
104
|
-
figure_t: type[base_figure_t] = type(
|
|
105
|
-
"figure_t",
|
|
106
|
-
(base_figure_t,),
|
|
107
|
-
{
|
|
108
|
-
"frame_class": frame_t,
|
|
109
|
-
"NewBackendFigure": backend_figure_t,
|
|
110
|
-
"NewBackendFrame": staticmethod(_NewFrame),
|
|
111
|
-
"AdjustLayout": _AdjustLayout,
|
|
112
|
-
"BackendShow": Show,
|
|
113
|
-
"layout": None,
|
|
114
|
-
"AsHTML": _AsHTML,
|
|
115
|
-
},
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
PLOTS = PlotsFromTemplate()
|
|
100
|
+
layout = NewBackendRowLayout(arranged_frames[0])
|
|
101
|
+
|
|
102
|
+
self.layout = layout
|
|
103
|
+
|
|
104
|
+
def AsHTML(self) -> str:
|
|
105
|
+
""""""
|
|
106
|
+
return HTMLofBackendContent(self.layout, INLINE)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
PLOTS = plot_e.NewPlotsTemplate()
|
|
120
110
|
PLOTS[plot_e.SCATTER][1] = backend_frame_t.scatter
|
|
121
111
|
|
|
122
112
|
|
|
@@ -4,20 +4,18 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2022
|
|
|
4
4
|
SEE COPYRIGHT NOTICE BELOW
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import dataclasses as d
|
|
9
8
|
import typing as h
|
|
10
9
|
|
|
11
10
|
import matplotlib.pyplot as pypl # noqa
|
|
12
11
|
import numpy as nmpy
|
|
13
12
|
import skimage.measure as msre
|
|
14
|
-
from babelplot.
|
|
15
|
-
from babelplot.
|
|
16
|
-
from babelplot.definition.plot import PlotsFromTemplate, plot_e, plot_type_h
|
|
17
|
-
from babelplot.type.base import backend_element_h
|
|
13
|
+
from babelplot.type.dimension import dim_e
|
|
14
|
+
from babelplot.type.ffp_base import backend_element_h
|
|
18
15
|
from babelplot.type.figure import figure_t as base_figure_t
|
|
19
16
|
from babelplot.type.frame import frame_t as base_frame_t
|
|
20
17
|
from babelplot.type.plot import plot_t as base_plot_t
|
|
18
|
+
from babelplot.type.plot_type import plot_e, plot_function_h, plot_type_h
|
|
21
19
|
from logger_36 import L
|
|
22
20
|
from matplotlib.artist import Artist as backend_plot_t # noqa
|
|
23
21
|
from matplotlib.container import Container as backend_plots_t # noqa
|
|
@@ -31,109 +29,14 @@ from mpl_toolkits.mplot3d import Axes3D as backend_frame_3d_t # noqa
|
|
|
31
29
|
|
|
32
30
|
import matplotlib as mlpl # noqa
|
|
33
31
|
|
|
34
|
-
NAME =
|
|
32
|
+
NAME = "matplotlib"
|
|
35
33
|
|
|
36
34
|
|
|
37
35
|
array_t = nmpy.ndarray
|
|
38
36
|
backend_frame_h = backend_frame_2d_t | backend_frame_3d_t
|
|
39
37
|
|
|
40
38
|
|
|
41
|
-
def
|
|
42
|
-
frame: backend_frame_h,
|
|
43
|
-
type_: plot_type_h | type[backend_plot_t],
|
|
44
|
-
plot_function: (
|
|
45
|
-
type[backend_plot_t] | h.Callable[..., backend_plot_t | h.Any] | None
|
|
46
|
-
),
|
|
47
|
-
*args,
|
|
48
|
-
title: str | None = None, # /!\ If _, then it is swallowed by kwargs!
|
|
49
|
-
**kwargs,
|
|
50
|
-
) -> tuple[
|
|
51
|
-
backend_plot_t | h.Any,
|
|
52
|
-
type[backend_plot_t] | h.Callable[..., backend_plot_t | h.Any],
|
|
53
|
-
]:
|
|
54
|
-
""""""
|
|
55
|
-
if plot_function is None:
|
|
56
|
-
# Next, priority is given to 2-D plots... which might be a problem if a 2-D and
|
|
57
|
-
# 3-D frame have plot types with the same name. For example, scatter in 2-D and
|
|
58
|
-
# 3-D.
|
|
59
|
-
if hasattr(backend_frame_2d_t, type_):
|
|
60
|
-
plot_function = getattr(backend_frame_2d_t, type_)
|
|
61
|
-
elif hasattr(backend_frame_3d_t, type_):
|
|
62
|
-
plot_function = getattr(backend_frame_3d_t, type_)
|
|
63
|
-
else:
|
|
64
|
-
raise ValueError(f"{type_}: Unknown {NAME} graph object.")
|
|
65
|
-
|
|
66
|
-
return plot_function(frame, *args, **kwargs), plot_function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def _NewFrame(
|
|
70
|
-
figure: backend_figure_t,
|
|
71
|
-
_: int,
|
|
72
|
-
__: int,
|
|
73
|
-
*args,
|
|
74
|
-
title: str | None = None,
|
|
75
|
-
dim: dim_e = dim_e.XY,
|
|
76
|
-
**kwargs,
|
|
77
|
-
) -> backend_frame_h:
|
|
78
|
-
""""""
|
|
79
|
-
if dim is dim_e.XY:
|
|
80
|
-
output = figure.subplots(*args, **kwargs)
|
|
81
|
-
elif dim is dim_e.XYZ:
|
|
82
|
-
# See note below
|
|
83
|
-
output = backend_frame_3d_t(figure, *args, auto_add_to_figure=False, **kwargs)
|
|
84
|
-
figure.add_axes(output)
|
|
85
|
-
else:
|
|
86
|
-
raise NotImplementedError(f"{dim}: Dimension management not implemented yet")
|
|
87
|
-
if title is not None:
|
|
88
|
-
output.set_title(title)
|
|
89
|
-
|
|
90
|
-
return output
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def _AdjustLayout(figure: figure_t, /) -> None:
|
|
94
|
-
""""""
|
|
95
|
-
raw_figure = figure.backend
|
|
96
|
-
|
|
97
|
-
if figure.title is not None:
|
|
98
|
-
raw_figure.suptitle(figure.title)
|
|
99
|
-
for frame in figure.frames:
|
|
100
|
-
if frame.title is not None:
|
|
101
|
-
frame.backend.set_title(frame.title)
|
|
102
|
-
for plot in frame.plots:
|
|
103
|
-
if plot.title is not None:
|
|
104
|
-
plot.backend.set_label(plot.title)
|
|
105
|
-
|
|
106
|
-
if figure.frames.__len__() < 2:
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
grid_spec = grid_spec_t(*figure.shape, figure=raw_figure)
|
|
110
|
-
bottoms, tops, lefts, rights = grid_spec.get_grid_positions(raw_figure)
|
|
111
|
-
|
|
112
|
-
for frame, (row, col) in zip(figure.frames, figure.locations):
|
|
113
|
-
left, bottom, width, height = (
|
|
114
|
-
lefts[col],
|
|
115
|
-
bottoms[row],
|
|
116
|
-
rights[col] - lefts[col],
|
|
117
|
-
tops[row] - bottoms[row],
|
|
118
|
-
)
|
|
119
|
-
frame.backend.set_position((left, bottom, width, height))
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def _Show(
|
|
123
|
-
figure: figure_t,
|
|
124
|
-
/,
|
|
125
|
-
) -> None:
|
|
126
|
-
""""""
|
|
127
|
-
raw = figure.backend
|
|
128
|
-
|
|
129
|
-
raw.show()
|
|
130
|
-
|
|
131
|
-
event_manager = raw.canvas
|
|
132
|
-
event_manager.mpl_connect("close_event", lambda _: event_manager.stop_event_loop())
|
|
133
|
-
event_manager.start_event_loop()
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def _DefaultProperties(type_: h.Callable, /) -> dict[str, h.Any]:
|
|
39
|
+
def _DefaultProperties(type_: type[plot_type_h], /) -> dict[str, h.Any]:
|
|
137
40
|
""""""
|
|
138
41
|
name = type_.__name__
|
|
139
42
|
properties = mlpl.rcParams.find_all(f"^{name}\\.")
|
|
@@ -151,16 +54,16 @@ def _SetProperty(
|
|
|
151
54
|
if isinstance(element, h.Sequence):
|
|
152
55
|
elements = element
|
|
153
56
|
for element in elements:
|
|
154
|
-
_SetProperty(element, name, value)
|
|
57
|
+
_SetProperty(element.raw, name, value)
|
|
155
58
|
return
|
|
156
59
|
|
|
157
60
|
if name == "marker":
|
|
158
61
|
new_marker = marker_style_t(value)
|
|
159
|
-
element.set_paths((new_marker.get_path(),))
|
|
62
|
+
element.raw.set_paths((new_marker.get_path(),))
|
|
160
63
|
else:
|
|
161
64
|
property_ = {name: value}
|
|
162
65
|
try:
|
|
163
|
-
pypl.setp(element, **property_)
|
|
66
|
+
pypl.setp(element.raw, **property_)
|
|
164
67
|
except AttributeError:
|
|
165
68
|
L.error(
|
|
166
69
|
f'Property "{name}": Invalid property for element of type "{type(element).__name__}"'
|
|
@@ -172,10 +75,10 @@ def _Property(
|
|
|
172
75
|
) -> h.Any:
|
|
173
76
|
""""""
|
|
174
77
|
if isinstance(element, h.Sequence):
|
|
175
|
-
return _Property(element[0], name)
|
|
78
|
+
return _Property(element[0].raw, name)
|
|
176
79
|
|
|
177
80
|
try:
|
|
178
|
-
output = pypl.getp(element, property=name)
|
|
81
|
+
output = pypl.getp(element.raw, property=name)
|
|
179
82
|
except AttributeError:
|
|
180
83
|
output = None
|
|
181
84
|
L.error(
|
|
@@ -185,41 +88,128 @@ def _Property(
|
|
|
185
88
|
return output
|
|
186
89
|
|
|
187
90
|
|
|
188
|
-
|
|
189
|
-
plot_t:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
91
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
|
92
|
+
class plot_t(base_plot_t):
|
|
93
|
+
_BackendDefaultProperties: h.ClassVar[h.Callable] = _DefaultProperties
|
|
94
|
+
_BackendSetProperty: h.ClassVar[h.Callable] = _SetProperty
|
|
95
|
+
_BackendProperty: h.ClassVar[h.Callable] = _Property
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
|
99
|
+
class frame_t(base_frame_t):
|
|
100
|
+
_BackendSetProperty: h.ClassVar[h.Callable] = _SetProperty
|
|
101
|
+
_BackendProperty: h.ClassVar[h.Callable] = _Property
|
|
102
|
+
|
|
103
|
+
def _NewPlot(
|
|
104
|
+
self,
|
|
105
|
+
plot_function: plot_function_h,
|
|
106
|
+
*args,
|
|
107
|
+
title: str | None = None, # /!\ If _, then it is swallowed by kwargs!
|
|
108
|
+
**kwargs,
|
|
109
|
+
) -> plot_t:
|
|
110
|
+
""""""
|
|
111
|
+
output = plot_t(
|
|
112
|
+
title=title,
|
|
113
|
+
property=kwargs.copy(),
|
|
114
|
+
backend_name=self.backend_name,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
output.raw = plot_function(self.raw, *args, **kwargs)
|
|
118
|
+
|
|
119
|
+
return output
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@d.dataclass(slots=True, repr=False, eq=False)
|
|
123
|
+
class figure_t(base_figure_t):
|
|
124
|
+
_BackendSetProperty: h.ClassVar[h.Callable] = _SetProperty
|
|
125
|
+
_BackendProperty: h.ClassVar[h.Callable] = _Property
|
|
126
|
+
|
|
127
|
+
@staticmethod
|
|
128
|
+
def _NewBackendFigure(*args, **kwargs) -> backend_figure_t:
|
|
129
|
+
""""""
|
|
130
|
+
return NewBackendFigure(*args, num=None, **kwargs)
|
|
131
|
+
|
|
132
|
+
def _NewFrame(
|
|
133
|
+
self,
|
|
134
|
+
title: str | None,
|
|
135
|
+
dim: dim_e,
|
|
136
|
+
row: int,
|
|
137
|
+
col: int,
|
|
138
|
+
*args,
|
|
139
|
+
**kwargs,
|
|
140
|
+
) -> frame_t:
|
|
141
|
+
""""""
|
|
142
|
+
output = frame_t(
|
|
143
|
+
title=title,
|
|
144
|
+
dim=dim,
|
|
145
|
+
backend_name=self.backend_name,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if dim is dim_e.XY:
|
|
149
|
+
raw = self.raw.subplots(*args, **kwargs)
|
|
150
|
+
elif dim is dim_e.XYZ:
|
|
151
|
+
# See note below
|
|
152
|
+
raw = backend_frame_3d_t(
|
|
153
|
+
self.raw, *args, auto_add_to_figure=False, **kwargs
|
|
154
|
+
)
|
|
155
|
+
self.raw.add_axes(raw)
|
|
156
|
+
else:
|
|
157
|
+
raise NotImplementedError(f"Frame dimension {dim} not implemented.")
|
|
158
|
+
if title is not None:
|
|
159
|
+
raw.set_title(title)
|
|
160
|
+
|
|
161
|
+
output.raw = raw
|
|
162
|
+
|
|
163
|
+
return output
|
|
164
|
+
|
|
165
|
+
def AdjustLayout(self) -> None:
|
|
166
|
+
""""""
|
|
167
|
+
figure_raw = self.raw
|
|
168
|
+
|
|
169
|
+
if self.title is not None:
|
|
170
|
+
figure_raw.suptitle(self.title)
|
|
171
|
+
for frame in self.frames:
|
|
172
|
+
if frame.title is not None:
|
|
173
|
+
frame.raw.set_title(frame.title)
|
|
174
|
+
for plot in frame.plots:
|
|
175
|
+
if plot.title is not None:
|
|
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)
|
|
186
|
+
|
|
187
|
+
if self.frames.__len__() < 2:
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
grid_spec = grid_spec_t(*self.shape, figure=figure_raw)
|
|
191
|
+
bottoms, tops, lefts, rights = grid_spec.get_grid_positions(figure_raw)
|
|
192
|
+
|
|
193
|
+
for frame, (row, col) in zip(self.frames, self.locations):
|
|
194
|
+
left, bottom, width, height = (
|
|
195
|
+
lefts[col],
|
|
196
|
+
bottoms[row],
|
|
197
|
+
rights[col] - lefts[col],
|
|
198
|
+
tops[row] - bottoms[row],
|
|
199
|
+
)
|
|
200
|
+
frame.raw.set_position((left, bottom, width, height))
|
|
201
|
+
|
|
202
|
+
def _BackendShow(self) -> None:
|
|
203
|
+
""""""
|
|
204
|
+
raw = self.raw
|
|
205
|
+
|
|
206
|
+
raw.show()
|
|
207
|
+
|
|
208
|
+
event_manager = raw.canvas
|
|
209
|
+
event_manager.mpl_connect(
|
|
210
|
+
"close_event", lambda _: event_manager.stop_event_loop()
|
|
211
|
+
)
|
|
212
|
+
event_manager.start_event_loop()
|
|
223
213
|
|
|
224
214
|
|
|
225
215
|
def _Polygon(
|
|
@@ -387,7 +377,7 @@ def _Text3(frame: backend_frame_2d_t, text, x, y, z, *_, **kwargs) -> backend_pl
|
|
|
387
377
|
return frame.text(x, y, z, text, **kwargs)
|
|
388
378
|
|
|
389
379
|
|
|
390
|
-
PLOTS =
|
|
380
|
+
PLOTS = plot_e.NewPlotsTemplate()
|
|
391
381
|
|
|
392
382
|
PLOTS[plot_e.SCATTER][1] = backend_frame_2d_t.scatter
|
|
393
383
|
PLOTS[plot_e.POLYLINE][1] = backend_frame_2d_t.plot
|
|
@@ -442,30 +432,30 @@ TRANSLATIONS = {
|
|
|
442
432
|
(backend_frame_3d_t.scatter, 2): "zs",
|
|
443
433
|
}
|
|
444
434
|
|
|
435
|
+
"""
|
|
436
|
+
From: https://matplotlib.org/stable/api/prev_api_changes/api_changes_3.4.0.html
|
|
437
|
+
*Axes3D automatically adding itself to Figure is deprecated*
|
|
438
|
+
|
|
439
|
+
New Axes3D objects previously added themselves to figures when they were created,
|
|
440
|
+
unlike all other Axes classes, which lead to them being added twice if
|
|
441
|
+
fig.add_subplot(111, projection='3d') was called.
|
|
442
|
+
|
|
443
|
+
This behavior is now deprecated and will warn. The new keyword argument
|
|
444
|
+
auto_add_to_figure controls the behavior and can be used to suppress the warning. The
|
|
445
|
+
default value will change to False in Matplotlib 3.5, and any non-False value will be
|
|
446
|
+
an error in Matplotlib 3.6.
|
|
447
|
+
|
|
448
|
+
In the future, Axes3D will need to be explicitly added to the figure
|
|
445
449
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
# New Axes3D objects previously added themselves to figures when they were created,
|
|
450
|
-
# unlike all other Axes classes, which lead to them being added twice if
|
|
451
|
-
# fig.add_subplot(111, projection='3d') was called.
|
|
452
|
-
#
|
|
453
|
-
# This behavior is now deprecated and will warn. The new keyword argument
|
|
454
|
-
# auto_add_to_figure controls the behavior and can be used to suppress the warning. The
|
|
455
|
-
# default value will change to False in Matplotlib 3.5, and any non-False value will be
|
|
456
|
-
# an error in Matplotlib 3.6.
|
|
457
|
-
#
|
|
458
|
-
# In the future, Axes3D will need to be explicitly added to the figure
|
|
459
|
-
#
|
|
460
|
-
# fig = Figure()
|
|
461
|
-
# ax = Axes3d(fig)
|
|
462
|
-
# fig.add_axes(ax)
|
|
463
|
-
#
|
|
464
|
-
# as needs to be done for other axes.Axes subclasses. Or, a 3D projection can be made
|
|
465
|
-
# via:
|
|
466
|
-
#
|
|
467
|
-
# fig.add_subplot(projection='3d')
|
|
450
|
+
fig = Figure()
|
|
451
|
+
ax = Axes3d(fig)
|
|
452
|
+
fig.add_axes(ax)
|
|
468
453
|
|
|
454
|
+
as needs to be done for other axes.Axes subclasses. Or, a 3D projection can be made
|
|
455
|
+
via:
|
|
456
|
+
|
|
457
|
+
fig.add_subplot(projection='3d')
|
|
458
|
+
"""
|
|
469
459
|
|
|
470
460
|
"""
|
|
471
461
|
COPYRIGHT NOTICE
|