From 79dc01e4292579aa6a45cb128735c21fdf627d16 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 11:03:47 +0200
Subject: [PATCH 1/7] add script to manipulate colors

---
 scripts/color.nu | 133 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)
 create mode 100644 scripts/color.nu

diff --git a/scripts/color.nu b/scripts/color.nu
new file mode 100644
index 00000000..d5cccea6
--- /dev/null
+++ b/scripts/color.nu
@@ -0,0 +1,133 @@
+export const WHITE = { r: 1.0, g: 1.0, b: 1.0 }
+export const BLACK = { r: 0.0, g: 0.0, b: 0.0 }
+export const RED = { r: 1.0, g: 0.0, b: 0.0 }
+export const GREEN = { r: 0.0, g: 1.0, b: 0.0 }
+export const BLUE = { r: 0.0, g: 0.0, b: 1.0 }
+
+def "error throw" [err: record<err: string, label: string, span: record<start: int, end: int>>] {
+    error make {
+        msg: $"(ansi red_bold)($err.err)(ansi reset)",
+        label: {
+            text: $err.label,
+            span: $err.span,
+        },
+    }
+}
+
+export def "color from-floats" [
+    r: float,
+    g: float,
+    b: float
+]: nothing -> record<r: float, g: float, b: float> {
+    if $r < 0.0 or $r > 1.0 {
+        error throw {
+            err: "invalid RGB channel",
+            label: $"should be between 0 and 1, found ($r)",
+            span: (metadata $r).span,
+        }
+    }
+    if $g < 0.0 or $g > 1.0 {
+        error throw {
+            err: "invalid RGB channel",
+            label: $"should be between 0 and 1, found ($g)",
+            span: (metadata $g).span,
+        }
+    }
+    if $b < 0.0 or $b > 1.0 {
+        error throw {
+            err: "invalid RGB channel",
+            label: $"should be between 0 and 1, found ($b)",
+            span: (metadata $b).span,
+        }
+    }
+
+    { r: $r, g: $g, b: $b }
+}
+
+export def "color from-ints" [
+    r: int,
+    g: int,
+    b: int
+]: nothing -> record<r: float, g: float, b: float> {
+    if $r < 0 or $r > 255 {
+        error throw {
+            err: "invalid RGB channel",
+            label: $"should be between 0 and 255, found ($r)",
+            span: (metadata $r).span,
+        }
+    }
+    if $g < 0 or $g > 255 {
+        error throw {
+            err: "invalid RGB channel",
+            label: $"should be between 0 and 255, found ($g)",
+            span: (metadata $g).span,
+        }
+    }
+    if $b < 0 or $b > 255 {
+        error throw {
+            err: "invalid RGB channel",
+            label: $"should be between 0 and 255, found ($b)",
+            span: (metadata $b).span,
+        }
+    }
+
+    { r: ($r / 255 | into float), g: ($g / 255 | into float), b: ($b / 255 | into float) }
+}
+
+def try-string-to-int []: string -> int {
+    try {
+        $"0x($in)" | into int
+    } catch {
+        get debug | parse --regex 'CantConvert { to_type: "(?<to>.*)", from_type: "(?<from>.*)", span: Span { (?<span>.*) }, help: Some\("(?<help>.*)"\) }' | into record | error make --unspanned { msg: ($in.help | str replace --all '\"' '"') }
+    }
+}
+
+export def "color from-string" [s: string]: nothing -> record<r: float, g: float, b: float> {
+    let res = $s
+        | parse --regex '^0x(?<r>..)(?<g>..)(?<b>..)$'
+        | into record
+
+    if $res == {} {
+        error throw {
+            err: "invalid HEX color format",
+            label: $"format should be '0xRRGGBB', found ($s)",
+            span: (metadata $s).span,
+        }
+    }
+
+    {
+        r: ($res.r | try-string-to-int | $in / 255),
+        g: ($res.g | try-string-to-int | $in / 255),
+        b: ($res.b | try-string-to-int | $in / 255),
+    }
+}
+
+export def "color mix" [
+    c1: record<r: float, g: float, b: float>,
+    c2: record<r: float, g: float, b: float>,
+    c: float,
+]: nothing -> record<r: float, g: float, b: float> {
+    {
+        r: ($c * $c1.r + (1 - $c) * $c2.r),
+        g: ($c * $c1.g + (1 - $c) * $c2.g),
+        b: ($c * $c1.b + (1 - $c) * $c2.b),
+    }
+}
+
+def float-to-u8-hex []: float -> string {
+    $in * 255
+        | math round --precision 0
+        | into int
+        | fmt
+        | get lowerhex
+        | parse "0x{n}"
+        | into record
+        | get n
+        | into string
+        | fill --alignment "right" --character '0' --width 2
+}
+
+export def "color to-hex" []: record<r: float, g: float, b: float> -> string {
+    $"#($in.r | float-to-u8-hex)($in.g | float-to-u8-hex)($in.b | float-to-u8-hex)"
+}
+
-- 
GitLab


From 2d39c41462de8a49d0dc9fb5806575bfe54ea26e Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 11:06:19 +0200
Subject: [PATCH 2/7] use "#" as the start of color format

---
 scripts/color.nu | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/color.nu b/scripts/color.nu
index d5cccea6..b97c134b 100644
--- a/scripts/color.nu
+++ b/scripts/color.nu
@@ -84,13 +84,13 @@ def try-string-to-int []: string -> int {
 
 export def "color from-string" [s: string]: nothing -> record<r: float, g: float, b: float> {
     let res = $s
-        | parse --regex '^0x(?<r>..)(?<g>..)(?<b>..)$'
+        | parse --regex '^#(?<r>..)(?<g>..)(?<b>..)$'
         | into record
 
     if $res == {} {
         error throw {
             err: "invalid HEX color format",
-            label: $"format should be '0xRRGGBB', found ($s)",
+            label: $"format should be '#RRGGBB', found ($s)",
             span: (metadata $s).span,
         }
     }
-- 
GitLab


From 0c761d46197d456221c7f799957a5d096781bd61 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 11:08:43 +0200
Subject: [PATCH 3/7] use hex colors

---
 scripts/inbreeding/plot.nu | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/scripts/inbreeding/plot.nu b/scripts/inbreeding/plot.nu
index 17807e9f..d6398789 100644
--- a/scripts/inbreeding/plot.nu
+++ b/scripts/inbreeding/plot.nu
@@ -3,6 +3,7 @@
 use std repeat
 
 use ../plot.nu gplt
+use ../color.nu *
 
 def "parse strategy" []: string -> record<type: string> {
     let s = $in
@@ -59,16 +60,16 @@ export def main [data: path, --save: path, --options: record<k: int>] {
         | rename --column { diversity: "points" }
         | insert style {|it|
             let color = match $it.strategy.n {
-                10 => "tab:red",
-                9 => "tab:orange",
-                8 => "tab:olive",
-                7 => "tab:blue",
-                6 => "tab:purple",
-                5 => "tab:green",
-                4 => "tab:cyan",
-                3 => "tab:brown",
-                2 => "tab:pink",
-                _ => "tab:gray",
+                10 => "#d62728",
+                9 => "#ff7f0e",
+                8 => "#bcbd22",
+                7 => "#1f77b4",
+                6 => "#9467bd",
+                5 => "#2ca02c",
+                4 => "#17becf",
+                3 => "#8c564b",
+                2 => "#e377c2",
+                _ => "#7f7f7f",
             }
 
             { color: $color, line: { alpha: ($it.strategy.p? | default 1.0) } }
-- 
GitLab


From 51d8b6e96583d5b777746c9397a0ecf82506bd2c Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 11:10:56 +0200
Subject: [PATCH 4/7] refactor into `get-color`

---
 scripts/inbreeding/plot.nu | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/scripts/inbreeding/plot.nu b/scripts/inbreeding/plot.nu
index d6398789..2cf38674 100644
--- a/scripts/inbreeding/plot.nu
+++ b/scripts/inbreeding/plot.nu
@@ -25,6 +25,21 @@ def "parse strategy" []: string -> record<type: string> {
     }
 }
 
+def get-color []: int -> string {
+    match $in {
+        10 => "#d62728",
+        9 => "#ff7f0e",
+        8 => "#bcbd22",
+        7 => "#1f77b4",
+        6 => "#9467bd",
+        5 => "#2ca02c",
+        4 => "#17becf",
+        3 => "#8c564b",
+        2 => "#e377c2",
+        _ => "#7f7f7f",
+    }
+}
+
 export def main [data: path, --save: path, --options: record<k: int>] {
     let data = open $data
     let l = $data.diversity.0 | length
@@ -59,18 +74,7 @@ export def main [data: path, --save: path, --options: record<k: int>] {
         }
         | rename --column { diversity: "points" }
         | insert style {|it|
-            let color = match $it.strategy.n {
-                10 => "#d62728",
-                9 => "#ff7f0e",
-                8 => "#bcbd22",
-                7 => "#1f77b4",
-                6 => "#9467bd",
-                5 => "#2ca02c",
-                4 => "#17becf",
-                3 => "#8c564b",
-                2 => "#e377c2",
-                _ => "#7f7f7f",
-            }
+            let color = $it.strategy.n | get-color
 
             { color: $color, line: { alpha: ($it.strategy.p? | default 1.0) } }
         }
-- 
GitLab


From 8145cd66a3900d026ecaa5843a3335306320746a Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 11:13:40 +0200
Subject: [PATCH 5/7] mix colors for "double" strategies

---
 scripts/inbreeding/plot.nu | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/scripts/inbreeding/plot.nu b/scripts/inbreeding/plot.nu
index 2cf38674..68652ebb 100644
--- a/scripts/inbreeding/plot.nu
+++ b/scripts/inbreeding/plot.nu
@@ -74,9 +74,23 @@ export def main [data: path, --save: path, --options: record<k: int>] {
         }
         | rename --column { diversity: "points" }
         | insert style {|it|
-            let color = $it.strategy.n | get-color
+            let color = match $it.strategy.type {
+                "single" => { $it.strategy.n | get-color },
+                "double" => {
+                    let c1 = $it.strategy.n | get-color | color from-string $in
+                    let c2 = $it.strategy.m | get-color | color from-string $in
+                    let c = $it.strategy.p
 
-            { color: $color, line: { alpha: ($it.strategy.p? | default 1.0) } }
+                    color mix $c1 $c2 $c | color to-hex
+                },
+            }
+
+            let alpha = match $it.strategy.type {
+                "single" => 1.0,
+                "double" => 0.5,
+            }
+
+            { color: $color, line: { alpha: $alpha } }
         }
         | reject strategy
         | save --force /tmp/graphs.json
-- 
GitLab


From e2ba7d475ee94b7de8a6a13e825cd064ddbab335 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 13:04:48 +0200
Subject: [PATCH 6/7] make hybrid strategies a bit more transparent

---
 scripts/inbreeding/plot.nu | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/inbreeding/plot.nu b/scripts/inbreeding/plot.nu
index 68652ebb..0bca8f9d 100644
--- a/scripts/inbreeding/plot.nu
+++ b/scripts/inbreeding/plot.nu
@@ -87,7 +87,7 @@ export def main [data: path, --save: path, --options: record<k: int>] {
 
             let alpha = match $it.strategy.type {
                 "single" => 1.0,
-                "double" => 0.5,
+                "double" => 0.3,
             }
 
             { color: $color, line: { alpha: $alpha } }
-- 
GitLab


From d37b6317546db4a6972ca1cf7a2459f7b33af465 Mon Sep 17 00:00:00 2001
From: "a.stevan" <antoine.stevan@isae-supaero.fr>
Date: Mon, 27 May 2024 13:05:05 +0200
Subject: [PATCH 7/7] make hybrid curves dashed

---
 scripts/inbreeding/plot.nu | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/scripts/inbreeding/plot.nu b/scripts/inbreeding/plot.nu
index 0bca8f9d..4a706353 100644
--- a/scripts/inbreeding/plot.nu
+++ b/scripts/inbreeding/plot.nu
@@ -89,8 +89,12 @@ export def main [data: path, --save: path, --options: record<k: int>] {
                 "single" => 1.0,
                 "double" => 0.3,
             }
+            let type = match $it.strategy.type {
+                "single" => "solid",
+                "double" => "dashed",
+            }
 
-            { color: $color, line: { alpha: $alpha } }
+            { color: $color, line: { alpha: $alpha, type: $type } }
         }
         | reject strategy
         | save --force /tmp/graphs.json
-- 
GitLab