icplot 0.4.0__tar.gz → 0.6.0__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.
- icplot-0.6.0/LICENSE +21 -0
- {icplot-0.4.0/src/icplot.egg-info → icplot-0.6.0}/PKG-INFO +21 -34
- {icplot-0.4.0 → icplot-0.6.0}/README.md +15 -10
- icplot-0.6.0/pyproject.toml +110 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/charts/tree.py +1 -1
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/converter/image.py +14 -9
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/graph/plot_group.py +0 -1
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/graph/series.py +0 -3
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/charts/pgfgantt.py +1 -1
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/formats/mermaid.py +5 -4
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/formats/tex.py +7 -4
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/graph/matplotlib.py +15 -6
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/graph/mpl.py +3 -1
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/graph/renderer.py +16 -8
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/render.py +0 -1
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/scene/cairo.py +9 -4
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/color.py +1 -1
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/theme_generator.py +2 -0
- {icplot-0.4.0 → icplot-0.6.0/src/icplot.egg-info}/PKG-INFO +21 -34
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot.egg-info/SOURCES.txt +1 -22
- icplot-0.6.0/src/icplot.egg-info/requires.txt +21 -0
- {icplot-0.4.0 → icplot-0.6.0}/test/test_cairo.py +1 -2
- {icplot-0.4.0 → icplot-0.6.0}/test/test_frontmatter.py +1 -2
- {icplot-0.4.0 → icplot-0.6.0}/test/test_image.py +1 -3
- {icplot-0.4.0 → icplot-0.6.0}/test/test_mermaid.py +1 -2
- {icplot-0.4.0 → icplot-0.6.0}/test/test_puml.py +1 -2
- {icplot-0.4.0 → icplot-0.6.0}/test/test_tex.py +1 -2
- icplot-0.6.0/test/test_theme_generator.py +33 -0
- {icplot-0.4.0 → icplot-0.6.0}/test/test_tree.py +1 -2
- icplot-0.4.0/LICENSE +0 -232
- icplot-0.4.0/pyproject.toml +0 -197
- icplot-0.4.0/src/icplot/geometry/__init__.py +0 -4
- icplot-0.4.0/src/icplot/geometry/base.py +0 -68
- icplot-0.4.0/src/icplot/geometry/mesh/__init__.py +0 -6
- icplot-0.4.0/src/icplot/geometry/mesh/cell.py +0 -74
- icplot-0.4.0/src/icplot/geometry/mesh/edge.py +0 -31
- icplot-0.4.0/src/icplot/geometry/mesh/mesh.py +0 -133
- icplot-0.4.0/src/icplot/geometry/mesh/openfoam/__init__.py +0 -3
- icplot-0.4.0/src/icplot/geometry/mesh/openfoam/blockmesh.py +0 -132
- icplot-0.4.0/src/icplot/geometry/mesh/openfoam/foamfile.py +0 -118
- icplot-0.4.0/src/icplot/geometry/mesh/openfoam/polymesh.py +0 -313
- icplot-0.4.0/src/icplot/geometry/mesh/operations.py +0 -120
- icplot-0.4.0/src/icplot/geometry/mesh/shapes.py +0 -403
- icplot-0.4.0/src/icplot/geometry/mesh/vertex.py +0 -95
- icplot-0.4.0/src/icplot/geometry/mesh/vtk.py +0 -47
- icplot-0.4.0/src/icplot/geometry/operations.py +0 -57
- icplot-0.4.0/src/icplot/geometry/shapes.py +0 -184
- icplot-0.4.0/src/icplot/geometry/transform.py +0 -66
- icplot-0.4.0/src/icplot/renderer/graph/vtk.py +0 -80
- icplot-0.4.0/src/icplot.egg-info/requires.txt +0 -44
- icplot-0.4.0/test/test_geometry.py +0 -65
- icplot-0.4.0/test/test_meshing.py +0 -132
- icplot-0.4.0/test/test_openfoam.py +0 -36
- icplot-0.4.0/test/test_polymesh.py +0 -132
- {icplot-0.4.0 → icplot-0.6.0}/setup.cfg +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/charts/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/charts/gantt.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/converter/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/converter/cli.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/converter/convert.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/graph/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/graph/axis.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/graph/plot.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/main_cli.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/py.typed +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/charts/svggantt.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/cli.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/config.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/formats/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/formats/plantuml.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/frontmatter.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/graph/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/graph/color.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/renderer/video.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/scene.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/__init__.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/cli.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/templates/puml.j2 +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/templates/tikz.j2 +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/theme.json +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot/theme/theme.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot.egg-info/dependency_links.txt +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot.egg-info/entry_points.txt +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/src/icplot.egg-info/top_level.txt +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/test/test_gantt_chart.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/test/test_line_plots.py +0 -0
- {icplot-0.4.0 → icplot-0.6.0}/test/test_plot_group.py +0 -0
icplot-0.6.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Irish Centre for High End Computing
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: icplot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Utilities for generating plots and graphics for technical reports.
|
|
5
|
-
Author
|
|
6
|
-
|
|
7
|
-
Project-URL:
|
|
5
|
+
Author: Irish Centre for High End Computing
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://git.ichec.ie/platform-engineering/modules/documentation/ichec-plot
|
|
8
|
+
Project-URL: Homepage, https://git.ichec.ie/platform-engineering/modules/documentation/ichec-plot
|
|
8
9
|
Keywords: Publishing,Technical Reports,Graphics
|
|
9
10
|
Classifier: Development Status :: 3 - Alpha
|
|
10
11
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: License :: OSI Approved ::
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
13
|
Classifier: Operating System :: OS Independent
|
|
13
14
|
Classifier: Topic :: System :: Distributed Computing
|
|
14
15
|
Requires-Python: >=3.10
|
|
@@ -17,37 +18,18 @@ License-File: LICENSE
|
|
|
17
18
|
Requires-Dist: iccore==0.2.3
|
|
18
19
|
Requires-Dist: graphviz
|
|
19
20
|
Requires-Dist: Jinja2
|
|
20
|
-
Provides-Extra: test
|
|
21
|
-
Requires-Dist: pytest; extra == "test"
|
|
22
|
-
Requires-Dist: pytest-cov; extra == "test"
|
|
23
|
-
Requires-Dist: pytest-sugar; extra == "test"
|
|
24
|
-
Requires-Dist: black; extra == "test"
|
|
25
|
-
Requires-Dist: isort; extra == "test"
|
|
26
|
-
Requires-Dist: mypy; extra == "test"
|
|
27
|
-
Requires-Dist: flake8; extra == "test"
|
|
28
|
-
Requires-Dist: pylint; extra == "test"
|
|
29
|
-
Requires-Dist: types-PyYAML; extra == "test"
|
|
30
21
|
Provides-Extra: cairo
|
|
31
22
|
Requires-Dist: CairoSVG; extra == "cairo"
|
|
32
|
-
Provides-Extra: scene
|
|
33
|
-
Requires-Dist: pycairo; extra == "scene"
|
|
34
23
|
Provides-Extra: imagemagick
|
|
35
24
|
Requires-Dist: wand; extra == "imagemagick"
|
|
36
25
|
Provides-Extra: plot
|
|
37
26
|
Requires-Dist: matplotlib; extra == "plot"
|
|
38
|
-
Provides-Extra: vtk
|
|
39
|
-
Requires-Dist: vtk; extra == "vtk"
|
|
40
|
-
Provides-Extra: geometry
|
|
41
|
-
Requires-Dist: scipy; extra == "geometry"
|
|
42
27
|
Provides-Extra: video
|
|
43
28
|
Requires-Dist: moviepy; extra == "video"
|
|
44
29
|
Provides-Extra: all
|
|
45
30
|
Requires-Dist: CairoSVG; extra == "all"
|
|
46
|
-
Requires-Dist: pycairo; extra == "all"
|
|
47
31
|
Requires-Dist: wand; extra == "all"
|
|
48
32
|
Requires-Dist: matplotlib; extra == "all"
|
|
49
|
-
Requires-Dist: vtk; extra == "all"
|
|
50
|
-
Requires-Dist: scipy; extra == "all"
|
|
51
33
|
Requires-Dist: moviepy; extra == "all"
|
|
52
34
|
Dynamic: license-file
|
|
53
35
|
|
|
@@ -55,6 +37,17 @@ Dynamic: license-file
|
|
|
55
37
|
|
|
56
38
|
This is a library used at [The Irish Centre for High End Computing (ICHEC)](https://www.ichec.ie) for generating plots, diagrams and other graphics for technical documents.
|
|
57
39
|
|
|
40
|
+
# Scope #
|
|
41
|
+
|
|
42
|
+
The library is **frozen to what its consumers use** — the `ichec-handbook`
|
|
43
|
+
build tool and `ichec-flow`. That means `converter`, `renderer`, `theme` and
|
|
44
|
+
`graph`: fixes and maintenance yes, new capability no.
|
|
45
|
+
|
|
46
|
+
The `geometry`/`mesh` 3D and OpenFOAM code has moved to
|
|
47
|
+
[icmesh](https://git.ichec.ie/platform-engineering/modules/ichec-mesh), taking
|
|
48
|
+
VTK and scipy with it — including VTK plot output, which is now
|
|
49
|
+
`icmesh.plot`. Install `icmesh` if you want it.
|
|
50
|
+
|
|
58
51
|
# Features #
|
|
59
52
|
|
|
60
53
|
The project has three primary modules:
|
|
@@ -104,7 +97,6 @@ Supported render inputs and targets are:
|
|
|
104
97
|
* Graph
|
|
105
98
|
* Backends:
|
|
106
99
|
* Matplotlib
|
|
107
|
-
* VTK
|
|
108
100
|
* Output formats:
|
|
109
101
|
* SVG
|
|
110
102
|
* PNG
|
|
@@ -125,10 +117,8 @@ Supported render inputs and targets are:
|
|
|
125
117
|
* Scene
|
|
126
118
|
* Backends:
|
|
127
119
|
* Cairo
|
|
128
|
-
* VTK
|
|
129
120
|
* Output formats:
|
|
130
121
|
* SVG
|
|
131
|
-
* VTK
|
|
132
122
|
|
|
133
123
|
## Themes ##
|
|
134
124
|
|
|
@@ -148,14 +138,11 @@ Backends are opt-in via extras:
|
|
|
148
138
|
|
|
149
139
|
| Extra | Pulls | Enables |
|
|
150
140
|
|---|---|---|
|
|
151
|
-
| `cairo` | CairoSVG | svg → png / pdf conversion |
|
|
152
|
-
| `scene` | pycairo | vector scene drawing (`renderer.scene.cairo`) |
|
|
141
|
+
| `cairo` | CairoSVG | svg → png / pdf conversion, and vector scene drawing |
|
|
153
142
|
| `imagemagick` | wand | pdf → png conversion (falls back to the `magick` CLI) |
|
|
154
143
|
| `plot` | matplotlib | 2D plotting (`renderer.graph`, `charts`) |
|
|
155
|
-
| `vtk` | vtk | 3D / mesh rendering (`geometry.mesh`) |
|
|
156
|
-
| `geometry` | scipy | geometry transforms (`geometry.operations`) |
|
|
157
144
|
| `video` | moviepy | video assembly (`renderer.video`) |
|
|
158
|
-
| `all` | all of the above | everything
|
|
145
|
+
| `all` | all of the above | everything |
|
|
159
146
|
|
|
160
147
|
For example, `pip install icplot[cairo]` for svg conversion, or
|
|
161
148
|
`pip install icplot[all]` for the full toolkit. The native `cairo` and
|
|
@@ -167,7 +154,7 @@ brew install imagemagick cairo
|
|
|
167
154
|
|
|
168
155
|
# Copyright #
|
|
169
156
|
|
|
170
|
-
Copyright
|
|
157
|
+
Copyright 2026 Irish Centre for High End Computing
|
|
171
158
|
|
|
172
|
-
The software in this repository can be used under the conditions of the
|
|
159
|
+
The software in this repository can be used under the conditions of the MIT license, which is available for reading in the accompanying LICENSE file.
|
|
173
160
|
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
This is a library used at [The Irish Centre for High End Computing (ICHEC)](https://www.ichec.ie) for generating plots, diagrams and other graphics for technical documents.
|
|
4
4
|
|
|
5
|
+
# Scope #
|
|
6
|
+
|
|
7
|
+
The library is **frozen to what its consumers use** — the `ichec-handbook`
|
|
8
|
+
build tool and `ichec-flow`. That means `converter`, `renderer`, `theme` and
|
|
9
|
+
`graph`: fixes and maintenance yes, new capability no.
|
|
10
|
+
|
|
11
|
+
The `geometry`/`mesh` 3D and OpenFOAM code has moved to
|
|
12
|
+
[icmesh](https://git.ichec.ie/platform-engineering/modules/ichec-mesh), taking
|
|
13
|
+
VTK and scipy with it — including VTK plot output, which is now
|
|
14
|
+
`icmesh.plot`. Install `icmesh` if you want it.
|
|
15
|
+
|
|
5
16
|
# Features #
|
|
6
17
|
|
|
7
18
|
The project has three primary modules:
|
|
@@ -51,7 +62,6 @@ Supported render inputs and targets are:
|
|
|
51
62
|
* Graph
|
|
52
63
|
* Backends:
|
|
53
64
|
* Matplotlib
|
|
54
|
-
* VTK
|
|
55
65
|
* Output formats:
|
|
56
66
|
* SVG
|
|
57
67
|
* PNG
|
|
@@ -72,10 +82,8 @@ Supported render inputs and targets are:
|
|
|
72
82
|
* Scene
|
|
73
83
|
* Backends:
|
|
74
84
|
* Cairo
|
|
75
|
-
* VTK
|
|
76
85
|
* Output formats:
|
|
77
86
|
* SVG
|
|
78
|
-
* VTK
|
|
79
87
|
|
|
80
88
|
## Themes ##
|
|
81
89
|
|
|
@@ -95,14 +103,11 @@ Backends are opt-in via extras:
|
|
|
95
103
|
|
|
96
104
|
| Extra | Pulls | Enables |
|
|
97
105
|
|---|---|---|
|
|
98
|
-
| `cairo` | CairoSVG | svg → png / pdf conversion |
|
|
99
|
-
| `scene` | pycairo | vector scene drawing (`renderer.scene.cairo`) |
|
|
106
|
+
| `cairo` | CairoSVG | svg → png / pdf conversion, and vector scene drawing |
|
|
100
107
|
| `imagemagick` | wand | pdf → png conversion (falls back to the `magick` CLI) |
|
|
101
108
|
| `plot` | matplotlib | 2D plotting (`renderer.graph`, `charts`) |
|
|
102
|
-
| `vtk` | vtk | 3D / mesh rendering (`geometry.mesh`) |
|
|
103
|
-
| `geometry` | scipy | geometry transforms (`geometry.operations`) |
|
|
104
109
|
| `video` | moviepy | video assembly (`renderer.video`) |
|
|
105
|
-
| `all` | all of the above | everything
|
|
110
|
+
| `all` | all of the above | everything |
|
|
106
111
|
|
|
107
112
|
For example, `pip install icplot[cairo]` for svg conversion, or
|
|
108
113
|
`pip install icplot[all]` for the full toolkit. The native `cairo` and
|
|
@@ -114,7 +119,7 @@ brew install imagemagick cairo
|
|
|
114
119
|
|
|
115
120
|
# Copyright #
|
|
116
121
|
|
|
117
|
-
Copyright
|
|
122
|
+
Copyright 2026 Irish Centre for High End Computing
|
|
118
123
|
|
|
119
|
-
The software in this repository can be used under the conditions of the
|
|
124
|
+
The software in this repository can be used under the conditions of the MIT license, which is available for reading in the accompanying LICENSE file.
|
|
120
125
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "icplot"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
license = { text = "MIT" }
|
|
5
|
+
authors = [
|
|
6
|
+
{ name="Irish Centre for High End Computing"},
|
|
7
|
+
]
|
|
8
|
+
description = "Utilities for generating plots and graphics for technical reports."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Topic :: System :: Distributed Computing"
|
|
17
|
+
]
|
|
18
|
+
keywords = ["Publishing", "Technical Reports", "Graphics"]
|
|
19
|
+
|
|
20
|
+
# Core is deliberately light: only what every import path needs. The heavy
|
|
21
|
+
# rendering backends (matplotlib/moviepy/wand) are optional extras
|
|
22
|
+
# so consumers that only use the converter or diagram renderer (e.g. the
|
|
23
|
+
# handbook build) can install a small footprint. Use icplot[all] for the
|
|
24
|
+
# previous behaviour of pulling every backend.
|
|
25
|
+
dependencies = ["iccore==0.2.3",
|
|
26
|
+
"graphviz",
|
|
27
|
+
"Jinja2"]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Repository = "https://git.ichec.ie/platform-engineering/modules/documentation/ichec-plot"
|
|
31
|
+
Homepage = "https://git.ichec.ie/platform-engineering/modules/documentation/ichec-plot"
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
# svg/pdf conversion (converter.svg_to_png / svg_to_pdf) and vector scene
|
|
35
|
+
# drawing (renderer.scene.cairo). CairoSVG pulls cairocffi, which dlopens
|
|
36
|
+
# libcairo at runtime — no C build step, and one cairo binding rather than two.
|
|
37
|
+
cairo = ["CairoSVG"]
|
|
38
|
+
|
|
39
|
+
# raster conversion via ImageMagick bindings (converter.pdf_to_png);
|
|
40
|
+
# falls back to the `magick` CLI if wand is absent
|
|
41
|
+
imagemagick = ["wand"]
|
|
42
|
+
|
|
43
|
+
# 2D plotting backend (icplot.renderer.graph / icplot.charts)
|
|
44
|
+
plot = ["matplotlib"]
|
|
45
|
+
|
|
46
|
+
# video assembly (renderer.video, driven from renderer.graph.mpl)
|
|
47
|
+
video = ["moviepy"]
|
|
48
|
+
|
|
49
|
+
# convenience aggregate — every backend
|
|
50
|
+
all = [
|
|
51
|
+
"CairoSVG",
|
|
52
|
+
"wand",
|
|
53
|
+
"matplotlib",
|
|
54
|
+
"moviepy",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[build-system]
|
|
58
|
+
requires = ["setuptools>=64", "setuptools-scm>=8"]
|
|
59
|
+
build-backend = "setuptools.build_meta"
|
|
60
|
+
|
|
61
|
+
# Version derived from the git tag (setuptools-scm). fallback_version keeps
|
|
62
|
+
# non-release jobs building on the shallow CI checkout, which has no tags.
|
|
63
|
+
[tool.setuptools_scm]
|
|
64
|
+
fallback_version = "0.0.0"
|
|
65
|
+
|
|
66
|
+
# Development toolchain (uv-native, PEP 735). CI installs it with
|
|
67
|
+
# `uv sync --group dev`. Deliberately free of the rendering backends: the lint
|
|
68
|
+
# job runs in the standard slim image, and pycairo has no wheel there — it
|
|
69
|
+
# builds against libcairo headers. The test job adds the backends with
|
|
70
|
+
# `--extra all` in an image that has those headers.
|
|
71
|
+
[dependency-groups]
|
|
72
|
+
dev = [
|
|
73
|
+
"ruff",
|
|
74
|
+
"mypy",
|
|
75
|
+
"pytest",
|
|
76
|
+
"pytest-cov",
|
|
77
|
+
"pytest-sugar",
|
|
78
|
+
"types-PyYAML",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[project.scripts]
|
|
82
|
+
icplot = "icplot.main_cli:main_cli"
|
|
83
|
+
|
|
84
|
+
[tool.setuptools.package-data]
|
|
85
|
+
"icplot" = ["py.typed", "controlDict", "theme/theme.json", "theme/templates/*.j2"]
|
|
86
|
+
|
|
87
|
+
[tool.setuptools.packages.find]
|
|
88
|
+
where = ["src"]
|
|
89
|
+
|
|
90
|
+
[tool.mypy]
|
|
91
|
+
ignore_missing_imports = true
|
|
92
|
+
|
|
93
|
+
[tool.ruff]
|
|
94
|
+
line-length = 88
|
|
95
|
+
target-version = "py310"
|
|
96
|
+
src = ["src", "test"]
|
|
97
|
+
|
|
98
|
+
[tool.ruff.lint]
|
|
99
|
+
# E/W pycodestyle, F pyflakes, I import-sort (was isort), N pep8-naming,
|
|
100
|
+
# UP pyupgrade, B bugbear. Extend deliberately, not by pulling in "ALL".
|
|
101
|
+
select = ["E", "W", "F", "I", "N", "UP", "B"]
|
|
102
|
+
|
|
103
|
+
[tool.ruff.lint.isort]
|
|
104
|
+
known-first-party = ["icplot", "utils"]
|
|
105
|
+
|
|
106
|
+
[tool.pytest.ini_options]
|
|
107
|
+
testpaths = ["test",]
|
|
108
|
+
log_cli = 1
|
|
109
|
+
log_cli_level = "debug"
|
|
110
|
+
addopts = "--cov=icplot --cov-report term --cov-fail-under=55 --cov-report xml:coverage.xml --cov-report html"
|
|
@@ -45,19 +45,24 @@ def _get_out_filename(source: Path, target: Path | None, extension: str) -> Path
|
|
|
45
45
|
return source.parent / f"{source.stem}.{extension}"
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
# This ensures proper handling when converting PDFs/SVGs,
|
|
51
|
-
# as some versions of ImageMagick ignore or misapply `-alpha off` if it
|
|
52
|
-
# appears before the input file.
|
|
48
|
+
# `-alpha off` must come *after* the source file: some ImageMagick versions
|
|
49
|
+
# ignore or misapply it when it precedes the input.
|
|
53
50
|
def _pdf_to_png(source: Path, target: Path | None = None, resolution: int = 300):
|
|
54
51
|
|
|
55
52
|
outfile = _get_out_filename(source, target, "png")
|
|
56
53
|
os.makedirs(outfile.parent, exist_ok=True)
|
|
57
|
-
cmd =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
cmd = [
|
|
55
|
+
"magick",
|
|
56
|
+
"-density",
|
|
57
|
+
str(resolution),
|
|
58
|
+
"-background",
|
|
59
|
+
"white",
|
|
60
|
+
str(source),
|
|
61
|
+
"-alpha",
|
|
62
|
+
"off",
|
|
63
|
+
str(outfile),
|
|
64
|
+
]
|
|
65
|
+
subprocess.run(cmd, check=True)
|
|
61
66
|
|
|
62
67
|
|
|
63
68
|
def pdf_to_png(source: Path, target: Path | None = None, resolution: int = 300):
|
|
@@ -16,13 +16,11 @@ from icplot.theme.color import Color
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class PlotSeriesBase(BaseModel, frozen=True):
|
|
19
|
-
|
|
20
19
|
min_value: float | None = None
|
|
21
20
|
max_value: float | None = None
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
class PlotSeriesCreate(PlotSeriesBase, frozen=True):
|
|
25
|
-
|
|
26
24
|
measurement: str
|
|
27
25
|
unit_name: str = ""
|
|
28
26
|
|
|
@@ -36,7 +34,6 @@ class PlotSeriesCreate(PlotSeriesBase, frozen=True):
|
|
|
36
34
|
|
|
37
35
|
|
|
38
36
|
class PlotSeriesPublic(PlotSeriesBase, frozen=True):
|
|
39
|
-
|
|
40
37
|
measurement: MeasurementPublicWithUnits
|
|
41
38
|
unit: UnitPublic
|
|
42
39
|
x: MeasurementPublicWithUnits | None
|
|
@@ -40,7 +40,7 @@ def _ganttbar(milestone) -> str:
|
|
|
40
40
|
|
|
41
41
|
def render(gantt: GanttChart, theme: "Theme | None" = None) -> str:
|
|
42
42
|
|
|
43
|
-
with open(Path(__file__).parent / "pgfgantt.tex",
|
|
43
|
+
with open(Path(__file__).parent / "pgfgantt.tex", encoding="utf-8") as f:
|
|
44
44
|
template = f.read()
|
|
45
45
|
|
|
46
46
|
milestones = gantt.milestones
|
|
@@ -6,6 +6,7 @@ Mermaid must already be set up on the system, eg. via the npm ecosystem.
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
8
|
import os
|
|
9
|
+
import shlex
|
|
9
10
|
import shutil
|
|
10
11
|
import subprocess
|
|
11
12
|
from pathlib import Path
|
|
@@ -39,9 +40,9 @@ def render(ctx: RenderContext):
|
|
|
39
40
|
if not browser_config and (env_path := os.environ.get("MMDC_PUPPETEER_CONFIG")):
|
|
40
41
|
browser_config = Path(env_path)
|
|
41
42
|
|
|
42
|
-
cmd =
|
|
43
|
+
cmd = ["mmdc", "-i", str(ctx.source), "-o", str(output_path)]
|
|
43
44
|
if browser_config:
|
|
44
|
-
cmd +=
|
|
45
|
-
logger.debug("Command: %s", cmd)
|
|
46
|
-
subprocess.run(cmd,
|
|
45
|
+
cmd += ["-p", str(browser_config)]
|
|
46
|
+
logger.debug("Command: %s", shlex.join(cmd))
|
|
47
|
+
subprocess.run(cmd, check=True)
|
|
47
48
|
logger.info("Done: %s", output_path.name)
|
|
@@ -5,6 +5,7 @@ This module has functionality for publishing Tex documents
|
|
|
5
5
|
import hashlib
|
|
6
6
|
import logging
|
|
7
7
|
import os
|
|
8
|
+
import shlex
|
|
8
9
|
import shutil
|
|
9
10
|
import subprocess
|
|
10
11
|
from pathlib import Path
|
|
@@ -38,12 +39,11 @@ def _run_commands(ctx: RenderContext, work_dir: Path):
|
|
|
38
39
|
logger.debug("Engine: %s | work_dir: %s", ctx.config.tex.build_engine, work_dir)
|
|
39
40
|
|
|
40
41
|
if ctx.config.tex.build_engine == "pdflatex":
|
|
41
|
-
cmd =
|
|
42
|
-
logger.info("Command: %s",
|
|
42
|
+
cmd = [ctx.config.tex.build_engine, *extra_flags, str(ctx.source)]
|
|
43
|
+
logger.info("Command: %s", shlex.join(cmd))
|
|
43
44
|
with open(work_dir / "stdout.txt", "w", encoding="utf-8") as f:
|
|
44
45
|
subprocess.run(
|
|
45
46
|
cmd,
|
|
46
|
-
shell=True,
|
|
47
47
|
check=True,
|
|
48
48
|
cwd=work_dir,
|
|
49
49
|
env=tex_env,
|
|
@@ -91,7 +91,10 @@ def render(ctx: RenderContext):
|
|
|
91
91
|
ctx.config.tex.build_engine,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
# Names a build directory, so collision resistance is all that is wanted.
|
|
95
|
+
path_hash = hashlib.md5(
|
|
96
|
+
str(ctx.source).encode(), usedforsecurity=False
|
|
97
|
+
).hexdigest()[:8]
|
|
95
98
|
work_dir = ctx.build_dir / f"{ctx.source.stem}_{path_hash}"
|
|
96
99
|
work_dir.mkdir(exist_ok=True, parents=True)
|
|
97
100
|
|
|
@@ -2,9 +2,9 @@ import logging
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import cast
|
|
4
4
|
|
|
5
|
-
from icplot.graph.series import LinePlotSeries # NOQA
|
|
6
5
|
from icplot.graph.series import (
|
|
7
6
|
ImageSeries,
|
|
7
|
+
LinePlotSeries, # NOQA
|
|
8
8
|
PlotSeries,
|
|
9
9
|
ScatterPlotSeries,
|
|
10
10
|
)
|
|
@@ -33,6 +33,11 @@ class MatplotlibColorMap(ColorMap):
|
|
|
33
33
|
super().__init__(label, mpl.colormaps[label])
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
# Module-level singleton rather than a constructed default argument, which
|
|
37
|
+
# would be built once at import time and shared silently across every call.
|
|
38
|
+
_DEFAULT_COLORMAP = MatplotlibColorMap("gist_rainbow")
|
|
39
|
+
|
|
40
|
+
|
|
36
41
|
def str_exact_values_formatter(x, pos):
|
|
37
42
|
"""
|
|
38
43
|
When using log scale, axis ticks come out as scientific notation by default,
|
|
@@ -158,9 +163,10 @@ def _render(fig, path: Path | None = None):
|
|
|
158
163
|
plt.switch_backend("Agg")
|
|
159
164
|
|
|
160
165
|
|
|
161
|
-
def render(
|
|
162
|
-
|
|
163
|
-
|
|
166
|
+
def render(plot: Plot, path: Path | None = None, cmap=None):
|
|
167
|
+
|
|
168
|
+
if cmap is None:
|
|
169
|
+
cmap = _DEFAULT_COLORMAP
|
|
164
170
|
|
|
165
171
|
colors = get_series_colors(cmap, plot)
|
|
166
172
|
|
|
@@ -169,7 +175,8 @@ def render(
|
|
|
169
175
|
if len(plot.y_axes) > 1:
|
|
170
176
|
axs.append(ax.twinx())
|
|
171
177
|
|
|
172
|
-
|
|
178
|
+
# colors is derived from plot.series, so the two are the same length.
|
|
179
|
+
for series, color in zip(plot.series, colors, strict=True):
|
|
173
180
|
_plot_series(axs, series, color)
|
|
174
181
|
|
|
175
182
|
_set_decorations(axs, plot)
|
|
@@ -185,7 +192,9 @@ def render_grid(
|
|
|
185
192
|
rows, cols, series = plot.get_subplots(num_samples)
|
|
186
193
|
fig, axs = plt.subplots(rows, cols)
|
|
187
194
|
|
|
188
|
-
|
|
195
|
+
# strict=False keeps the existing behaviour: plt.subplots(rows, cols) can
|
|
196
|
+
# return more axes than there are series when the grid is not full.
|
|
197
|
+
for ax, series_item in zip(axs, series, strict=False):
|
|
189
198
|
_plot_series(ax, series_item)
|
|
190
199
|
|
|
191
200
|
_render(fig, path)
|
|
@@ -151,7 +151,9 @@ def plot_array(path: Path, series: PlotSeriesPublic, data_series: Series):
|
|
|
151
151
|
raise RuntimeError("Attempted to plot series with missing data")
|
|
152
152
|
|
|
153
153
|
for idx, (x, values) in enumerate(
|
|
154
|
-
zip
|
|
154
|
+
# strict=False preserves the existing zip-to-shortest behaviour; the
|
|
155
|
+
# x array and the measurement array are not guaranteed equal length.
|
|
156
|
+
zip(data_series.get_array(data_series.x).data, array.data, strict=False)
|
|
155
157
|
):
|
|
156
158
|
fig, ax = plt.subplots()
|
|
157
159
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import os
|
|
3
|
+
from collections.abc import Callable
|
|
2
4
|
from pathlib import Path
|
|
3
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
4
6
|
|
|
5
7
|
from iccore.data import Series
|
|
6
8
|
from iccore.data.series import convert_units
|
|
@@ -12,11 +14,12 @@ from icplot.graph.plot_group import PlotGroupPublic, PlotSeriesPublic
|
|
|
12
14
|
from icplot.graph.series import LinePlotSeries
|
|
13
15
|
from icplot.renderer.graph.matplotlib import render
|
|
14
16
|
|
|
15
|
-
from . import mpl
|
|
17
|
+
from . import mpl
|
|
16
18
|
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
17
20
|
|
|
18
|
-
class PlotConfig(BaseModel, frozen=True):
|
|
19
21
|
|
|
22
|
+
class PlotConfig(BaseModel, frozen=True):
|
|
20
23
|
series_attr: str
|
|
21
24
|
x_attr: str
|
|
22
25
|
plots: dict[str, Plot]
|
|
@@ -39,7 +42,6 @@ def make_plots(
|
|
|
39
42
|
# Each 'y attribute' in the config corresponds to a 'plot' of this
|
|
40
43
|
# attribute's values.
|
|
41
44
|
for y_attr, plot_template in config.plots.items():
|
|
42
|
-
|
|
43
45
|
series = []
|
|
44
46
|
for label in series_labels:
|
|
45
47
|
# Get results for this series
|
|
@@ -55,7 +57,7 @@ def make_plots(
|
|
|
55
57
|
)
|
|
56
58
|
if not points:
|
|
57
59
|
continue
|
|
58
|
-
x, y = [list(xy) for xy in zip(*points)]
|
|
60
|
+
x, y = [list(xy) for xy in zip(*points, strict=True)]
|
|
59
61
|
|
|
60
62
|
if label in config.colormap:
|
|
61
63
|
series.append(
|
|
@@ -79,13 +81,18 @@ def plot(
|
|
|
79
81
|
results: list[Any],
|
|
80
82
|
config: PlotConfig,
|
|
81
83
|
point_func: Callable,
|
|
82
|
-
output_dir: Path =
|
|
84
|
+
output_dir: Path | None = None,
|
|
83
85
|
):
|
|
84
86
|
"""
|
|
85
87
|
For a given set of results and plot config generate the
|
|
86
88
|
corresponding plots and render them to files.
|
|
87
89
|
"""
|
|
88
90
|
|
|
91
|
+
# Resolved per call, not once at import: the previous default froze the
|
|
92
|
+
# working directory at the moment this module was first imported.
|
|
93
|
+
if output_dir is None:
|
|
94
|
+
output_dir = Path(os.getcwd())
|
|
95
|
+
|
|
89
96
|
for p in make_plots(results, config, point_func):
|
|
90
97
|
render(p, output_dir / f"{p.name}.svg")
|
|
91
98
|
|
|
@@ -123,5 +130,6 @@ def plot_series(
|
|
|
123
130
|
if "mpl" in group.formats:
|
|
124
131
|
mpl.plot(output_path, group, series, converted_data_series)
|
|
125
132
|
|
|
126
|
-
if "vtk" in group.formats
|
|
127
|
-
|
|
133
|
+
if "vtk" in group.formats:
|
|
134
|
+
# Moved to icmesh.plot — warn rather than silently drop the request.
|
|
135
|
+
logger.warning("vtk plot output moved to icmesh; skipping %s", output_path)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# cairocffi, not pycairo: same drawing API, but it dlopens libcairo instead of
|
|
4
|
+
# building against its headers, and CairoSVG already pulls it in.
|
|
5
|
+
import cairocffi as cairo
|
|
4
6
|
|
|
5
7
|
from icplot.scene import Rectangle, Scene
|
|
6
8
|
|
|
@@ -54,6 +56,9 @@ def draw_scene(cr, scene: Scene):
|
|
|
54
56
|
|
|
55
57
|
|
|
56
58
|
def render(scene: Scene, path: Path):
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
# cairocffi surfaces take a str and are not context managers.
|
|
60
|
+
surface = cairo.SVGSurface(str(path), scene.size[0], scene.size[1])
|
|
61
|
+
try:
|
|
62
|
+
draw_scene(cairo.Context(surface), scene)
|
|
63
|
+
finally:
|
|
64
|
+
surface.finish()
|
|
@@ -100,6 +100,8 @@ def generate_theme(output_dir: Path, theme_path: Path, template_dir: Path) -> No
|
|
|
100
100
|
|
|
101
101
|
env = Environment(
|
|
102
102
|
loader=FileSystemLoader(str(template_dir)),
|
|
103
|
+
# Targets are PlantUML and TeX, not HTML — escaping would corrupt them.
|
|
104
|
+
autoescape=False,
|
|
103
105
|
keep_trailing_newline=True,
|
|
104
106
|
trim_blocks=True,
|
|
105
107
|
lstrip_blocks=True,
|