icplot 0.1.2__tar.gz → 0.1.4__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 (38) hide show
  1. {icplot-0.1.2/src/icplot.egg-info → icplot-0.1.4}/PKG-INFO +3 -3
  2. {icplot-0.1.2 → icplot-0.1.4}/pyproject.toml +2 -2
  3. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/axis.py +5 -0
  4. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/generator.py +6 -5
  5. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/matplotlib.py +70 -13
  6. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/plot.py +5 -3
  7. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/series.py +3 -0
  8. {icplot-0.1.2 → icplot-0.1.4/src/icplot.egg-info}/PKG-INFO +3 -3
  9. {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/requires.txt +1 -1
  10. icplot-0.1.4/test/test_line_plots.py +63 -0
  11. icplot-0.1.2/test/test_line_plots.py +0 -29
  12. {icplot-0.1.2 → icplot-0.1.4}/LICENSE +0 -0
  13. {icplot-0.1.2 → icplot-0.1.4}/README.md +0 -0
  14. {icplot-0.1.2 → icplot-0.1.4}/setup.cfg +0 -0
  15. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/__init__.py +0 -0
  16. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/cairo_interface.py +0 -0
  17. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/color.py +0 -0
  18. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/convert.py +0 -0
  19. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/__init__.py +0 -0
  20. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/gantt.py +0 -0
  21. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/gantt_renderer.py +0 -0
  22. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/pgfgantt.py +0 -0
  23. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/geometry.py +0 -0
  24. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/__init__.py +0 -0
  25. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/image_utils.py +0 -0
  26. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/main_cli.py +0 -0
  27. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/py.typed +0 -0
  28. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/tex.py +0 -0
  29. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/trace/__init__.py +0 -0
  30. {icplot-0.1.2 → icplot-0.1.4}/src/icplot/trace/trace.py +0 -0
  31. {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/SOURCES.txt +0 -0
  32. {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/dependency_links.txt +0 -0
  33. {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/entry_points.txt +0 -0
  34. {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/top_level.txt +0 -0
  35. {icplot-0.1.2 → icplot-0.1.4}/test/test_cairo_interface.py +0 -0
  36. {icplot-0.1.2 → icplot-0.1.4}/test/test_gantt_chart.py +0 -0
  37. {icplot-0.1.2 → icplot-0.1.4}/test/test_image_utils.py +0 -0
  38. {icplot-0.1.2 → icplot-0.1.4}/test/test_tex_interface.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: icplot
3
- Version: 0.1.2
3
+ Version: 0.1.4
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.1.8
19
+ Requires-Dist: iccore==0.1.9
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.1.2"
3
+ version = "0.1.4"
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.1.8"]
21
+ "iccore==0.1.9"]
22
22
 
23
23
  [project.urls]
24
24
  Repository = "https://git.ichec.ie/performance/toolshed/icplot"
@@ -29,6 +29,11 @@ class PlotAxis(BaseModel, frozen=True):
29
29
 
30
30
  label: str = ""
31
31
  ticks: Range | None = None
32
+ scale: str = "linear"
33
+ text_fontsize: int = 10
34
+ tick_fontsize: int = 10
35
+ max_ticks: int = 0
36
+ limits: dict = {}
32
37
 
33
38
  @property
34
39
  def resolved_ticks(self) -> list:
@@ -45,23 +45,24 @@ def make_plots(
45
45
 
46
46
  # Use a user-provided 'point_func' to get the series 'x, y' points
47
47
  # from the results, given a 'x_attr, y_attr' pair
48
- points = [point_func(r, config.x_attr, y_attr) for r in label_results].sort(
49
- key=lambda x: x[0]
48
+ all_points = [point_func(r, config.x_attr, y_attr) for r in label_results]
49
+ points = sorted(
50
+ [x for x in all_points if x is not None], key=lambda x: x[0]
50
51
  )
51
- x, y = zip(*points)
52
+ x, y = [list(xy) for xy in zip(*points)]
52
53
 
53
54
  if label in config.colormap:
54
55
  series.append(
55
56
  LinePlotSeries(
56
57
  x=x,
57
58
  y=y,
58
- label=label,
59
+ label=str(label),
59
60
  highlight=True,
60
61
  color=config.colormap[label],
61
62
  )
62
63
  )
63
64
  else:
64
- series.append(LinePlotSeries(x=x, y=y, label=label))
65
+ series.append(LinePlotSeries(x=x, y=y, label=str(label)))
65
66
  plots.append(plot_template.copy(update={"name": y_attr, "series": series}))
66
67
  return plots
67
68
 
@@ -8,10 +8,12 @@ import matplotlib as mpl # NOQA
8
8
  default_backend = mpl.get_backend()
9
9
  mpl.use("Agg")
10
10
  import matplotlib.pyplot as plt # NOQA
11
+ from matplotlib.ticker import FuncFormatter # NOQA
11
12
 
12
13
  from icplot.color import ColorMap, Color # NOQA
13
14
  from .series import PlotSeries, LinePlotSeries, ScatterPlotSeries, ImageSeries # NOQA
14
15
  from .plot import Plot, GridPlot, get_series_colors # NOQA
16
+ from .axis import PlotAxis # NOQA
15
17
 
16
18
 
17
19
  class MatplotlibColorMap(ColorMap):
@@ -23,21 +25,74 @@ class MatplotlibColorMap(ColorMap):
23
25
  super().__init__(label, mpl.colormaps[label])
24
26
 
25
27
 
26
- def _set_decorations(axs, plot: Plot):
27
- ax = axs[0]
28
+ def str_exact_values_formatter(x, pos):
29
+ """
30
+ When using log scale, axis ticks come out as scientific notation by default,
31
+ then when using plain formatter values less than 1 come out as 0. A way around
32
+ this is this custom formatter.
33
+ """
34
+ if x.is_integer():
35
+ return str(int(x))
36
+ else:
37
+ return str(x)
38
+
39
+
40
+ def _set_legend_decorations(axs, plot):
28
41
  if plot.legend.lower() != "none":
29
- ax.legend(loc=plot.legend)
30
- if plot.x_axis.label:
31
- ax.set_xlabel(plot.x_axis.label)
32
- for idx, y_axis in enumerate(plot.y_axes):
42
+ if len(axs) == 1:
43
+ axs[0].legend(loc=plot.legend, frameon=False, fontsize=plot.legend_fontsize)
44
+ else:
45
+ axs[0].legend(
46
+ loc="upper left", frameon=False, fontsize=plot.legend_fontsize
47
+ )
48
+ axs[1].legend(
49
+ loc="upper right", frameon=False, fontsize=plot.legend_fontsize
50
+ )
51
+
52
+
53
+ def _set_x_axis_decorations(x_axis: PlotAxis, ax):
54
+ ax.set_yscale(x_axis.scale)
55
+ ax.tick_params(axis="x", labelsize=x_axis.tick_fontsize)
56
+ if x_axis.label:
57
+ ax.set_xlabel(x_axis.label, fontsize=x_axis.text_fontsize)
58
+ if x_axis.ticks:
59
+ ax.set_xticks(x_axis.resolved_ticks)
60
+ if x_axis.max_ticks:
61
+ ax.xaxis.set_major_locator(plt.MaxNLocator(x_axis.max_ticks))
62
+ for key, item in x_axis.limits.items():
63
+ if key == "left" or key == "xmin":
64
+ ax.set_xlim(xmin=item)
65
+ elif key == "right" or key == "xmax":
66
+ ax.set_xlim(xmax=item)
67
+
68
+
69
+ def _set_y_axes_decorations(y_axes: list[PlotAxis], axs):
70
+ for idx, y_axis in enumerate(y_axes):
71
+ axs[idx].set_yscale(y_axis.scale)
72
+ axs[idx].tick_params(axis="y", labelsize=y_axis.tick_fontsize)
73
+ if y_axis.scale == "log":
74
+ formatter = FuncFormatter(str_exact_values_formatter)
75
+ axs[idx].yaxis.set_major_formatter(formatter)
33
76
  if y_axis.label:
34
- axs[idx].set_ylabel(y_axis.label)
77
+ axs[idx].set_ylabel(y_axis.label, fontsize=y_axis.text_fontsize)
35
78
  if y_axis.ticks:
36
79
  axs[idx].set_yticks(y_axis.resolved_ticks)
37
- if plot.x_axis.ticks:
38
- ax.set_xticks(plot.x_axis.resolved_ticks)
80
+ if y_axis.max_ticks:
81
+ axs[idx].yaxis.set_major_locator(plt.MaxNLocator(y_axis.max_ticks))
82
+ for key, item in y_axis.limits.items():
83
+ if key == "bottom" or key == "ymin":
84
+ axs[idx].set_ylim(ymin=item)
85
+ elif key == "top" or key == "ymax":
86
+ axs[idx].set_ylim(ymax=item)
87
+
88
+
89
+ def _set_decorations(axs, plot: Plot):
90
+ _set_legend_decorations(axs, plot)
91
+ _set_x_axis_decorations(plot.x_axis, axs[0])
92
+ _set_y_axes_decorations(plot.y_axes, axs)
39
93
  if plot.title:
40
- ax.set_title(plot.title)
94
+ axs[0].set_title(plot.title, fontsize=plot.title_fontsize)
95
+ axs[0].set_aspect(plot.aspect)
41
96
 
42
97
 
43
98
  def _plot_line(axs, series: LinePlotSeries, color: Color | None):
@@ -47,13 +102,15 @@ def _plot_line(axs, series: LinePlotSeries, color: Color | None):
47
102
  ax = axs[1]
48
103
 
49
104
  if color:
50
- render_color: list | None = series.color.as_list()
105
+ render_color: list | None = color.as_list()
51
106
  else:
52
107
  render_color = None
53
-
54
- ax.plot(
108
+ ax.errorbar(
55
109
  series.x,
56
110
  series.y,
111
+ xerr=series.x_err,
112
+ yerr=series.y_err,
113
+ capsize=series.err_capsize,
57
114
  label=series.label,
58
115
  color=render_color,
59
116
  marker=series.marker,
@@ -18,13 +18,15 @@ class Plot(BaseModel, frozen=True):
18
18
  """
19
19
 
20
20
  title: str = ""
21
- legend_label: str = ""
22
21
  name: str = ""
23
22
  x_axis: PlotAxis = PlotAxis()
24
23
  y_axes: list[PlotAxis] = [PlotAxis()]
25
24
  plot_type: str = ""
26
25
  series: list[PlotSeries] = []
27
26
  legend: str = "none"
27
+ aspect: str = "auto"
28
+ legend_fontsize: int = 10
29
+ title_fontsize: int = 10
28
30
 
29
31
 
30
32
  class GridPlot(Plot, frozen=True):
@@ -65,7 +67,7 @@ class GridPlot(Plot, frozen=True):
65
67
  return rows, cols, subplots
66
68
 
67
69
 
68
- def get_series_colors(cmap: ColorMap, plot: Plot) -> list[Color | None]:
70
+ def get_series_colors(cmap: ColorMap, plot: Plot) -> list[Color]:
69
71
 
70
72
  count = 0
71
73
  num_colorable = len([s for s in plot.series if not s.highlight])
@@ -75,6 +77,6 @@ def get_series_colors(cmap: ColorMap, plot: Plot) -> list[Color | None]:
75
77
  color = cmap.get_color(count, num_colorable)
76
78
  count = count + 1
77
79
  else:
78
- color = None
80
+ color = s.color
79
81
  colors.append(color)
80
82
  return colors
@@ -41,6 +41,9 @@ class LinePlotSeries(PlotSeries, frozen=True):
41
41
 
42
42
  x: list
43
43
  y: list
44
+ x_err: float | list[float] | list[list[float]] | None = None
45
+ y_err: float | list[float] | list[list[float]] | None = None
46
+ err_capsize: float = 2.0
44
47
  marker: str = "o"
45
48
  series_type: str = "line"
46
49
  drawstyle: str = "default"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: icplot
3
- Version: 0.1.2
3
+ Version: 0.1.4
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.1.8
19
+ Requires-Dist: iccore==0.1.9
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
  wand
2
2
  matplotlib
3
- iccore==0.1.8
3
+ iccore==0.1.9
4
4
 
5
5
  [cairo]
6
6
  pycairo
@@ -0,0 +1,63 @@
1
+ from pathlib import Path
2
+
3
+ from icplot.graph import Plot, LinePlotSeries, PlotAxis, Range
4
+ from icplot.graph import matplotlib
5
+
6
+
7
+ def test_line_plot():
8
+
9
+ data = [([0, 5, 10], [1, 2, 3]), ([0, 5, 10], [3, 6, 9]), ([0, 5, 10], [4, 8, 12])]
10
+
11
+ series = []
12
+ for idx, [x, y] in enumerate(data):
13
+ series_config = {"label": f"Series {idx}", "x": x, "y": y}
14
+ series.append(LinePlotSeries(**series_config))
15
+
16
+ x_axis_config = {
17
+ "label": "x_axis",
18
+ "ticks": Range(lower=0, upper=11, step=2),
19
+ "scale": "linear",
20
+ "text_fontsize": 10,
21
+ "tick_fontsize": 10,
22
+ "max_ticks": 0,
23
+ "limits": {"bottom": 0},
24
+ }
25
+ x_axis = PlotAxis(**x_axis_config)
26
+ y_axis_config = {
27
+ "label": "y_axis",
28
+ "ticks": Range(lower=0, upper=16, step=5),
29
+ "scale": "linear",
30
+ "text_fontsize": 10,
31
+ "tick_fontsize": 10,
32
+ "max_ticks": 0,
33
+ "limits": {"upper": 15},
34
+ }
35
+ y_axis = PlotAxis(**y_axis_config)
36
+ plot_config = {
37
+ "title": "Title",
38
+ "name": "test",
39
+ "x_axis": x_axis,
40
+ "y_axes": [y_axis],
41
+ "plot_type": "",
42
+ "series": series,
43
+ "legend": "upper left",
44
+ "aspect": "auto",
45
+ "legend_fontsize": 10,
46
+ "title_fontsize": 10,
47
+ }
48
+
49
+ plot = Plot(**plot_config)
50
+
51
+ output_path = Path() / "output.svg"
52
+ matplotlib.render(plot, output_path)
53
+
54
+ assert output_path.exists()
55
+ output_path.unlink()
56
+
57
+
58
+ def test_error_line_plot():
59
+ pass
60
+
61
+
62
+ def test_twin_line_plot():
63
+ pass
@@ -1,29 +0,0 @@
1
- from pathlib import Path
2
-
3
- from icplot.graph import Plot, LinePlotSeries
4
- from icplot.graph import matplotlib
5
-
6
-
7
- def test_line_plot():
8
-
9
- data = [([0, 5, 10], [1, 2, 3]), ([0, 5, 10], [3, 6, 9]), ([0, 5, 10], [4, 8, 12])]
10
-
11
- series = []
12
- for idx, [x, y] in enumerate(data):
13
- series_config = {"label": f"Series {idx}", "x": x, "y": y}
14
- series.append(LinePlotSeries(**series_config))
15
-
16
- plot_config = {
17
- "title": "test",
18
- "legend_label": "test_legend",
19
- "series": series,
20
- "x_axis": {"label": "test_x", "ticks": {"lower": 0, "upper": 10, "step": 5}},
21
- }
22
-
23
- plot = Plot(**plot_config)
24
-
25
- output_path = Path() / "output.svg"
26
- matplotlib.render(plot, output_path)
27
-
28
- assert output_path.exists()
29
- output_path.unlink()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes