icplot 0.2.4__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. icplot/{gantt → charts}/gantt.py +2 -3
  2. icplot/{tree.py → charts/tree.py} +2 -3
  3. icplot/converter/__init__.py +3 -0
  4. icplot/converter/cli.py +27 -0
  5. icplot/converter/convert.py +32 -0
  6. icplot/{image_utils.py → converter/image.py} +26 -10
  7. icplot/geometry/base.py +6 -0
  8. icplot/{mesh → geometry/mesh}/edge.py +1 -1
  9. icplot/{mesh → geometry/mesh}/mesh.py +30 -4
  10. icplot/{mesh → geometry/mesh}/openfoam/blockmesh.py +2 -3
  11. icplot/{mesh → geometry/mesh}/openfoam/polymesh.py +4 -6
  12. icplot/{mesh → geometry/mesh}/shapes.py +87 -7
  13. icplot/{mesh → geometry/mesh}/vertex.py +16 -1
  14. icplot/geometry/shapes.py +29 -0
  15. icplot/geometry/transform.py +2 -2
  16. icplot/graph/__init__.py +3 -4
  17. icplot/graph/plot.py +2 -53
  18. icplot/graph/plot_group.py +1 -1
  19. icplot/graph/series.py +3 -4
  20. icplot/main_cli.py +13 -62
  21. icplot/renderer/__init__.py +5 -0
  22. icplot/renderer/charts/pgfgantt.py +71 -0
  23. icplot/{gantt/gantt_renderer.py → renderer/charts/svggantt.py} +8 -6
  24. icplot/renderer/cli.py +58 -0
  25. icplot/renderer/config.py +41 -0
  26. icplot/renderer/formats/__init__.py +1 -0
  27. icplot/renderer/formats/mermaid.py +47 -0
  28. icplot/renderer/formats/plantuml.py +37 -0
  29. icplot/renderer/formats/tex.py +120 -0
  30. icplot/renderer/graph/__init__.py +3 -0
  31. icplot/renderer/graph/color.py +17 -0
  32. icplot/{graph → renderer/graph}/matplotlib.py +15 -7
  33. icplot/{graph → renderer/graph}/mpl.py +8 -8
  34. icplot/{graph/generator.py → renderer/graph/renderer.py} +43 -8
  35. icplot/{graph → renderer/graph}/vtk.py +2 -3
  36. icplot/renderer/render.py +149 -0
  37. icplot/{cairo_interface.py → renderer/scene/cairo.py} +5 -5
  38. icplot/{graph → renderer}/video.py +2 -3
  39. icplot/scene.py +1 -1
  40. icplot/theme/__init__.py +0 -0
  41. icplot/theme/cli.py +50 -0
  42. icplot/theme/color.py +97 -0
  43. icplot/theme/templates/puml.j2 +91 -0
  44. icplot/theme/templates/tikz.j2 +100 -0
  45. icplot/theme/theme.json +81 -0
  46. icplot/theme/theme.py +117 -0
  47. icplot/theme/theme_generator.py +119 -0
  48. {icplot-0.2.4.dist-info → icplot-0.3.1.dist-info}/METADATA +66 -18
  49. icplot-0.3.1.dist-info/RECORD +65 -0
  50. {icplot-0.2.4.dist-info → icplot-0.3.1.dist-info}/WHEEL +1 -1
  51. icplot/color.py +0 -50
  52. icplot/convert.py +0 -51
  53. icplot/gantt/__init__.py +0 -1
  54. icplot/gantt/pgfgantt.py +0 -15
  55. icplot/mermaid.py +0 -39
  56. icplot/tex.py +0 -78
  57. icplot/trace/__init__.py +0 -1
  58. icplot-0.2.4.dist-info/RECORD +0 -50
  59. icplot/{trace/trace.py → charts/__init__.py} +0 -0
  60. icplot/{mesh → geometry/mesh}/__init__.py +1 -1
  61. icplot/{mesh → geometry/mesh}/cell.py +0 -0
  62. icplot/{mesh → geometry/mesh}/openfoam/__init__.py +1 -1
  63. icplot/{mesh → geometry/mesh}/openfoam/foamfile.py +0 -0
  64. icplot/{mesh → geometry/mesh}/operations.py +1 -1
  65. icplot/{mesh → geometry/mesh}/vtk.py +2 -2
  66. {icplot-0.2.4.dist-info → icplot-0.3.1.dist-info}/entry_points.txt +0 -0
  67. {icplot-0.2.4.dist-info → icplot-0.3.1.dist-info}/licenses/LICENSE +0 -0
  68. {icplot-0.2.4.dist-info → icplot-0.3.1.dist-info}/top_level.txt +0 -0
@@ -4,11 +4,10 @@ This module represents a gantt chard
4
4
 
5
5
  from datetime import datetime
6
6
 
7
- from pydantic import BaseModel
8
-
9
7
  from iccore.project import Milestone
8
+ from pydantic import BaseModel
10
9
 
11
- from icplot.color import Color
10
+ from icplot.theme.color import Color
12
11
 
13
12
 
14
13
  class GanttChart(BaseModel, frozen=True):
@@ -1,13 +1,12 @@
1
+ import logging
1
2
  import os
2
3
  import shutil
3
- import logging
4
4
  from dataclasses import dataclass
5
- from typing import Callable
6
5
  from pathlib import Path
6
+ from typing import Callable
7
7
 
8
8
  import graphviz
9
9
 
10
-
11
10
  logger = logging.getLogger(__name__)
12
11
 
13
12
 
@@ -0,0 +1,3 @@
1
+ from .image import pdf_to_png, svg_to_pdf, svg_to_png
2
+
3
+ __all__ = ["pdf_to_png", "svg_to_pdf", "svg_to_png"]
@@ -0,0 +1,27 @@
1
+ from pathlib import Path
2
+
3
+ from .convert import convert
4
+
5
+
6
+ def convert_cli(args):
7
+
8
+ source = args.source.resolve()
9
+ target = Path(args.target).resolve() if args.target else None
10
+ convert(source, target)
11
+
12
+
13
+ def register_parser(subparsers):
14
+
15
+ convert_parser = subparsers.add_parser("convert")
16
+ convert_parser.add_argument(
17
+ "source",
18
+ type=Path,
19
+ help="Path to file to be converted from",
20
+ )
21
+ convert_parser.add_argument(
22
+ "--target",
23
+ type=str,
24
+ default="",
25
+ help="Path to file to be converted to",
26
+ )
27
+ convert_parser.set_defaults(func=convert_cli)
@@ -0,0 +1,32 @@
1
+ """
2
+ Module supporting conversion between image formats
3
+ """
4
+
5
+ import logging
6
+ from pathlib import Path
7
+
8
+ from .image import pdf_to_png, svg_to_pdf, svg_to_png
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ def convert(source: Path, target: Path | None = None):
14
+ """
15
+ Convert between image formats using the source and target
16
+ file extensions as format hints.
17
+ """
18
+
19
+ logger.info("Converting %s", source)
20
+
21
+ if source.suffix == ".pdf":
22
+ pdf_to_png(source, target)
23
+ elif source.suffix == ".svg":
24
+ if target:
25
+ if target.suffix == ".png":
26
+ svg_to_png(source, target)
27
+ elif target.suffix == ".pdf":
28
+ svg_to_pdf(source, target)
29
+ else:
30
+ svg_to_png(source)
31
+
32
+ logger.info("Finished conversion")
@@ -5,34 +5,36 @@ formats
5
5
 
6
6
  import logging
7
7
  import os
8
+ import shutil
9
+ import subprocess
8
10
  from pathlib import Path
9
11
 
12
+ logger = logging.getLogger(__name__)
13
+
10
14
  _HAS_WAND = True
11
15
  try:
12
- from wand.image import Image
13
16
  from wand.color import Color
17
+ from wand.image import Image
14
18
  except ImportError as e:
15
- logging.getLogger(__name__).warning(
16
- "Disabling Wand stupport. Failed to load with: %s", e
17
- )
19
+ logger.debug("wand not available: %s", e)
18
20
  _HAS_WAND = False
19
21
 
20
22
  _HAS_CAIRO_SVG = True
21
23
  try:
22
24
  import cairosvg
23
25
  except ImportError as e:
24
- logging.getLogger(__name__).warning(
25
- "Disabling CairoSVG stupport. Failed to load with: %s", e
26
- )
26
+ logger.debug("cairosvg not available: %s", e)
27
27
  _HAS_CAIRO_SVG = False
28
28
 
29
- logger = logging.getLogger(__name__)
30
-
31
29
 
32
30
  def has_wand() -> bool:
33
31
  return _HAS_WAND
34
32
 
35
33
 
34
+ def has_magick() -> bool:
35
+ return bool(shutil.which("magick"))
36
+
37
+
36
38
  def has_cairo_svg() -> bool:
37
39
  return _HAS_CAIRO_SVG
38
40
 
@@ -43,13 +45,27 @@ def _get_out_filename(source: Path, target: Path | None, extension: str) -> Path
43
45
  return source.parent / f"{source.stem}.{extension}"
44
46
 
45
47
 
48
+ def _pdf_to_png(source: Path, target: Path | None = None, resolution: int = 300):
49
+
50
+ outfile = _get_out_filename(source, target, "png")
51
+ os.makedirs(outfile.parent, exist_ok=True)
52
+ cmd = (
53
+ f"magick -density {resolution} -background white -alpha off {source} {outfile}"
54
+ )
55
+ subprocess.run(cmd, shell=True, check=True)
56
+
57
+
46
58
  def pdf_to_png(source: Path, target: Path | None = None, resolution: int = 300):
47
59
  """
48
60
  Convert a pdf to png with white background
49
61
  """
50
62
 
51
63
  if not has_wand():
52
- raise RuntimeError("Loading Wand failed - no pdf to png support")
64
+ if has_magick():
65
+ _pdf_to_png(source, target, resolution)
66
+ return
67
+ else:
68
+ raise RuntimeError("Loading Wand failed - no pdf to png support")
53
69
 
54
70
  outfile = _get_out_filename(source, target, "png")
55
71
  os.makedirs(outfile.parent, exist_ok=True)
icplot/geometry/base.py CHANGED
@@ -1,8 +1,11 @@
1
1
  from __future__ import annotations
2
+
2
3
  from dataclasses import dataclass
3
4
 
4
5
  import numpy as np
5
6
 
7
+ from .operations import get_point_distance
8
+
6
9
 
7
10
  @dataclass(frozen=True)
8
11
  class Vector:
@@ -47,6 +50,9 @@ class Point:
47
50
  def subtract(self, v: Vector) -> Vector:
48
51
  return Vector(self.x - v.x, self.y - v.y, self.z - v.z)
49
52
 
53
+ def get_distance(self, p: Point) -> float:
54
+ return get_point_distance(p.as_array(), self.as_array())
55
+
50
56
 
51
57
  @dataclass(frozen=True)
52
58
  class Bounds:
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
 
3
- from icplot.geometry import Point, segment_contains_point, get_segment_distance
3
+ from icplot.geometry import Point, get_segment_distance, segment_contains_point
4
4
 
5
5
  from .vertex import Vertex
6
6
 
@@ -4,13 +4,14 @@ over performance. Consider something else for high performance meshing.
4
4
  """
5
5
 
6
6
  from __future__ import annotations
7
+
7
8
  from dataclasses import dataclass
8
9
 
9
- from icplot.geometry import Point, Vector, Transform, Bounds
10
+ from icplot.geometry import Bounds, Point, Shape, Transform, Vector
10
11
 
11
- from .vertex import Vertex, find_closest_vertex
12
12
  from .cell import Cell, flip_normals
13
13
  from .edge import Edge, contains_point, get_distance
14
+ from .vertex import Vertex, find_closest_vertex
14
15
 
15
16
 
16
17
  @dataclass(frozen=True)
@@ -49,7 +50,7 @@ class Mesh:
49
50
  ymin = min(ymin, v.y)
50
51
  ymax = max(ymax, v.y)
51
52
  zmin = min(zmin, v.z)
52
- zmax = min(zmax, v.z)
53
+ zmax = max(zmax, v.z)
53
54
  return Bounds(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax)
54
55
 
55
56
  def flip_normals(self) -> Mesh:
@@ -67,8 +68,28 @@ class Mesh:
67
68
  vertices=tuple(v.translate(delta) for v in self.vertices), cells=self.cells
68
69
  )
69
70
 
70
- def move_by(self, x: float, y: float, z: float) -> Mesh:
71
+ def scale_by(self, factor: float) -> Mesh:
72
+ return Mesh(
73
+ vertices=tuple(v.scale(factor) for v in self.vertices), cells=self.cells
74
+ )
75
+
76
+ def rotate_to(self, vec: Vector) -> Mesh:
77
+ return Mesh(
78
+ vertices=tuple(v.rotate_to(vec) for v in self.vertices), cells=self.cells
79
+ )
80
+
81
+ def move_by(
82
+ self, x: float, y: float, z: float, selection: list[int] | None = None
83
+ ) -> Mesh:
71
84
  delta = Vector(x, y, z)
85
+ if selection:
86
+ return Mesh(
87
+ vertices=tuple(
88
+ v.translate(delta) if v.id in selection else v.copy()
89
+ for v in self.vertices
90
+ ),
91
+ cells=self.cells,
92
+ )
72
93
  return Mesh(
73
94
  vertices=tuple(v.translate(delta) for v in self.vertices), cells=self.cells
74
95
  )
@@ -105,3 +126,8 @@ class Mesh:
105
126
  vertices=tuple(Vertex(v.x, v.y, v.z, v.id) for v in self.vertices),
106
127
  cells=tuple(Cell(c.vertices, c.type) for c in self.cells),
107
128
  )
129
+
130
+ def select_region(self, region: Shape) -> list[int]:
131
+ return [
132
+ v.id for v in self.vertices if region.contains_point(Point(v.x, v.y, v.z))
133
+ ]
@@ -2,14 +2,13 @@
2
2
  Meshing utilities for use in openfoam
3
3
  """
4
4
 
5
+ import os
5
6
  import shutil
6
7
  import subprocess
7
- import os
8
8
  from pathlib import Path
9
9
  from typing import cast
10
10
 
11
-
12
- from icplot.mesh import Edge, HexCell, Mesh, Patch
11
+ from icplot.geometry.mesh import Edge, HexCell, Mesh, Patch
13
12
 
14
13
  from .foamfile import FoamFile, write_header
15
14
 
@@ -1,11 +1,11 @@
1
1
  from dataclasses import dataclass
2
- from pathlib import Path
3
2
  from functools import cmp_to_key
3
+ from pathlib import Path
4
4
 
5
5
  from icplot.geometry import Point
6
- from icplot.mesh import Vertex, Mesh, get_hex_faces
6
+ from icplot.geometry.mesh import Mesh, Vertex, get_hex_faces
7
7
 
8
- from .foamfile import read_foamfile, FoamFile, write_header
8
+ from .foamfile import FoamFile, read_foamfile, write_header
9
9
 
10
10
 
11
11
  @dataclass(frozen=True)
@@ -65,10 +65,8 @@ class PolymeshPatch:
65
65
 
66
66
  def read_polymesh(path: Path) -> Polymesh:
67
67
 
68
- points_file = read_foamfile(path / "points")
68
+ _ = read_foamfile(path / "points")
69
69
  # faces_file = read_foamfile(path / "faces")
70
- print(points_file)
71
- # print(faces_file)
72
70
  return Polymesh((), (), ())
73
71
 
74
72
 
@@ -1,21 +1,21 @@
1
1
  import numpy as np
2
2
 
3
3
  from icplot.geometry import (
4
- Point,
5
- Quad,
6
4
  Annulus,
7
- Transform,
8
5
  Circle,
9
6
  Cuboid,
10
- Vector,
11
7
  Cylinder,
8
+ Point,
9
+ Quad,
10
+ Shape,
11
+ Transform,
12
+ Vector,
12
13
  )
13
14
 
15
+ from .cell import Cell, HexCell
14
16
  from .mesh import Mesh
17
+ from .operations import close_mesh, map_radial, merge_meshes, mesh_extrude
15
18
  from .vertex import Vertex, find_closest
16
- from .cell import Cell, HexCell
17
-
18
- from .operations import map_radial, close_mesh, merge_meshes, mesh_extrude
19
19
 
20
20
 
21
21
  def mesh_rectangle(rect: Quad, num_width: int = 10, num_height: int = 10) -> Mesh:
@@ -187,6 +187,73 @@ def mesh_cylinder_basic(
187
187
  )
188
188
 
189
189
 
190
+ """
191
+ def _mesh_cylinder_block(radius,
192
+ top_loc,
193
+ bottom_loc,
194
+ boundary_fraction,
195
+ num_radial,
196
+ num_circumferential,
197
+ cell_height,
198
+ top_hole: Hole | None = None,
199
+ bottom_hole: Hole | None = None) -> Mesh:
200
+ length = height - hole_loc.z
201
+ num_cells_in_block = int(num_height*length/height) + 1
202
+ block = mesh_cylinder_basic(Cylinder(diameter=radius*2, length=length),
203
+ boundary_fraction,
204
+ num_radial,
205
+ num_circumferential,
206
+ num_cells_in_block)
207
+ block = block.move_by(0.0, 0.0, hole_loc.z)
208
+ selection = block.select_region(holes[0])
209
+ block = block.move_by(0.0, 0.0, (length/num_cells_in_block)/8.0, selection)
210
+ """
211
+
212
+
213
+ def _mesh_compound_cylinder_with_holes(
214
+ inlet_radius,
215
+ inlet_height,
216
+ radius,
217
+ height,
218
+ boundary_fraction,
219
+ num_circumferential,
220
+ num_radial,
221
+ num_height,
222
+ holes: list[Shape],
223
+ ) -> Mesh:
224
+
225
+ # Mesh the core cylinder in blocks at the hole locations
226
+ hole_loc = holes[0].transform.location
227
+
228
+ length = height - hole_loc.z
229
+ num_cells_in_block = int(num_height * length / height) + 1
230
+ block = mesh_cylinder_basic(
231
+ Cylinder(diameter=radius * 2, length=length),
232
+ boundary_fraction,
233
+ num_radial,
234
+ num_circumferential,
235
+ num_cells_in_block,
236
+ )
237
+ block = block.move_by(0.0, 0.0, hole_loc.z)
238
+ selection = block.select_region(holes[0])
239
+ block = block.move_by(0.0, 0.0, (length / num_cells_in_block) / 8.0, selection)
240
+
241
+ length = hole_loc.z
242
+ num_cells_in_block = int(num_height * length / height) + 1
243
+ block = mesh_cylinder_basic(
244
+ Cylinder(diameter=radius * 2, length=length),
245
+ boundary_fraction,
246
+ num_radial,
247
+ num_circumferential,
248
+ num_cells_in_block,
249
+ )
250
+ block = block.move_by(0.0, 0.0, 0.0)
251
+ selection = block.select_region(holes[0])
252
+ block = block.move_by(0.0, 0.0, -(length / num_cells_in_block) / 8.0, selection)
253
+
254
+ return merge_meshes(block, block)
255
+
256
+
190
257
  def mesh_compound_cylinder(
191
258
  inlet_radius,
192
259
  inlet_height,
@@ -196,8 +263,21 @@ def mesh_compound_cylinder(
196
263
  num_circumferential,
197
264
  num_radial,
198
265
  num_height,
266
+ holes: list[Shape] | None = None,
199
267
  ) -> Mesh:
200
268
 
269
+ if holes:
270
+ return _mesh_compound_cylinder_with_holes(
271
+ inlet_radius,
272
+ inlet_height,
273
+ radius,
274
+ height,
275
+ boundary_fraction,
276
+ num_circumferential,
277
+ num_radial,
278
+ num_height,
279
+ holes,
280
+ )
201
281
  inner = mesh_cylinder_basic(
202
282
  Cylinder(diameter=inlet_radius * 2, length=2 * inlet_height + height),
203
283
  boundary_fraction,
@@ -1,9 +1,12 @@
1
1
  from __future__ import annotations
2
+
2
3
  from dataclasses import dataclass
3
4
 
4
5
  import numpy as np
5
6
 
6
- from icplot.geometry import Point, Vector, get_point_distance
7
+ from icplot.geometry import Point, Vector, get_point_distance, get_rotation_matrix
8
+
9
+ _GLOBAL_Z = np.array([0.0, 0.0, 1.0])
7
10
 
8
11
 
9
12
  @dataclass(frozen=True)
@@ -21,6 +24,9 @@ class Vertex:
21
24
  def from_point(p: Point, id: int = -1) -> Vertex:
22
25
  return Vertex(p.x, p.y, p.z, id)
23
26
 
27
+ def copy(self) -> Vertex:
28
+ return Vertex(self.x, self.y, self.z, self.id)
29
+
24
30
  def as_array(self) -> np.ndarray:
25
31
  return np.array([self.x, self.y, self.z])
26
32
 
@@ -33,6 +39,15 @@ class Vertex:
33
39
  def translate(self, v: Vector) -> Vertex:
34
40
  return Vertex(self.x + v.x, self.y + v.y, self.z + v.z, self.id)
35
41
 
42
+ def scale(self, factor: float) -> Vertex:
43
+ return Vertex(self.x * factor, self.y * factor, self.z * factor, self.id)
44
+
45
+ def rotate_to(self, v: Vector) -> Vertex:
46
+ loc = np.array([self.x, self.y, self.z])
47
+ rot = get_rotation_matrix(_GLOBAL_Z, v.as_array())
48
+ loc_rot = rot.dot(loc)
49
+ return Vertex(loc_rot[0], loc_rot[1], loc_rot[2], self.id)
50
+
36
51
 
37
52
  def find_closest(verts: list[Vertex], point: Point) -> int:
38
53
 
icplot/geometry/shapes.py CHANGED
@@ -5,6 +5,7 @@ dependent work.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
8
+
8
9
  from dataclasses import dataclass
9
10
 
10
11
  from .base import Point, Vector
@@ -19,6 +20,9 @@ class Shape:
19
20
 
20
21
  transform: Transform = Transform()
21
22
 
23
+ def contains_point(self, p: Point) -> bool:
24
+ raise NotImplementedError()
25
+
22
26
 
23
27
  @dataclass(frozen=True)
24
28
  class Circle(Shape):
@@ -75,6 +79,21 @@ class Cuboid(Shape):
75
79
  def translate(self, v: Vector) -> Cuboid:
76
80
  return Cuboid(self.transform.translate(v), self.width, self.height, self.depth)
77
81
 
82
+ def contains_point(self, p: Point) -> bool:
83
+ in_x = (
84
+ p.x >= self.transform.location.x
85
+ and p.x <= self.transform.location.x + self.width
86
+ )
87
+ in_y = (
88
+ p.y >= self.transform.location.y
89
+ and p.y <= self.transform.location.y + self.height
90
+ )
91
+ in_z = (
92
+ p.z >= self.transform.location.z
93
+ and p.z <= self.transform.location.z + self.depth
94
+ )
95
+ return in_x and in_y and in_z
96
+
78
97
  @property
79
98
  def points(self) -> list[Point]:
80
99
 
@@ -110,6 +129,16 @@ class Cylinder(Shape):
110
129
  def end(self) -> Point:
111
130
  return self.transform.get_point_at_normal_offset(self.length)
112
131
 
132
+ def contains_point(self, p: Point) -> bool:
133
+ in_radius = p.get_distance(self.transform.location) <= self.diameter / 2.0
134
+ if not in_radius:
135
+ return False
136
+ in_height = (
137
+ p.z >= self.transform.location.z
138
+ and p.z <= self.transform.location.z + self.length
139
+ )
140
+ return in_height
141
+
113
142
 
114
143
  @dataclass(frozen=True)
115
144
  class Revolution(Shape):
@@ -1,11 +1,11 @@
1
1
  from __future__ import annotations
2
+
2
3
  from dataclasses import dataclass
3
4
 
4
5
  import numpy as np
5
6
 
6
7
  from .base import Point, Vector
7
- from .operations import get_three_point_normal, get_rotation_matrix
8
-
8
+ from .operations import get_rotation_matrix, get_three_point_normal
9
9
 
10
10
  _GLOBAL_Z = np.array([0.0, 0.0, 1.0])
11
11
 
icplot/graph/__init__.py CHANGED
@@ -1,7 +1,6 @@
1
- from .plot import * # NOQA
2
- from .series import * # NOQA
3
1
  from .axis import * # NOQA
4
- from .generator import plot_file
2
+ from .plot import * # NOQA
5
3
  from .plot_group import PlotGroupCreate, PlotGroupPublic
4
+ from .series import * # NOQA
6
5
 
7
- __all__ = ["plot_file", "PlotGroupCreate", "PlotGroupPublic"]
6
+ __all__ = ["PlotGroupCreate", "PlotGroupPublic"]
icplot/graph/plot.py CHANGED
@@ -3,20 +3,11 @@ This module has content for generating plots
3
3
  """
4
4
 
5
5
  import random
6
- from pathlib import Path
7
- import os
8
6
 
9
7
  from pydantic import BaseModel
10
8
 
11
- from iccore.data import Series
12
- from iccore.data.series import convert_units
13
-
14
- from icplot.color import ColorMap, Color
15
- from icplot.graph import mpl, vtk
16
-
17
9
  from .axis import PlotAxis
18
- from .series import LinePlotSeries, ScatterPlotSeries, ImageSeries
19
- from .plot_group import PlotGroupPublic, PlotSeriesPublic
10
+ from .series import ImageSeries, LinePlotSeries, ScatterPlotSeries
20
11
 
21
12
 
22
13
  class Plot(BaseModel, frozen=True):
@@ -52,7 +43,7 @@ class GridPlot(Plot, frozen=True):
52
43
  data: list = []
53
44
 
54
45
  def get_series_indices(self, num_samples: int = 0):
55
- rows = num_samples // self.stride
46
+ rows = max(1, num_samples // self.stride)
56
47
  cols = num_samples // rows
57
48
  len_data = len(self.data)
58
49
 
@@ -78,45 +69,3 @@ class GridPlot(Plot, frozen=True):
78
69
  subplots.append(self.data[index])
79
70
  count += 1
80
71
  return rows, cols, subplots
81
-
82
-
83
- def get_series_colors(cmap: ColorMap, plot: Plot) -> list[Color]:
84
-
85
- count = 0
86
- num_colorable = len([s for s in plot.series if not s.highlight])
87
- colors = []
88
- for s in plot.series:
89
- if not s.highlight:
90
- color = cmap.get_color(count, num_colorable)
91
- count = count + 1
92
- else:
93
- color = s.color
94
- colors.append(color)
95
- return colors
96
-
97
-
98
- def plot_series(
99
- path: Path,
100
- group: PlotGroupPublic,
101
- series: PlotSeriesPublic,
102
- data_series: Series,
103
- ):
104
-
105
- output_path = path / series.measurement.product_name
106
-
107
- os.makedirs(output_path, exist_ok=True)
108
-
109
- # Convert units
110
- if series.measurement.unit != series.unit:
111
- converted_data_series = convert_units(
112
- data_series,
113
- ((series.measurement.name, series.measurement.unit, series.unit),),
114
- )
115
- else:
116
- converted_data_series = data_series
117
-
118
- if "mpl" in group.formats:
119
- mpl.plot(output_path, group, series, converted_data_series)
120
-
121
- if "vtk" in group.formats and data_series.y:
122
- vtk.save(output_path, group, series, converted_data_series)
@@ -2,8 +2,8 @@
2
2
  Module to handle generation of plots
3
3
  """
4
4
 
5
- from datetime import datetime
6
5
  from dataclasses import dataclass
6
+ from datetime import datetime
7
7
 
8
8
  from pydantic import BaseModel
9
9
 
icplot/graph/series.py CHANGED
@@ -4,16 +4,15 @@ A data series in a plot
4
4
 
5
5
  import typing
6
6
 
7
- from pydantic import BaseModel
8
-
9
7
  from iccore.data import (
10
- ProductPublicWithMeasurements,
11
8
  MeasurementPublicWithUnits,
9
+ ProductPublicWithMeasurements,
12
10
  Unit,
13
11
  UnitPublic,
14
12
  )
13
+ from pydantic import BaseModel
15
14
 
16
- from icplot.color import Color
15
+ from icplot.theme.color import Color
17
16
 
18
17
 
19
18
  class PlotSeriesBase(BaseModel, frozen=True):