icplot 0.0.9__tar.gz → 0.0.10__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.
Files changed (37) hide show
  1. {icplot-0.0.9/src/icplot.egg-info → icplot-0.0.10}/PKG-INFO +2 -2
  2. {icplot-0.0.9 → icplot-0.0.10}/pyproject.toml +2 -2
  3. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/cairo_interface.py +4 -24
  4. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/color.py +13 -11
  5. icplot-0.0.10/src/icplot/gantt/__init__.py +1 -0
  6. icplot-0.0.10/src/icplot/gantt/gantt.py +19 -0
  7. icplot-0.0.10/src/icplot/gantt/gantt_renderer.py +59 -0
  8. icplot-0.0.10/src/icplot/gantt/pgfgantt_interface.py +26 -0
  9. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/image_utils.py +19 -4
  10. icplot-0.0.10/src/icplot/py.typed +0 -0
  11. {icplot-0.0.9 → icplot-0.0.10/src/icplot.egg-info}/PKG-INFO +2 -2
  12. {icplot-0.0.9 → icplot-0.0.10}/src/icplot.egg-info/SOURCES.txt +5 -2
  13. {icplot-0.0.9 → icplot-0.0.10}/src/icplot.egg-info/requires.txt +1 -1
  14. icplot-0.0.10/test/test_cairo_interface.py +29 -0
  15. {icplot-0.0.9 → icplot-0.0.10}/test/test_gantt_chart.py +0 -5
  16. icplot-0.0.9/src/icplot/gantt.py +0 -64
  17. icplot-0.0.9/src/icplot/project_elements.py +0 -4
  18. icplot-0.0.9/test/test_cairo_interface.py +0 -6
  19. {icplot-0.0.9 → icplot-0.0.10}/LICENSE +0 -0
  20. {icplot-0.0.9 → icplot-0.0.10}/README.md +0 -0
  21. {icplot-0.0.9 → icplot-0.0.10}/setup.cfg +0 -0
  22. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/__init__.py +0 -0
  23. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/geometry.py +0 -0
  24. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/graph/__init__.py +0 -0
  25. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/graph/axis.py +0 -0
  26. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/graph/matplotlib.py +2 -2
  27. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/graph/plot.py +0 -0
  28. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/graph/plotter.py +0 -0
  29. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/graph/series.py +0 -0
  30. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/main_cli.py +0 -0
  31. {icplot-0.0.9 → icplot-0.0.10}/src/icplot/tex_interface.py +0 -0
  32. {icplot-0.0.9 → icplot-0.0.10}/src/icplot.egg-info/dependency_links.txt +0 -0
  33. {icplot-0.0.9 → icplot-0.0.10}/src/icplot.egg-info/entry_points.txt +0 -0
  34. {icplot-0.0.9 → icplot-0.0.10}/src/icplot.egg-info/top_level.txt +0 -0
  35. {icplot-0.0.9 → icplot-0.0.10}/test/test_image_utils.py +0 -0
  36. {icplot-0.0.9 → icplot-0.0.10}/test/test_line_plots.py +0 -0
  37. {icplot-0.0.9 → icplot-0.0.10}/test/test_tex_interface.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: icplot
3
- Version: 0.0.9
3
+ Version: 0.0.10
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
@@ -16,7 +16,7 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: wand
18
18
  Requires-Dist: matplotlib
19
- Requires-Dist: iccore==0.0.10
19
+ Requires-Dist: iccore==0.1.0
20
20
  Provides-Extra: test
21
21
  Requires-Dist: pytest; extra == "test"
22
22
  Requires-Dist: pytest-cov; extra == "test"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "icplot"
3
- version = "0.0.9"
3
+ version = "0.0.10"
4
4
  authors = [
5
5
  { name="James Grogan, Irish Centre for High End Computing", email="james.grogan@ichec.ie" },
6
6
  ]
@@ -18,7 +18,7 @@ keywords = ["Publishing", "Technical Reports", "Graphics"]
18
18
 
19
19
  dependencies = ["wand",
20
20
  "matplotlib",
21
- "iccore==0.0.10"]
21
+ "iccore==0.1.0"]
22
22
 
23
23
  [project.urls]
24
24
  Repository = "https://git.ichec.ie/performance/toolshed/icplot"
@@ -1,8 +1,8 @@
1
- import os
2
1
  from pathlib import Path
2
+
3
3
  import cairo
4
4
 
5
- from .geometry import Scene, Rectangle, Color, TextPath
5
+ from .geometry import Scene, Rectangle
6
6
 
7
7
 
8
8
  class CairoInterface:
@@ -52,29 +52,9 @@ class CairoInterface:
52
52
  if item.item_type == "shape":
53
53
  self.draw_shape(cr, item)
54
54
  elif item.item_type == "text":
55
- self.draw_text(cr, text)
55
+ self.draw_text(cr, item)
56
56
 
57
- def draw_svg(self, scene, path):
57
+ def draw_svg(self, scene: Scene, path: Path):
58
58
  with cairo.SVGSurface(path, scene.size[0], scene.size[1]) as surface:
59
59
  cr = cairo.Context(surface)
60
60
  self.draw_scene(cr, scene)
61
-
62
-
63
- if __name__ == "__main__":
64
-
65
- cairo_interface = CairoInterface()
66
-
67
- scene = Scene()
68
-
69
- rect = Rectangle(20, 20)
70
- rect.location = (10, 10)
71
- rect.fill = Color(0.5, 0.5, 1, 0.5)
72
- rect.stroke = Color(0.5, 0.0, 0.0, 0.5)
73
- scene.items.append(rect)
74
-
75
- text = TextPath("Hello World")
76
- text.location = (5, 5)
77
- scene.items.append(text)
78
-
79
- output_path = Path(os.getcwd()) / "output.svg"
80
- cairo_interface.draw_svg(scene, output_path)
@@ -4,26 +4,26 @@ This module handles colors
4
4
 
5
5
  from typing import Callable
6
6
 
7
- from iccore.serialization import Serializable
7
+ from pydantic import BaseModel
8
8
 
9
9
 
10
- class Color(Serializable):
10
+ class Color(BaseModel):
11
11
  """
12
12
  A color class, internal storage is rgba as float.
13
13
  """
14
14
 
15
- def __init__(self, r: float = 0.0, g: float = 0.0, b: float = 0.0, a: float = 1.0):
16
- self.r = r
17
- self.g = g
18
- self.b = b
19
- self.a = a
15
+ r: float = 0.0
16
+ g: float = 0.0
17
+ b: float = 0.0
18
+ a: float = 1.0
20
19
 
21
20
  @staticmethod
22
- def from_list(data: list):
23
- return Color(data[0], data[1], data[2])
21
+ def from_rgba(r: float = 0.0, b: float = 0.0, g: float = 0.0, a: float = 1.0):
22
+ return Color(**{"r": r, "g": g, "b": b, "a": a})
24
23
 
25
- def serialize(self):
26
- return {"r": self.r, "g": self.g, "b": self.b, "a": self.a}
24
+ @staticmethod
25
+ def from_list(data: list):
26
+ return Color(**{"r": data[0], "g": data[1], "b": data[2]})
27
27
 
28
28
  def as_list(self) -> list:
29
29
  return [self.r, self.g, self.b]
@@ -31,6 +31,8 @@ class Color(Serializable):
31
31
  def is_black(self) -> bool:
32
32
  return self.r == 0.0 and self.g == 0.0 and self.b == 0.0 and self.a == 1.0
33
33
 
34
+ def serialize(self) -> str:
35
+ return f"r: {self.r}, g: {self.g}, b: {self.b}, a: {self.a}"
34
36
 
35
37
  class ColorMap:
36
38
  """
@@ -0,0 +1 @@
1
+ from .gantt import * # NOQA
@@ -0,0 +1,19 @@
1
+ from datetime import datetime
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from iccore.project import Milestone
6
+
7
+ from icplot.color import Color
8
+
9
+
10
+ class GanttChart(BaseModel):
11
+
12
+ milestones: list[Milestone] = []
13
+ title: str = ""
14
+ start_date: datetime | None = None
15
+ end_date: datetime | None = None
16
+ bar_max_height: float = 0.1
17
+ height: int = 100
18
+ width: int = 500
19
+ bar_color: Color = Color.from_rgba(0.7, 0, 0)
@@ -0,0 +1,59 @@
1
+ from iccore.project import Milestone
2
+ from icplot.geometry import Scene, Rectangle
3
+
4
+ from .gantt import GanttChart
5
+
6
+
7
+ class GanttRenderer:
8
+
9
+ def _add_milestone(
10
+ self, gantt: GanttChart, scene: Scene, milestone: Milestone, chart_range, yloc
11
+ ):
12
+ # chart_delta = chart_range[1] - chart_range[0]
13
+ chart_delta = 0
14
+ start_delta = milestone.start_date - chart_range[0]
15
+ # milestone_delta = milestone.due_date - milestone.start_date
16
+ milestone_delta = 0
17
+
18
+ start_frac = float(start_delta / chart_delta)
19
+ milestone_frac = float(milestone_delta / chart_delta)
20
+
21
+ w = milestone_frac * gantt.width
22
+ h = gantt.bar_max_height * gantt.height
23
+ x = start_frac * gantt.width
24
+ y = yloc
25
+
26
+ rect = Rectangle(w, h)
27
+ rect.location = (x, y)
28
+ rect.fill = gantt.bar_color
29
+ scene.items.append(rect)
30
+
31
+ def _add_milestones(self, gantt: GanttChart, scene: Scene):
32
+
33
+ if not gantt.milestones:
34
+ return
35
+
36
+ milestones = gantt.milestones
37
+ # milestones.sort(key=lambda x: x.start_date, reverse=True)
38
+
39
+ start_date = gantt.start_date
40
+ end_date = gantt.end_date
41
+ if not start_date:
42
+ start_date = milestones[0].start_date
43
+
44
+ # if not end_date:
45
+ # end_date = max(m.due_date for m in milestones)
46
+
47
+ chart_range = (start_date, end_date)
48
+ yloc = 0.0
49
+ bar_height = gantt.bar_max_height * gantt.height
50
+ for milestone in milestones:
51
+ self._add_milestone(gantt, scene, milestone, chart_range, yloc)
52
+ yloc += bar_height
53
+
54
+ def render(self, gantt: GanttChart) -> Scene:
55
+ scene = Scene()
56
+
57
+ self._add_milestones(gantt, scene)
58
+
59
+ return scene
@@ -0,0 +1,26 @@
1
+ from pathlib import Path
2
+
3
+ from .gantt import GanttChart
4
+
5
+
6
+ class PgfGanttRenderer:
7
+
8
+ def __init__(self):
9
+ self.template: str = ""
10
+
11
+ def _load_template(self):
12
+ if self.template:
13
+ return
14
+
15
+ with open(Path(__file__).parent / "pgfgantt.tex", "r", encoding="utf-8") as f:
16
+ self.template = f.read()
17
+
18
+ def render(self, gantt: GanttChart) -> str:
19
+
20
+ output = self.template
21
+
22
+ if gantt.title:
23
+ title_str = f"\\title{{{gantt.title}}}"
24
+ output.replace("%%TITLE%%", title_str)
25
+
26
+ return output
@@ -1,3 +1,8 @@
1
+ """
2
+ This module has functions for converting between image
3
+ formats
4
+ """
5
+
1
6
  import logging
2
7
  from pathlib import Path
3
8
 
@@ -12,14 +17,16 @@ logger = logging.getLogger(__name__)
12
17
  def _get_out_filename(source: Path, target: Path | None, extension: str) -> Path:
13
18
  if target:
14
19
  return target
15
- else:
16
- return source.parent / f"{source.stem}.{extension}"
20
+ return source.parent / f"{source.stem}.{extension}"
17
21
 
18
22
 
19
- def pdf_to_png(source: Path, target: Path | None = None):
23
+ def pdf_to_png(source: Path, target: Path | None = None, resolution: int = 300):
24
+ """
25
+ Convert a pdf to png with white background
26
+ """
20
27
 
21
28
  outfile = _get_out_filename(source, target, "png")
22
- with Image(filename=source, resolution=300) as img:
29
+ with Image(filename=source, resolution=resolution) as img:
23
30
  img.format = "png"
24
31
  img.background_color = Color("white")
25
32
  img.alpha_channel = "remove"
@@ -27,10 +34,18 @@ def pdf_to_png(source: Path, target: Path | None = None):
27
34
 
28
35
 
29
36
  def svg_to_png(source: Path, target: Path | None = None):
37
+ """
38
+ Convert an svg to png
39
+ """
40
+
30
41
  outfile = _get_out_filename(source, target, "png")
31
42
  cairosvg.svg2png(url=str(source), write_to=str(outfile))
32
43
 
33
44
 
34
45
  def svg_to_pdf(source: Path, target: Path | None = None):
46
+ """
47
+ Convert an svg to pdf
48
+ """
49
+
35
50
  outfile = _get_out_filename(source, target, "pdf")
36
51
  cairosvg.svg2pdf(url=str(source), write_to=str(outfile))
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: icplot
3
- Version: 0.0.9
3
+ Version: 0.0.10
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
@@ -16,7 +16,7 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: wand
18
18
  Requires-Dist: matplotlib
19
- Requires-Dist: iccore==0.0.10
19
+ Requires-Dist: iccore==0.1.0
20
20
  Provides-Extra: test
21
21
  Requires-Dist: pytest; extra == "test"
22
22
  Requires-Dist: pytest-cov; extra == "test"
@@ -5,11 +5,10 @@ setup.cfg
5
5
  src/icplot/__init__.py
6
6
  src/icplot/cairo_interface.py
7
7
  src/icplot/color.py
8
- src/icplot/gantt.py
9
8
  src/icplot/geometry.py
10
9
  src/icplot/image_utils.py
11
10
  src/icplot/main_cli.py
12
- src/icplot/project_elements.py
11
+ src/icplot/py.typed
13
12
  src/icplot/tex_interface.py
14
13
  src/icplot.egg-info/PKG-INFO
15
14
  src/icplot.egg-info/SOURCES.txt
@@ -17,6 +16,10 @@ src/icplot.egg-info/dependency_links.txt
17
16
  src/icplot.egg-info/entry_points.txt
18
17
  src/icplot.egg-info/requires.txt
19
18
  src/icplot.egg-info/top_level.txt
19
+ src/icplot/gantt/__init__.py
20
+ src/icplot/gantt/gantt.py
21
+ src/icplot/gantt/gantt_renderer.py
22
+ src/icplot/gantt/pgfgantt_interface.py
20
23
  src/icplot/graph/__init__.py
21
24
  src/icplot/graph/axis.py
22
25
  src/icplot/graph/matplotlib.py
@@ -1,6 +1,6 @@
1
1
  wand
2
2
  matplotlib
3
- iccore==0.0.10
3
+ iccore==0.1.0
4
4
 
5
5
  [cairo]
6
6
  pycairo
@@ -0,0 +1,29 @@
1
+ from pathlib import Path
2
+ import os
3
+ import shutil
4
+
5
+ from icplot.cairo_interface import CairoInterface
6
+ from icplot.geometry import Scene, Rectangle, TextPath
7
+ from icplot.color import Color
8
+
9
+
10
+ def test_cairo_interface():
11
+
12
+ cairo_interface = CairoInterface()
13
+ scene = Scene()
14
+
15
+ rect = Rectangle(20, 20)
16
+ rect.location = (10, 10)
17
+ rect.fill = Color.from_rgba(0.5, 0.5, 1, 0.5)
18
+ rect.stroke = Color.from_rgba(0.5, 0.0, 0.0, 0.5)
19
+ scene.items.append(rect)
20
+
21
+ text = TextPath("Hello World")
22
+ text.location = (5, 5)
23
+ scene.items.append(text)
24
+
25
+ output_dir = Path(os.getcwd()) / "test_cairo_interface"
26
+ os.makedirs(output_dir, exist_ok=True)
27
+ cairo_interface.draw_svg(scene, output_dir / "output.svg")
28
+ shutil.rmtree(output_dir)
29
+
@@ -24,8 +24,3 @@ def test_gantt_chart():
24
24
  gantt = GanttChart()
25
25
  gantt.milestones = [milestone0, milestone1]
26
26
 
27
- output_path = Path(os.getcwd()) / "gantt.svg"
28
-
29
- gantt.plot(output_path)
30
-
31
- output_path.unlink()
@@ -1,64 +0,0 @@
1
- from pathlib import Path
2
- from .cairo_interface import CairoInterface
3
- from .geometry import Scene, Color, Rectangle
4
-
5
-
6
- class GanttChart:
7
-
8
- def __init__(self):
9
- self.milestones = []
10
- self.start_date = None
11
- self.end_date = None
12
- self.milestone_bar_max_height = 0.1
13
- self.height = 100
14
- self.width = 500
15
- self.milestone_color = Color(0.7, 0, 0)
16
-
17
- def _add_milestone(self, scene, milestone, chart_range, yloc):
18
- chart_delta = chart_range[1] - chart_range[0]
19
- start_delta = milestone.start_date - chart_range[0]
20
- milestone_delta = milestone.due_date - milestone.start_date
21
-
22
- start_frac = float(start_delta / chart_delta)
23
- milestone_frac = float(milestone_delta / chart_delta)
24
-
25
- w = milestone_frac * self.width
26
- h = self.milestone_bar_max_height * self.height
27
- x = start_frac * self.width
28
- y = yloc
29
-
30
- rect = Rectangle(w, h)
31
- rect.location = (x, y)
32
- rect.fill = self.milestone_color
33
- scene.items.append(rect)
34
-
35
- def _add_milestones(self, scene):
36
-
37
- if not self.milestones:
38
- return
39
-
40
- milestones = self.milestones
41
- milestones.sort(key=lambda x: x.start_date, reverse=True)
42
-
43
- start_date = self.start_date
44
- end_date = self.end_date
45
- if not start_date:
46
- start_date = milestones[0].start_date
47
-
48
- if not end_date:
49
- end_date = max(m.due_date for m in milestones)
50
-
51
- chart_range = (start_date, end_date)
52
- yloc = 0
53
- bar_height = self.milestone_bar_max_height * self.height
54
- for milestone in milestones:
55
- self._add_milestone(scene, milestone, chart_range, yloc)
56
- yloc += bar_height
57
-
58
- def plot(self, path: Path):
59
- scene = Scene()
60
-
61
- self._add_milestones(scene)
62
-
63
- renderer = CairoInterface()
64
- renderer.draw_svg(scene, path)
@@ -1,4 +0,0 @@
1
- class GitlabUser:
2
-
3
- def __init__(self):
4
- self.name = ""
@@ -1,6 +0,0 @@
1
- from icplot.cairo_interface import CairoInterface
2
-
3
-
4
- def test_cairo_interface():
5
-
6
- cairo_interface = CairoInterface()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -75,11 +75,11 @@ class MatplotlibPlotter(Plotter):
75
75
 
76
76
  fig, ax = plt.subplots()
77
77
 
78
- self.set_decorations(ax, plot)
79
-
80
78
  for series in plot.series:
81
79
  self.plot_series(ax, series)
82
80
 
81
+ self.set_decorations(ax, plot)
82
+
83
83
  self.render(fig, path)
84
84
 
85
85
  def plot_grid(self, plot: GridPlot, path: Path | None = None, num_samples: int = 0):
File without changes
File without changes
File without changes
File without changes