Skip to content

Commit 27cd96f

Browse files
committed
Tabelplot param flow - wip
1 parent 7871705 commit 27cd96f

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
^{:kindly/hide-code true
2+
:clay {:title "Tableplot Tutorial: Customizing Plots with Parameter Substitution"
3+
:quarto {:author [:daslu]
4+
:description "Learn how to customize Tableplot visualizations using substitution parameters."
5+
:category :clojure
6+
:type :post
7+
:draft true
8+
:date "2025-11-10"
9+
:tags [:data-visualization :tableplot :tutorial]}}}
10+
(ns data-visualization.tableplot-parameter-flow
11+
(:require [scicloj.kindly.v4.kind :as kind]
12+
[tablecloth.api :as tc]
13+
[scicloj.tableplot.v1.plotly :as plotly]))
14+
15+
^:kindly/hide-code
16+
(kind/hiccup
17+
[:style
18+
".printed-clojure {
19+
max-height:400px;
20+
overflow-y: auto;
21+
}
22+
"])
23+
24+
;; ## Introduction
25+
;;
26+
;; [Tableplot](https://scicloj.github.io/tableplot/) is a declarative plotting library
27+
;; that makes it easy to create interactive visualizations from tabular data. One of its
28+
;; most powerful features is **parameter substitution** - the ability to customize plot
29+
;; appearance and behavior by passing parameters that override defaults.
30+
;;
31+
;; This tutorial is a brief intro to this feature.
32+
33+
;; ## An example problem
34+
;;
35+
;; Let's start with a basic dataset and plot:
36+
37+
;; Assume we have some data.
38+
39+
(def sample-data
40+
(tc/dataset {:x [1 2 3 4 5]
41+
:y [2 4 3 5 7]}))
42+
43+
sample-data
44+
45+
;; In this tutorial, we'll use Tableplot's [Plotly.js](https://plotly.com/javascript/) API,
46+
;; which generates interactive Plotly.js visualizations. Tableplot also supports other backends
47+
;; like Vega-Lite and an experimental transpilation API.
48+
;; We can make a basic line plot. This is really easy, because the
49+
;; `:x` and `:y` columns are used by default for the plot's axes.
50+
51+
(-> sample-data
52+
plotly/layer-line)
53+
54+
;; Assume that now wish to to colour the grid lines: vertical by green,
55+
;; horizontal by red. After all, what would be a
56+
;; better way to teach Tufte's [data-ink ratio](https://infovis-wiki.net/wiki/Data-Ink_Ratio) principle than doing exactly
57+
;; what it asks us to avoid, by adding some chartjunk?
58+
59+
;; Here are a few ways we can do it.
60+
61+
;; ### A brief look inside
62+
63+
;; By default, when used in [Kindly](https://scicloj.github.io/kindly-noted/)-compatible
64+
;; tools like [Clay](https://scicloj.github.io/clay/) and in Clojure Civitas posts,
65+
;; Tableplot's plots are configured to be displayed visually.
66+
67+
;; But we can also change the `kind` annotation, so that we can see them as plain
68+
;; Clojure data structures.
69+
70+
(-> sample-data
71+
plotly/layer-line
72+
kind/pprint)
73+
74+
;; You see, what the API functions such as `plotly/layer-line`
75+
;; generate certain maps called
76+
;; [templats](https://github.com/jsa-aerial/hanami?tab=readme-ov-file#templates-substitution-keys-and-transformations),
77+
;; a brilliant notion coming from
78+
;; the [Hanami](https://github.com/jsa-aerial/hanami) library.
79+
80+
;; This is not the resulting Plotly.js specification yet.
81+
;; It is a potential for it, specifiying lots of partial intermediate
82+
;; values, called susbsitution keys.
83+
;; By Tableplot's convetion, substitution keys will be keywords beginning with `=`,
84+
;; such as `:=layout` or `:=mark-color`.
85+
;; They can have default values, which can also be functions computing
86+
;; them from the values defined by other keys. On the user side,
87+
;; we may override any of these, as we'll see below.
88+
89+
;; What if we actually want to see not the template, but the resulting
90+
;; Plotly.js specification? This is what `plotly/plot` is for.
91+
92+
(-> sample-data
93+
plotly/layer-line
94+
plotly/plot
95+
kind/pprint)
96+
97+
;; ## Using the relevant substitution keys
98+
99+
;; Sometimes, what we need can be precisely specified in Tableplot.
100+
;; You may find the following in Tabelplot's
101+
;; [Plotly API reference](https://scicloj.github.io/tableplot/tableplot_book.plotly_reference.html#yaxis-gridcolor):
102+
103+
;; - [`:=xaxis-gridcolor`](https://scicloj.github.io/tableplot/tableplot_book.plotly_reference.html#xaxis-gridcolor) - The color for the x axis grid lines
104+
;; - [`:=yaxis-gridcolor`](https://scicloj.github.io/tableplot/tableplot_book.plotly_reference.html#yaxis-gridcolor) - The color for the y axis grid lines
105+
106+
;; To use them, you can add a `base` before your plot layers,
107+
;; and configure it with these keys:
108+
109+
(-> sample-data
110+
(plotly/base {:=xaxis-gridcolor "green"
111+
:=yaxis-gridcolor "red"})
112+
plotly/layer-line)
113+
114+
;; ### A brief look inside
115+
116+
;; Let us see what actually has changed in the
117+
;; resulting specification:
118+
119+
(-> sample-data
120+
(plotly/base {:=xaxis-gridcolor "green"
121+
:=yaxis-gridcolor "red"})
122+
plotly/layer-line
123+
plotly/plot
124+
kind/pprint)
125+
126+
;; ## Overriding a broader-scope key
127+
128+
;; Sometimes, you will not find exactly what you need in Tabeplot's
129+
;; prarameter system. Plotly.js itself will always be richer and more
130+
;; flexible.
131+
132+
;; Imagine that the above `:=xaxis-gridcolor` & `:=yaxis-gridcolor` would
133+
;; not be supported.
134+
135+
;; If you read about
136+
;; [Styling and Coloring Axes and the Zero-Line](https://plotly.com/javascript/axes/#styling-and-coloring-axes-and-the-zero-line)
137+
;; in the Plotly.js docs, you will
138+
;; see that, under the `layout` part of the specification,
139+
;; you can specificy `gridcolor` for each of the axes.
140+
141+
;; In Tableplot, we can specify the whole layout using `:=layout`, and thus
142+
;; have anything we need in there.
143+
144+
;; - [`:=layout`](https://scicloj.github.io/tableplot/tableplot_book.plotly_reference.html#layout) - The layout part of the resulting Plotly.js specification
145+
146+
;; By the way, if you read further in that link to the docs, you will see
147+
;; that `:=layout` depends on `:=xaxis-gridcolor` and `:=yaxis-gridcolor`,
148+
;; among other things. When we specified those narrow-scope keys
149+
;; in our previous example, we actually went through affecting the
150+
;; broad-scope key, `:=layout`.
151+
152+
(-> sample-data
153+
(plotly/base {:=layout {:xaxis {:gridcolor "green"}
154+
:yaxis {:gridcolor "red"}}})
155+
plotly/layer-line)
156+
157+
;; Notice that a few other details of the aesthetics have changed,
158+
;; like the plot's background color.
159+
160+
;; That is what happens when we override the whole `:layout`.
161+
;; It is a powerful option, that you may or may not like, depending on
162+
;; your use case.
163+
164+
;; ### A brief look inside
165+
166+
;; Let us see what happens:
167+
168+
(-> sample-data
169+
(plotly/base {:=layout {:xaxis {:gridcolor "green"}
170+
:yaxis {:gridcolor "red"}}})
171+
plotly/layer-line
172+
plotly/plot
173+
kind/pprint)
174+
175+
;; As expected this time, the layout is small and simple,
176+
;; just what you specified.
177+
178+
;; ### Overriding the target `:=layuot`
179+
180+
;; Sometimes, you wish to work with Plotly.js high-level notions,
181+
;; but in a more refined way, preserving most of what we have.
182+
183+
;; Can we do it?
184+
185+
;; Of course, the answer has been was in front of us the whole time:
186+
;; [It's just data](https://www.youtube.com/watch?v=jlPaby7suOc&t=1000s).
187+
188+
;; We do not need to use Tableplot's API for everything.
189+
;; After we call `plotly/plot`, we can process the actual Plotly.js
190+
;; specification, as data.
191+
192+
(-> sample-data
193+
plotly/layer-line
194+
plotly/plot
195+
(assoc-in [:layout :xaxis :gridcolor] "green")
196+
(assoc-in [:layout :yaxis :gridcolor] "red"))

0 commit comments

Comments
 (0)