icplot 0.1.4__tar.gz → 0.1.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.
- {icplot-0.1.4/src/icplot.egg-info → icplot-0.1.6}/PKG-INFO +15 -5
- {icplot-0.1.4 → icplot-0.1.6}/README.md +8 -1
- icplot-0.1.6/pyproject.toml +154 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/cairo_interface.py +1 -1
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/convert.py +13 -2
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/gantt/gantt.py +7 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/gantt/gantt_renderer.py +5 -4
- icplot-0.1.6/src/icplot/geometry.py +151 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/graph/axis.py +4 -2
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/graph/matplotlib.py +3 -6
- icplot-0.1.6/src/icplot/graph/mpl.py +216 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/graph/plot.py +37 -2
- icplot-0.1.6/src/icplot/graph/plot_group.py +63 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/graph/series.py +7 -0
- icplot-0.1.6/src/icplot/graph/video.py +35 -0
- icplot-0.1.6/src/icplot/graph/vtk.py +54 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/main_cli.py +12 -1
- icplot-0.1.6/src/icplot/mermaid.py +39 -0
- icplot-0.1.6/src/icplot/mesh/__init__.py +1 -0
- icplot-0.1.6/src/icplot/mesh/foam.py +56 -0
- icplot-0.1.6/src/icplot/mesh/mesh.py +79 -0
- icplot-0.1.4/src/icplot/geometry.py → icplot-0.1.6/src/icplot/scene.py +25 -1
- {icplot-0.1.4 → icplot-0.1.6/src/icplot.egg-info}/PKG-INFO +15 -5
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot.egg-info/SOURCES.txt +12 -1
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot.egg-info/requires.txt +3 -1
- {icplot-0.1.4 → icplot-0.1.6}/test/test_cairo_interface.py +1 -1
- {icplot-0.1.4 → icplot-0.1.6}/test/test_line_plots.py +1 -1
- icplot-0.1.6/test/test_mermaid.py +24 -0
- icplot-0.1.6/test/test_mesh.py +13 -0
- icplot-0.1.4/test/test_tex_interface.py → icplot-0.1.6/test/test_tex.py +1 -1
- icplot-0.1.4/pyproject.toml +0 -108
- {icplot-0.1.4 → icplot-0.1.6}/LICENSE +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/setup.cfg +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/__init__.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/color.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/gantt/__init__.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/gantt/pgfgantt.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/graph/__init__.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/graph/generator.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/image_utils.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/py.typed +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/tex.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/trace/__init__.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot/trace/trace.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot.egg-info/dependency_links.txt +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot.egg-info/entry_points.txt +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/src/icplot.egg-info/top_level.txt +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/test/test_gantt_chart.py +0 -0
- {icplot-0.1.4 → icplot-0.1.6}/test/test_image_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: icplot
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Utilities for generating plots and graphics for technical reports.
|
|
5
5
|
Author-email: "James Grogan, Irish Centre for High End Computing" <james.grogan@ichec.ie>
|
|
6
6
|
Project-URL: Repository, https://git.ichec.ie/performance/toolshed/icplot
|
|
@@ -11,12 +11,14 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Topic :: System :: Distributed Computing
|
|
14
|
-
Requires-Python: >=3.
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Requires-Dist: wand
|
|
18
18
|
Requires-Dist: matplotlib
|
|
19
|
-
Requires-Dist:
|
|
19
|
+
Requires-Dist: vtk
|
|
20
|
+
Requires-Dist: moviepy
|
|
21
|
+
Requires-Dist: iccore==0.1.13
|
|
20
22
|
Provides-Extra: test
|
|
21
23
|
Requires-Dist: pytest; extra == "test"
|
|
22
24
|
Requires-Dist: pytest-cov; extra == "test"
|
|
@@ -28,6 +30,7 @@ Requires-Dist: pylint; extra == "test"
|
|
|
28
30
|
Provides-Extra: cairo
|
|
29
31
|
Requires-Dist: pycairo; extra == "cairo"
|
|
30
32
|
Requires-Dist: CairoSVG; extra == "cairo"
|
|
33
|
+
Dynamic: license-file
|
|
31
34
|
|
|
32
35
|
# icplot
|
|
33
36
|
|
|
@@ -38,8 +41,9 @@ This is a library used at [The Irish Centre for High End Computing (ICHEC)](http
|
|
|
38
41
|
The project has support for:
|
|
39
42
|
|
|
40
43
|
* Coverting image formats between pdf, svg and png
|
|
41
|
-
* Building pdf output from tex files, including tikz.
|
|
44
|
+
* Building pdf and png output from tex files, including tikz.
|
|
42
45
|
* Generating plots based on a serializable data model to support reproducible research
|
|
46
|
+
* Generating mermaid plots
|
|
43
47
|
|
|
44
48
|
To covert between image formats you can do:
|
|
45
49
|
|
|
@@ -53,6 +57,12 @@ To render a Tex tikz image as pdf and png you can do:
|
|
|
53
57
|
icplot convert --source my_tikz.tex
|
|
54
58
|
```
|
|
55
59
|
|
|
60
|
+
To render a Mermaid plot as png you can do:
|
|
61
|
+
|
|
62
|
+
``` shell
|
|
63
|
+
icplot convert --source my_mermaid.mmd
|
|
64
|
+
```
|
|
65
|
+
|
|
56
66
|
To generate a plot or collection of plots from a yaml description you can do:
|
|
57
67
|
|
|
58
68
|
``` shell
|
|
@@ -7,8 +7,9 @@ This is a library used at [The Irish Centre for High End Computing (ICHEC)](http
|
|
|
7
7
|
The project has support for:
|
|
8
8
|
|
|
9
9
|
* Coverting image formats between pdf, svg and png
|
|
10
|
-
* Building pdf output from tex files, including tikz.
|
|
10
|
+
* Building pdf and png output from tex files, including tikz.
|
|
11
11
|
* Generating plots based on a serializable data model to support reproducible research
|
|
12
|
+
* Generating mermaid plots
|
|
12
13
|
|
|
13
14
|
To covert between image formats you can do:
|
|
14
15
|
|
|
@@ -22,6 +23,12 @@ To render a Tex tikz image as pdf and png you can do:
|
|
|
22
23
|
icplot convert --source my_tikz.tex
|
|
23
24
|
```
|
|
24
25
|
|
|
26
|
+
To render a Mermaid plot as png you can do:
|
|
27
|
+
|
|
28
|
+
``` shell
|
|
29
|
+
icplot convert --source my_mermaid.mmd
|
|
30
|
+
```
|
|
31
|
+
|
|
25
32
|
To generate a plot or collection of plots from a yaml description you can do:
|
|
26
33
|
|
|
27
34
|
``` shell
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "icplot"
|
|
3
|
+
version = "0.1.6"
|
|
4
|
+
authors = [
|
|
5
|
+
{ name="James Grogan, Irish Centre for High End Computing", email="james.grogan@ichec.ie" },
|
|
6
|
+
]
|
|
7
|
+
description = "Utilities for generating plots and graphics for technical reports."
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
|
14
|
+
"Operating System :: OS Independent",
|
|
15
|
+
"Topic :: System :: Distributed Computing"
|
|
16
|
+
]
|
|
17
|
+
keywords = ["Publishing", "Technical Reports", "Graphics"]
|
|
18
|
+
|
|
19
|
+
dependencies = ["wand",
|
|
20
|
+
"matplotlib",
|
|
21
|
+
"vtk",
|
|
22
|
+
"moviepy",
|
|
23
|
+
"iccore==0.1.13"]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Repository = "https://git.ichec.ie/performance/toolshed/icplot"
|
|
27
|
+
Homepage = "https://git.ichec.ie/performance/toolshed/icplot"
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
test = [
|
|
31
|
+
"pytest",
|
|
32
|
+
"pytest-cov",
|
|
33
|
+
"pytest-sugar",
|
|
34
|
+
"black",
|
|
35
|
+
"mypy",
|
|
36
|
+
"flake8",
|
|
37
|
+
"pylint"
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
cairo = [
|
|
41
|
+
"pycairo",
|
|
42
|
+
"CairoSVG"
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[build-system]
|
|
46
|
+
requires = ["setuptools", "wheel"]
|
|
47
|
+
build-backend = "setuptools.build_meta"
|
|
48
|
+
|
|
49
|
+
[project.scripts]
|
|
50
|
+
icplot = "icplot.main_cli:main_cli"
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.package-data]
|
|
53
|
+
"icplot" = ["py.typed"]
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.packages.find]
|
|
56
|
+
where = ["src"]
|
|
57
|
+
|
|
58
|
+
[tool.mypy]
|
|
59
|
+
ignore_missing_imports = true
|
|
60
|
+
|
|
61
|
+
[tool.pylint.main]
|
|
62
|
+
|
|
63
|
+
source-roots = ["src"]
|
|
64
|
+
fail-under = 9.33
|
|
65
|
+
|
|
66
|
+
[tool.pylint.basic]
|
|
67
|
+
|
|
68
|
+
class-const-naming-style = "UPPER_CASE"
|
|
69
|
+
class-naming-style = "PascalCase"
|
|
70
|
+
const-naming-style = "UPPER_CASE"
|
|
71
|
+
docstring-min-length = -1
|
|
72
|
+
|
|
73
|
+
function-naming-style = "snake_case"
|
|
74
|
+
method-naming-style = "snake_case"
|
|
75
|
+
module-naming-style = "snake_case"
|
|
76
|
+
variable-naming-style = "snake_case"
|
|
77
|
+
|
|
78
|
+
no-docstring-rgx = "^_"
|
|
79
|
+
|
|
80
|
+
[tool.pylint.design]
|
|
81
|
+
# Maximum number of arguments for function / method.
|
|
82
|
+
max-args = 6
|
|
83
|
+
# Maximum number of attributes for a class (see R0902).
|
|
84
|
+
max-attributes = 7
|
|
85
|
+
# Minimum number of public methods for a class (see R0903).
|
|
86
|
+
min-public-methods = 1
|
|
87
|
+
|
|
88
|
+
[tool.pylint.logging]
|
|
89
|
+
# The type of string formatting that logging methods do. `old` means using %
|
|
90
|
+
# formatting, `new` is for `{}` formatting.
|
|
91
|
+
logging-format-style = "old"
|
|
92
|
+
|
|
93
|
+
# Disable the message, report, category or checker with the given id(s). You can
|
|
94
|
+
# either give multiple identifiers separated by comma (,) or put this option
|
|
95
|
+
# multiple times (only on the command line, not in the configuration file where
|
|
96
|
+
# it should appear only once). You can also use "--disable=all" to disable
|
|
97
|
+
# everything first and then re-enable specific checks. For example, if you want
|
|
98
|
+
# to run only the similarities checker, you can use "--disable=all
|
|
99
|
+
# --enable=similarities". If you want to run only the classes checker, but have
|
|
100
|
+
# no Warning level messages displayed, use "--disable=all --enable=classes
|
|
101
|
+
# --disable=W".
|
|
102
|
+
disable = ["raw-checker-failed", "missing-module-docstring", "missing-function-docstring", "bad-inline-option", "locally-disabled", "file-ignored", "suppressed-message", "useless-suppression", "deprecated-pragma", "use-symbolic-message-instead", "use-implicit-booleaness-not-comparison-to-string", "use-implicit-booleaness-not-comparison-to-zero"]
|
|
103
|
+
|
|
104
|
+
[tool.pytest.ini_options]
|
|
105
|
+
testpaths = ["test",]
|
|
106
|
+
log_cli = 1
|
|
107
|
+
log_cli_level = "debug"
|
|
108
|
+
addopts = "--cov=icplot --cov-report term --cov-fail-under=59 --cov-report xml:coverage.xml --cov-report html"
|
|
109
|
+
|
|
110
|
+
[tool.tox]
|
|
111
|
+
requires = ["tox"]
|
|
112
|
+
env_list = ["format_check", "lint", "style", "type", "3.10", "3.13", "docs"]
|
|
113
|
+
skip_missing_interpreters = true
|
|
114
|
+
|
|
115
|
+
[tool.tox.env_run_base]
|
|
116
|
+
description = "Run Unit and Integration Tests"
|
|
117
|
+
deps = [".[test, cairo]"]
|
|
118
|
+
commands = [["pytest", "test"]]
|
|
119
|
+
|
|
120
|
+
[tool.tox.env.format_apply]
|
|
121
|
+
description = "Run Format Apply"
|
|
122
|
+
skip_install = true
|
|
123
|
+
deps = ["black"]
|
|
124
|
+
commands = [["black", "src"], ["black", "test"]]
|
|
125
|
+
|
|
126
|
+
[tool.tox.env.format_check]
|
|
127
|
+
description = "Run Format Check"
|
|
128
|
+
skip_install = true
|
|
129
|
+
deps = ["black"]
|
|
130
|
+
commands = [
|
|
131
|
+
["black", "--check", "--diff", "src"],
|
|
132
|
+
["black", "--check", "--diff", "test"]]
|
|
133
|
+
|
|
134
|
+
[tool.tox.env.lint]
|
|
135
|
+
description = "Run Linter"
|
|
136
|
+
deps = ["pylint"]
|
|
137
|
+
commands = [["pylint", "src"]]
|
|
138
|
+
|
|
139
|
+
[tool.tox.env.style]
|
|
140
|
+
description = "Run Style Check"
|
|
141
|
+
skip_install = true
|
|
142
|
+
deps = ["flake8"]
|
|
143
|
+
commands = [["flake8", "src"]]
|
|
144
|
+
|
|
145
|
+
[tool.tox.env.type]
|
|
146
|
+
description = "Run Type Checks"
|
|
147
|
+
deps = ["mypy", ".[types]"]
|
|
148
|
+
commands = [["mypy", "src"]]
|
|
149
|
+
|
|
150
|
+
[tool.tox.env.docs]
|
|
151
|
+
description = "Generate Documentation"
|
|
152
|
+
changedir = "docs"
|
|
153
|
+
deps = ["sphinx"]
|
|
154
|
+
commands = [["sphinx-build","-W", "-b","html","-d","{envtmpdir}/doctrees","."," {envtmpdir}/html"]]
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module supporting conversion between various formats
|
|
3
|
+
"""
|
|
4
|
+
|
|
1
5
|
import logging
|
|
2
6
|
import os
|
|
3
7
|
from pathlib import Path
|
|
4
8
|
|
|
5
|
-
from icplot import tex
|
|
9
|
+
from icplot import tex, mermaid
|
|
6
10
|
from icplot.tex import TexBuildSettings
|
|
7
11
|
from icplot.image_utils import pdf_to_png, svg_to_pdf, svg_to_png
|
|
8
12
|
|
|
@@ -10,7 +14,9 @@ from icplot.image_utils import pdf_to_png, svg_to_pdf, svg_to_png
|
|
|
10
14
|
logger = logging.getLogger(__name__)
|
|
11
15
|
|
|
12
16
|
|
|
13
|
-
def convert(
|
|
17
|
+
def convert(
|
|
18
|
+
source: Path, target: Path, build_dir: Path, extra_config: Path | None = None
|
|
19
|
+
):
|
|
14
20
|
"""
|
|
15
21
|
Convert the file at source outputing at target and using
|
|
16
22
|
the source and target file extensions as format hints.
|
|
@@ -36,5 +42,10 @@ def convert(source: Path, target: Path, build_dir: Path):
|
|
|
36
42
|
target = Path(os.getcwd())
|
|
37
43
|
settings = TexBuildSettings(source, build_dir, target)
|
|
38
44
|
tex.build(settings)
|
|
45
|
+
elif source.suffix == ".mmd":
|
|
46
|
+
if not target:
|
|
47
|
+
target = Path(os.getcwd())
|
|
48
|
+
settings = TexBuildSettings(source, build_dir, target)
|
|
49
|
+
mermaid.convert(source, target, extra_config)
|
|
39
50
|
|
|
40
51
|
logger.info("Finished conversion")
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module represents a gantt chard
|
|
3
|
+
"""
|
|
4
|
+
|
|
1
5
|
from datetime import datetime
|
|
2
6
|
|
|
3
7
|
from pydantic import BaseModel
|
|
@@ -8,6 +12,9 @@ from icplot.color import Color
|
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
class GanttChart(BaseModel, frozen=True):
|
|
15
|
+
"""
|
|
16
|
+
A gantt chart
|
|
17
|
+
"""
|
|
11
18
|
|
|
12
19
|
milestones: list[Milestone] = []
|
|
13
20
|
title: str = ""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from iccore.project import Milestone
|
|
2
|
-
from icplot.
|
|
2
|
+
from icplot.scene import Scene, SceneItem, Rectangle
|
|
3
3
|
|
|
4
4
|
from .gantt import GanttChart
|
|
5
5
|
|
|
@@ -25,10 +25,11 @@ def _render_milestone(
|
|
|
25
25
|
return rect
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def _render_milestones(gantt: GanttChart):
|
|
28
|
+
def _render_milestones(gantt: GanttChart) -> list[SceneItem]:
|
|
29
29
|
|
|
30
|
+
scene_items: list = []
|
|
30
31
|
if not gantt.milestones:
|
|
31
|
-
return
|
|
32
|
+
return scene_items
|
|
32
33
|
|
|
33
34
|
milestones = gantt.milestones
|
|
34
35
|
# milestones.sort(key=lambda x: x.start_date, reverse=True)
|
|
@@ -44,7 +45,7 @@ def _render_milestones(gantt: GanttChart):
|
|
|
44
45
|
chart_range = (start_date, end_date)
|
|
45
46
|
yloc = 0.0
|
|
46
47
|
bar_height = gantt.bar_max_height * gantt.height
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
for milestone in milestones:
|
|
49
50
|
item = _render_milestone(gantt, milestone, chart_range, yloc)
|
|
50
51
|
scene_items.append(item)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for primitive geometries. This is used to keep dependencies simple,
|
|
3
|
+
consider a real geometry library like cgal for more complex or performance
|
|
4
|
+
dependent work.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
import copy
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Vector:
|
|
14
|
+
"""
|
|
15
|
+
A 3d spatial vector
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
x: float
|
|
19
|
+
y: float = 0.0
|
|
20
|
+
z: float = 0.0
|
|
21
|
+
|
|
22
|
+
def scale(self, factor: float) -> Vector:
|
|
23
|
+
return Vector(self.x * factor, self.y * factor, self.z * factor)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class Point:
|
|
28
|
+
"""
|
|
29
|
+
A location in 3d space
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
x: float
|
|
33
|
+
y: float = 0.0
|
|
34
|
+
z: float = 0.0
|
|
35
|
+
|
|
36
|
+
def translate(self, v: Vector) -> Point:
|
|
37
|
+
return Point(self.x + v.x, self.y + v.y, self.z + v.z)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class Shape:
|
|
42
|
+
"""
|
|
43
|
+
A shape in 3d space, defaults to having a normal to Z
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
loc: Point
|
|
47
|
+
normal: Vector = Vector(0.0, 0.0, 1.0)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass(frozen=True)
|
|
51
|
+
class Quad(Shape):
|
|
52
|
+
"""
|
|
53
|
+
A regular quadrilateral in 3d space, defaults to be normal to Z
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
width: float = 1.0
|
|
57
|
+
height: float = 1.0
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def points(self) -> list[Point]:
|
|
61
|
+
p = copy.deepcopy(self.loc)
|
|
62
|
+
return [
|
|
63
|
+
p,
|
|
64
|
+
p.translate(Vector(self.width)),
|
|
65
|
+
p.translate(Vector(self.width, self.height)),
|
|
66
|
+
p.translate(Vector(0.0, self.height)),
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
def translate(self, v: Vector) -> Quad:
|
|
70
|
+
return Quad(self.loc.translate(v), self.normal, self.width, self.height)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class Cuboid(Shape):
|
|
75
|
+
"""
|
|
76
|
+
A regular cuboid
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
loc: Point
|
|
80
|
+
width: float = 1.0
|
|
81
|
+
height: float = 1.0
|
|
82
|
+
depth: float = 1.0
|
|
83
|
+
|
|
84
|
+
def translate(self, v: Vector) -> Cuboid:
|
|
85
|
+
return Cuboid(
|
|
86
|
+
self.loc.translate(v), self.normal, self.width, self.height, self.depth
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def points(self) -> list[Point]:
|
|
91
|
+
|
|
92
|
+
base = Quad(self.loc, self.normal, self.width, self.height)
|
|
93
|
+
top = base.translate(self.normal.scale(self.depth))
|
|
94
|
+
return base.points + top.points
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass(frozen=True)
|
|
98
|
+
class Cylinder(Shape):
|
|
99
|
+
"""
|
|
100
|
+
A cylinder
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
diameter: float = 1.0
|
|
104
|
+
length: float = 1.0
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def start(self) -> Point:
|
|
108
|
+
return self.loc
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def end(self) -> Point:
|
|
112
|
+
return self.loc.translate(self.normal.scale(self.length))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass(frozen=True)
|
|
116
|
+
class Revolution(Shape):
|
|
117
|
+
"""
|
|
118
|
+
A revolved profile sitting on the plane given by the loc
|
|
119
|
+
and normal and revolved about the normal.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
diameter: float = 1.0
|
|
123
|
+
length: float = 1.0
|
|
124
|
+
profile: str = "arc"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@dataclass(frozen=True)
|
|
128
|
+
class CuboidGrid:
|
|
129
|
+
"""
|
|
130
|
+
A irregular grid composed of cuboids. Can be useful for
|
|
131
|
+
generating topological meshes like OpenFoam's blockMesh.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
x_locs: list[float]
|
|
135
|
+
y_locs: list[float]
|
|
136
|
+
z_locs: list[float]
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def cuboids(self) -> list[Cuboid]:
|
|
140
|
+
ret = []
|
|
141
|
+
|
|
142
|
+
for kdx, z in enumerate(self.z_locs[:-1]):
|
|
143
|
+
for jdx, y in enumerate(self.y_locs[:-1]):
|
|
144
|
+
for idx, x in enumerate(self.x_locs[:-1]):
|
|
145
|
+
width = self.x_locs[idx + 1] - x
|
|
146
|
+
height = self.y_locs[jdx + 1] - y
|
|
147
|
+
depth = self.z_locs[kdx + 1] - z
|
|
148
|
+
ret.append(
|
|
149
|
+
Cuboid(Point(x, y, z), width=width, height=height, depth=depth)
|
|
150
|
+
)
|
|
151
|
+
return ret
|
|
@@ -28,7 +28,7 @@ class PlotAxis(BaseModel, frozen=True):
|
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
label: str = ""
|
|
31
|
-
ticks: Range | None = None
|
|
31
|
+
ticks: Range | list[int] | None = None
|
|
32
32
|
scale: str = "linear"
|
|
33
33
|
text_fontsize: int = 10
|
|
34
34
|
tick_fontsize: int = 10
|
|
@@ -38,5 +38,7 @@ class PlotAxis(BaseModel, frozen=True):
|
|
|
38
38
|
@property
|
|
39
39
|
def resolved_ticks(self) -> list:
|
|
40
40
|
if self.ticks:
|
|
41
|
-
|
|
41
|
+
if isinstance(self.ticks, Range):
|
|
42
|
+
return self.ticks.eval()
|
|
43
|
+
return self.ticks
|
|
42
44
|
return []
|
|
@@ -31,10 +31,7 @@ def str_exact_values_formatter(x, pos):
|
|
|
31
31
|
then when using plain formatter values less than 1 come out as 0. A way around
|
|
32
32
|
this is this custom formatter.
|
|
33
33
|
"""
|
|
34
|
-
if x.is_integer()
|
|
35
|
-
return str(int(x))
|
|
36
|
-
else:
|
|
37
|
-
return str(x)
|
|
34
|
+
return str(int(x)) if x.is_integer else str(x)
|
|
38
35
|
|
|
39
36
|
|
|
40
37
|
def _set_legend_decorations(axs, plot):
|
|
@@ -80,9 +77,9 @@ def _set_y_axes_decorations(y_axes: list[PlotAxis], axs):
|
|
|
80
77
|
if y_axis.max_ticks:
|
|
81
78
|
axs[idx].yaxis.set_major_locator(plt.MaxNLocator(y_axis.max_ticks))
|
|
82
79
|
for key, item in y_axis.limits.items():
|
|
83
|
-
if key
|
|
80
|
+
if key in ("bottom", "ymin"):
|
|
84
81
|
axs[idx].set_ylim(ymin=item)
|
|
85
|
-
elif key
|
|
82
|
+
elif key in ("top", "ymax"):
|
|
86
83
|
axs[idx].set_ylim(ymax=item)
|
|
87
84
|
|
|
88
85
|
|