icplot 0.1.3__tar.gz → 0.1.5__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.3/src/icplot.egg-info → icplot-0.1.5}/PKG-INFO +13 -5
- {icplot-0.1.3 → icplot-0.1.5}/README.md +8 -1
- {icplot-0.1.3 → icplot-0.1.5}/pyproject.toml +3 -3
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/convert.py +13 -2
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/graph/axis.py +4 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/graph/matplotlib.py +68 -16
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/graph/plot.py +5 -3
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/graph/series.py +3 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/main_cli.py +12 -1
- icplot-0.1.5/src/icplot/mermaid.py +39 -0
- {icplot-0.1.3 → icplot-0.1.5/src/icplot.egg-info}/PKG-INFO +13 -5
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot.egg-info/SOURCES.txt +3 -1
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot.egg-info/requires.txt +1 -1
- icplot-0.1.5/test/test_line_plots.py +63 -0
- icplot-0.1.5/test/test_mermaid.py +24 -0
- icplot-0.1.3/test/test_tex_interface.py → icplot-0.1.5/test/test_tex.py +1 -1
- icplot-0.1.3/test/test_line_plots.py +0 -29
- {icplot-0.1.3 → icplot-0.1.5}/LICENSE +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/setup.cfg +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/__init__.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/cairo_interface.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/color.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/gantt/__init__.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/gantt/gantt.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/gantt/gantt_renderer.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/gantt/pgfgantt.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/geometry.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/graph/__init__.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/graph/generator.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/image_utils.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/py.typed +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/tex.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/trace/__init__.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot/trace/trace.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot.egg-info/dependency_links.txt +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot.egg-info/entry_points.txt +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/src/icplot.egg-info/top_level.txt +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/test/test_cairo_interface.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/test/test_gantt_chart.py +0 -0
- {icplot-0.1.3 → icplot-0.1.5}/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.5
|
|
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,12 @@ 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: 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"
|
|
@@ -28,6 +28,7 @@ Requires-Dist: pylint; extra == "test"
|
|
|
28
28
|
Provides-Extra: cairo
|
|
29
29
|
Requires-Dist: pycairo; extra == "cairo"
|
|
30
30
|
Requires-Dist: CairoSVG; extra == "cairo"
|
|
31
|
+
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
# icplot
|
|
33
34
|
|
|
@@ -38,8 +39,9 @@ This is a library used at [The Irish Centre for High End Computing (ICHEC)](http
|
|
|
38
39
|
The project has support for:
|
|
39
40
|
|
|
40
41
|
* Coverting image formats between pdf, svg and png
|
|
41
|
-
* Building pdf output from tex files, including tikz.
|
|
42
|
+
* Building pdf and png output from tex files, including tikz.
|
|
42
43
|
* Generating plots based on a serializable data model to support reproducible research
|
|
44
|
+
* Generating mermaid plots
|
|
43
45
|
|
|
44
46
|
To covert between image formats you can do:
|
|
45
47
|
|
|
@@ -53,6 +55,12 @@ To render a Tex tikz image as pdf and png you can do:
|
|
|
53
55
|
icplot convert --source my_tikz.tex
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
To render a Mermaid plot as png you can do:
|
|
59
|
+
|
|
60
|
+
``` shell
|
|
61
|
+
icplot convert --source my_mermaid.mmd
|
|
62
|
+
```
|
|
63
|
+
|
|
56
64
|
To generate a plot or collection of plots from a yaml description you can do:
|
|
57
65
|
|
|
58
66
|
``` 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
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "icplot"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.5"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="James Grogan, Irish Centre for High End Computing", email="james.grogan@ichec.ie" },
|
|
6
6
|
]
|
|
7
7
|
description = "Utilities for generating plots and graphics for technical reports."
|
|
8
8
|
readme = "README.md"
|
|
9
|
-
requires-python = ">=3.
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
10
|
classifiers = [
|
|
11
11
|
"Development Status :: 3 - Alpha",
|
|
12
12
|
"Programming Language :: Python :: 3",
|
|
@@ -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"
|
|
@@ -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")
|
|
@@ -30,6 +30,10 @@ class PlotAxis(BaseModel, frozen=True):
|
|
|
30
30
|
label: str = ""
|
|
31
31
|
ticks: Range | None = None
|
|
32
32
|
scale: str = "linear"
|
|
33
|
+
text_fontsize: int = 10
|
|
34
|
+
tick_fontsize: int = 10
|
|
35
|
+
max_ticks: int = 0
|
|
36
|
+
limits: dict = {}
|
|
33
37
|
|
|
34
38
|
@property
|
|
35
39
|
def resolved_ticks(self) -> list:
|
|
@@ -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,26 +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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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):
|
|
37
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)
|
|
38
76
|
if y_axis.label:
|
|
39
|
-
axs[idx].set_ylabel(y_axis.label)
|
|
77
|
+
axs[idx].set_ylabel(y_axis.label, fontsize=y_axis.text_fontsize)
|
|
40
78
|
if y_axis.ticks:
|
|
41
79
|
axs[idx].set_yticks(y_axis.resolved_ticks)
|
|
42
|
-
|
|
43
|
-
|
|
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)
|
|
44
93
|
if plot.title:
|
|
45
|
-
|
|
94
|
+
axs[0].set_title(plot.title, fontsize=plot.title_fontsize)
|
|
95
|
+
axs[0].set_aspect(plot.aspect)
|
|
46
96
|
|
|
47
97
|
|
|
48
98
|
def _plot_line(axs, series: LinePlotSeries, color: Color | None):
|
|
@@ -55,10 +105,12 @@ def _plot_line(axs, series: LinePlotSeries, color: Color | None):
|
|
|
55
105
|
render_color: list | None = color.as_list()
|
|
56
106
|
else:
|
|
57
107
|
render_color = None
|
|
58
|
-
|
|
59
|
-
ax.plot(
|
|
108
|
+
ax.errorbar(
|
|
60
109
|
series.x,
|
|
61
110
|
series.y,
|
|
111
|
+
xerr=series.x_err,
|
|
112
|
+
yerr=series.y_err,
|
|
113
|
+
capsize=series.err_capsize,
|
|
62
114
|
label=series.label,
|
|
63
115
|
color=render_color,
|
|
64
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"
|
|
@@ -20,7 +20,12 @@ def convert_cli(args):
|
|
|
20
20
|
else:
|
|
21
21
|
target = None
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
if args.extra_config:
|
|
24
|
+
extra_config = Path(args.extra_config).resolve()
|
|
25
|
+
else:
|
|
26
|
+
extra_config = None
|
|
27
|
+
|
|
28
|
+
icplot.convert(args.source.resolve(), target, args.buid_dir.resolve(), extra_config)
|
|
24
29
|
|
|
25
30
|
|
|
26
31
|
def plot_cli(args):
|
|
@@ -57,6 +62,12 @@ def main_cli():
|
|
|
57
62
|
default=Path(os.getcwd()) / "_build/tikz",
|
|
58
63
|
help="Path for build output",
|
|
59
64
|
)
|
|
65
|
+
convert_parser.add_argument(
|
|
66
|
+
"--extra_config",
|
|
67
|
+
type=str,
|
|
68
|
+
default="",
|
|
69
|
+
help="Extra config for third party tooling, e.g. puppeteer for mermaid",
|
|
70
|
+
)
|
|
60
71
|
convert_parser.set_defaults(func=convert_cli)
|
|
61
72
|
|
|
62
73
|
plot_parser = subparsers.add_parser("plot")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Interface for generating mermaid plots.
|
|
3
|
+
|
|
4
|
+
Mermaid must already be set up on the system, eg. via the npm ecosystem.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import subprocess
|
|
8
|
+
import shutil
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def has_mermaid() -> bool:
|
|
18
|
+
"""
|
|
19
|
+
True if the mermaid cli is found in the environment
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
return bool(shutil.which("mmdc"))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def convert(input_path: Path, work_dir: Path, browser_config: Path | None = None):
|
|
26
|
+
|
|
27
|
+
if not has_mermaid():
|
|
28
|
+
raise RuntimeError("Mermaid CLI 'mmdc' not found in path.")
|
|
29
|
+
|
|
30
|
+
os.makedirs(work_dir, exist_ok=True)
|
|
31
|
+
|
|
32
|
+
output_path = work_dir / f"{input_path.stem}.png"
|
|
33
|
+
|
|
34
|
+
logger.info("Converting: %s to %s", input_path, output_path)
|
|
35
|
+
|
|
36
|
+
cmd = f"mmdc -i {input_path} -o {output_path}"
|
|
37
|
+
if browser_config:
|
|
38
|
+
cmd += f" -p {browser_config}"
|
|
39
|
+
subprocess.run(cmd, shell=True, check=True)
|
|
@@ -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.5
|
|
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,12 @@ 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: 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"
|
|
@@ -28,6 +28,7 @@ Requires-Dist: pylint; extra == "test"
|
|
|
28
28
|
Provides-Extra: cairo
|
|
29
29
|
Requires-Dist: pycairo; extra == "cairo"
|
|
30
30
|
Requires-Dist: CairoSVG; extra == "cairo"
|
|
31
|
+
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
# icplot
|
|
33
34
|
|
|
@@ -38,8 +39,9 @@ This is a library used at [The Irish Centre for High End Computing (ICHEC)](http
|
|
|
38
39
|
The project has support for:
|
|
39
40
|
|
|
40
41
|
* Coverting image formats between pdf, svg and png
|
|
41
|
-
* Building pdf output from tex files, including tikz.
|
|
42
|
+
* Building pdf and png output from tex files, including tikz.
|
|
42
43
|
* Generating plots based on a serializable data model to support reproducible research
|
|
44
|
+
* Generating mermaid plots
|
|
43
45
|
|
|
44
46
|
To covert between image formats you can do:
|
|
45
47
|
|
|
@@ -53,6 +55,12 @@ To render a Tex tikz image as pdf and png you can do:
|
|
|
53
55
|
icplot convert --source my_tikz.tex
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
To render a Mermaid plot as png you can do:
|
|
59
|
+
|
|
60
|
+
``` shell
|
|
61
|
+
icplot convert --source my_mermaid.mmd
|
|
62
|
+
```
|
|
63
|
+
|
|
56
64
|
To generate a plot or collection of plots from a yaml description you can do:
|
|
57
65
|
|
|
58
66
|
``` shell
|
|
@@ -9,6 +9,7 @@ src/icplot/convert.py
|
|
|
9
9
|
src/icplot/geometry.py
|
|
10
10
|
src/icplot/image_utils.py
|
|
11
11
|
src/icplot/main_cli.py
|
|
12
|
+
src/icplot/mermaid.py
|
|
12
13
|
src/icplot/py.typed
|
|
13
14
|
src/icplot/tex.py
|
|
14
15
|
src/icplot.egg-info/PKG-INFO
|
|
@@ -33,4 +34,5 @@ test/test_cairo_interface.py
|
|
|
33
34
|
test/test_gantt_chart.py
|
|
34
35
|
test/test_image_utils.py
|
|
35
36
|
test/test_line_plots.py
|
|
36
|
-
test/
|
|
37
|
+
test/test_mermaid.py
|
|
38
|
+
test/test_tex.py
|
|
@@ -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
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from iccore.test_utils import get_test_data_dir, get_test_output_dir
|
|
5
|
+
|
|
6
|
+
from icplot import mermaid
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_mermaid():
|
|
10
|
+
|
|
11
|
+
if not mermaid.has_mermaid():
|
|
12
|
+
return
|
|
13
|
+
|
|
14
|
+
# Pass in the browser config so we can also run headless
|
|
15
|
+
# on the CI
|
|
16
|
+
browser_config = Path(__file__).parent.parent / "infra/puppeteer-config.json"
|
|
17
|
+
|
|
18
|
+
output_dir = get_test_output_dir()
|
|
19
|
+
source = get_test_data_dir() / "test.mmd"
|
|
20
|
+
|
|
21
|
+
mermaid.convert(source, output_dir, browser_config)
|
|
22
|
+
assert Path(output_dir / "test.png").exists()
|
|
23
|
+
|
|
24
|
+
shutil.rmtree(output_dir)
|
|
@@ -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
|