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.
- {icplot-0.1.2/src/icplot.egg-info → icplot-0.1.4}/PKG-INFO +3 -3
- {icplot-0.1.2 → icplot-0.1.4}/pyproject.toml +2 -2
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/axis.py +5 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/generator.py +6 -5
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/matplotlib.py +70 -13
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/plot.py +5 -3
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/series.py +3 -0
- {icplot-0.1.2 → icplot-0.1.4/src/icplot.egg-info}/PKG-INFO +3 -3
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/requires.txt +1 -1
- icplot-0.1.4/test/test_line_plots.py +63 -0
- icplot-0.1.2/test/test_line_plots.py +0 -29
- {icplot-0.1.2 → icplot-0.1.4}/LICENSE +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/README.md +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/setup.cfg +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/__init__.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/cairo_interface.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/color.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/convert.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/__init__.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/gantt.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/gantt_renderer.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/gantt/pgfgantt.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/geometry.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/graph/__init__.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/image_utils.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/main_cli.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/py.typed +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/tex.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/trace/__init__.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot/trace/trace.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/SOURCES.txt +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/dependency_links.txt +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/entry_points.txt +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/src/icplot.egg-info/top_level.txt +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/test/test_cairo_interface.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/test/test_gantt_chart.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/test/test_image_utils.py +0 -0
- {icplot-0.1.2 → icplot-0.1.4}/test/test_tex_interface.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: icplot
|
|
3
|
-
Version: 0.1.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
49
|
-
|
|
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
|
|
27
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: icplot
|
|
3
|
-
Version: 0.1.
|
|
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.
|
|
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"
|
|
@@ -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
|
|
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
|