diff --git a/examples/benches/README.md b/examples/benches/README.md index b123bab220291c6e782ce83d81622959b87d3c54..e03ea8051a71d3779154e2008cdbfa42543d7f52 100644 --- a/examples/benches/README.md +++ b/examples/benches/README.md @@ -63,8 +63,9 @@ for graph in [ ( $linalg | where op == $graph.op - | rename --column { n: "x", mean: "measurement", stddev: "error" } + | rename --column { n: "x", mean: "y", stddev: "e" } | group-by name --to-table + | rename --column { group: "name", items: "points" } | to json ) ] @@ -92,8 +93,9 @@ python scripts/plot/plot.py ...[ } else { $it.name | parse "setup on {curve}" | into record | get curve }} - | rename --column { degree: "x", mean: "measurement", stddev: "error" } + | rename --column { degree: "x", mean: "y", stddev: "e" } | group-by name --to-table + | rename --column { group: "name", items: "points" } | to json ) ] @@ -114,8 +116,9 @@ python scripts/plot/plot.py ...[ | ns-to-ms $.times | compute-stats $.times | insert degree { get label | parse "degree {d}" | into record | get d | into int } - | rename --column { degree: "x", mean: "measurement", stddev: "error" } + | rename --column { degree: "x", mean: "y", stddev: "e" } | group-by name --to-table + | rename --column { group: "name", items: "points" } | to json ) ] @@ -140,10 +143,11 @@ python scripts/plot/plot.py --title "recoding with k = 4" ( | flatten --all label | insert case { $"($in.name) / ($in.shards)" } | where k == 4 # $k$ has a negligible influence on _recoding_ - | rename --column { bytes: "x", mean: "measurement", stddev: "error" } + | rename --column { bytes: "x", mean: "y", stddev: "e" } | group-by case --to-table + | rename --column { group: "name", items: "points" } | insert style {|it| - let g = $it.group | parse "{c} / {s}" | into record | into int s + let g = $it.name | parse "{c} / {s}" | into record | into int s let c = match $g.c { "BLS-12-381" => "blue" "BN-254" => "orange" diff --git a/scripts/plot/plot.py b/scripts/plot/plot.py index 662903952250fa2723730f7f31688f7651f2a934..97aefe2cf636bd75120078cdc8e82683823dde40 100644 --- a/scripts/plot/plot.py +++ b/scripts/plot/plot.py @@ -4,13 +4,36 @@ import sys import matplotlib.pyplot as plt import argparse +from typing import List, TypedDict + +# all fields of a `Points` should have the same length +class Points(TypedDict): + x: List[float] + y: List[float] + e: List[float] + +class LineStyle(TypedDict): + marker: str + type: str + width: int + +class Style(TypedDict): + color: str + line: LineStyle + alpha: float + +class Graph(TypedDict): + name: str + points: Points + style: Style + HELP = """## Example ```nuon [ { - group: "Alice", - items: [ - [ x, measurement, error ]; + name: "Alice", + points: [ + [ x, y, e ]; [ 1, 1143, 120 ], [ 2, 1310, 248 ], [ 4, 1609, 258 ], @@ -21,9 +44,9 @@ HELP = """## Example style = {}, # optional, see section below }, { - group: "Bob", - items: [ - [ x, measurement, error ]; + name: "Bob", + points: [ + [ x, y, e ]; [ 1, 2388, 374 ], [ 2, 2738, 355 ], [ 4, 3191, 470 ], @@ -55,7 +78,7 @@ default values have been chosen: # see [`HELP`] def plot( - data, + graphs: List[Graph], title: str, x_label: str, y_label: str, @@ -66,10 +89,10 @@ def plot( ): fig, ax = plt.subplots(layout=plot_layout) - for group in data: - xs = [x["x"] for x in group["items"]] - ys = [x["measurement"] for x in group["items"]] - zs = [x["error"] for x in group["items"]] + for g in graphs: + xs = [x["x"] for x in g["points"]] + ys = [x["y"] for x in g["points"]] + zs = [x["e"] for x in g["points"]] down = [y - z for (y, z) in zip(ys, zs)] up = [y + z for (y, z) in zip(ys, zs)] @@ -81,15 +104,15 @@ def plot( "linewidth": None, } alpha = 0.3 - if "style" in group: - custom_style = group["style"] + if "style" in g: + custom_style = g["style"] style["color"] = custom_style.get("color", None) style["marker"] = custom_style.get("line", {}).get("marker", style["marker"]) style["linestyle"] = custom_style.get("line", {}).get("type", style["linestyle"]) style["linewidth"] = custom_style.get("line", {}).get("width", style["linewidth"]) alpha = custom_style.get("alpha", alpha) - ax.plot(xs, ys, label=group["group"], **style) + ax.plot(xs, ys, label=g["name"], **style) if style["color"] is None: ax.fill_between(xs, down, up, alpha=alpha) else: @@ -119,7 +142,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter ) - parser.add_argument("data", type=str, help=f"the actual data to show in a multibar plot\n\n{HELP}" + parser.add_argument("graphs", type=str, help=f"the list of graphs to plot\n\n{HELP}" ) parser.add_argument("--title", "-t", type=str, help="the title of the plot") parser.add_argument("--x-label", "-x", type=str, help="the x label of the plot") @@ -133,7 +156,7 @@ if __name__ == "__main__": plot_layout = "constrained" if args.fullscreen else None plot( - json.loads(args.data), + json.loads(args.graphs), args.title, args.x_label, args.y_label,