Skip to content

Commit b4c0954

Browse files
committed
aog wip
1 parent 6bf404c commit b4c0954

1 file changed

Lines changed: 48 additions & 42 deletions

File tree

src/data_visualization/aog_in_clojure_part1.clj

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,8 @@
126126
;; decisions. This is for Tableplot maintainers, contributors, and curious users who
127127
;; want to provide early feedback on the approach.
128128

129-
;; # Setup
130-
;;
131-
;; ### 📖 Reading This Document
129+
;
130+
;; # 📖 Reading This Document
132131
;;
133132
;; Throughout this document, section headers use emojis to indicate the type of content:
134133
;;
@@ -139,6 +138,9 @@
139138
;; This convention helps you navigate the document and quickly find what you're looking for:
140139
;; conceptual explanations (📖), working code (⚙️), or usage examples (🧪).
141140

141+
;; # Setup
142+
143+
;; ### ⚙️ Dependencies
142144
;;
143145
;; This notebook relies on several libraries from the Clojure data science ecosystem.
144146
;; Here's what we use and why:
@@ -185,6 +187,10 @@
185187
;; [**Fastmath**](https://github.com/generateme/fastmath) handles our statistical computations, particularly linear
186188
;; regression. It's a comprehensive math library for Clojure.
187189
;;
190+
;; [**Malli**](https://github.com/metosin/malli) provides schema validation for plot specifications.
191+
;; We define schemas for layers, aesthetics, and plot types to catch errors early
192+
;; and generate helpful error messages. Validation is optional but recommended.
193+
;;
188194
;; [**RDatasets**](https://vincentarelbundock.github.io/Rdatasets/articles/data.html) provides classic datasets (penguins, mtcars, iris) for examples.
189195
;; It is made available in Clojure through [metamorph.ml](https://github.com/scicloj/metamorph.ml).
190196

@@ -202,9 +208,9 @@
202208
;; This approach of
203209
;; ["describing a higher-level 'intent' how your tabular data should be transformed"](https://aog.makie.org/dev/tutorials/intro-i)
204210
;; aligns naturally with Clojure's functional and declarative tendencies—something
205-
;; we've seen in libraries like Hanami, Oz, and others in the ecosystem.
211+
;; we've seen in libraries like Hanami, Tableplot, and others in the ecosystem.
206212
;;
207-
;; We chose AoG because it seemed small enough to grasp and reproduce, while still being
213+
;; We chose AoG because it seemed well-thought, small enough to grasp and reproduce, while still being
208214
;; reasonably complete in its scope.
209215

210216
;; ### 📖 Glossary: Visualization Terminology
@@ -378,7 +384,7 @@
378384
;; **2. Two compositional operators**
379385
;; - `=*` merges layers (like Julia's `*`): `(=* data mapping geom)`
380386
;; - `=+` overlays layers (like Julia's `+`): `(=+ scatter linear)`
381-
;; - Threading-macro friendly: `(-> data (mapping :x :y) (scatter))`
387+
;; - Threading-macro friendly, implicitly merging: `(-> data (mapping :x :y) (scatter))`
382388
;;
383389
;; **3. Minimal delegation strategy**
384390
;; - We compute: statistical transforms, domains (when needed)
@@ -397,7 +403,7 @@
397403
;; - Enables clear distinction between plot configuration and layer data
398404
;;
399405
;; **6. Multi-target rendering**
400-
;; - Same plot spec works across `:geom`, `:vl`, `:plotly`
406+
;; - Same plot spec works across `:geom`, `:vl`, `:plotly` rendering targsts
401407
;; - Backend selection via `:=target` key
402408
;; - Consistent behavior and theming
403409

@@ -416,9 +422,9 @@
416422
;;
417423
;; **Utilities**:
418424
;; - `(plot spec)` - explicitly render (usually auto-displays)
419-
;; - `(facet spec {:col :species})` - add faceting
420-
;; - `(scale :x {:domain [0 100]})` - customize scales
421-
;; - `(target :geom)`, `(size 800 600)` - set plot-level properties
425+
;; - `(facet {:col :species})` - add faceting (compositional)
426+
;; - `(scale :x {:domain [0 100]})` - customize scales (compositional)
427+
;; - `(target :geom)`, `(size 800 600)` - set plot-level properties (compositional)
422428
;;
423429
;; **Auto-display:** Plot specs returned by `=*`, `=+`, and constructors automatically
424430
;; display as plots in Kindly-compatible notebooks. Use `kind/pprint` to inspect
@@ -1230,23 +1236,23 @@
12301236
"Add faceting to a plot specification.
12311237
12321238
Args:
1233-
- spec: Plot spec with :=layers
12341239
- facet-spec: Map with :row and/or :col keys specifying faceting variables
12351240
1236-
Returns plot spec with faceting applied to all layers.
1241+
Returns layer spec with faceting properties.
1242+
1243+
When called with spec as first arg, merges faceting into that spec.
12371244
12381245
Examples:
1239-
(facet spec {:col :species})
1240-
(facet spec {:row :sex :col :island})
1246+
(facet {:col :species})
1247+
(facet {:row :sex :col :island})
12411248
12421249
Threading-friendly:
12431250
(-> penguins (mapping :x :y) (scatter) (facet {:col :species}))"
1244-
[spec facet-spec]
1245-
(displays-as-plot
1251+
([facet-spec]
12461252
(let [facet-keys (update-keys facet-spec =key)]
1247-
(update spec :=layers
1248-
(fn [layers]
1249-
(mapv #(merge % facet-keys) layers))))))
1253+
{:=layers [facet-keys]}))
1254+
([spec facet-spec]
1255+
(=* spec (facet facet-spec))))
12501256

12511257
(defn scale
12521258
"Specify scale properties for an aesthetic.
@@ -3136,30 +3142,30 @@ iris
31363142
;; ### 🧪 Example 10: Simple Column Faceting
31373143
;;
31383144
;; Facet a scatter plot by species - this creates 3 side-by-side plots.
3139-
(facet (=* (data penguins)
3140-
(mapping :bill-length-mm :bill-depth-mm)
3141-
(scatter))
3142-
{:col :species})
3145+
(=* (data penguins)
3146+
(mapping :bill-length-mm :bill-depth-mm)
3147+
(scatter)
3148+
(facet {:col :species}))
31433149

31443150
(kind/test-last [#(and (map? %)
31453151
(contains? % :=layers)
31463152
(= (:=col (first (:=layers %))) :species))])
31473153

31483154
;; Faceted histogram - per-species histograms with shared scales:
31493155

3150-
(facet (-> penguins
3151-
(mapping :bill-length-mm nil)
3152-
(histogram))
3153-
{:col :species})
3156+
(-> penguins
3157+
(mapping :bill-length-mm nil)
3158+
(histogram)
3159+
(facet {:col :species}))
31543160

31553161
;; ### 🧪 Example 11: Row Faceting
31563162
;;
31573163
;; Facet by rows creates vertically stacked panels
31583164

3159-
(facet (=* (data penguins)
3160-
(mapping :bill-length-mm :bill-depth-mm)
3161-
(scatter))
3162-
{:row :species})
3165+
(=* (data penguins)
3166+
(mapping :bill-length-mm :bill-depth-mm)
3167+
(scatter)
3168+
(facet {:row :species}))
31633169

31643170
(kind/test-last [#(and (map? %)
31653171
(contains? % :=layers)
@@ -3170,10 +3176,10 @@ iris
31703176
;; Create a 2D grid of facets.
31713177
;; This creates a 3×2 grid (3 islands × 2 sexes = 6 panels)
31723178

3173-
(facet (=* (data penguins)
3174-
(mapping :bill-length-mm :bill-depth-mm)
3175-
(scatter))
3176-
{:row :island :col :sex})
3179+
(=* (data penguins)
3180+
(mapping :bill-length-mm :bill-depth-mm)
3181+
(scatter)
3182+
(facet {:row :island :col :sex}))
31773183

31783184
(kind/test-last [#(and (map? %)
31793185
(contains? % :=layers)
@@ -3195,13 +3201,13 @@ iris
31953201
;; by species (color) AND island (facet column), computing separate
31963202
;; regressions for each (species × island) combination.
31973203

3198-
(facet (=* (data penguins)
3199-
(mapping :bill-length-mm
3200-
:bill-depth-mm
3201-
{:color :species})
3202-
(=+ (scatter {:alpha 0.5})
3203-
(linear)))
3204-
{:col :island})
3204+
(=* (data penguins)
3205+
(mapping :bill-length-mm
3206+
:bill-depth-mm
3207+
{:color :species})
3208+
(=+ (scatter {:alpha 0.5})
3209+
(linear))
3210+
(facet {:col :island}))
32053211

32063212
;; equivalently:
32073213
(-> (data penguins)

0 commit comments

Comments
 (0)