From b2aba206621ecae49d168cd31bd9debff6df1e66 Mon Sep 17 00:00:00 2001 From: "Cvetomir M. Dimov" Date: Sun, 1 Jun 2025 21:35:58 +0200 Subject: [PATCH 1/8] First iteration of plot grid. --- src/scicloj/tableplot/v1/plotly.clj | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index d1d90d8..1197a26 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -1401,4 +1401,42 @@ then the density is estimated in groups. plotly-xform)) +(defn grid-layout + ([plots] + (grid-layout plots (-> plots count math/sqrt math/ceil))) + ([plots nrow] + (let [axis {:showline false + :zeroline false + :gridcolor "#ffff" + :ticklen 4} + n (count plots) + nrow (if (> nrow n) n nrow) + ncol (-> (/ n nrow) math/ceil) + step-row (/ 1.0 nrow) + step-col (/ 1.0 ncol)] + (into {} + (concat + (map #(vector (keyword (str "xaxis" %)) (conj axis {:domain (vector (* step-row (dec %)) (* step-row %))})) + (range 1 (inc nrow))) + (map #(vector (keyword (str "yaxis" %)) (conj axis {:domain (vector (* step-col (dec %)) (* step-col %))})) + (range 1 (inc ncol)))))))) + +(defn grid-traces + ([plots] + (grid-traces plots (-> plots count math/sqrt math/ceil))) + ([plots nrow] + (let [n (count plots) + nrow (if (> nrow n) n nrow) + ncol (-> (/ n nrow) math/ceil)] + (mapcat (fn [plot-layers xaxis yaxis] (map (fn [layer] (conj layer {:xaxis (str "x" xaxis) + :yaxis (str "y" yaxis)})) plot-layers)) + (->> plots (map plotly/plot) (map :data)) + (mapcat #(repeat ncol %) (range 1 (inc nrow))) + (cycle (range 1 (inc ncol))))))) + +(defn grid [plots nrow] + (kind/plotly + {:data (grid-traces plots nrow) + :layout (grid-layout plots nrow)})) + From ff00ae98649b0adb3b8df81b157fd7b790a8786e Mon Sep 17 00:00:00 2001 From: "Cvetomir M. Dimov" Date: Sun, 15 Jun 2025 15:32:32 +0300 Subject: [PATCH 2/8] Redefined grid-traces and grid-layout as substitution maps --- src/scicloj/tableplot/v1/plotly.clj | 93 ++++++++++++++++------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index 1197a26..49d9fd0 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -462,6 +462,42 @@ The design matrix simply uses these columns without any additional transformatio {:hovermode :closest :dragmode :select}))))) + +(dag/defn-with-deps submap->grid-nrows + [=inner-plots] + (-> =inner-plots count math/sqrt math/ceil)) + +(dag/defn-with-deps submap->grid-layout ;; define + ([=inner-plots =grid-nrows] ;; grid-nrows; be default derived from grid-nplots + (let [axis {:showline false + :zeroline false + :gridcolor "#ffff" + :ticklen 4} + n (count =inner-plots) + nrow (if (> grid-nrows n) n grid-nrows) + ncol (-> (/ n nrow) math/ceil) + step-row (/ 1.0 nrow) + step-col (/ 1.0 ncol)] + (into {} + (concat + (map #(vector (keyword (str "xaxis" %)) (conj axis {:domain (vector (* step-row (dec %)) (* step-row %))})) + (range 1 (inc nrow))) + (map #(vector (keyword (str "yaxis" %)) (conj axis {:domain (vector (* step-col (dec %)) (* step-col %))})) + (range 1 (inc ncol)))))))) ;; no gaps between plots + +(dag/defn-with-deps grid-traces-no-xform + ([=inner-plots =grid-nrows] + (let [n (count =inner-plots) + nrow (if (> =grid-nrows n) n nrow) + ncol (-> (/ n nrow) math/ceil)] + (mapcat (fn [plot-layers xaxis yaxis] + (map (fn [layer] (conj layer {:xaxis (str "x" xaxis) + :yaxis (str "y" yaxis)})) + plot-layers)) + (->> =inner-plots (map :data)) + (mapcat #(repeat ncol %) (range 1 (inc nrow))) + (cycle (range 1 (inc ncol))))))) + (def standard-defaults [[:=stat :=dataset "The data resulting from a possible statistical transformation."] @@ -609,6 +645,14 @@ The design matrix simply uses these columns without any additional transformatio "The color for the y axis grid lines."] [:=colnames hc/RMV "Column names for a SPLOM plot."] + [:=inner-plots hc/RMV + "List of plots (used in a grid)"] + [:=grid-nrows submap->grid-nrows + "The number of rows in a plot grid."] + [:=grid-layout submap->grid-layout + "The layout of a plot grid."] + [:=grid-traces grid-traces-no-xform + "The trace of a plot grid."] [:=splom-layout submap->splom-layout "The layout for a SPLOM plot."] [:=splom-traces submap->splom-traces @@ -1387,7 +1431,6 @@ then the density is estimated in groups. (defn splom "Show a SPLOM (ScatterPLOt Matrix) of given dimensions of a dataset. - 🔑 **Main useful keys:** `:=dataset` `:=colnames` `:=color` `:=color-type` `:=symbol` @@ -1400,43 +1443,11 @@ then the density is estimated in groups. :layout :=splom-layout) plotly-xform)) - -(defn grid-layout - ([plots] - (grid-layout plots (-> plots count math/sqrt math/ceil))) - ([plots nrow] - (let [axis {:showline false - :zeroline false - :gridcolor "#ffff" - :ticklen 4} - n (count plots) - nrow (if (> nrow n) n nrow) - ncol (-> (/ n nrow) math/ceil) - step-row (/ 1.0 nrow) - step-col (/ 1.0 ncol)] - (into {} - (concat - (map #(vector (keyword (str "xaxis" %)) (conj axis {:domain (vector (* step-row (dec %)) (* step-row %))})) - (range 1 (inc nrow))) - (map #(vector (keyword (str "yaxis" %)) (conj axis {:domain (vector (* step-col (dec %)) (* step-col %))})) - (range 1 (inc ncol)))))))) - -(defn grid-traces - ([plots] - (grid-traces plots (-> plots count math/sqrt math/ceil))) - ([plots nrow] - (let [n (count plots) - nrow (if (> nrow n) n nrow) - ncol (-> (/ n nrow) math/ceil)] - (mapcat (fn [plot-layers xaxis yaxis] (map (fn [layer] (conj layer {:xaxis (str "x" xaxis) - :yaxis (str "y" yaxis)})) plot-layers)) - (->> plots (map plotly/plot) (map :data)) - (mapcat #(repeat ncol %) (range 1 (inc nrow))) - (cycle (range 1 (inc ncol))))))) - -(defn grid [plots nrow] - (kind/plotly - {:data (grid-traces plots nrow) - :layout (grid-layout plots nrow)})) - - +(defn grid + "Arrange a list of plots into a grid." + [plots] + (plotly-xform + {:data :=grid-traces-no-xform + :layout :=grid-layout + ::ht/defaults (assoc standard-defaults-man + :inner-plots plots)})) From 873c0505e0685e80bc1baa598cea277b0e0fb879 Mon Sep 17 00:00:00 2001 From: daslu Date: Thu, 19 Jun 2025 11:24:49 +0300 Subject: [PATCH 3/8] little fixes to the grid branch --- src/scicloj/tableplot/v1/plotly.clj | 68 +++++++++++++++-------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index a6e9054..61d260b 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -463,39 +463,43 @@ The design matrix simply uses these columns without any additional transformatio :dragmode :select}))))) (dag/defn-with-deps submap->grid-nrows + nil [=inner-plots] (-> =inner-plots count math/sqrt math/ceil)) -(dag/defn-with-deps submap->grid-layout ;; define - ([=inner-plots =grid-nrows] ;; grid-nrows; be default derived from grid-nplots - (let [axis {:showline false - :zeroline false - :gridcolor "#ffff" - :ticklen 4} - n (count =inner-plots) - nrow (if (> grid-nrows n) n grid-nrows) - ncol (-> (/ n nrow) math/ceil) - step-row (/ 1.0 nrow) - step-col (/ 1.0 ncol)] - (into {} - (concat - (map #(vector (keyword (str "xaxis" %)) (conj axis {:domain (vector (* step-row (dec %)) (* step-row %))})) - (range 1 (inc nrow))) - (map #(vector (keyword (str "yaxis" %)) (conj axis {:domain (vector (* step-col (dec %)) (* step-col %))})) - (range 1 (inc ncol)))))))) ;; no gaps between plots +(dag/defn-with-deps submap->grid-layout + ;; define + nil + [=inner-plots =grid-nrows] ;; grid-nrows; be default derived from grid-nplots + (let [axis {:showline false + :zeroline false + :gridcolor "#ffff" + :ticklen 4} + n (count =inner-plots) + nrow (if (> =grid-nrows n) n =grid-nrows) + ncol (-> (/ n nrow) math/ceil) + step-row (/ 1.0 nrow) + step-col (/ 1.0 ncol)] + (into {} + (concat + (map #(vector (keyword (str "xaxis" %)) (conj axis {:domain (vector (* step-row (dec %)) (* step-row %))})) + (range 1 (inc nrow))) + (map #(vector (keyword (str "yaxis" %)) (conj axis {:domain (vector (* step-col (dec %)) (* step-col %))})) + (range 1 (inc ncol))))))) ;; no gaps between plots (dag/defn-with-deps grid-traces-no-xform - ([=inner-plots =grid-nrows] - (let [n (count =inner-plots) - nrow (if (> =grid-nrows n) n nrow) - ncol (-> (/ n nrow) math/ceil)] - (mapcat (fn [plot-layers xaxis yaxis] - (map (fn [layer] (conj layer {:xaxis (str "x" xaxis) - :yaxis (str "y" yaxis)})) - plot-layers)) - (->> =inner-plots (map :data)) - (mapcat #(repeat ncol %) (range 1 (inc nrow))) - (cycle (range 1 (inc ncol))))))) + nil + [=inner-plots =grid-nrows] + (let [n (count =inner-plots) + nrow (min =grid-nrows n) + ncol (-> (/ n nrow) math/ceil)] + (mapcat (fn [plot-layers xaxis yaxis] + (map (fn [layer] (conj layer {:xaxis (str "x" xaxis) + :yaxis (str "y" yaxis)})) + plot-layers)) + (->> =inner-plots (map :data)) + (mapcat #(repeat ncol %) (range 1 (inc nrow))) + (cycle (range 1 (inc ncol)))))) (dag/defn-with-deps submap->colnames "Extract all column names of the dataset." @@ -1454,7 +1458,7 @@ then the density is estimated in groups. "Arrange a list of plots into a grid." [plots] (plotly-xform - {:data :=grid-traces-no-xform - :layout :=grid-layout - ::ht/defaults (assoc standard-defaults-man - :inner-plots plots)})) + {:data :=grid-traces-no-xform + :layout :=grid-layout + ::ht/defaults (assoc standard-defaults + :inner-plots plots)})) From 82f0e5a36fc8388a4c6c2bd49b39c9479f90c79a Mon Sep 17 00:00:00 2001 From: daslu Date: Thu, 19 Jun 2025 11:27:31 +0300 Subject: [PATCH 4/8] minor code simplification --- src/scicloj/tableplot/v1/plotly.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index 61d260b..713ffdd 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -476,7 +476,7 @@ The design matrix simply uses these columns without any additional transformatio :gridcolor "#ffff" :ticklen 4} n (count =inner-plots) - nrow (if (> =grid-nrows n) n =grid-nrows) + nrow (min =grid-nrows n) ncol (-> (/ n nrow) math/ceil) step-row (/ 1.0 nrow) step-col (/ 1.0 ncol)] From f9d2d88b03391a6cd2058606ae02070cfa427ea0 Mon Sep 17 00:00:00 2001 From: daslu Date: Thu, 19 Jun 2025 11:33:42 +0300 Subject: [PATCH 5/8] typo --- src/scicloj/tableplot/v1/plotly.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index 713ffdd..a1c0840 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -1460,5 +1460,5 @@ then the density is estimated in groups. (plotly-xform {:data :=grid-traces-no-xform :layout :=grid-layout - ::ht/defaults (assoc standard-defaults + ::ht/defaults (assoc standard-defaults-map :inner-plots plots)})) From 68132abfa6265f47b70dcb7498c4c7ab1ea41b81 Mon Sep 17 00:00:00 2001 From: daslu Date: Thu, 19 Jun 2025 11:53:06 +0300 Subject: [PATCH 6/8] grid WIP --- src/scicloj/tableplot/v1/plotly.clj | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index a1c0840..1425555 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -463,7 +463,7 @@ The design matrix simply uses these columns without any additional transformatio :dragmode :select}))))) (dag/defn-with-deps submap->grid-nrows - nil + "Compute the number of rows for a grid given its inner plots." [=inner-plots] (-> =inner-plots count math/sqrt math/ceil)) @@ -487,7 +487,7 @@ The design matrix simply uses these columns without any additional transformatio (map #(vector (keyword (str "yaxis" %)) (conj axis {:domain (vector (* step-col (dec %)) (* step-col %))})) (range 1 (inc ncol))))))) ;; no gaps between plots -(dag/defn-with-deps grid-traces-no-xform +(dag/defn-with-deps submap->grid-traces nil [=inner-plots =grid-nrows] (let [n (count =inner-plots) @@ -660,7 +660,7 @@ The design matrix simply uses these columns without any additional transformatio "The number of rows in a plot grid."] [:=grid-layout submap->grid-layout "The layout of a plot grid."] - [:=grid-traces grid-traces-no-xform + [:=grid-traces submap->grid-traces "The trace of a plot grid."] [:=colnames submap->colnames "Column names for a SPLOM plot. The default is all columns of the dataset."] @@ -1457,8 +1457,10 @@ then the density is estimated in groups. (defn grid "Arrange a list of plots into a grid." [plots] - (plotly-xform - {:data :=grid-traces-no-xform - :layout :=grid-layout - ::ht/defaults (assoc standard-defaults-map - :inner-plots plots)})) + (-> {:data :=grid-traces + :layout :=grid-layout + ::ht/defaults (merge standard-defaults-map + {:=inner-plots plots})} + plotly-xform)) + + From a4abd132d665d19aa3616c1f61450043cde5a368 Mon Sep 17 00:00:00 2001 From: daslu Date: Thu, 19 Jun 2025 11:55:40 +0300 Subject: [PATCH 7/8] grid - a little simplification --- src/scicloj/tableplot/v1/plotly.clj | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index 1425555..038797a 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -658,10 +658,6 @@ The design matrix simply uses these columns without any additional transformatio "List of plots (used in a grid)"] [:=grid-nrows submap->grid-nrows "The number of rows in a plot grid."] - [:=grid-layout submap->grid-layout - "The layout of a plot grid."] - [:=grid-traces submap->grid-traces - "The trace of a plot grid."] [:=colnames submap->colnames "Column names for a SPLOM plot. The default is all columns of the dataset."] [:=splom-layout submap->splom-layout @@ -1457,10 +1453,12 @@ then the density is estimated in groups. (defn grid "Arrange a list of plots into a grid." [plots] - (-> {:data :=grid-traces - :layout :=grid-layout - ::ht/defaults (merge standard-defaults-map - {:=inner-plots plots})} + (-> view-base + (assoc ::ht/defaults + (merge standard-defaults-map + {:=traces submap->grid-traces + :=layout submap->grid-layout + :=inner-plots plots})) plotly-xform)) From 89bd8e434aa42448f594b2d389878baffefcc815 Mon Sep 17 00:00:00 2001 From: daslu Date: Thu, 19 Jun 2025 12:09:23 +0300 Subject: [PATCH 8/8] grid WIP --- src/scicloj/tableplot/v1/plotly.clj | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/scicloj/tableplot/v1/plotly.clj b/src/scicloj/tableplot/v1/plotly.clj index 038797a..54fa65d 100644 --- a/src/scicloj/tableplot/v1/plotly.clj +++ b/src/scicloj/tableplot/v1/plotly.clj @@ -744,6 +744,7 @@ The design matrix simply uses these columns without any additional transformatio (base submap)))) + (defn plot "The `plot` function realizes a template as a Plotly.js specification." [template] @@ -1453,12 +1454,10 @@ then the density is estimated in groups. (defn grid "Arrange a list of plots into a grid." [plots] - (-> view-base - (assoc ::ht/defaults - (merge standard-defaults-map - {:=traces submap->grid-traces - :=layout submap->grid-layout - :=inner-plots plots})) - plotly-xform)) + (base view-base + (merge standard-defaults-map + {:=traces submap->grid-traces + :=layout submap->grid-layout + :=inner-plots plots})))