7 Methods
A method is the bundle that determines how data becomes a visual element. It combines three concepts:
- mark β what shape to draw (points, bars, lines, β¦)
- stat β what computation to apply first (pass through, bin, count, regress, β¦)
- position β how overlapping groups share space (identity, dodge, stack, fill)
Layer functions (sk/lay-point, sk/lay-histogram, sk/lay-bar, sk/lay-lm, etc.) each add a layer with the corresponding method. When no layer is added, napkinsketch infers a method from the column types.
All built-in methods are registered in a data registry. The tables below are generated from that registry β they stay in sync with the code.
(ns napkinsketch-book.methods
(:require
;; Kindly β notebook rendering protocol
[scicloj.kindly.v4.kind :as kind]
;; Napkinsketch β composable plotting
[scicloj.napkinsketch.api :as sk]
;; Method registry β for inspecting method data
[scicloj.napkinsketch.method :as method]
;; String utilities
[clojure.string :as str]))Two helpers used by several tables below.
(defn used-by
"Sorted comma-separated method names whose `field` equals `value`."
[field value]
(->> (method/registered)
(filter (fn [[_ m]] (= value (or (get m field) :identity))))
(map (comp name key))
sort
(str/join ", ")))(defn distinct-in-order
"Distinct values of `field` across methods, in first-seen order."
[field]
(let [seen (volatile! #{})]
(reduce (fn [acc k]
(let [v (get (method/lookup k) field)]
(if (@seen v) acc
(do (vswap! seen conj v) (conj acc v)))))
[] method/method-order)))Methods
Each row is a registered method showing its mark, stat, and position.
(kind/table
{:column-names ["Method" "Mark" "Stat" "Position"]
:row-maps
(for [k method/method-order
:let [m (method/lookup k)]]
{"Method" (kind/code (pr-str k))
"Mark" (kind/code (pr-str (:mark m)))
"Stat" (kind/code (pr-str (:stat m)))
"Position" (kind/code (pr-str (or (:position m) :identity)))})})| Method | Mark | Stat | Position |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Marks
A mark is the visual shape drawn for each data point or group. Several methods may share the same mark β for instance, histogram and value-bar both draw bars, and lm (linear model) and loess (local regression) both draw lines.
(kind/table
{:column-names ["Mark" "Shape" "Used by"]
:row-maps
(for [mk (distinct-in-order :mark)]
{"Mark" (kind/code (pr-str mk))
"Shape" (sk/mark-doc mk)
"Used by" (used-by :mark mk)})})| Mark | Shape | Used by |
|---|---|---|
|
Filled circle | point |
|
Connected path | line, lm, loess |
|
Horizontal-then-vertical path | step |
|
Filled region under a curve | area, density, stacked-area |
|
Vertical rectangles (binned) | histogram |
|
Positioned rectangles | bar, stacked-bar, stacked-bar-fill, value-bar |
|
Grid of colored cells | density2d, tile |
|
Iso-value polylines | contour |
|
Box-and-whisker | boxplot |
|
Mirrored density shape | violin |
|
Stacked density curves | ridgeline |
|
Point with error bar | summary |
|
Vertical error bar | errorbar |
|
Stem with dot | lollipop |
|
Data-driven label | text |
|
Label with background box | label |
|
Axis-margin tick marks | rug |
Stats
A stat (statistical transform) processes raw data before rendering. Each stat takes data-space inputs and produces the geometry that its mark will draw.
(kind/table
{:column-names ["Stat" "What it computes" "Used by"]
:row-maps
(for [st (distinct-in-order :stat)]
{"Stat" (kind/code (pr-str st))
"What it computes" (sk/stat-doc st)
"Used by" (used-by :stat st)})})| Stat | What it computes | Used by |
|---|---|---|
|
Pass-through β no transform | area, errorbar, label, line, lollipop, point, rug, stacked-area, step, text, value-bar |
|
Bin numerical values into ranges | histogram |
|
Count occurrences per category | bar, stacked-bar, stacked-bar-fill |
|
Linear model (lm) β OLS regression line + optional confidence band | lm |
|
LOESS (local regression) smoothing | loess |
|
KDE (kernel density estimation) β 1D | density |
|
2D grid binning (heatmap counts) | tile |
|
2D Gaussian KDE (kernel density estimation) | contour, density2d |
|
Five-number summary + outliers | boxplot |
|
KDE per category (density profile) | ridgeline, violin |
|
Mean Β± standard error per category | summary |
Positions
A position adjustment determines how groups share a categorical axis slot. Position runs between stat computation and rendering.
(kind/table
{:column-names ["Position" "What it does" "Used by"]
:row-maps
(for [pos [:identity :dodge :stack :fill]]
{"Position" (kind/code (pr-str pos))
"What it does" (sk/position-doc pos)
"Used by" (used-by :position pos)})})| Position | What it does | Used by |
|---|---|---|
|
Plot at exact data coordinates (groups overlap) | area, bar, boxplot, contour, density, density2d, errorbar, histogram, label, line, lm, loess, lollipop, point, ridgeline, rug, step, summary, text, tile, value-bar, violin |
|
Shift groups side-by-side within a band | |
|
Pile groups cumulatively | stacked-area, stacked-bar |
|
Stack normalized to [0, 1] (proportions) | stacked-bar-fill |
You can override the default position by passing :position in the layer options. When multiple layers share :position :dodge, they are coordinated together β error bars automatically align with bars.
Layer Options
The options map passed to lay- functions controls aesthetics, statistical parameters, and spatial adjustments for that layer.
Universal options
Accepted by every method:
(kind/table
{:column-names ["Option" "Description"]
:row-maps
(for [k method/universal-layer-options]
{"Option" (kind/code (pr-str k))
"Description" (get method/layer-option-docs k)})})| Option | Description |
|---|---|
|
Column keyword (categorical grouping) or literal color string |
|
Column keyword (per-point opacity) or fixed number 0.0β1.0 |
|
Column keyword for grouping without color |
|
Position adjustment keyword β how overlapping groups are arranged (see sk/position-doc) |
Method-specific options
Some methods accept additional keys beyond the universal set. Methods not listed here accept only the universal options above.
(kind/table
{:column-names ["Method" "Additional options"]
:row-maps
(for [k method/method-order
:let [m (method/lookup k)
accepts (:accepts m)]
:when (seq accepts)]
{"Method" (kind/code (pr-str k))
"Additional options" accepts})})| Method | Additional options |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All layer option keys
(kind/table
{:column-names ["Option" "Description"]
:row-maps
(for [[k desc] (sort-by key method/layer-option-docs)]
{"Option" (kind/code (pr-str k))
"Description" desc})})| Option | Description |
|---|---|
|
Column keyword (per-point opacity) or fixed number 0.0β1.0 |
|
Smoothing bandwidth for density and LOESS methods |
|
Column keyword (categorical grouping) or literal color string |
|
Column keyword for tile fill values (pre-computed heatmap) |
|
Column keyword for grouping without color |
|
true or pixel amount β random offset to reduce overplotting |
|
2D KDE grid resolution β number of bins per axis (default 25) |
|
Number of contour iso-levels (default 5) |
|
Histogram normalization β :density (area integrates to 1) or nil |
|
Shift all x-coordinates by this data-space amount |
|
Shift all y-coordinates by this data-space amount |
|
Position adjustment keyword β how overlapping groups are arranged (see sk/position-doc) |
|
true to show SE (standard error) confidence ribbon around fitted line |
|
Number of bootstrap resamples for LOESS confidence ribbon (default 200) |
|
Column keyword for per-point shape |
|
Rug tick position β :x (default), :y, or :both |
|
Column keyword or fixed number β point radius or stroke width |
|
Column keyword for label content |
|
Column keyword for upper error bound |
|
Column keyword for lower error bound |
Whatβs Next
- Scatter Plots β see point, line, and regression methods in action
- Distributions β histograms, density, boxplots, violins
- Customization β colors, palettes, themes, and per-layer options