Public API for plotje -- composable plotting in Clojure.
Public API for plotje -- composable plotting in Clojure.
(->pose x)(->pose x caller)Lift the input to a pose. The first atomic step of the pipeline. Polymorphic on input:
pose-kind (validated, *config*
captured, Kindly auto-render metadata attached); idempotent on
input that already carries the metadata, so repeated lifts are
cheap;:data set and no mapping, run through
prepare-pose so the Kindly metadata is attached.Throws on nil or non-collection scalars. Use (pj/pose) for an
explicit empty leaf instead of passing nil.
The optional caller argument names the public-facing function
shown in error messages, so users see "pj/lay-point requires
data..." rather than an internal helper name. Defaults to
"pj/->pose".
(->pose data) -- raw dataset becomes a leaf pose(->pose pose) -- already a pose; idempotent liftLift the input to a pose. The first atomic step of the pipeline. Polymorphic on input: - a pose-shaped map flows through `pose-kind` (validated, `*config*` captured, Kindly auto-render metadata attached); idempotent on input that already carries the metadata, so repeated lifts are cheap; - raw data (a dataset, vector of row maps, or column map) becomes a leaf pose with `:data` set and no mapping, run through `prepare-pose` so the Kindly metadata is attached. Throws on nil or non-collection scalars. Use `(pj/pose)` for an explicit empty leaf instead of passing nil. The optional `caller` argument names the public-facing function shown in error messages, so users see "pj/lay-point requires data..." rather than an internal helper name. Defaults to "pj/->pose". - `(->pose data)` -- raw dataset becomes a leaf pose - `(->pose pose)` -- already a pose; idempotent lift
(arrange plots)(arrange plots opts)Arrange multiple leaf poses in a grid. Returns a composite pose
that renders through the compositor via membrane -- so :svg,
:bufimg, and any other membrane target work uniformly.
Inputs must be leaf poses. Pre-rendered hiccup is not accepted;
build your own [:div ...] if you need to combine already-rendered
values outside the library.
Opts:
:cols -- explicit column count (default: min(4, n-plots)).
:title -- centered title band above the grid.
:width -- total composite width in pixels.
:height -- total composite height in pixels.
:share-scales -- subset of #{:x :y} shared across cells
(default: #{}).
(arrange [fr-a fr-b]) -- 1x2 row.
(arrange [fr-a fr-b fr-c] {:cols 2 :width 900}) -- 2x2 grid (wraps).
(arrange [[fr-a fr-b] [fr-c fr-d]]) -- explicit 2x2 grid.
Arrange multiple leaf poses in a grid. Returns a composite pose
that renders through the compositor via membrane -- so `:svg`,
`:bufimg`, and any other membrane target work uniformly.
Inputs must be leaf poses. Pre-rendered hiccup is not accepted;
build your own `[:div ...]` if you need to combine already-rendered
values outside the library.
Opts:
- `:cols` -- explicit column count (default: min(4, n-plots)).
- `:title` -- centered title band above the grid.
- `:width` -- total composite width in pixels.
- `:height` -- total composite height in pixels.
- `:share-scales` -- subset of `#{:x :y}` shared across cells
(default: `#{}`).
- `(arrange [fr-a fr-b])` -- 1x2 row.
- `(arrange [fr-a fr-b fr-c] {:cols 2 :width 900})` -- 2x2 grid (wraps).
- `(arrange [[fr-a fr-b] [fr-c fr-d]])` -- explicit 2x2 grid.(composite-draft? x)Return true if x is a composite draft (a tree of sub-drafts with
shared chrome-spec, returned by pj/draft on a composite pose).
Return true if x is a composite draft (a tree of sub-drafts with shared chrome-spec, returned by `pj/draft` on a composite pose).
(composite-plan? x)Return true if x is a composite plan (a tree of sub-plots with shared chrome).
Return true if x is a composite plan (a tree of sub-plots with shared chrome).
(config)Return the effective resolved configuration as a map.
Merges: library defaults < plotje.edn < set-config! < *config*.
Useful for inspecting which values are in effect.
(config) -- show current resolved config.Return the effective resolved configuration as a map. Merges: library defaults < `plotje.edn` < `set-config!` < `*config*`. Useful for inspecting which values are in effect. - `(config)` -- show current resolved config.
Documentation metadata for configuration keys. Maps each config key to [category description]. Use with (pj/config) to build reference tables.
Documentation metadata for configuration keys. Maps each config key to [category description]. Use with (pj/config) to build reference tables.
(coord pose coord-type)Set coordinate transform on a pose. Coord is plot-level -- it applies across every panel. On a composite pose the coord attaches to the root so every descendant leaf inherits it at plan time.
Supported coord-types:
:cartesian -- standard x-right, y-up mapping (the default).:flip -- swap x and y axes (horizontal bars / boxplots).:fixed -- equal aspect ratio (1 data unit = 1 data unit).:polar -- radial mapping: x to angle, y to radius.Set coordinate transform on a pose. Coord is plot-level -- it applies across every panel. On a composite pose the coord attaches to the root so every descendant leaf inherits it at plan time. Supported coord-types: - `:cartesian` -- standard x-right, y-up mapping (the default). - `:flip` -- swap x and y axes (horizontal bars / boxplots). - `:fixed` -- equal aspect ratio (1 data unit = 1 data unit). - `:polar` -- radial mapping: x to angle, y to radius.
(coord-doc k)Return the prose description for a coordinate type keyword.
Returns "(no description)" if no [:key :doc] defmethod is registered.
(coord-doc :polar) returns "Radial mapping: x->angle, y->radius".Return the prose description for a coordinate type keyword. Returns `"(no description)"` if no `[:key :doc]` defmethod is registered. - `(coord-doc :polar)` returns `"Radial mapping: x->angle, y->radius"`.
(cross xs ys)Build a vector of [x y] pairs from two column-name sequences. Pair
with pj/pose for SPLOM grids: when an MxN rectangle of pairs is
threaded through pj/pose, the result is an MxN composite with
shared scales.
(pj/cross [:a :b] [:c :d]) returns [[:a :c] [:a :d] [:b :c] [:b :d]].Build a vector of `[x y]` pairs from two column-name sequences. Pair with `pj/pose` for SPLOM grids: when an MxN rectangle of pairs is threaded through `pj/pose`, the result is an MxN composite with shared scales. - `(pj/cross [:a :b] [:c :d])` returns `[[:a :c] [:a :d] [:b :c] [:b :d]]`.
(draft pose)(draft pose opts)Resolve raw input into a draft. Literal composition of the atomic
steps: (-> x ->pose pose->draft). The 2-arity folds opts into
the pose with pj/options first, mirroring pj/plan and pj/plot:
(-> x ->pose (options opts) draft).
For a leaf pose, returns a LeafDraft record (:layers is a
vector of flat maps, one per applicable layer with merged scope;
:opts carries the pose-level options that flow into the plan
stage). For a composite pose, returns a CompositeDraft carrying
per-leaf drafts (each contextualized -- shared-scale domains
injected, suppress-* flags applied), the resolved chrome geometry,
and the layout (path -> rect).
(draft pose)(draft pose {:width 800 :title "Plot"})Resolve raw input into a draft. Literal composition of the atomic
steps: `(-> x ->pose pose->draft)`. The 2-arity folds opts into
the pose with `pj/options` first, mirroring `pj/plan` and `pj/plot`:
`(-> x ->pose (options opts) draft)`.
For a leaf pose, returns a `LeafDraft` record (`:layers` is a
vector of flat maps, one per applicable layer with merged scope;
`:opts` carries the pose-level options that flow into the plan
stage). For a composite pose, returns a `CompositeDraft` carrying
per-leaf drafts (each contextualized -- shared-scale domains
injected, suppress-* flags applied), the resolved chrome geometry,
and the layout (path -> rect).
- `(draft pose)`
- `(draft pose {:width 800 :title "Plot"})`(draft->membrane draft)(draft->membrane draft opts)Compose draft -> plan -> membrane. The 2-arity takes an opts map
for plan->membrane (e.g. {:tooltip true}).
(draft->membrane (draft pose))(draft->membrane (draft pose) {:tooltip true})Compose draft -> plan -> membrane. The 2-arity takes an opts map
for `plan->membrane` (e.g. `{:tooltip true}`).
- `(draft->membrane (draft pose))`
- `(draft->membrane (draft pose) {:tooltip true})`(draft->plan draft)Single-step transition: convert a draft into a plan. Dispatches on
draft shape -- a LeafDraft carries :layers and pose-level :opts
that flow into plan/draft->plan; a CompositeDraft goes through
compositor/composite-draft->plan (which uses the chrome-spec already
baked in at draft emission).
Plan-stage opts (:width, :height, :title, ...) ride on the
draft itself -- on the LeafDraft's :opts for leaves, on the
CompositeDraft's chrome-spec for composites. Set them on the pose
via pj/options before drafting.
(draft->plan (draft pose))Single-step transition: convert a draft into a plan. Dispatches on draft shape -- a `LeafDraft` carries `:layers` and pose-level `:opts` that flow into `plan/draft->plan`; a `CompositeDraft` goes through `compositor/composite-draft->plan` (which uses the chrome-spec already baked in at draft emission). Plan-stage opts (`:width`, `:height`, `:title`, ...) ride on the draft itself -- on the `LeafDraft`'s `:opts` for leaves, on the `CompositeDraft`'s chrome-spec for composites. Set them on the pose via `pj/options` before drafting. - `(draft->plan (draft pose))`
(draft->plot draft format opts)Compose draft -> plan -> plot for the given format.
(draft->plot (draft pose) :svg {})(draft->plot (draft pose) :bufimg {})Compose draft -> plan -> plot for the given format.
- `(draft->plot (draft pose) :svg {})`
- `(draft->plot (draft pose) :bufimg {})`(draft? x)Return true if x is a draft -- the intermediate representation
produced by pj/pose->draft (and so by pj/draft). A draft is
either a LeafDraft record (leaf pose) or a CompositeDraft
record (composite pose). Used by cross-stage misuse guards on
pj/plan and pj/plot.
Return true if x is a draft -- the intermediate representation produced by `pj/pose->draft` (and so by `pj/draft`). A draft is either a `LeafDraft` record (leaf pose) or a `CompositeDraft` record (composite pose). Used by cross-stage misuse guards on `pj/plan` and `pj/plot`.
(explain-plan plan)Explain why a plan does not conform to the Malli schema.
Returns nil if valid, or a Malli explanation map if invalid.
(explain-plan (plan pose))Explain why a plan does not conform to the Malli schema. Returns `nil` if valid, or a Malli explanation map if invalid. - `(explain-plan (plan pose))`
(facet pose col)(facet pose col direction)Facet a pose by a column.
direction is :col (default, horizontal row) or :row (vertical
column). Faceting is plot-level -- every panel is faceted the same way.
Composite poses are not supported yet.
Facet a pose by a column. `direction` is `:col` (default, horizontal row) or `:row` (vertical column). Faceting is plot-level -- every panel is faceted the same way. Composite poses are not supported yet.
(facet-grid pose col-col row-col)Facet a pose by two columns (2D grid). Faceting is plot-level -- every panel is faceted the same way. Composite poses are not supported yet.
Facet a pose by two columns (2D grid). Faceting is plot-level -- every panel is faceted the same way. Composite poses are not supported yet.
(lay pose-or-data layer-type-key)(lay pose-or-data layer-type-key opts)Add a root-scope layer. The layer attaches to :layers and flows to
every descendant leaf at plan time (composite) or renders on the
single panel (leaf).
Add a root-scope layer. The layer attaches to `:layers` and flows to every descendant leaf at plan time (composite) or renders on the single panel (leaf).
(lay-area pose-or-data)(lay-area pose-or-data x-or-opts)(lay-area pose-or-data x y-or-opts)(lay-area pose-or-data x y opts)Add :area layer type -- filled region between y and the baseline.
Requires x and y (both numerical). Accepts :color, :alpha.
Accepted options: :alpha :color :color-type :data :group :mark :position :stat :x :x-type :y :y-type.
Add `:area` layer type -- filled region between y and the baseline.
Requires x and y (both numerical). Accepts `:color`, `:alpha`.
Accepted options: :alpha :color :color-type :data :group :mark :position
:stat :x :x-type :y :y-type.(lay-band-h _pose-or-data)(lay-band-h pose-or-data x-or-opts)(lay-band-h pose-or-data x y-or-opts)(lay-band-h pose-or-data x y opts)Add :band-h layer -- horizontal shaded band between y = y-min and y = y-max.
Position comes from opts (not data columns); :y-min and :y-max are
required and :y-min must be <= :y-max.
Accepts :y-min (required), :y-max (required), :color (literal
string), :alpha. Bounds may be numeric or temporal (LocalDate,
LocalDateTime, Instant, java.util.Date); temporal values are
converted internally to match the y-axis scale.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the band there (only panels matching that leaf show it).
(lay-band-h pose {:y-min 2 :y-max 4}) -- root-level, flows to every panel.(lay-band-h pose :x :y {:y-min 2 :y-max 4}) -- panel-scope (columns pick
or create a sub-pose).(lay-band-h pose {:y-min 2 :y-max 4 :color "blue" :alpha 0.3})
-- with color and opacity overrides.Accepted options: :alpha :color :data :mark :stat :x :y :y-max :y-min.
Add `:band-h` layer -- horizontal shaded band between y = y-min and y = y-max.
Position comes from opts (not data columns); `:y-min` and `:y-max` are
required and `:y-min` must be <= `:y-max`.
Accepts `:y-min` (required), `:y-max` (required), `:color` (literal
string), `:alpha`. Bounds may be numeric or temporal (LocalDate,
LocalDateTime, Instant, java.util.Date); temporal values are
converted internally to match the y-axis scale.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the band there (only panels matching that leaf show it).
- `(lay-band-h pose {:y-min 2 :y-max 4})` -- root-level, flows to every panel.
- `(lay-band-h pose :x :y {:y-min 2 :y-max 4})` -- panel-scope (columns pick
or create a sub-pose).
- `(lay-band-h pose {:y-min 2 :y-max 4 :color "blue" :alpha 0.3})`
-- with color and opacity overrides.
Accepted options: :alpha :color :data :mark :stat :x :y :y-max :y-min.(lay-band-v _pose-or-data)(lay-band-v pose-or-data x-or-opts)(lay-band-v pose-or-data x y-or-opts)(lay-band-v pose-or-data x y opts)Add :band-v layer -- vertical shaded band between x = x-min and x = x-max.
Position comes from opts (not data columns); :x-min and :x-max are
required and :x-min must be <= :x-max.
Accepts :x-min (required), :x-max (required), :color (literal
string), :alpha. Bounds may be numeric or temporal (LocalDate,
LocalDateTime, Instant, java.util.Date); temporal values are
converted internally to match the x-axis scale.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the band there (only panels matching that leaf show it).
(lay-band-v pose {:x-min 4 :x-max 6}) -- root-level, flows to every panel.(lay-band-v pose :x :y {:x-min 4 :x-max 6}) -- panel-scope (columns pick
or create a sub-pose).(lay-band-v pose {:x-min 4 :x-max 6 :color "blue" :alpha 0.3})
-- with color and opacity overrides.Accepted options: :alpha :color :data :mark :stat :x :x-max :x-min :y.
Add `:band-v` layer -- vertical shaded band between x = x-min and x = x-max.
Position comes from opts (not data columns); `:x-min` and `:x-max` are
required and `:x-min` must be <= `:x-max`.
Accepts `:x-min` (required), `:x-max` (required), `:color` (literal
string), `:alpha`. Bounds may be numeric or temporal (LocalDate,
LocalDateTime, Instant, java.util.Date); temporal values are
converted internally to match the x-axis scale.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the band there (only panels matching that leaf show it).
- `(lay-band-v pose {:x-min 4 :x-max 6})` -- root-level, flows to every panel.
- `(lay-band-v pose :x :y {:x-min 4 :x-max 6})` -- panel-scope (columns pick
or create a sub-pose).
- `(lay-band-v pose {:x-min 4 :x-max 6 :color "blue" :alpha 0.3})`
-- with color and opacity overrides.
Accepted options: :alpha :color :data :mark :stat :x :x-max :x-min :y.(lay-bar pose-or-data)(lay-bar pose-or-data x-or-opts)(lay-bar pose-or-data x y-or-opts)(lay-bar pose-or-data x y opts)Add :bar layer type -- count occurrences of each category.
X-only: pass one categorical column. Accepts :color for grouped bars.
Accepted options: :alpha :color :color-type :data :group :mark :position :stat :x :x-type :y :y-type.
Add `:bar` layer type -- count occurrences of each category.
X-only: pass one categorical column. Accepts `:color` for grouped bars.
Accepted options: :alpha :color :color-type :data :group :mark :position
:stat :x :x-type :y :y-type.(lay-boxplot pose-or-data)(lay-boxplot pose-or-data x-or-opts)(lay-boxplot pose-or-data x y-or-opts)(lay-boxplot pose-or-data x y opts)Add :boxplot layer type -- box-and-whisker plot.
Requires categorical x and numerical y. Shows median, quartiles,
whiskers, and outliers. Accepts :color for grouped boxplots.
Accepted options: :alpha :box-width :color :color-type :data :group :mark :position :size :stat :x :x-type :y :y-type.
Add `:boxplot` layer type -- box-and-whisker plot.
Requires categorical x and numerical y. Shows median, quartiles,
whiskers, and outliers. Accepts `:color` for grouped boxplots.
Accepted options: :alpha :box-width :color :color-type :data :group :mark
:position :size :stat :x :x-type :y :y-type.(lay-contour pose-or-data)(lay-contour pose-or-data x-or-opts)(lay-contour pose-or-data x y-or-opts)(lay-contour pose-or-data x y opts)Add :contour layer type -- iso-density contour lines from 2D KDE.
Requires x and y (both numerical). Accepts {:levels 10} for
the number of contour levels.
Accepted options: :alpha :color :color-type :data :group :levels :mark :position :size :stat :x :x-type :y :y-type.
Add `:contour` layer type -- iso-density contour lines from 2D KDE.
Requires x and y (both numerical). Accepts {`:levels` 10} for
the number of contour levels.
Accepted options: :alpha :color :color-type :data :group :levels :mark
:position :size :stat :x :x-type :y :y-type.(lay-density pose-or-data)(lay-density pose-or-data x-or-opts)(lay-density pose-or-data x y-or-opts)(lay-density pose-or-data x y opts)Add :density layer type -- kernel density estimate curve.
X-only: pass one numerical column. Accepts :color, :bandwidth.
Accepted options: :alpha :bandwidth :color :color-type :data :group :mark :position :stat :x :x-type :y :y-type.
Add `:density` layer type -- kernel density estimate curve.
X-only: pass one numerical column. Accepts `:color`, `:bandwidth`.
Accepted options: :alpha :bandwidth :color :color-type :data :group :mark
:position :stat :x :x-type :y :y-type.(lay-density-2d pose-or-data)(lay-density-2d pose-or-data x-or-opts)(lay-density-2d pose-or-data x y-or-opts)(lay-density-2d pose-or-data x y opts)Add :density-2d layer type -- 2D kernel density heatmap.
Requires x and y (both numerical). Produces a smoothed density
surface as colored tiles with a continuous gradient legend.
Accepted options: :alpha :color :color-type :data :density-2d-grid :group :mark :position :stat :x :x-type :y :y-type.
Add `:density-2d` layer type -- 2D kernel density heatmap.
Requires x and y (both numerical). Produces a smoothed density
surface as colored tiles with a continuous gradient legend.
Accepted options: :alpha :color :color-type :data :density-2d-grid :group
:mark :position :stat :x :x-type :y :y-type.(lay-errorbar pose-or-data)(lay-errorbar pose-or-data x-or-opts)(lay-errorbar pose-or-data x y-or-opts)(lay-errorbar pose-or-data x y opts)Add :errorbar layer type -- vertical error bars from pre-computed bounds.
Requires x, y, and {:y-min :col :y-max :col} for lower/upper bounds.
Accepted options: :alpha :cap-width :color :color-type :data :group :mark :nudge-x :nudge-y :position :size :stat :x :x-type :y :y-max :y-min :y-type.
Add `:errorbar` layer type -- vertical error bars from pre-computed bounds.
Requires x, y, and {`:y-min` `:col` `:y-max` `:col`} for lower/upper bounds.
Accepted options: :alpha :cap-width :color :color-type :data :group :mark
:nudge-x :nudge-y :position :size :stat :x :x-type :y
:y-max :y-min :y-type.(lay-histogram pose-or-data)(lay-histogram pose-or-data x-or-opts)(lay-histogram pose-or-data x y-or-opts)(lay-histogram pose-or-data x y opts)Add :histogram layer type -- bin numerical values into bars.
X-only: pass one column. Accepts :bins (count), :binwidth, :color,
:normalize (:density for density-normalized heights).
Accepted options: :alpha :bins :binwidth :color :color-type :data :group :mark :normalize :position :stat :x :x-type :y :y-type.
Add `:histogram` layer type -- bin numerical values into bars.
X-only: pass one column. Accepts `:bins` (count), `:binwidth`, `:color`,
`:normalize` (`:density` for density-normalized heights).
Accepted options: :alpha :bins :binwidth :color :color-type :data :group
:mark :normalize :position :stat :x :x-type :y :y-type.(lay-interval-h pose-or-data)(lay-interval-h pose-or-data x-or-opts)(lay-interval-h pose-or-data x y-or-opts)(lay-interval-h pose-or-data x y opts)Add :interval-h layer type -- horizontal bar from x to x-end at categorical y.
Each row becomes one rectangle; the y column is treated categorically
so each distinct value occupies its own lane.
Required: x (numeric or temporal start), y (categorical lane),
:x-end column ref in opts (numeric or temporal end).
Accepts :color, :alpha, :interval-thickness (band fill fraction,
0.0-1.0, default 0.7).
(lay-interval-h data :start :task {:x-end :end :color :status})
Accepted options: :alpha :color :color-type :data :group :interval-thickness :mark :stat :x :x-end :x-type :y :y-type.
Add `:interval-h` layer type -- horizontal bar from x to x-end at categorical y.
Each row becomes one rectangle; the y column is treated categorically
so each distinct value occupies its own lane.
Required: x (numeric or temporal start), y (categorical lane),
:x-end column ref in opts (numeric or temporal end).
Accepts `:color`, `:alpha`, `:interval-thickness` (band fill fraction,
0.0-1.0, default 0.7).
(lay-interval-h data :start :task {:x-end :end :color :status})
Accepted options: :alpha :color :color-type :data :group
:interval-thickness :mark :stat :x :x-end :x-type :y
:y-type.(lay-label pose-or-data)(lay-label pose-or-data x-or-opts)(lay-label pose-or-data x y-or-opts)(lay-label pose-or-data x y opts)Add :label layer type -- text labels with background box at data coordinates.
Like :text but with a rectangular background for readability.
Accepted options: :alpha :color :color-type :data :font-size :group :mark :nudge-x :nudge-y :position :stat :text :x :x-type :y :y-type.
Add `:label` layer type -- text labels with background box at data coordinates.
Like `:text` but with a rectangular background for readability.
Accepted options: :alpha :color :color-type :data :font-size :group :mark
:nudge-x :nudge-y :position :stat :text :x :x-type :y
:y-type.(lay-line pose-or-data)(lay-line pose-or-data x-or-opts)(lay-line pose-or-data x y-or-opts)(lay-line pose-or-data x y opts)Add :line layer type -- connected line through data points.
Requires x (numerical) and y (numerical).
Accepts :color, :alpha, :size (stroke width), :nudge-x, :nudge-y.
Accepted options: :alpha :color :color-type :data :group :mark :nudge-x :nudge-y :position :size :stat :x :x-type :y :y-type.
Add `:line` layer type -- connected line through data points.
Requires x (numerical) and y (numerical).
Accepts `:color`, `:alpha`, `:size` (stroke width), `:nudge-x`, `:nudge-y`.
Accepted options: :alpha :color :color-type :data :group :mark :nudge-x
:nudge-y :position :size :stat :x :x-type :y :y-type.(lay-lollipop pose-or-data)(lay-lollipop pose-or-data x-or-opts)(lay-lollipop pose-or-data x y-or-opts)(lay-lollipop pose-or-data x y opts)Add :lollipop layer type -- dot on a stem from the baseline.
Requires categorical x and numerical y. Like value-bar but with
a circle+line instead of a filled rectangle.
Accepted options: :alpha :color :color-type :data :group :mark :position :size :stat :x :x-type :y :y-type.
Add `:lollipop` layer type -- dot on a stem from the baseline.
Requires categorical x and numerical y. Like value-bar but with
a circle+line instead of a filled rectangle.
Accepted options: :alpha :color :color-type :data :group :mark :position
:size :stat :x :x-type :y :y-type.(lay-point pose-or-data)(lay-point pose-or-data x-or-opts)(lay-point pose-or-data x y-or-opts)(lay-point pose-or-data x y opts)Add a :point (scatter) layer to a pose.
Without columns -> bare layer at the pose's root (flows to every leaf).
With columns -> position-bearing layer (attaches to the matching leaf
via DFS-last identity, or appends a new sub-pose on miss).
(lay-point fr) -- bare layer at root.(lay-point fr {:color :species}) -- bare layer with aesthetic opts.(lay-point data :x :y) -- coerce data to a leaf, then attach.(lay-point data :x :y {:color :c}) -- same with aesthetic opts.Accepted options: :alpha :color :color-type :data :group :jitter :mark :nudge-x :nudge-y :position :shape :size :stat :text :x :x-type :y :y-type.
Add a `:point` (scatter) layer to a pose.
Without columns -> bare layer at the pose's root (flows to every leaf).
With columns -> position-bearing layer (attaches to the matching leaf
via DFS-last identity, or appends a new sub-pose on miss).
- `(lay-point fr)` -- bare layer at root.
- `(lay-point fr {:color :species})` -- bare layer with aesthetic opts.
- `(lay-point data :x :y)` -- coerce data to a leaf, then attach.
- `(lay-point data :x :y {:color :c})` -- same with aesthetic opts.
Accepted options: :alpha :color :color-type :data :group :jitter :mark
:nudge-x :nudge-y :position :shape :size :stat :text :x
:x-type :y :y-type.(lay-ridgeline pose-or-data)(lay-ridgeline pose-or-data x-or-opts)(lay-ridgeline pose-or-data x y-or-opts)(lay-ridgeline pose-or-data x y opts)Add :ridgeline layer type -- stacked density curves by category.
Requires categorical x and numerical y. Categories stack vertically
with density curves rendered horizontally.
Accepted options: :alpha :bandwidth :color :color-type :data :group :mark :position :stat :x :x-type :y :y-type.
Add `:ridgeline` layer type -- stacked density curves by category.
Requires categorical x and numerical y. Categories stack vertically
with density curves rendered horizontally.
Accepted options: :alpha :bandwidth :color :color-type :data :group :mark
:position :stat :x :x-type :y :y-type.(lay-rug pose-or-data)(lay-rug pose-or-data x-or-opts)(lay-rug pose-or-data x y-or-opts)(lay-rug pose-or-data x y opts)Add :rug layer type -- short tick marks along the axis showing individual values.
X-only: pass one column. Often layered with density or scatter.
Accepted options: :alpha :color :color-type :data :group :length :mark :position :side :stat :x :x-type :y :y-type.
Add `:rug` layer type -- short tick marks along the axis showing individual values.
X-only: pass one column. Often layered with density or scatter.
Accepted options: :alpha :color :color-type :data :group :length :mark
:position :side :stat :x :x-type :y :y-type.(lay-rule-h _pose-or-data)(lay-rule-h pose-or-data x-or-opts)(lay-rule-h pose-or-data x y-or-opts)(lay-rule-h pose-or-data x y opts)Add :rule-h layer -- horizontal reference line at y = y-intercept.
Position comes from opts (not data columns); :y-intercept is required.
Accepts :y-intercept (numeric or temporal -- LocalDate, LocalDateTime,
Instant, java.util.Date) and :color (literal string).
Temporal values are converted internally to match the y-axis scale
so date-axis annotations work without manual conversion.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the rule there (only panels matching that leaf show it).
(lay-rule-h pose {:y-intercept 3}) -- root-level, flows to every panel.(lay-rule-h pose :x :y {:y-intercept 3}) -- panel-scope (columns pick
or create a sub-pose).(lay-rule-h pose {:y-intercept 3 :color "red"}) -- with override color.(lay-rule-h pose {:y-intercept (java.time.LocalDate/parse "2024-01-01")})
-- temporal intercept on a date axis.Accepted options: :alpha :color :data :mark :stat :x :y :y-intercept.
Add `:rule-h` layer -- horizontal reference line at y = y-intercept.
Position comes from opts (not data columns); `:y-intercept` is required.
Accepts `:y-intercept` (numeric or temporal -- LocalDate, LocalDateTime,
Instant, java.util.Date) and `:color` (literal string).
Temporal values are converted internally to match the y-axis scale
so date-axis annotations work without manual conversion.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the rule there (only panels matching that leaf show it).
- `(lay-rule-h pose {:y-intercept 3})` -- root-level, flows to every panel.
- `(lay-rule-h pose :x :y {:y-intercept 3})` -- panel-scope (columns pick
or create a sub-pose).
- `(lay-rule-h pose {:y-intercept 3 :color "red"})` -- with override color.
- `(lay-rule-h pose {:y-intercept (java.time.LocalDate/parse "2024-01-01")})`
-- temporal intercept on a date axis.
Accepted options: :alpha :color :data :mark :stat :x :y :y-intercept.(lay-rule-v _pose-or-data)(lay-rule-v pose-or-data x-or-opts)(lay-rule-v pose-or-data x y-or-opts)(lay-rule-v pose-or-data x y opts)Add :rule-v layer -- vertical reference line at x = x-intercept.
Position comes from opts (not data columns); :x-intercept is required.
Accepts :x-intercept (numeric or temporal -- LocalDate, LocalDateTime,
Instant, java.util.Date) and :color (literal string).
Temporal values are converted internally to match the x-axis scale
so date-axis annotations work without manual conversion.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the rule there (only panels matching that leaf show it).
(lay-rule-v pose {:x-intercept 5}) -- root-level, flows to every panel.(lay-rule-v pose :x :y {:x-intercept 5}) -- panel-scope (columns pick
or create a sub-pose).(lay-rule-v pose {:x-intercept 5 :color "red"}) -- with override color.(lay-rule-v pose {:x-intercept #inst "2008-09-15"}) -- temporal
intercept on a date axis.Accepted options: :alpha :color :data :mark :stat :x :x-intercept :y.
Add `:rule-v` layer -- vertical reference line at x = x-intercept.
Position comes from opts (not data columns); `:x-intercept` is required.
Accepts `:x-intercept` (numeric or temporal -- LocalDate, LocalDateTime,
Instant, java.util.Date) and `:color` (literal string).
Temporal values are converted internally to match the x-axis scale
so date-axis annotations work without manual conversion.
The 4-arity finds or creates a sub-pose with these x/y columns
and attaches the rule there (only panels matching that leaf show it).
- `(lay-rule-v pose {:x-intercept 5})` -- root-level, flows to every panel.
- `(lay-rule-v pose :x :y {:x-intercept 5})` -- panel-scope (columns pick
or create a sub-pose).
- `(lay-rule-v pose {:x-intercept 5 :color "red"})` -- with override color.
- `(lay-rule-v pose {:x-intercept #inst "2008-09-15"})` -- temporal
intercept on a date axis.
Accepted options: :alpha :color :data :mark :stat :x :x-intercept :y.(lay-smooth pose-or-data)(lay-smooth pose-or-data x-or-opts)(lay-smooth pose-or-data x y-or-opts)(lay-smooth pose-or-data x y opts)Add :smooth layer type -- a smoothed trend line.
Defaults to LOESS (local regression). Pass {:stat :linear-model} for
ordinary least squares instead. Requires x and y (both numerical).
Accepts {:confidence-band true} for a confidence ribbon.
Accepted options: :alpha :bandwidth :bootstrap-resamples :color :color-type :confidence-band :data :group :level :mark :nudge-x :nudge-y :position :size :stat :x :x-type :y :y-type.
Add `:smooth` layer type -- a smoothed trend line.
Defaults to LOESS (local regression). Pass {`:stat` `:linear-model`} for
ordinary least squares instead. Requires x and y (both numerical).
Accepts {`:confidence-band` true} for a confidence ribbon.
Accepted options: :alpha :bandwidth :bootstrap-resamples :color
:color-type :confidence-band :data :group :level :mark
:nudge-x :nudge-y :position :size :stat :x :x-type :y
:y-type.(lay-step pose-or-data)(lay-step pose-or-data x-or-opts)(lay-step pose-or-data x y-or-opts)(lay-step pose-or-data x y opts)Add :step layer type -- staircase line (horizontal then vertical).
Requires x and y (both numerical).
Accepted options: :alpha :color :color-type :data :group :mark :position :size :stat :x :x-type :y :y-type.
Add `:step` layer type -- staircase line (horizontal then vertical).
Requires x and y (both numerical).
Accepted options: :alpha :color :color-type :data :group :mark :position
:size :stat :x :x-type :y :y-type.(lay-summary pose-or-data)(lay-summary pose-or-data x-or-opts)(lay-summary pose-or-data x y-or-opts)(lay-summary pose-or-data x y opts)Add :summary layer type -- mean +/- standard error per category.
Requires categorical x and numerical y. Shows a point at the mean
with error bars for +/- 1 SE. Accepts :color for grouped summaries.
Accepted options: :alpha :color :color-type :data :group :mark :position :size :stat :x :x-type :y :y-type.
Add `:summary` layer type -- mean +/- standard error per category.
Requires categorical x and numerical y. Shows a point at the mean
with error bars for +/- 1 SE. Accepts `:color` for grouped summaries.
Accepted options: :alpha :color :color-type :data :group :mark :position
:size :stat :x :x-type :y :y-type.(lay-text pose-or-data)(lay-text pose-or-data x-or-opts)(lay-text pose-or-data x y-or-opts)(lay-text pose-or-data x y opts)Add :text layer type -- text labels at data coordinates.
Requires x, y, and {:text :column} for label content.
Accepted options: :alpha :color :color-type :data :font-size :group :mark :nudge-x :nudge-y :position :stat :text :x :x-type :y :y-type.
Add `:text` layer type -- text labels at data coordinates.
Requires x, y, and {`:text` `:column`} for label content.
Accepted options: :alpha :color :color-type :data :font-size :group :mark
:nudge-x :nudge-y :position :stat :text :x :x-type :y
:y-type.(lay-tile pose-or-data)(lay-tile pose-or-data x-or-opts)(lay-tile pose-or-data x y-or-opts)(lay-tile pose-or-data x y opts)Add :tile layer type -- colored grid cells (heatmap).
With :fill option: pre-computed tile colors from a column.
Without :fill: auto-binned 2D histogram (stat :bin2d).
Accepted options: :alpha :color :color-type :data :density-2d-grid :fill :group :mark :position :stat :x :x-type :y :y-type.
Add `:tile` layer type -- colored grid cells (heatmap).
With `:fill` option: pre-computed tile colors from a column.
Without `:fill`: auto-binned 2D histogram (stat `:bin2d`).
Accepted options: :alpha :color :color-type :data :density-2d-grid :fill
:group :mark :position :stat :x :x-type :y :y-type.(lay-value-bar pose-or-data)(lay-value-bar pose-or-data x-or-opts)(lay-value-bar pose-or-data x y-or-opts)(lay-value-bar pose-or-data x y opts)Add :value-bar layer type -- bars with pre-computed heights.
Requires categorical x and numerical y. Unlike :bar (which counts),
:value-bar uses the y value directly as the bar height.
Accepted options: :alpha :color :color-type :data :group :mark :position :stat :x :x-type :y :y-type.
Add `:value-bar` layer type -- bars with pre-computed heights.
Requires categorical x and numerical y. Unlike `:bar` (which counts),
`:value-bar` uses the y value directly as the bar height.
Accepted options: :alpha :color :color-type :data :group :mark :position
:stat :x :x-type :y :y-type.(lay-violin pose-or-data)(lay-violin pose-or-data x-or-opts)(lay-violin pose-or-data x y-or-opts)(lay-violin pose-or-data x y opts)Add :violin layer type -- mirrored density estimate by category.
Requires categorical x and numerical y. Accepts :color, :bandwidth.
Accepted options: :alpha :bandwidth :color :color-type :data :group :mark :position :size :stat :x :x-type :y :y-type.
Add `:violin` layer type -- mirrored density estimate by category.
Requires categorical x and numerical y. Accepts `:color`, `:bandwidth`.
Accepted options: :alpha :bandwidth :color :color-type :data :group :mark
:position :size :stat :x :x-type :y :y-type.Documentation for layer option keys accepted by lay- functions. Maps each key to a description string.
Documentation for layer option keys accepted by lay- functions. Maps each key to a description string.
(layer-type-lookup k)Look up a registered layer type by keyword. Returns the layer-type map
(with :mark, :stat, :position, :doc), or nil if not found.
(layer-type-lookup :histogram) returns {:mark :bar, :stat :bin, ...}.Look up a registered layer type by keyword. Returns the layer-type map
(with `:mark`, `:stat`, `:position`, `:doc`), or `nil` if not found.
- `(layer-type-lookup :histogram)` returns `{:mark :bar, :stat :bin, ...}`.(layer-type? x)Return true if x is a layer type (mark + stat + position bundle from the registry).
Return true if x is a layer type (mark + stat + position bundle from the registry).
(leaf-draft? x)Return true if x is a leaf draft (a LeafDraft record carrying
:layers -- a vector of layer maps -- and :opts -- the
pose-level options that flow into the plan stage).
Return true if x is a leaf draft (a `LeafDraft` record carrying `:layers` -- a vector of layer maps -- and `:opts` -- the pose-level options that flow into the plan stage).
(leaf-plan? x)Return true if x is a leaf plan (single-pose resolved geometry).
Return true if x is a leaf plan (single-pose resolved geometry).
(mark-doc k)Return the prose description for a mark keyword.
Returns "(no description)" if no [:key :doc] defmethod is registered.
(mark-doc :point) returns "Filled circle".Return the prose description for a mark keyword. Returns `"(no description)"` if no `[:key :doc]` defmethod is registered. - `(mark-doc :point)` returns `"Filled circle"`.
(membrane pose)(membrane pose opts)Resolve a pose into a membrane tree. Literal composition of the
atomic steps: (let [pose (->pose x), opts (:opts pose {})] (-> pose pose->draft draft->plan (plan->membrane opts))).
The let lifts the pose once so the chain can pluck pose-level
opts and pass them to plan->membrane. The 2-arity folds opts
into the pose with pj/options first.
Returns a vector of membrane.ui drawing primitives carrying
plan-derived :total-width, :total-height, and :title as
metadata. Render-time options (:tooltip, :theme, :palette,
:color-scale, :color-midpoint) ride along on the pose's
:opts and reach plan->membrane through this call.
Useful for exploring rendering targets beyond the SVG and Java2D
backends Plotje wires in today: any consumer that walks a
membrane tree (a Membrane backend, a custom serializer) can take
the result of pj/membrane directly.
(membrane pose)(membrane pose {:tooltip true})Resolve a pose into a membrane tree. Literal composition of the
atomic steps: `(let [pose (->pose x), opts (:opts pose {})]
(-> pose
pose->draft
draft->plan
(plan->membrane opts)))`.
The let lifts the pose once so the chain can pluck pose-level
opts and pass them to `plan->membrane`. The 2-arity folds opts
into the pose with `pj/options` first.
Returns a vector of `membrane.ui` drawing primitives carrying
plan-derived `:total-width`, `:total-height`, and `:title` as
metadata. Render-time options (`:tooltip`, `:theme`, `:palette`,
`:color-scale`, `:color-midpoint`) ride along on the pose's
`:opts` and reach `plan->membrane` through this call.
Useful for exploring rendering targets beyond the SVG and Java2D
backends Plotje wires in today: any consumer that walks a
membrane tree (a Membrane backend, a custom serializer) can take
the result of `pj/membrane` directly.
- `(membrane pose)`
- `(membrane pose {:tooltip true})`(membrane->plot membrane-tree format opts)Convert a membrane drawable tree into a figure for the given format.
Dispatches on format keyword; :svg is always available.
Reads :total-width, :total-height, and :title from
(meta membrane-tree) to size and label the canvas, falling back
to opts if metadata is absent. See the MembraneMeta schema in
scicloj.plotje.impl.membrane-schema for the metadata contract.
(membrane->plot (plan->membrane (plan pose)) :svg {})Convert a membrane drawable tree into a figure for the given format.
Dispatches on format keyword; `:svg` is always available.
Reads `:total-width`, `:total-height`, and `:title` from
`(meta membrane-tree)` to size and label the canvas, falling back
to `opts` if metadata is absent. See the `MembraneMeta` schema in
`scicloj.plotje.impl.membrane-schema` for the metadata contract.
- `(membrane->plot (plan->membrane (plan pose)) :svg {})`(membrane-mark-doc k)Return the prose description for how a mark renders to membrane drawables.
Returns "(no description)" if no [:key :doc] defmethod is registered.
(membrane-mark-doc :point) returns "Translated colored rounded-rectangles".Return the prose description for how a mark renders to membrane drawables. Returns `"(no description)"` if no `[:key :doc]` defmethod is registered. - `(membrane-mark-doc :point)` returns `"Translated colored rounded-rectangles"`.
(options pose opts)Set plot-level options (title, labels, width, height, etc.).
Nested maps (e.g. :theme) are deep-merged.
:width and :height are coerced to long (rounded) so the plan carries
integer pixel dimensions through to render. On a composite pose
the options attach to the root so every descendant leaf inherits
them at plan time.
Set plot-level options (title, labels, width, height, etc.). Nested maps (e.g. `:theme`) are deep-merged. `:width` and `:height` are coerced to long (rounded) so the plan carries integer pixel dimensions through to render. On a composite pose the options attach to the root so every descendant leaf inherits them at plan time.
(plan pose)(plan pose opts)Convert a pose into a plan. Literal composition of the atomic
steps: (-> x ->pose pose->draft draft->plan). The 2-arity folds
opts into the pose with pj/options first:
(-> x ->pose (options opts) plan).
For a leaf pose, returns a Plan record with one panel per facet
variant. For a composite pose, returns a CompositePlan record
with :sub-plots tying each leaf path to its rect and sub-plan,
plus :chrome carrying the resolved layout geometry (title-band,
grid-rect, strip labels, shared-legend spec).
(plan pose)(plan pose {:title "My Plot"})Convert a pose into a plan. Literal composition of the atomic
steps: `(-> x ->pose pose->draft draft->plan)`. The 2-arity folds
opts into the pose with `pj/options` first:
`(-> x ->pose (options opts) plan)`.
For a leaf pose, returns a `Plan` record with one panel per facet
variant. For a composite pose, returns a `CompositePlan` record
with `:sub-plots` tying each leaf path to its rect and sub-plan,
plus `:chrome` carrying the resolved layout geometry (title-band,
grid-rect, strip labels, shared-legend spec).
- `(plan pose)`
- `(plan pose {:title "My Plot"})`(plan->membrane plan-data)(plan->membrane plan-data opts)Convert a plan into a membrane drawable tree.
The 1-arity uses no rendering options. The 2-arity takes an
opts map with optional :tooltip, :theme, :palette, etc.
The returned vector carries plan-derived :total-width,
:total-height, and :title as Clojure metadata. Backends
reading the membrane tree (e.g. via pj/membrane->plot) pick
these up via (meta tree) to size and label the canvas. The
contract is captured by the MembraneMeta schema in
scicloj.plotje.impl.membrane-schema.
(plan->membrane (plan fr))(plan->membrane (plan fr) {:tooltip true})Convert a plan into a membrane drawable tree.
The 1-arity uses no rendering options. The 2-arity takes an
opts map with optional `:tooltip`, `:theme`, `:palette`, etc.
The returned vector carries plan-derived `:total-width`,
`:total-height`, and `:title` as Clojure metadata. Backends
reading the membrane tree (e.g. via `pj/membrane->plot`) pick
these up via `(meta tree)` to size and label the canvas. The
contract is captured by the `MembraneMeta` schema in
`scicloj.plotje.impl.membrane-schema`.
- `(plan->membrane (plan fr))`
- `(plan->membrane (plan fr) {:tooltip true})`(plan->plot plan format opts)Convert a plan into a figure for the given format.
Dispatches on format keyword. Each renderer is a separate namespace
that registers a defmethod; :svg is always available.
(plan->plot (plan fr) :svg {})(plan->plot (plan fr) :plotly {})Convert a plan into a figure for the given format.
Dispatches on format keyword. Each renderer is a separate namespace
that registers a defmethod; `:svg` is always available.
- `(plan->plot (plan fr) :svg {})`
- `(plan->plot (plan fr) :plotly {})`(plan-layer? x)Return true if x is a plan-layer (resolved geometry for one mark).
Return true if x is a plan-layer (resolved geometry for one mark).
(plan? x)Return true if x is a plan (leaf or composite) -- the resolved
geometry returned by pj/plan.
Return true if x is a plan (leaf or composite) -- the resolved geometry returned by `pj/plan`.
(plot pose)(plot pose opts)Render a pose to a figure. The format keyword in the pose's
:opts ({:format :svg} -- default; {:format :bufimg} for
raster PNG via Java2D; or any other registered backend) selects
which membrane->plot defmethod runs.
On a composite pose, leaves are rendered individually and tiled
via the layout in the resolved chrome, in the same chosen format.
The pose flows through the canonical
pose -> draft -> plan -> membrane -> plot pipeline for both
leaf and composite shapes. pj/plot is a literal composition of
the public atomic steps:
(let [pose (->pose x) opts (:opts pose {}) fmt (or (:format opts) :svg)] (-> pose pose->draft draft->plan (plan->membrane opts) (membrane->plot fmt opts)))
Plan-derived dimensions and title ride on the membrane vector's
Clojure metadata; the membrane->plot defmethod reads them from
there.
(plot pose)(plot pose {:width 800 :title "My Plot"})(plot pose {:format :bufimg}) -- returns a BufferedImage.Render a pose to a figure. The format keyword in the pose's
`:opts` (`{:format :svg}` -- default; `{:format :bufimg}` for
raster PNG via Java2D; or any other registered backend) selects
which `membrane->plot` defmethod runs.
On a composite pose, leaves are rendered individually and tiled
via the layout in the resolved chrome, in the same chosen format.
The pose flows through the canonical
`pose -> draft -> plan -> membrane -> plot` pipeline for both
leaf and composite shapes. pj/plot is a literal composition of
the public atomic steps:
`(let [pose (->pose x)
opts (:opts pose {})
fmt (or (:format opts) :svg)]
(-> pose
pose->draft
draft->plan
(plan->membrane opts)
(membrane->plot fmt opts)))`
Plan-derived dimensions and title ride on the membrane vector's
Clojure metadata; the `membrane->plot` defmethod reads them from
there.
- `(plot pose)`
- `(plot pose {:width 800 :title "My Plot"})`
- `(plot pose {:format :bufimg})` -- returns a BufferedImage.Documentation for plot-level option keys. These are accepted by pj/options, pj/plan, and pj/plot but are inherently per-plot (text content or nested config override). Maps each key to [category description].
Documentation for plot-level option keys. These are accepted by pj/options, pj/plan, and pj/plot but are inherently per-plot (text content or nested config override). Maps each key to [category description].
(pose)(pose x)(pose x y)(pose x y z)(pose x y z opts)Construct or extend a pose.
On raw data (first argument is not itself a pose):
(pj/pose) -- empty leaf.(pj/pose data) -- leaf with data; on 1-3 column datasets the
mapping is auto-inferred (:x, then :y, then :color) so the
pose renders without an explicit mapping call.(pj/pose data {:color :species}) -- leaf with aesthetic mapping.(pj/pose data :x-col) -- leaf with {:x :x-col}.(pj/pose data :x-col {:color :c}) -- univariate x with opts.(pj/pose data :x-col :y-col) -- leaf with :x and :y.(pj/pose data :x-col :y-col {:color :c}) -- positional x/y with opts.(pj/pose data [[:a :b] [:c :d]]) -- multi-pair: N bivariate panels.(pj/pose data [:a :b :c]) -- multi-pair: N univariate panels.(pj/pose data (pj/cross cols cols) {:color :c}) -- multi-pair plus
aesthetic mapping at the composite root.Threaded over an existing pose (first argument is a pose):
(pj/pose fr) -- pass-through; lifts a literal map for notebook
auto-render if it is not already tagged.(pj/pose fr :x-col :y-col) -- extend a leaf-without-position, or
promote a leaf-with-position into a 2-panel composite, or append a
panel to a composite.(pj/pose fr :x-col :y-col {:color :c}) -- same, with aesthetic
routed to the composite root on promote.(pj/pose fr {:color :c}) -- aesthetic-only: extend mapping or
(on leaf-with-position) promote.(pj/pose fr [[:a :b] [:c :d]]) -- multi-pair: append N panels.(pj/pose fr (pj/cross cols cols)) -- SPLOM N^2 panels in one call.(pj/pose fr (pj/cross cols cols) {:color :c}) -- SPLOM plus aesthetic
mapping at the composite root.(pj/pose fr {:data X :color :c}) -- extend mapping AND replace the
top-level data with X.On a hand-built pose-shaped map (1-arity, input has :layers or
:poses): the map is validated and tagged with Kindly auto-render
metadata, but its keys are not reordered and its :data is not
coerced -- the typed shape is preserved verbatim. A flat composite
(:poses of leaf maps) is supported; literal nested composites
(any sub-pose itself has :poses) are rejected, matching
pj/arrange's rule that its elements must be leaves.
Construct or extend a pose.
**On raw data (first argument is not itself a pose):**
- `(pj/pose)` -- empty leaf.
- `(pj/pose data)` -- leaf with data; on 1-3 column datasets the
mapping is auto-inferred (`:x`, then `:y`, then `:color`) so the
pose renders without an explicit mapping call.
- `(pj/pose data {:color :species})` -- leaf with aesthetic mapping.
- `(pj/pose data :x-col)` -- leaf with `{:x :x-col}`.
- `(pj/pose data :x-col {:color :c})` -- univariate x with opts.
- `(pj/pose data :x-col :y-col)` -- leaf with `:x` and `:y`.
- `(pj/pose data :x-col :y-col {:color :c})` -- positional x/y with opts.
- `(pj/pose data [[:a :b] [:c :d]])` -- multi-pair: N bivariate panels.
- `(pj/pose data [:a :b :c])` -- multi-pair: N univariate panels.
- `(pj/pose data (pj/cross cols cols) {:color :c})` -- multi-pair plus
aesthetic mapping at the composite root.
**Threaded over an existing pose (first argument is a pose):**
- `(pj/pose fr)` -- pass-through; lifts a literal map for notebook
auto-render if it is not already tagged.
- `(pj/pose fr :x-col :y-col)` -- extend a leaf-without-position, or
promote a leaf-with-position into a 2-panel composite, or append a
panel to a composite.
- `(pj/pose fr :x-col :y-col {:color :c})` -- same, with aesthetic
routed to the composite root on promote.
- `(pj/pose fr {:color :c})` -- aesthetic-only: extend mapping or
(on leaf-with-position) promote.
- `(pj/pose fr [[:a :b] [:c :d]])` -- multi-pair: append N panels.
- `(pj/pose fr (pj/cross cols cols))` -- SPLOM N^2 panels in one call.
- `(pj/pose fr (pj/cross cols cols) {:color :c})` -- SPLOM plus aesthetic
mapping at the composite root.
- `(pj/pose fr {:data X :color :c})` -- extend mapping AND replace the
top-level data with X.
**On a hand-built pose-shaped map (1-arity, input has `:layers` or
`:poses`):** the map is validated and tagged with Kindly auto-render
metadata, but its keys are not reordered and its `:data` is not
coerced -- the typed shape is preserved verbatim. A flat composite
(`:poses` of leaf maps) is supported; literal nested composites
(any sub-pose itself has `:poses`) are rejected, matching
`pj/arrange`'s rule that its elements must be leaves.(pose->draft pose)Single-step transition: convert a pose into a draft. Dispatches on
pose shape -- a leaf pose becomes a LeafDraft (a record carrying
:layers -- a vector of one map per applicable layer with merged
scope -- and :opts -- the pose-level options that flow into the
plan stage); a composite pose becomes a CompositeDraft carrying
per-leaf drafts (each contextualized with shared-scale domains and
chrome-driven opt adjustments), the resolved chrome geometry, and
the layout (path -> rect).
(pose->draft (pj/lay-point data :x :y))Single-step transition: convert a pose into a draft. Dispatches on pose shape -- a leaf pose becomes a `LeafDraft` (a record carrying `:layers` -- a vector of one map per applicable layer with merged scope -- and `:opts` -- the pose-level options that flow into the plan stage); a composite pose becomes a `CompositeDraft` carrying per-leaf drafts (each contextualized with shared-scale domains and chrome-driven opt adjustments), the resolved chrome geometry, and the layout (path -> rect). - `(pose->draft (pj/lay-point data :x :y))`
(pose? x)Return true if x is a pose-shaped plain map (a map carrying at
least one of :layers or :poses).
Return true if x is a pose-shaped plain map (a map carrying at least one of `:layers` or `:poses`).
(position-doc k)Return the prose description for a position keyword.
Returns "(no description)" if no [:key :doc] defmethod is registered.
(position-doc :dodge) returns "Shift groups side-by-side within a band".Return the prose description for a position keyword. Returns `"(no description)"` if no `[:key :doc]` defmethod is registered. - `(position-doc :dodge)` returns `"Shift groups side-by-side within a band"`.
(registered-layer-types)Return all registered layer types as a map of keyword -> layer-type map. Useful for generating documentation tables.
Return all registered layer types as a map of keyword -> layer-type map. Useful for generating documentation tables.
(save pose path)(save pose path opts)Save a plot to a file. Format resolution, in precedence order:
:format in the 3-arity opts map wins (must be :svg or
:png).:format on the pose's :opts (:svg or :png; legacy
:bufimg is translated to :png)..svg -> :svg,
.png -> :png).:svg.When the resolved format and the path extension disagree, prints a warning -- the file still gets the bytes the resolved format produces, but the extension is misleading.
The save vocabulary names the file format. The plot vocabulary
(pj/plot's :format) names the JVM return type -- :svg for
hiccup, :bufimg for a Java2D BufferedImage. A pose-level
:format flows into both contexts; save reinterprets :bufimg
as :png because what hits the disk is a PNG file.
Arguments:
pose -- a pose.path -- file path (string or java.io.File).opts -- same options as plot, but :format accepts only :svg
or :png.Tooltip and brush interactivity are not included in saved files. Returns the path.
(save my-pose "plot.svg") -- SVG.(save my-pose "plot.png") -- inferred PNG.(save my-pose "plot.svg" {:format :png}) -- opts override (warns).Save a plot to a file. Format resolution, in precedence order:
1. `:format` in the 3-arity `opts` map wins (must be `:svg` or
`:png`).
2. `:format` on the pose's `:opts` (`:svg` or `:png`; legacy
`:bufimg` is translated to `:png`).
3. Otherwise inferred from the path extension (`.svg` -> `:svg`,
`.png` -> `:png`).
4. Default `:svg`.
When the resolved format and the path extension disagree, prints
a warning -- the file still gets the bytes the resolved format
produces, but the extension is misleading.
The save vocabulary names the file format. The plot vocabulary
(`pj/plot`'s `:format`) names the JVM return type -- `:svg` for
hiccup, `:bufimg` for a Java2D BufferedImage. A pose-level
`:format` flows into both contexts; save reinterprets `:bufimg`
as `:png` because what hits the disk is a PNG file.
Arguments:
- `pose` -- a pose.
- `path` -- file path (string or `java.io.File`).
- `opts` -- same options as plot, but `:format` accepts only `:svg`
or `:png`.
Tooltip and brush interactivity are not included in saved files.
Returns the path.
- `(save my-pose "plot.svg")` -- SVG.
- `(save my-pose "plot.png")` -- inferred PNG.
- `(save my-pose "plot.svg" {:format :png})` -- opts override (warns).(scale pose channel scale-type)Set scale on a pose. Scale is plot-level -- it applies across every
panel. Accepts a type keyword or a scale spec map with :type, optional
:domain, and optional :breaks (explicit tick locations). On a composite
pose the scale attaches to the root so every descendant leaf inherits
it at plan time.
Channels and accepted scale types:
:x, :y) accept :linear, :log, :categorical.:size, :alpha, :fill, :color) accept
:linear and :log only -- :categorical does not apply.:shape, :group) accept :categorical
only -- :linear and :log do not apply to a discrete encoding.The :domain on a discrete scale gives explicit category order for the
legend.
(scale pose :x :log) -- log scale on x-axis.(scale pose :x {:type :categorical :domain [...]}) -- explicit
category order.(scale pose :y {:type :linear :breaks [0 5 10]}) -- pin tick locations.(scale pose :y {:type :log :domain [1 1000]}) -- log scale with
explicit range.(scale pose :size :log) -- log-spaced point sizes.(scale pose :fill :log) -- log-spaced tile fill.(scale pose :shape {:type :categorical :domain [...]}) -- shape
legend order.Set scale on a pose. Scale is plot-level -- it applies across every
panel. Accepts a type keyword or a scale spec map with `:type`, optional
`:domain`, and optional `:breaks` (explicit tick locations). On a composite
pose the scale attaches to the root so every descendant leaf inherits
it at plan time.
Channels and accepted scale types:
- Axis channels (`:x`, `:y`) accept `:linear`, `:log`, `:categorical`.
- Continuous visual channels (`:size`, `:alpha`, `:fill`, `:color`) accept
`:linear` and `:log` only -- `:categorical` does not apply.
- Discrete visual channels (`:shape`, `:group`) accept `:categorical`
only -- `:linear` and `:log` do not apply to a discrete encoding.
The `:domain` on a discrete scale gives explicit category order for the
legend.
- `(scale pose :x :log)` -- log scale on x-axis.
- `(scale pose :x {:type :categorical :domain [...]})` -- explicit
category order.
- `(scale pose :y {:type :linear :breaks [0 5 10]})` -- pin tick locations.
- `(scale pose :y {:type :log :domain [1 1000]})` -- log scale with
explicit range.
- `(scale pose :size :log)` -- log-spaced point sizes.
- `(scale pose :fill :log)` -- log-spaced tile fill.
- `(scale pose :shape {:type :categorical :domain [...]})` -- shape
legend order.(scale-doc k)Return the prose description for a scale keyword.
Returns "(no description)" if no [:key :doc] defmethod is registered.
(scale-doc :linear) returns "Continuous linear mapping".Return the prose description for a scale keyword. Returns `"(no description)"` if no `[:key :doc]` defmethod is registered. - `(scale-doc :linear)` returns `"Continuous linear mapping"`.
(set-config! m)Set global config overrides. Persists across calls until reset.
(set-config! {:palette :dark2 :theme {:bg "#FFFFFF"}}) -- override
palette and background.(set-config! nil) -- reset to defaults.Set global config overrides. Persists across calls until reset.
- `(set-config! {:palette :dark2 :theme {:bg "#FFFFFF"}})` -- override
palette and background.
- `(set-config! nil)` -- reset to defaults.(stat-doc k)Return the prose description for a stat keyword.
Returns "(no description)" if no [:key :doc] defmethod is registered.
(stat-doc :bin) returns "Bin numerical values into ranges".Return the prose description for a stat keyword. Returns `"(no description)"` if no `[:key :doc]` defmethod is registered. - `(stat-doc :bin)` returns `"Bin numerical values into ranges"`.
(svg-summary svg-or-pose)(svg-summary svg-or-pose theme)Extract structural summary from SVG hiccup for testing.
Returns a map with :width, :height, :panels, :points, :lines,
:polygons, :tiles, :visible-tiles, and :texts -- useful for asserting
plot structure.
Accepts SVG hiccup or a pose (auto-renders to SVG first).
(svg-summary (plot fr)) -- summary of rendered SVG.(svg-summary my-pose) -- auto-renders pose (leaf or composite).Extract structural summary from SVG hiccup for testing. Returns a map with `:width`, `:height`, `:panels`, `:points`, `:lines`, `:polygons`, `:tiles`, `:visible-tiles`, and `:texts` -- useful for asserting plot structure. Accepts SVG hiccup or a pose (auto-renders to SVG first). - `(svg-summary (plot fr))` -- summary of rendered SVG. - `(svg-summary my-pose)` -- auto-renders pose (leaf or composite).
(valid-plan? plan)Check if a plan conforms to the Malli schema.
(valid-plan? (plan pose)) -- true if valid.Check if a plan conforms to the Malli schema. - `(valid-plan? (plan pose))` -- true if valid.
(with-config config-map & body)Execute body with thread-local config overrides.
Overrides take precedence over set-config! and defaults,
but plot options still win.
(with-config {:theme {:bg "#FFF"}} (plot ...))Execute body with thread-local config overrides.
Overrides take precedence over `set-config!` and defaults,
but plot options still win.
- `(with-config {:theme {:bg "#FFF"}} (plot ...))`(with-data pose data)Supply or replace the top-level dataset on a pose. Useful for building a template once and applying it to different datasets:
(def template (-> (pj/pose)
(pj/pose :x :y {:color :group})
pj/lay-point
(pj/lay-smooth {:stat :linear-model})))
(-> template (pj/with-data my-data))
(-> template (pj/with-data other-data))
At attach time, every keyword column reference in the template's
mapping, layers, sub-poses, and facet options must exist in the
dataset -- otherwise an error is thrown naming the missing columns
and listing what is available. Per-layer / per-sub-pose :data
still overrides the top-level data.
Supply or replace the top-level dataset on a pose.
Useful for building a template once and applying it to different
datasets:
(def template (-> (pj/pose)
(pj/pose :x :y {:color :group})
pj/lay-point
(pj/lay-smooth {:stat :linear-model})))
(-> template (pj/with-data my-data))
(-> template (pj/with-data other-data))
At attach time, every keyword column reference in the template's
mapping, layers, sub-poses, and facet options must exist in the
dataset -- otherwise an error is thrown naming the missing columns
and listing what is available. Per-layer / per-sub-pose `:data`
still overrides the top-level data.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |