From 2668221a7a254b36c880cea60b7f4081c348b7ae Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 18:38:28 +0200 Subject: [PATCH 1/7] [api] add `FillMode` for "toself" --- src/plotly/plotly_types.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plotly/plotly_types.nim b/src/plotly/plotly_types.nim index e44bb99..eaf862d 100644 --- a/src/plotly/plotly_types.nim +++ b/src/plotly/plotly_types.nim @@ -43,6 +43,7 @@ type Unset = "" ToNextY = "tonexty" ToZeroY = "tozeroy" + ToSelf = "toself" PlotMode* {.pure.} = enum Lines = "lines" From 8a42008d5c6489cd1b322f06d498fa53b4cc404f Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 18:38:43 +0200 Subject: [PATCH 2/7] [api] allow to disable outlines (for error bands) --- src/plotly/api.nim | 4 +++- src/plotly/plotly_types.nim | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plotly/api.nim b/src/plotly/api.nim index 413850f..072538c 100644 --- a/src/plotly/api.nim +++ b/src/plotly/api.nim @@ -342,8 +342,10 @@ func `%`*(t: Trace): JsonNode = if t.xs.len > 0: fields.parseBarFields(t) of PlotType.Scatter, PlotType.ScatterGL: - if t.lineWidth > 0: + if not t.hideLine and t.lineWidth > 0: fields["line"] = %* {"width": t.lineWidth} + elif t.hideLine: + fields["line"] = %* {"width": 0} else: discard diff --git a/src/plotly/plotly_types.nim b/src/plotly/plotly_types.nim index eaf862d..1110705 100644 --- a/src/plotly/plotly_types.nim +++ b/src/plotly/plotly_types.nim @@ -220,6 +220,7 @@ type orientation*: Orientation of Scatter, ScatterGL: lineWidth*: int + hideLine*: bool # can be used to force line to be width 0 (for backwards compatiblity) else: discard From 4a76daa678a6f8ec940febb9114a9da6aa9c8de4 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 18:38:59 +0200 Subject: [PATCH 3/7] [examples] add example for manual error band plot --- examples/fig21_error_band.nim | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/fig21_error_band.nim diff --git a/examples/fig21_error_band.nim b/examples/fig21_error_band.nim new file mode 100644 index 0000000..49fe121 --- /dev/null +++ b/examples/fig21_error_band.nim @@ -0,0 +1,43 @@ +import sequtils +import plotly +import chroma +from std / algorithm import reversed + +# simple example showcasing error bands (by hand) + +let + d = Trace[float](mode: PlotMode.LinesMarkers, `type`: PlotType.Scatter) + size = @[16.float] +d.marker = Marker[float](size: size) +d.xs = @[1'f64, 2, 3, 4, 5] +d.ys = @[1'f64, 2, 1, 9, 5] + +# Create a Trace for the error band +let + dBand = Trace[float](mode: PlotMode.Lines, `type`: PlotType.Scatter, + opacity: 0.75, # opacity 75% to be prettier + fill: ToSelf, # `ToSelf` means the filling is done to its own data + hideLine: true) # line width 0 disables the outline +# Create X data that is first increasing and then decreasing +dBand.xs = concat(d.xs, d.xs.reversed) +# Assign the actual ribbon band. Currently needs to be a seq +dBand.marker = Marker[float](color: @[color(0.6, 0.6, 0.6)]) + +# define some errors we will use (symmetric) +let yErr = d.ys.mapIt(0.25) +# now create the first upper band range +var yErrs = newSeqOfCap[float](d.ys.len * 2) # first upper, then lower +for i in 0 ..< d.ys.len: # upper errors + yErrs.add(d.ys[i] + yErr[i]) +# and now the lower +for i in countdown(d.ys.high, 0): # lower errors + yErrs.add(d.ys[i] - yErr[i]) +dBand.ys = yErrs + +let + layout = Layout(title: "testing", width: 1200, height: 400, + xaxis: Axis(title: "my x-axis"), + yaxis: Axis(title: "y-axis too"), autosize: false) + p = Plot[float](layout: layout, traces: @[d, dBand]) # assign both traces +echo p.save() +p.show() From db3b012ef322dcb2a88f8e08e72f0e06c39c79a9 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 18:41:55 +0200 Subject: [PATCH 4/7] [examples] add error band example to all.nim examples --- examples/all.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/all.nim b/examples/all.nim index 9f691d5..9c0f0ea 100644 --- a/examples/all.nim +++ b/examples/all.nim @@ -14,3 +14,4 @@ import fig15_horizontalBarPlot import fig16_plotly_sugar import fig17_color_font_legend import fig18_subplots +import fig21_error_band From 2f47a81836fc51f6d507114811c69190167e3ad0 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 18:43:30 +0200 Subject: [PATCH 5/7] update changelog --- changelog.org | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/changelog.org b/changelog.org index 4dce8ac..685d7f6 100644 --- a/changelog.org +++ b/changelog.org @@ -1,3 +1,10 @@ +* v0.3.3 +- add ~hideLine~ for ~Trace~ object for scatter plots, in order to set + the line width to 0. Used for backwards compatibility, because + setting a value of 0 would be the default. +- add ~FillMode~ value of ~toSelf~ to allow colored bands / filled + polygons +- add example for a manual error band * v0.3.2 - fix behavior of =show= when =--threads:on= for =Grid= usage, in particular for example 18. =filename= argument is now optional, From 5899846dcdeb9b2a2c871d0f34f4f4d2c166b529 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 18:49:29 +0200 Subject: [PATCH 6/7] update CI --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e3be18..b9d36a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,15 +18,15 @@ jobs: strategy: fail-fast: false matrix: - branch: [version-1-4, devel] + branch: [version-1-6, version-2-0, devel] target: [linux, macos, windows] include: - target: linux - builder: ubuntu-18.04 + builder: ubuntu-latest - target: macos - builder: macos-10.15 + builder: macos-latest - target: windows - builder: windows-2019 + builder: windows-latest name: '${{ matrix.target }} (${{ matrix.branch }})' runs-on: ${{ matrix.builder }} steps: From 61dacc1e6b3f50bfd00a8b5b104af49738764649 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Tue, 9 Apr 2024 19:03:29 +0200 Subject: [PATCH 7/7] [tests] disable tests expected to fail w/o `threads:on` Nowadays we compile with `--threads:on` by default! --- tests/plotly/test_api.nim | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/plotly/test_api.nim b/tests/plotly/test_api.nim index b8355b9..6be6163 100644 --- a/tests/plotly/test_api.nim +++ b/tests/plotly/test_api.nim @@ -495,20 +495,21 @@ suite "show w/ filename without threads fails compilation": xs: xs, ys: ys) let plt = Plot[float](layout: layout, traces: @[d]) - ## NOTE: the following tests assume the test is compiled without `--threads:on`! - test "Plot - saveImage fails": - check compileFails(plt.saveImage("test.svg")) + when not compileOption("threads"): + ## NOTE: the following tests assume the test is compiled without `--threads:on`! + test "Plot - saveImage fails": + check compileFails(plt.saveImage("test.svg")) - test "PlotJson - saveImage fails": - check compileFails(plt.toPlotJson.saveImage("test.svg")) + test "PlotJson - saveImage fails": + check compileFails(plt.toPlotJson.saveImage("test.svg")) - test "Plot - show w/ filename w/o threads:on fails": - check compileFails(plt.show("test.svg")) + test "Plot - show w/ filename w/o threads:on fails": + check compileFails(plt.show("test.svg")) - test "PlotJson - show w/ filename w/o threads:on fails": - check compileFails(plt.toPlotJson.show("test.svg")) + test "PlotJson - show w/ filename w/o threads:on fails": + check compileFails(plt.toPlotJson.show("test.svg")) - test "Grid - show w/ filename w/o threads:on fails": - var grid = createGrid(1) - grid[0] = plt - check compileFails(grid.show("test.svg")) + test "Grid - show w/ filename w/o threads:on fails": + var grid = createGrid(1) + grid[0] = plt + check compileFails(grid.show("test.svg"))