icplot 0.0.13__tar.gz → 0.1.1__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.0.13/src/icplot.egg-info → icplot-0.1.1}/PKG-INFO +2 -2
- {icplot-0.0.13 → icplot-0.1.1}/pyproject.toml +2 -2
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/color.py +1 -1
- icplot-0.1.1/src/icplot/convert.py +40 -0
- icplot-0.1.1/src/icplot/graph/__init__.py +6 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/graph/generator.py +14 -3
- icplot-0.1.1/src/icplot/graph/matplotlib.py +116 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/graph/plot.py +14 -1
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/graph/series.py +9 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/image_utils.py +6 -1
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/main_cli.py +8 -41
- {icplot-0.0.13 → icplot-0.1.1/src/icplot.egg-info}/PKG-INFO +2 -2
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot.egg-info/SOURCES.txt +1 -1
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot.egg-info/requires.txt +1 -1
- {icplot-0.0.13 → icplot-0.1.1}/test/test_line_plots.py +2 -4
- icplot-0.0.13/src/icplot/graph/__init__.py +0 -2
- icplot-0.0.13/src/icplot/graph/matplotlib.py +0 -101
- icplot-0.0.13/src/icplot/graph/plotter.py +0 -23
- {icplot-0.0.13 → icplot-0.1.1}/LICENSE +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/README.md +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/setup.cfg +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/__init__.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/cairo_interface.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/gantt/__init__.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/gantt/gantt.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/gantt/gantt_renderer.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/gantt/pgfgantt.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/geometry.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/graph/axis.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/py.typed +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/tex.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/trace/__init__.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot/trace/trace.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot.egg-info/dependency_links.txt +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot.egg-info/entry_points.txt +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/src/icplot.egg-info/top_level.txt +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/test/test_cairo_interface.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/test/test_gantt_chart.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/test/test_image_utils.py +0 -0
- {icplot-0.0.13 → icplot-0.1.1}/test/test_tex_interface.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: icplot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.1
|
|
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.6
|
|
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.
|
|
3
|
+
version = "0.1.1"
|
|
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.6"]
|
|
22
22
|
|
|
23
23
|
[project.urls]
|
|
24
24
|
Repository = "https://git.ichec.ie/performance/toolshed/icplot"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from icplot import tex
|
|
6
|
+
from icplot.tex import TexBuildSettings
|
|
7
|
+
from icplot.image_utils import pdf_to_png, svg_to_pdf, svg_to_png
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def convert(source: Path, target: Path, build_dir: Path):
|
|
14
|
+
"""
|
|
15
|
+
Convert the file at source outputing at target and using
|
|
16
|
+
the source and target file extensions as format hints.
|
|
17
|
+
|
|
18
|
+
Some conversions require a build_dir for intermediate or
|
|
19
|
+
temporary output
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
logger.info("Converting between %s and %s", source, target)
|
|
23
|
+
|
|
24
|
+
if source.suffix == ".pdf":
|
|
25
|
+
pdf_to_png(source, target)
|
|
26
|
+
elif source.suffix == ".svg":
|
|
27
|
+
if target:
|
|
28
|
+
if target.suffix == ".png":
|
|
29
|
+
svg_to_png(source, target)
|
|
30
|
+
elif target.suffix == ".pdf":
|
|
31
|
+
svg_to_pdf(source, target)
|
|
32
|
+
else:
|
|
33
|
+
svg_to_png(source)
|
|
34
|
+
elif source.suffix == ".tex":
|
|
35
|
+
if not target:
|
|
36
|
+
target = Path(os.getcwd())
|
|
37
|
+
settings = TexBuildSettings(source, build_dir, target)
|
|
38
|
+
tex.build(settings)
|
|
39
|
+
|
|
40
|
+
logger.info("Finished conversion")
|
|
@@ -5,9 +5,11 @@ from pathlib import Path
|
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel
|
|
7
7
|
|
|
8
|
+
from iccore.serialization import read_yaml
|
|
9
|
+
|
|
8
10
|
from .plot import Plot
|
|
9
11
|
from .series import LinePlotSeries
|
|
10
|
-
from .matplotlib import
|
|
12
|
+
from .matplotlib import render
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class PlotConfig(BaseModel):
|
|
@@ -73,7 +75,6 @@ def plot(
|
|
|
73
75
|
config: PlotConfig,
|
|
74
76
|
point_func: Callable,
|
|
75
77
|
output_dir: Path = Path(os.getcwd()),
|
|
76
|
-
plotter=MatplotlibPlotter(),
|
|
77
78
|
):
|
|
78
79
|
"""
|
|
79
80
|
For a given set of results and plot config generate the
|
|
@@ -81,4 +82,14 @@ def plot(
|
|
|
81
82
|
"""
|
|
82
83
|
|
|
83
84
|
for p in make_plots(results, config, point_func):
|
|
84
|
-
|
|
85
|
+
render(p, output_dir / f"{p.name}.svg")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def plot_file(config_path: Path, output_dir: Path):
|
|
89
|
+
config = read_yaml(config_path)
|
|
90
|
+
|
|
91
|
+
if ["plots"] not in config:
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
for p in [Plot(**p) for p in config["plots"]]:
|
|
95
|
+
render(p, output_dir)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import logging
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
5
|
+
logging.getLogger("matplotlib").setLevel(logging.WARNING)
|
|
6
|
+
import matplotlib as mpl # NOQA
|
|
7
|
+
|
|
8
|
+
default_backend = mpl.get_backend()
|
|
9
|
+
mpl.use("Agg")
|
|
10
|
+
import matplotlib.pyplot as plt # NOQA
|
|
11
|
+
|
|
12
|
+
from icplot.color import ColorMap # NOQA
|
|
13
|
+
from .series import PlotSeries, LinePlotSeries, ScatterPlotSeries, ImageSeries # NOQA
|
|
14
|
+
from .plot import Plot, GridPlot, apply_colors # NOQA
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MatplotlibColorMap(ColorMap):
|
|
18
|
+
"""
|
|
19
|
+
A matplotlib based colormap
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, label: str):
|
|
23
|
+
super().__init__(label, mpl.colormaps[label])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _set_decorations(axs, plot: Plot):
|
|
27
|
+
ax = axs[0]
|
|
28
|
+
if plot.legend != "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):
|
|
33
|
+
if y_axis.label:
|
|
34
|
+
axs[idx].set_ylabel(y_axis.label)
|
|
35
|
+
if y_axis.ticks:
|
|
36
|
+
axs[idx].set_yticks(y_axis.resolved_ticks)
|
|
37
|
+
if plot.x_axis.ticks:
|
|
38
|
+
ax.set_xticks(plot.x_axis.resolved_ticks)
|
|
39
|
+
if plot.title:
|
|
40
|
+
ax.set_title(plot.title)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _plot_line(axs, series: LinePlotSeries):
|
|
44
|
+
if not series.position_right:
|
|
45
|
+
ax = axs[0]
|
|
46
|
+
else:
|
|
47
|
+
ax = axs[1]
|
|
48
|
+
ax.plot(
|
|
49
|
+
series.x,
|
|
50
|
+
series.y,
|
|
51
|
+
label=series.label,
|
|
52
|
+
color=series.color.as_list(),
|
|
53
|
+
marker=series.marker,
|
|
54
|
+
drawstyle=series.drawstyle,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _plot_scatter(ax, series: ScatterPlotSeries):
|
|
59
|
+
ax.scatter(series.data, label=series.label, color=series.color.as_list())
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _plot_image(ax, series: ImageSeries):
|
|
63
|
+
ax.imshow(series.data)
|
|
64
|
+
ax.axis("off")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _plot_series(axs, series: PlotSeries):
|
|
68
|
+
ax = axs[0]
|
|
69
|
+
if series.series_type == "line":
|
|
70
|
+
_plot_line(axs, cast(LinePlotSeries, series))
|
|
71
|
+
elif series.series_type == "scatter":
|
|
72
|
+
_plot_scatter(ax, cast(ScatterPlotSeries, series))
|
|
73
|
+
elif series.series_type == "image":
|
|
74
|
+
_plot_image(ax, cast(ImageSeries, series))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _render(fig, path: Path | None = None):
|
|
78
|
+
if path:
|
|
79
|
+
fig.savefig(path)
|
|
80
|
+
else:
|
|
81
|
+
plt.switch_backend(default_backend)
|
|
82
|
+
fig.show()
|
|
83
|
+
plt.switch_backend("Agg")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def render(
|
|
87
|
+
plot: Plot, path: Path | None = None, cmap=MatplotlibColorMap("gist_rainbow")
|
|
88
|
+
):
|
|
89
|
+
|
|
90
|
+
apply_colors(cmap, plot)
|
|
91
|
+
|
|
92
|
+
fig, ax = plt.subplots()
|
|
93
|
+
axs = [ax]
|
|
94
|
+
if len(plot.y_axes) > 1:
|
|
95
|
+
axs.append(ax.twinx())
|
|
96
|
+
|
|
97
|
+
for series in plot.series:
|
|
98
|
+
_plot_series(axs, series)
|
|
99
|
+
|
|
100
|
+
_set_decorations(axs, plot)
|
|
101
|
+
|
|
102
|
+
_render(fig, path)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def render_grid(
|
|
106
|
+
plot: GridPlot,
|
|
107
|
+
path: Path | None = None,
|
|
108
|
+
num_samples: int = 0,
|
|
109
|
+
):
|
|
110
|
+
rows, cols, series = plot.get_subplots(num_samples)
|
|
111
|
+
fig, axs = plt.subplots(rows, cols)
|
|
112
|
+
|
|
113
|
+
for ax, series_item in zip(axs, series):
|
|
114
|
+
_plot_series(ax, series_item)
|
|
115
|
+
|
|
116
|
+
_render(fig, path)
|
|
@@ -6,6 +6,8 @@ import random
|
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
|
|
9
|
+
from icplot.color import ColorMap
|
|
10
|
+
|
|
9
11
|
from .axis import PlotAxis
|
|
10
12
|
from .series import PlotSeries
|
|
11
13
|
|
|
@@ -19,9 +21,10 @@ class Plot(BaseModel):
|
|
|
19
21
|
legend_label: str = ""
|
|
20
22
|
name: str = ""
|
|
21
23
|
x_axis: PlotAxis = PlotAxis()
|
|
22
|
-
|
|
24
|
+
y_axes: list[PlotAxis] = [PlotAxis()]
|
|
23
25
|
plot_type: str = ""
|
|
24
26
|
series: list[PlotSeries] = []
|
|
27
|
+
legend: str = "upper left"
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
class GridPlot(Plot):
|
|
@@ -60,3 +63,13 @@ class GridPlot(Plot):
|
|
|
60
63
|
subplots.append(self.data[index])
|
|
61
64
|
count += 1
|
|
62
65
|
return rows, cols, subplots
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def apply_colors(cmap: ColorMap, plot: Plot):
|
|
69
|
+
non_highlight = []
|
|
70
|
+
for idx, series in enumerate(plot.series):
|
|
71
|
+
if not series.highlight:
|
|
72
|
+
non_highlight.append(series)
|
|
73
|
+
|
|
74
|
+
for idx, series in enumerate(non_highlight):
|
|
75
|
+
series.color = cmap.get_color(idx, non_highlight)
|
|
@@ -8,12 +8,16 @@ from icplot.color import Color
|
|
|
8
8
|
class PlotSeries(BaseModel):
|
|
9
9
|
"""
|
|
10
10
|
A data series in a plot, such as a single line in a line-plot
|
|
11
|
+
|
|
12
|
+
:param position_right: allows the series to be plotted on the right y-axis.
|
|
13
|
+
:type position_right: bool, optional
|
|
11
14
|
"""
|
|
12
15
|
|
|
13
16
|
label: str
|
|
14
17
|
color: Color = Color()
|
|
15
18
|
series_type: str = ""
|
|
16
19
|
highlight: bool = False
|
|
20
|
+
position_right: bool = False
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
class ImageSeries(PlotSeries):
|
|
@@ -29,12 +33,17 @@ class ImageSeries(PlotSeries):
|
|
|
29
33
|
class LinePlotSeries(PlotSeries):
|
|
30
34
|
"""
|
|
31
35
|
A plot series for line plots
|
|
36
|
+
|
|
37
|
+
:param drawstyle: Naming comes from matplotlib API, allows for various square plots,
|
|
38
|
+
default is a normal point to point line plot.
|
|
39
|
+
:type drawstyle: str, optional
|
|
32
40
|
"""
|
|
33
41
|
|
|
34
42
|
x: list
|
|
35
43
|
y: list
|
|
36
44
|
marker: str = "o"
|
|
37
45
|
series_type: str = "line"
|
|
46
|
+
drawstyle: str = "default"
|
|
38
47
|
|
|
39
48
|
|
|
40
49
|
class ScatterPlotSeries(PlotSeries):
|
|
@@ -4,13 +4,14 @@ formats
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
|
+
import os
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
|
|
9
10
|
from wand.image import Image
|
|
10
11
|
from wand.color import Color
|
|
11
|
-
|
|
12
12
|
import cairosvg
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
16
|
|
|
16
17
|
|
|
@@ -26,6 +27,8 @@ def pdf_to_png(source: Path, target: Path | None = None, resolution: int = 300):
|
|
|
26
27
|
"""
|
|
27
28
|
|
|
28
29
|
outfile = _get_out_filename(source, target, "png")
|
|
30
|
+
os.makedirs(outfile.parent, exist_ok=True)
|
|
31
|
+
|
|
29
32
|
with Image(filename=source, resolution=resolution) as img:
|
|
30
33
|
img.format = "png"
|
|
31
34
|
img.background_color = Color("white")
|
|
@@ -39,6 +42,7 @@ def svg_to_png(source: Path, target: Path | None = None):
|
|
|
39
42
|
"""
|
|
40
43
|
|
|
41
44
|
outfile = _get_out_filename(source, target, "png")
|
|
45
|
+
os.makedirs(outfile.parent, exist_ok=True)
|
|
42
46
|
cairosvg.svg2png(url=str(source), write_to=str(outfile))
|
|
43
47
|
|
|
44
48
|
|
|
@@ -48,4 +52,5 @@ def svg_to_pdf(source: Path, target: Path | None = None):
|
|
|
48
52
|
"""
|
|
49
53
|
|
|
50
54
|
outfile = _get_out_filename(source, target, "pdf")
|
|
55
|
+
os.makedirs(outfile.parent, exist_ok=True)
|
|
51
56
|
cairosvg.svg2pdf(url=str(source), write_to=str(outfile))
|
|
@@ -5,62 +5,29 @@ from pathlib import Path
|
|
|
5
5
|
import os
|
|
6
6
|
|
|
7
7
|
from iccore.cli_utils import launch_common
|
|
8
|
-
from iccore.serialization import read_yaml
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
from icplot.image_utils import pdf_to_png, svg_to_png, svg_to_pdf
|
|
13
|
-
from icplot import tex
|
|
14
|
-
from icplot.tex import TexBuildSettings
|
|
9
|
+
import icplot
|
|
10
|
+
import icplot.graph
|
|
15
11
|
|
|
16
12
|
logger = logging.getLogger(__name__)
|
|
17
13
|
|
|
18
14
|
|
|
19
|
-
def
|
|
15
|
+
def convert_cli(args):
|
|
20
16
|
launch_common(args)
|
|
21
17
|
|
|
22
|
-
logger.info("Startubg conversion between %s and %s", args.source, args.target)
|
|
23
|
-
|
|
24
18
|
if args.target:
|
|
25
19
|
target = Path(args.target).resolve()
|
|
26
20
|
else:
|
|
27
21
|
target = None
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
pdf_to_png(args.source.resolve(), target)
|
|
31
|
-
elif args.source.suffix == ".svg":
|
|
32
|
-
if target:
|
|
33
|
-
if target.suffix == ".png":
|
|
34
|
-
svg_to_png(args.source.resolve(), target)
|
|
35
|
-
elif target.suffix == ".pdf":
|
|
36
|
-
svg_to_pdf(args.source.resolve(), target)
|
|
37
|
-
else:
|
|
38
|
-
svg_to_png(args.source)
|
|
39
|
-
elif args.source.suffix == ".tex":
|
|
40
|
-
if args.target:
|
|
41
|
-
target = Path(args.target).resolve()
|
|
42
|
-
else:
|
|
43
|
-
target = Path(os.getcwd())
|
|
44
|
-
|
|
45
|
-
settings = TexBuildSettings(
|
|
46
|
-
args.source.resolve(), args.build_dir.resolve(), args.target
|
|
47
|
-
)
|
|
48
|
-
tex.build(settings)
|
|
23
|
+
icplot.convert(args.source.resolve(), target, args.buid_dir.resolve())
|
|
49
24
|
|
|
50
|
-
logger.info("Finished conversion")
|
|
51
25
|
|
|
52
|
-
|
|
53
|
-
def plot(args):
|
|
26
|
+
def plot_cli(args):
|
|
54
27
|
|
|
55
28
|
launch_common(args)
|
|
56
29
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
plotter = MatplotlibPlotter()
|
|
60
|
-
if ["plots"] in config:
|
|
61
|
-
for eachplot in config["plots"]:
|
|
62
|
-
plot = Plot(**eachplot)
|
|
63
|
-
plotter.plot(plot, args.output_dir.resolve())
|
|
30
|
+
icplot.graph.plot_file(args.config.resolve(), args.output_dir.resolve())
|
|
64
31
|
|
|
65
32
|
|
|
66
33
|
def main_cli():
|
|
@@ -90,7 +57,7 @@ def main_cli():
|
|
|
90
57
|
default=Path(os.getcwd()) / "_build/tikz",
|
|
91
58
|
help="Path for build output",
|
|
92
59
|
)
|
|
93
|
-
convert_parser.set_defaults(func=
|
|
60
|
+
convert_parser.set_defaults(func=convert_cli)
|
|
94
61
|
|
|
95
62
|
plot_parser = subparsers.add_parser("plot")
|
|
96
63
|
plot_parser.add_argument("--config", type=Path, help="Path to the plot config")
|
|
@@ -100,7 +67,7 @@ def main_cli():
|
|
|
100
67
|
default=Path(os.getcwd()),
|
|
101
68
|
help="Path to the plot output directory",
|
|
102
69
|
)
|
|
103
|
-
plot_parser.set_defaults(func=
|
|
70
|
+
plot_parser.set_defaults(func=plot_cli)
|
|
104
71
|
|
|
105
72
|
args = parser.parse_args()
|
|
106
73
|
args.func(args)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: icplot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.1
|
|
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.6
|
|
20
20
|
Provides-Extra: test
|
|
21
21
|
Requires-Dist: pytest; extra == "test"
|
|
22
22
|
Requires-Dist: pytest-cov; extra == "test"
|
|
@@ -5,6 +5,7 @@ setup.cfg
|
|
|
5
5
|
src/icplot/__init__.py
|
|
6
6
|
src/icplot/cairo_interface.py
|
|
7
7
|
src/icplot/color.py
|
|
8
|
+
src/icplot/convert.py
|
|
8
9
|
src/icplot/geometry.py
|
|
9
10
|
src/icplot/image_utils.py
|
|
10
11
|
src/icplot/main_cli.py
|
|
@@ -25,7 +26,6 @@ src/icplot/graph/axis.py
|
|
|
25
26
|
src/icplot/graph/generator.py
|
|
26
27
|
src/icplot/graph/matplotlib.py
|
|
27
28
|
src/icplot/graph/plot.py
|
|
28
|
-
src/icplot/graph/plotter.py
|
|
29
29
|
src/icplot/graph/series.py
|
|
30
30
|
src/icplot/trace/__init__.py
|
|
31
31
|
src/icplot/trace/trace.py
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
3
|
from icplot.graph import Plot, LinePlotSeries
|
|
4
|
-
from icplot.graph
|
|
4
|
+
from icplot.graph import matplotlib
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def test_line_plot():
|
|
@@ -24,9 +24,7 @@ def test_line_plot():
|
|
|
24
24
|
plot = Plot(**plot_config)
|
|
25
25
|
|
|
26
26
|
output_path = Path() / "output.svg"
|
|
27
|
-
|
|
28
|
-
plotter = MatplotlibPlotter()
|
|
29
|
-
plotter.plot(plot, output_path)
|
|
27
|
+
matplotlib.render(plot, output_path)
|
|
30
28
|
|
|
31
29
|
assert output_path.exists()
|
|
32
30
|
output_path.unlink()
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
import logging
|
|
3
|
-
from typing import cast
|
|
4
|
-
|
|
5
|
-
logging.getLogger("matplotlib").setLevel(logging.WARNING)
|
|
6
|
-
import matplotlib as mpl # NOQA
|
|
7
|
-
|
|
8
|
-
default_backend = mpl.get_backend()
|
|
9
|
-
mpl.use("Agg")
|
|
10
|
-
import matplotlib.pyplot as plt # NOQA
|
|
11
|
-
|
|
12
|
-
from icplot.color import ColorMap # NOQA
|
|
13
|
-
from .series import PlotSeries, LinePlotSeries, ScatterPlotSeries, ImageSeries # NOQA
|
|
14
|
-
from .plot import Plot, GridPlot # NOQA
|
|
15
|
-
from .plotter import Plotter # NOQA
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class MatplotlibColorMap(ColorMap):
|
|
19
|
-
"""
|
|
20
|
-
A matplotlib based colormap
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def __init__(self, label: str):
|
|
24
|
-
super().__init__(label, mpl.colormaps[label])
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class MatplotlibPlotter(Plotter):
|
|
28
|
-
"""
|
|
29
|
-
A plot backend for matplotlib
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
def __init__(self, cmap_label="gist_rainbow"):
|
|
33
|
-
super().__init__(MatplotlibColorMap(cmap_label))
|
|
34
|
-
|
|
35
|
-
def set_decorations(self, ax, plot: Plot):
|
|
36
|
-
ax.legend(loc="upper left")
|
|
37
|
-
if plot.x_axis.label:
|
|
38
|
-
ax.set_xlabel(plot.x_axis.label)
|
|
39
|
-
if plot.y_axis.label:
|
|
40
|
-
ax.set_ylabel(plot.y_axis.label)
|
|
41
|
-
if plot.x_axis.ticks:
|
|
42
|
-
ax.set_xticks(plot.x_axis.resolved_ticks)
|
|
43
|
-
if plot.y_axis.ticks:
|
|
44
|
-
ax.set_yticks(plot.y_axis.resolved_ticks)
|
|
45
|
-
if plot.title:
|
|
46
|
-
ax.set_title(plot.title)
|
|
47
|
-
|
|
48
|
-
def plot_line(self, ax, series: LinePlotSeries):
|
|
49
|
-
ax.plot(
|
|
50
|
-
series.x,
|
|
51
|
-
series.y,
|
|
52
|
-
label=series.label,
|
|
53
|
-
color=series.color.as_list(),
|
|
54
|
-
marker=series.marker,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
def plot_scatter(self, ax, series: ScatterPlotSeries):
|
|
58
|
-
ax.scatter(series.data, label=series.label, color=series.color.as_list())
|
|
59
|
-
|
|
60
|
-
def plot_image(self, ax, series: ImageSeries):
|
|
61
|
-
ax.imshow(series.data)
|
|
62
|
-
ax.axis("off")
|
|
63
|
-
|
|
64
|
-
def plot_series(self, ax, series: PlotSeries):
|
|
65
|
-
if series.series_type == "line":
|
|
66
|
-
self.plot_line(ax, cast(LinePlotSeries, series))
|
|
67
|
-
elif series.series_type == "scatter":
|
|
68
|
-
self.plot_scatter(ax, cast(ScatterPlotSeries, series))
|
|
69
|
-
elif series.series_type == "image":
|
|
70
|
-
self.plot_image(ax, cast(ImageSeries, series))
|
|
71
|
-
|
|
72
|
-
def plot(self, plot: Plot, path: Path | None = None):
|
|
73
|
-
|
|
74
|
-
self.apply_cmap_colors(plot)
|
|
75
|
-
|
|
76
|
-
fig, ax = plt.subplots()
|
|
77
|
-
|
|
78
|
-
for series in plot.series:
|
|
79
|
-
self.plot_series(ax, series)
|
|
80
|
-
|
|
81
|
-
self.set_decorations(ax, plot)
|
|
82
|
-
|
|
83
|
-
self.render(fig, path)
|
|
84
|
-
|
|
85
|
-
def plot_grid(self, plot: GridPlot, path: Path | None = None, num_samples: int = 0):
|
|
86
|
-
|
|
87
|
-
rows, cols, series = plot.get_subplots(num_samples)
|
|
88
|
-
fig, axs = plt.subplots(rows, cols)
|
|
89
|
-
|
|
90
|
-
for ax, series_item in zip(axs, series):
|
|
91
|
-
self.plot_series(ax, series_item)
|
|
92
|
-
|
|
93
|
-
self.render(fig, path)
|
|
94
|
-
|
|
95
|
-
def render(self, fig, path: Path | None = None):
|
|
96
|
-
if path:
|
|
97
|
-
fig.savefig(path)
|
|
98
|
-
else:
|
|
99
|
-
plt.switch_backend(default_backend)
|
|
100
|
-
fig.show()
|
|
101
|
-
plt.switch_backend("Agg")
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from icplot.color import ColorMap
|
|
4
|
-
|
|
5
|
-
from .plot import Plot
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Plotter:
|
|
9
|
-
|
|
10
|
-
def __init__(self, cmap: ColorMap):
|
|
11
|
-
self.cmap = cmap
|
|
12
|
-
|
|
13
|
-
def apply_cmap_colors(self, plot: Plot):
|
|
14
|
-
non_highlight = []
|
|
15
|
-
for idx, series in enumerate(plot.series):
|
|
16
|
-
if not series.highlight:
|
|
17
|
-
non_highlight.append(series)
|
|
18
|
-
|
|
19
|
-
for idx, series in enumerate(non_highlight):
|
|
20
|
-
series.color = self.cmap.get_color(idx, non_highlight)
|
|
21
|
-
|
|
22
|
-
def plot(self, plot: Plot, path: Path | None = None):
|
|
23
|
-
pass
|
|
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
|