icplot 0.3.5__tar.gz → 0.5.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.5.0/LICENSE +21 -0
- icplot-0.5.0/PKG-INFO +172 -0
- {icplot-0.3.5 → icplot-0.5.0}/README.md +29 -4
- icplot-0.5.0/pyproject.toml +124 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/charts/tree.py +1 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/converter/image.py +14 -9
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/mesh.py +0 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/openfoam/blockmesh.py +3 -4
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/openfoam/foamfile.py +1 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/openfoam/polymesh.py +4 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/shapes.py +0 -2
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/vertex.py +0 -2
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/shapes.py +0 -2
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/graph/plot_group.py +0 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/graph/series.py +0 -3
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/charts/pgfgantt.py +1 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/formats/mermaid.py +5 -4
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/formats/tex.py +7 -4
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/graph/matplotlib.py +15 -6
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/graph/mpl.py +3 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/graph/renderer.py +9 -5
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/render.py +0 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/color.py +1 -1
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/theme_generator.py +2 -0
- icplot-0.5.0/src/icplot.egg-info/PKG-INFO +172 -0
- icplot-0.5.0/src/icplot.egg-info/requires.txt +33 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_image.py +0 -1
- icplot-0.3.5/LICENSE +0 -232
- icplot-0.3.5/PKG-INFO +0 -142
- icplot-0.3.5/pyproject.toml +0 -164
- icplot-0.3.5/src/icplot.egg-info/PKG-INFO +0 -142
- icplot-0.3.5/src/icplot.egg-info/requires.txt +0 -23
- {icplot-0.3.5 → icplot-0.5.0}/setup.cfg +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/charts/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/charts/gantt.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/converter/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/converter/cli.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/converter/convert.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/base.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/cell.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/edge.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/openfoam/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/operations.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/mesh/vtk.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/operations.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/geometry/transform.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/graph/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/graph/axis.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/graph/plot.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/main_cli.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/py.typed +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/charts/svggantt.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/cli.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/config.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/formats/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/formats/plantuml.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/frontmatter.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/graph/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/graph/color.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/graph/vtk.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/scene/cairo.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/renderer/video.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/scene.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/__init__.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/cli.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/templates/puml.j2 +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/templates/tikz.j2 +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/theme.json +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot/theme/theme.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot.egg-info/SOURCES.txt +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot.egg-info/dependency_links.txt +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot.egg-info/entry_points.txt +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/src/icplot.egg-info/top_level.txt +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_cairo.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_frontmatter.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_gantt_chart.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_geometry.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_line_plots.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_mermaid.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_meshing.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_openfoam.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_plot_group.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_polymesh.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_puml.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_tex.py +0 -0
- {icplot-0.3.5 → icplot-0.5.0}/test/test_tree.py +0 -0
icplot-0.5.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.
|
icplot-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: icplot
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Utilities for generating plots and graphics for technical reports.
|
|
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
|
|
9
|
+
Keywords: Publishing,Technical Reports,Graphics
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: iccore==0.2.3
|
|
19
|
+
Requires-Dist: graphviz
|
|
20
|
+
Requires-Dist: Jinja2
|
|
21
|
+
Provides-Extra: cairo
|
|
22
|
+
Requires-Dist: CairoSVG; extra == "cairo"
|
|
23
|
+
Provides-Extra: scene
|
|
24
|
+
Requires-Dist: pycairo; extra == "scene"
|
|
25
|
+
Provides-Extra: imagemagick
|
|
26
|
+
Requires-Dist: wand; extra == "imagemagick"
|
|
27
|
+
Provides-Extra: plot
|
|
28
|
+
Requires-Dist: matplotlib; extra == "plot"
|
|
29
|
+
Provides-Extra: vtk
|
|
30
|
+
Requires-Dist: vtk; extra == "vtk"
|
|
31
|
+
Provides-Extra: geometry
|
|
32
|
+
Requires-Dist: scipy; extra == "geometry"
|
|
33
|
+
Provides-Extra: video
|
|
34
|
+
Requires-Dist: moviepy; extra == "video"
|
|
35
|
+
Provides-Extra: all
|
|
36
|
+
Requires-Dist: CairoSVG; extra == "all"
|
|
37
|
+
Requires-Dist: pycairo; extra == "all"
|
|
38
|
+
Requires-Dist: wand; extra == "all"
|
|
39
|
+
Requires-Dist: matplotlib; extra == "all"
|
|
40
|
+
Requires-Dist: vtk; extra == "all"
|
|
41
|
+
Requires-Dist: scipy; extra == "all"
|
|
42
|
+
Requires-Dist: moviepy; extra == "all"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# icplot
|
|
46
|
+
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
# Scope #
|
|
50
|
+
|
|
51
|
+
The library is **frozen to what its consumers use** — the `ichec-handbook`
|
|
52
|
+
build tool and `ichec-flow`. That means `converter`, `renderer`, `theme` and
|
|
53
|
+
`graph`: fixes and maintenance yes, new capability no (planning#136). The
|
|
54
|
+
`geometry`/`mesh` 3D and OpenFOAM code is still here but is scheduled to move
|
|
55
|
+
to a module of its own, and its optional-dependency weight goes with it.
|
|
56
|
+
|
|
57
|
+
# Features #
|
|
58
|
+
|
|
59
|
+
The project has three primary modules:
|
|
60
|
+
|
|
61
|
+
`converter`: Converts between image formats, such as pdf, svg and png
|
|
62
|
+
`renderer`: Render text based inputs as svg, pdf or png images or videos
|
|
63
|
+
`theme`: Generate and apply themes from a design system
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Converter ##
|
|
67
|
+
|
|
68
|
+
To covert between image formats you can do:
|
|
69
|
+
|
|
70
|
+
``` shell
|
|
71
|
+
icplot convert --source my_image.svg --target my_image.png
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Supported conversions are:
|
|
75
|
+
|
|
76
|
+
* svg -> png
|
|
77
|
+
* svg -> pdf
|
|
78
|
+
* pdf -> png
|
|
79
|
+
|
|
80
|
+
## Renderer ##
|
|
81
|
+
|
|
82
|
+
Render a range of text based formats to images or videos. For example,
|
|
83
|
+
|
|
84
|
+
``` shell
|
|
85
|
+
icplot render --file uml_diagram.puml
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
renders the PlantUML file to png and svg.
|
|
89
|
+
|
|
90
|
+
Supported render inputs and targets are:
|
|
91
|
+
|
|
92
|
+
* PlantUml
|
|
93
|
+
* SVG
|
|
94
|
+
* PNG
|
|
95
|
+
* Latex/Tikz
|
|
96
|
+
* PDF
|
|
97
|
+
* SVG
|
|
98
|
+
* PNG
|
|
99
|
+
* Mermaid
|
|
100
|
+
* SVG
|
|
101
|
+
* PNG
|
|
102
|
+
* Custom JSON
|
|
103
|
+
* Graph
|
|
104
|
+
* Backends:
|
|
105
|
+
* Matplotlib
|
|
106
|
+
* VTK
|
|
107
|
+
* Output formats:
|
|
108
|
+
* SVG
|
|
109
|
+
* PNG
|
|
110
|
+
* MP4
|
|
111
|
+
* Tree
|
|
112
|
+
* Backends:
|
|
113
|
+
* Graphviz
|
|
114
|
+
* Output formats:
|
|
115
|
+
* SVG
|
|
116
|
+
* PNG
|
|
117
|
+
* Gantt
|
|
118
|
+
* Backends:
|
|
119
|
+
* Cairo
|
|
120
|
+
* PgfGantt
|
|
121
|
+
* Output formats:
|
|
122
|
+
* SVG
|
|
123
|
+
* PNG
|
|
124
|
+
* Scene
|
|
125
|
+
* Backends:
|
|
126
|
+
* Cairo
|
|
127
|
+
* VTK
|
|
128
|
+
* Output formats:
|
|
129
|
+
* SVG
|
|
130
|
+
* VTK
|
|
131
|
+
|
|
132
|
+
## Themes ##
|
|
133
|
+
|
|
134
|
+
The library supports themeing with an Angular Material 3 motivated design system. Plots can be themed by adapting a version of `theme.json` included in this module's source. Currently Tikz and PlantUML support themeing.
|
|
135
|
+
|
|
136
|
+
# Installation #
|
|
137
|
+
|
|
138
|
+
The package is available on PyPI. The core install is deliberately light — it
|
|
139
|
+
does not pull the heavy rendering backends, so consumers that only need part of
|
|
140
|
+
the library (e.g. a docs build that just converts svg to png) stay small:
|
|
141
|
+
|
|
142
|
+
``` shell
|
|
143
|
+
pip install icplot
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Backends are opt-in via extras:
|
|
147
|
+
|
|
148
|
+
| Extra | Pulls | Enables |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| `cairo` | CairoSVG | svg → png / pdf conversion |
|
|
151
|
+
| `scene` | pycairo | vector scene drawing (`renderer.scene.cairo`) |
|
|
152
|
+
| `imagemagick` | wand | pdf → png conversion (falls back to the `magick` CLI) |
|
|
153
|
+
| `plot` | matplotlib | 2D plotting (`renderer.graph`, `charts`) |
|
|
154
|
+
| `vtk` | vtk | 3D / mesh rendering (`geometry.mesh`) |
|
|
155
|
+
| `geometry` | scipy | geometry transforms (`geometry.operations`) |
|
|
156
|
+
| `video` | moviepy | video assembly (`renderer.video`) |
|
|
157
|
+
| `all` | all of the above | everything (previous default behaviour) |
|
|
158
|
+
|
|
159
|
+
For example, `pip install icplot[cairo]` for svg conversion, or
|
|
160
|
+
`pip install icplot[all]` for the full toolkit. The native `cairo` and
|
|
161
|
+
`imagemagick` system libraries are also required for those backends; on Mac:
|
|
162
|
+
|
|
163
|
+
``` shell
|
|
164
|
+
brew install imagemagick cairo
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
# Copyright #
|
|
168
|
+
|
|
169
|
+
Copyright 2026 Irish Centre for High End Computing
|
|
170
|
+
|
|
171
|
+
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.
|
|
172
|
+
|
|
@@ -2,6 +2,14 @@
|
|
|
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 (planning#136). The
|
|
10
|
+
`geometry`/`mesh` 3D and OpenFOAM code is still here but is scheduled to move
|
|
11
|
+
to a module of its own, and its optional-dependency weight goes with it.
|
|
12
|
+
|
|
5
13
|
# Features #
|
|
6
14
|
|
|
7
15
|
The project has three primary modules:
|
|
@@ -83,13 +91,30 @@ The library supports themeing with an Angular Material 3 motivated design system
|
|
|
83
91
|
|
|
84
92
|
# Installation #
|
|
85
93
|
|
|
86
|
-
The package is available on PyPI.
|
|
94
|
+
The package is available on PyPI. The core install is deliberately light — it
|
|
95
|
+
does not pull the heavy rendering backends, so consumers that only need part of
|
|
96
|
+
the library (e.g. a docs build that just converts svg to png) stay small:
|
|
87
97
|
|
|
88
98
|
``` shell
|
|
89
99
|
pip install icplot
|
|
90
100
|
```
|
|
91
101
|
|
|
92
|
-
|
|
102
|
+
Backends are opt-in via extras:
|
|
103
|
+
|
|
104
|
+
| Extra | Pulls | Enables |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `cairo` | CairoSVG | svg → png / pdf conversion |
|
|
107
|
+
| `scene` | pycairo | vector scene drawing (`renderer.scene.cairo`) |
|
|
108
|
+
| `imagemagick` | wand | pdf → png conversion (falls back to the `magick` CLI) |
|
|
109
|
+
| `plot` | matplotlib | 2D plotting (`renderer.graph`, `charts`) |
|
|
110
|
+
| `vtk` | vtk | 3D / mesh rendering (`geometry.mesh`) |
|
|
111
|
+
| `geometry` | scipy | geometry transforms (`geometry.operations`) |
|
|
112
|
+
| `video` | moviepy | video assembly (`renderer.video`) |
|
|
113
|
+
| `all` | all of the above | everything (previous default behaviour) |
|
|
114
|
+
|
|
115
|
+
For example, `pip install icplot[cairo]` for svg conversion, or
|
|
116
|
+
`pip install icplot[all]` for the full toolkit. The native `cairo` and
|
|
117
|
+
`imagemagick` system libraries are also required for those backends; on Mac:
|
|
93
118
|
|
|
94
119
|
``` shell
|
|
95
120
|
brew install imagemagick cairo
|
|
@@ -97,7 +122,7 @@ brew install imagemagick cairo
|
|
|
97
122
|
|
|
98
123
|
# Copyright #
|
|
99
124
|
|
|
100
|
-
Copyright
|
|
125
|
+
Copyright 2026 Irish Centre for High End Computing
|
|
101
126
|
|
|
102
|
-
The software in this repository can be used under the conditions of the
|
|
127
|
+
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.
|
|
103
128
|
|
|
@@ -0,0 +1,124 @@
|
|
|
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/vtk/scipy/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). CairoSVG pulls
|
|
35
|
+
# cairocffi, which dlopens libcairo at runtime (no C build step needed).
|
|
36
|
+
cairo = [
|
|
37
|
+
"CairoSVG"
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# vector scene drawing (renderer.scene.cairo). pycairo (module `cairo`)
|
|
41
|
+
# builds against libcairo — needs the cairo headers + a C toolchain at install.
|
|
42
|
+
scene = ["pycairo"]
|
|
43
|
+
|
|
44
|
+
# raster conversion via ImageMagick bindings (converter.pdf_to_png);
|
|
45
|
+
# falls back to the `magick` CLI if wand is absent
|
|
46
|
+
imagemagick = ["wand"]
|
|
47
|
+
|
|
48
|
+
# 2D plotting backend (icplot.renderer.graph / icplot.charts)
|
|
49
|
+
plot = ["matplotlib"]
|
|
50
|
+
|
|
51
|
+
# 3D / mesh backend (icplot.geometry.mesh, vtk graph backend)
|
|
52
|
+
vtk = ["vtk"]
|
|
53
|
+
|
|
54
|
+
# geometry transforms (icplot.geometry.operations)
|
|
55
|
+
geometry = ["scipy"]
|
|
56
|
+
|
|
57
|
+
# video assembly (icplot.renderer.video)
|
|
58
|
+
video = ["moviepy"]
|
|
59
|
+
|
|
60
|
+
# convenience aggregate — every backend (pre-split behaviour)
|
|
61
|
+
all = [
|
|
62
|
+
"CairoSVG",
|
|
63
|
+
"pycairo",
|
|
64
|
+
"wand",
|
|
65
|
+
"matplotlib",
|
|
66
|
+
"vtk",
|
|
67
|
+
"scipy",
|
|
68
|
+
"moviepy"
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[build-system]
|
|
72
|
+
requires = ["setuptools>=64", "setuptools-scm>=8"]
|
|
73
|
+
build-backend = "setuptools.build_meta"
|
|
74
|
+
|
|
75
|
+
# Version derived from the git tag (setuptools-scm). fallback_version keeps
|
|
76
|
+
# non-release jobs building on the shallow CI checkout, which has no tags.
|
|
77
|
+
[tool.setuptools_scm]
|
|
78
|
+
fallback_version = "0.0.0"
|
|
79
|
+
|
|
80
|
+
# Development toolchain (uv-native, PEP 735). CI installs it with
|
|
81
|
+
# `uv sync --group dev`. Deliberately free of the rendering backends: the lint
|
|
82
|
+
# job runs in the standard slim image, and pycairo has no wheel there — it
|
|
83
|
+
# builds against libcairo headers. The test job adds the backends with
|
|
84
|
+
# `--extra all` in an image that has those headers.
|
|
85
|
+
[dependency-groups]
|
|
86
|
+
dev = [
|
|
87
|
+
"ruff",
|
|
88
|
+
"mypy",
|
|
89
|
+
"pytest",
|
|
90
|
+
"pytest-cov",
|
|
91
|
+
"pytest-sugar",
|
|
92
|
+
"types-PyYAML",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[project.scripts]
|
|
96
|
+
icplot = "icplot.main_cli:main_cli"
|
|
97
|
+
|
|
98
|
+
[tool.setuptools.package-data]
|
|
99
|
+
"icplot" = ["py.typed", "controlDict", "theme/theme.json", "theme/templates/*.j2"]
|
|
100
|
+
|
|
101
|
+
[tool.setuptools.packages.find]
|
|
102
|
+
where = ["src"]
|
|
103
|
+
|
|
104
|
+
[tool.mypy]
|
|
105
|
+
ignore_missing_imports = true
|
|
106
|
+
|
|
107
|
+
[tool.ruff]
|
|
108
|
+
line-length = 88
|
|
109
|
+
target-version = "py310"
|
|
110
|
+
src = ["src", "test"]
|
|
111
|
+
|
|
112
|
+
[tool.ruff.lint]
|
|
113
|
+
# E/W pycodestyle, F pyflakes, I import-sort (was isort), N pep8-naming,
|
|
114
|
+
# UP pyupgrade, B bugbear. Extend deliberately, not by pulling in "ALL".
|
|
115
|
+
select = ["E", "W", "F", "I", "N", "UP", "B"]
|
|
116
|
+
|
|
117
|
+
[tool.ruff.lint.isort]
|
|
118
|
+
known-first-party = ["icplot"]
|
|
119
|
+
|
|
120
|
+
[tool.pytest.ini_options]
|
|
121
|
+
testpaths = ["test",]
|
|
122
|
+
log_cli = 1
|
|
123
|
+
log_cli_level = "debug"
|
|
124
|
+
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):
|
|
@@ -125,8 +125,7 @@ def generate_mesh(mesh: Mesh, case_dir: Path):
|
|
|
125
125
|
if not control_dict.exists():
|
|
126
126
|
shutil.copy(Path(__file__).parent / "controlDict", control_dict)
|
|
127
127
|
|
|
128
|
-
cmd =
|
|
129
|
-
subprocess.run(cmd, cwd=case_dir,
|
|
128
|
+
cmd = ["blockMesh", "-case", str(case_dir)]
|
|
129
|
+
subprocess.run(cmd, cwd=case_dir, check=True)
|
|
130
130
|
|
|
131
|
-
cmd
|
|
132
|
-
subprocess.run(cmd, cwd=case_dir, shell=True, check=True)
|
|
131
|
+
subprocess.run(cmd + ["-write-vtk"], cwd=case_dir, check=True)
|
|
@@ -53,7 +53,10 @@ class Polymesh:
|
|
|
53
53
|
class PolymeshPatch:
|
|
54
54
|
name: str
|
|
55
55
|
faces: tuple[Face, ...]
|
|
56
|
-
|
|
56
|
+
# Mirrors the field name in OpenFOAM's own polyMesh/boundary file, which
|
|
57
|
+
# this class both parses and writes back out — renaming it to snake_case
|
|
58
|
+
# would put the Python attribute out of step with the format on disk.
|
|
59
|
+
startFace: int # noqa: N815
|
|
57
60
|
type: str = "patch"
|
|
58
61
|
|
|
59
62
|
def has_face(self, face: Face) -> bool:
|
|
@@ -102,7 +102,6 @@ def _close_circle(inner_mesh: Mesh, outer_mesh: Mesh, num_circumferential: int)
|
|
|
102
102
|
new_cells = []
|
|
103
103
|
count = 0
|
|
104
104
|
for idx in range(num_circumferential):
|
|
105
|
-
|
|
106
105
|
next_id = idx + 1
|
|
107
106
|
if next_id == num_circumferential:
|
|
108
107
|
next_id = 0
|
|
@@ -317,7 +316,6 @@ def mesh_cuboids(
|
|
|
317
316
|
for cuboid in cuboids:
|
|
318
317
|
vert_ids = []
|
|
319
318
|
for p in cuboid.points:
|
|
320
|
-
|
|
321
319
|
if not verts:
|
|
322
320
|
verts.append(Vertex.from_point(p, 0))
|
|
323
321
|
vert_ids.append(0)
|
|
@@ -57,7 +57,6 @@ def find_closest(verts: list[Vertex], point: Point) -> int:
|
|
|
57
57
|
min_id = -1
|
|
58
58
|
min_distance = 0.0
|
|
59
59
|
for idx, v in enumerate(verts):
|
|
60
|
-
|
|
61
60
|
distance = v.get_distance(point)
|
|
62
61
|
|
|
63
62
|
if idx == 0:
|
|
@@ -80,7 +79,6 @@ def find_closest_vertex(verts: tuple[Vertex, ...], v: Vertex) -> Vertex:
|
|
|
80
79
|
min_id = -1
|
|
81
80
|
min_distance = 0.0
|
|
82
81
|
for idx, vert in enumerate(verts):
|
|
83
|
-
|
|
84
82
|
distance = vert.get_vertex_distance(v)
|
|
85
83
|
|
|
86
84
|
if idx == 0:
|
|
@@ -26,13 +26,11 @@ class Shape:
|
|
|
26
26
|
|
|
27
27
|
@dataclass(frozen=True)
|
|
28
28
|
class Circle(Shape):
|
|
29
|
-
|
|
30
29
|
radius: float = 1.0
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
@dataclass(frozen=True)
|
|
34
33
|
class Annulus(Shape):
|
|
35
|
-
|
|
36
34
|
outer_radius: float = 1.0
|
|
37
35
|
inner_radius: float = 0.5
|
|
38
36
|
angle: float = 360 # degrees
|
|
@@ -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)
|