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.
:height -- total composite height.
: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.
- `:height` -- total composite height.
- `: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).
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as pj/pose would, so (draft data)
works without an explicit pj/pose call.
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)`.
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as `pj/pose` would, so `(draft data)`
works without an explicit `pj/pose` call.
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}).
Render-stage options set on the original pose via pj/options
(:theme, :palette, ...) ride on the draft's :opts and form
the base; any opts passed here override them per key. This keeps
the explicit pipeline consistent with pj/plot, which feeds the
pose's opts into the membrane stage.
(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}`).
Render-stage options set on the original pose via `pj/options`
(`:theme`, `:palette`, ...) ride on the draft's `:opts` and form
the base; any opts passed here override them per key. This keeps
the explicit pipeline consistent with `pj/plot`, which feeds the
pose's opts into the membrane stage.
- `(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.
Render-stage options set on the original pose via pj/options
(:theme, :palette, ...) ride on the draft's :opts and form
the base; the passed opts override them per key.
(draft->plot (draft pose) :svg {})(draft->plot (draft pose) :bufimg {})Compose draft -> plan -> plot for the given format.
Render-stage options set on the original pose via `pj/options`
(`:theme`, `:palette`, ...) ride on the draft's `:opts` and form
the base; the passed opts override them per key.
- `(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-membrane membrane)Explain why a membrane does not conform to the Malli schema.
Returns nil if valid, or a Malli explanation map if invalid.
(explain-membrane (membrane pose))Explain why a membrane does not conform to the Malli schema. Returns `nil` if valid, or a Malli explanation map if invalid. - `(explain-membrane (membrane pose))`
(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.
(frames plan-or-pose)Where a plot's panels sit on the canvas, and how to get between data space and drawing space.
Takes a plan or a pose; a pose is planned first. Returns a map:
:canvas -- [x y width height] of the whole image, in drawing units:panels -- one entry per panel, each carrying :row, :col,
:coord, :x-domain, :y-domain, :x-scale, :y-scale,
:invertible? and :framesA panel's :frames names two rectangles, both [x y width height]
in canvas coordinates: :panel-box (the panel with its axis margin)
and :drawing-area (the background inside that margin, where data
marks are clipped). The canvas is reported once, at the top: it
belongs to the plot rather than to any panel.
The result contains no functions, so it can be printed, compared and
read back from pr-str. To map between the spaces, pass a panel entry
to pj/to-drawing or pj/to-data.
For a composite, every cell's panels report canvas coordinates, so their rectangles can be compared without further arithmetic.
This is the same computation the renderer draws with. Use it to place your own annotations beside a plot, to compose a Plotje membrane with hand-built Membrane views, or to read a pointer position back as data.
(frames my-pose)(-> my-plan frames :panels first :frames :drawing-area)Where a plot's panels sit on the canvas, and how to get between data space and drawing space. Takes a plan or a pose; a pose is planned first. Returns a map: - `:canvas` -- `[x y width height]` of the whole image, in drawing units - `:panels` -- one entry per panel, each carrying `:row`, `:col`, `:coord`, `:x-domain`, `:y-domain`, `:x-scale`, `:y-scale`, `:invertible?` and `:frames` A panel's `:frames` names two rectangles, both `[x y width height]` in canvas coordinates: `:panel-box` (the panel with its axis margin) and `:drawing-area` (the background inside that margin, where data marks are clipped). The canvas is reported once, at the top: it belongs to the plot rather than to any panel. The result contains no functions, so it can be printed, compared and read back from `pr-str`. To map between the spaces, pass a panel entry to `pj/to-drawing` or `pj/to-data`. For a composite, every cell's panels report canvas coordinates, so their rectangles can be compared without further arithmetic. This is the same computation the renderer draws with. Use it to place your own annotations beside a plot, to compose a Plotje membrane with hand-built Membrane views, or to read a pointer position back as data. - `(frames my-pose)` - `(-> my-plan frames :panels first :frames :drawing-area)`
(infer-mapping fr)Infer and attach a default mapping to a pose that carries data but
no mapping yet -- the fresh leaf pj/->pose produces from raw
input. Position and color are taken from the first 1-3 columns
(1 column to :x, 2 columns to :x and :y, 3 columns add
:color).
A pose that already has a mapping, has layers, is composite, or
has 4+ columns is returned unchanged, so the step is idempotent
and safe to include anywhere in a pipeline. This is the step that
lets raw data render a sensible default: the user-facing entry
points (pj/pose 1-arity and the shortcuts pj/draft, pj/plan,
pj/membrane, pj/plot, pj/save) apply it right after
pj/->pose, while pj/->pose itself stays a bare structural lift.
(-> data pj/->pose pj/infer-mapping) -- lift, then default map(pj/infer-mapping built-pose) -- no-op on an already-mapped poseInfer and attach a default mapping to a pose that carries data but no mapping yet -- the fresh leaf `pj/->pose` produces from raw input. Position and color are taken from the first 1-3 columns (1 column to `:x`, 2 columns to `:x` and `:y`, 3 columns add `:color`). A pose that already has a mapping, has layers, is composite, or has 4+ columns is returned unchanged, so the step is idempotent and safe to include anywhere in a pipeline. This is the step that lets raw data render a sensible default: the user-facing entry points (`pj/pose` 1-arity and the shortcuts `pj/draft`, `pj/plan`, `pj/membrane`, `pj/plot`, `pj/save`) apply it right after `pj/->pose`, while `pj/->pose` itself stays a bare structural lift. - `(-> data pj/->pose pj/infer-mapping)` -- lift, then default map - `(pj/infer-mapping built-pose)` -- no-op on an already-mapped pose
(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 (fill), :alpha,
and an opt-in outline on the top curve: :stroke (outline color),
:stroke-width, :stroke-dash.
Accepted options: :alpha :color :color-type :data :group :in :mark :offset-x :offset-y :position :stat :stroke :stroke-dash :stroke-width :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` (fill), `:alpha`,
and an opt-in outline on the top curve: `:stroke` (outline color),
`:stroke-width`, `:stroke-dash`.
Accepted options: :alpha :color :color-type :data :group :in :mark
:offset-x :offset-y :position :stat :stroke :stroke-dash
:stroke-width :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 :offset-x :offset-y :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 :offset-x :offset-y :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 :offset-x :offset-y :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 :offset-x :offset-y :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 a :bar layer type.
The stat is inferred from whether a y column is present, and overridable:
pass {:stat :count} to count even with a y column, or {:stat :identity}
to require an explicit height. :color (with :position :dodge/:stack)
gives grouped or stacked bars.
The categorical axis can be x (vertical bars) or y (horizontal bars):
(pj/lay-bar :value :category) with a categorical y draws horizontal value
bars, no pj/coord needed. (Stacked/filled horizontal bars are not yet
supported directly -- put the category on x and add (pj/coord :flip).)
To treat a numeric column as categorical, pass {:x-type :categorical}
(or {:y-type :categorical}).
When both axes are numeric or temporal ((pj/lay-bar :x :y) with no
categorical axis), each bar sits at its x position with a width taken from
0.9 of the smallest gap between adjacent x values -- a time-series or
numeric-position bar chart. Pass {:bar-width n} (data units) to set the
width. Grouped numeric bars currently overlap rather than dodge.
Accepted options: :alpha :bar-width :color :color-type :data :group :in :mark :offset-x :offset-y :position :stat :x :x-type :y :y-type.
Add a `:bar` layer type.
- One column (x only): counts occurrences of each category. Requires a
categorical x.
- Two columns (x and y): uses the y value directly as the bar height.
The stat is inferred from whether a y column is present, and overridable:
pass `{:stat :count}` to count even with a y column, or `{:stat :identity}`
to require an explicit height. `:color` (with `:position` `:dodge`/`:stack`)
gives grouped or stacked bars.
The categorical axis can be x (vertical bars) or y (horizontal bars):
`(pj/lay-bar :value :category)` with a categorical y draws horizontal value
bars, no `pj/coord` needed. (Stacked/filled horizontal bars are not yet
supported directly -- put the category on x and add `(pj/coord :flip)`.)
To treat a numeric column as categorical, pass `{:x-type :categorical}`
(or `{:y-type :categorical}`).
When both axes are numeric or temporal (`(pj/lay-bar :x :y)` with no
categorical axis), each bar sits at its x position with a width taken from
`0.9` of the smallest gap between adjacent x values -- a time-series or
numeric-position bar chart. Pass `{:bar-width n}` (data units) to set the
width. Grouped numeric bars currently overlap rather than dodge.
Accepted options: :alpha :bar-width :color :color-type :data :group :in
:mark :offset-x :offset-y :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 :in :mark :offset-x :offset-y :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 :in
:mark :offset-x :offset-y :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 :in :levels :mark :offset-x :offset-y :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 :in :levels :mark
:offset-x :offset-y :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 (fill),
:bandwidth, and an opt-in outline on the curve: :stroke (outline
color), :stroke-width, :stroke-dash (:dashed/:dotted/:solid
or a raw [dash gap] vector).
Accepted options: :alpha :bandwidth :color :color-type :data :group :in :mark :offset-x :offset-y :position :stat :stroke :stroke-dash :stroke-width :trim :x :x-type :y :y-type.
Add `:density` layer type -- kernel density estimate curve.
X-only: pass one numerical column. Accepts `:color` (fill),
`:bandwidth`, and an opt-in outline on the curve: `:stroke` (outline
color), `:stroke-width`, `:stroke-dash` (`:dashed`/`:dotted`/`:solid`
or a raw `[dash gap]` vector).
Accepted options: :alpha :bandwidth :color :color-type :data :group :in
:mark :offset-x :offset-y :position :stat :stroke
:stroke-dash :stroke-width :trim :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 :in :mark :offset-x :offset-y :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
:in :mark :offset-x :offset-y :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 :in :mark :nudge-x :nudge-y :offset-x :offset-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 :in
:mark :nudge-x :nudge-y :offset-x :offset-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 :in :mark :normalize :offset-x :offset-y :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
:in :mark :normalize :offset-x :offset-y :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 :in :interval-thickness :mark :offset-x :offset-y :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 :in
:interval-thickness :mark :offset-x :offset-y :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 on a background box at data
coordinates, for readability over dense data.
:label is the :text layer type with {:box true} preset, so it
draws through the same mark and takes the same options, including
:align-x/:align-y (defaults :left/:center); the box follows the
anchored text. Pass :box to shape it -- {:box {:corner-radius 0}}
for square corners, {:box false} for bare text.
Accepted options: :align-x :align-y :alpha :box :color :color-type :data :font-size :font-style :font-weight :group :in :mark :nudge-x :nudge-y :offset-x :offset-y :position :stat :text :x :x-type :y :y-type.
Add `:label` layer type -- text labels on a background box at data
coordinates, for readability over dense data.
`:label` is the `:text` layer type with `{:box true}` preset, so it
draws through the same mark and takes the same options, including
`:align-x`/`:align-y` (defaults `:left`/`:center`); the box follows the
anchored text. Pass `:box` to shape it -- `{:box {:corner-radius 0}}`
for square corners, `{:box false}` for bare text.
Accepted options: :align-x :align-y :alpha :box :color :color-type :data
:font-size :font-style :font-weight :group :in :mark
:nudge-x :nudge-y :offset-x :offset-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), :stroke-dash
(:dashed/:dotted/:solid or a raw [dash gap] vector), :nudge-x,
:nudge-y.
Accepted options: :alpha :color :color-type :data :group :in :mark :nudge-x :nudge-y :offset-x :offset-y :position :size :stat :stroke-dash :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), `:stroke-dash`
(`:dashed`/`:dotted`/`:solid` or a raw `[dash gap]` vector), `:nudge-x`,
`:nudge-y`.
Accepted options: :alpha :color :color-type :data :group :in :mark
:nudge-x :nudge-y :offset-x :offset-y :position :size
:stat :stroke-dash :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 a value bar but with
a circle+line instead of a filled rectangle.
Accepted options: :alpha :color :color-type :data :group :in :mark :offset-x :offset-y :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 a value bar but with
a circle+line instead of a filled rectangle.
Accepted options: :alpha :color :color-type :data :group :in :mark
:offset-x :offset-y :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 layer options.(lay-point data :x :y) -- coerce data to a leaf, then attach.(lay-point data :x :y {:color :c}) -- same with layer options.Accepted options: :alpha :color :color-type :data :group :in :jitter :mark :nudge-x :nudge-y :offset-x :offset-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 layer options.
- `(lay-point data :x :y)` -- coerce data to a leaf, then attach.
- `(lay-point data :x :y {:color :c})` -- same with layer options.
Accepted options: :alpha :color :color-type :data :group :in :jitter :mark
:nudge-x :nudge-y :offset-x :offset-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 :in :mark :offset-x :offset-y :position :stat :trim :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 :in
:mark :offset-x :offset-y :position :stat :trim :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 :in :length :mark :offset-x :offset-y :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 :in :length :mark
:offset-x :offset-y :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), :color (literal string), and :stroke-dash
(:dashed/:dotted/:solid or a raw [dash gap] vector).
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 :offset-x :offset-y :stat :stroke-dash :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), `:color` (literal string), and `:stroke-dash`
(`:dashed`/`:dotted`/`:solid` or a raw `[dash gap]` vector).
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 :offset-x :offset-y :stat
:stroke-dash :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), :color (literal string), and :stroke-dash
(:dashed/:dotted/:solid or a raw [dash gap] vector).
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 :offset-x :offset-y :stat :stroke-dash :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), `:color` (literal string), and `:stroke-dash`
(`:dashed`/`:dotted`/`:solid` or a raw `[dash gap]` vector).
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 :offset-x :offset-y :stat
:stroke-dash :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, and
:stroke-dash.
Accepted options: :alpha :bandwidth :bootstrap-resamples :color :color-type :confidence-band :data :group :in :level :mark :nudge-x :nudge-y :offset-x :offset-y :position :size :stat :stroke-dash :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, and
`:stroke-dash`.
Accepted options: :alpha :bandwidth :bootstrap-resamples :color
:color-type :confidence-band :data :group :in :level
:mark :nudge-x :nudge-y :offset-x :offset-y :position
:size :stat :stroke-dash :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). Accepts :stroke-dash.
Accepted options: :alpha :color :color-type :data :group :in :mark :offset-x :offset-y :position :size :stat :stroke-dash :x :x-type :y :y-type.
Add `:step` layer type -- staircase line (horizontal then vertical).
Requires x and y (both numerical). Accepts `:stroke-dash`.
Accepted options: :alpha :color :color-type :data :group :in :mark
:offset-x :offset-y :position :size :stat :stroke-dash
: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 :in :mark :offset-x :offset-y :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 :in :mark
:offset-x :offset-y :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.
:align-x (:left/:center/:right, default :left) and :align-y
(:top/:center/:bottom, default :center) set which part of the
text lands on the data point -- e.g. :align-x :right tucks the label
inside a bar's end, extending leftward.
:box puts the text on a background box: true for the default box,
or a map of box properties ({:corner-radius 8}). pj/lay-label is
this layer with the box on.
Accepted options: :align-x :align-y :alpha :box :color :color-type :data :font-size :font-style :font-weight :group :in :mark :nudge-x :nudge-y :offset-x :offset-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.
`:align-x` (`:left`/`:center`/`:right`, default `:left`) and `:align-y`
(`:top`/`:center`/`:bottom`, default `:center`) set which part of the
text lands on the data point -- e.g. `:align-x :right` tucks the label
inside a bar's end, extending leftward.
`:box` puts the text on a background box: `true` for the default box,
or a map of box properties (`{:corner-radius 8}`). `pj/lay-label` is
this layer with the box on.
Accepted options: :align-x :align-y :alpha :box :color :color-type :data
:font-size :font-style :font-weight :group :in :mark
:nudge-x :nudge-y :offset-x :offset-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 :in :mark :offset-x :offset-y :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 :in :mark :offset-x :offset-y :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 :in :mark :offset-x :offset-y :position :size :stat :trim :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 :in
:mark :offset-x :offset-y :position :size :stat :trim :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 PlotjeMembrane. 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 PlotjeMembrane -- a Membrane UI component (implements
IOrigin, IBounds, IChildren) carrying the rendered drawables
plus plan-derived width and height; the title, when set, rides as
:plotje/title. 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 Membrane backend can consume
the result of pj/membrane via the standard Membrane protocols.
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as pj/pose would, so
(membrane data) works without an explicit pj/pose call.
(membrane pose)(membrane pose {:tooltip true})Resolve a pose into a `PlotjeMembrane`. 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 `PlotjeMembrane` -- a Membrane UI component (implements
`IOrigin`, `IBounds`, `IChildren`) carrying the rendered drawables
plus plan-derived width and height; the title, when set, rides as
`:plotje/title`. 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 Membrane backend can consume
the result of `pj/membrane` via the standard Membrane protocols.
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as `pj/pose` would, so
`(membrane data)` works without an explicit `pj/pose` call.
- `(membrane pose)`
- `(membrane pose {:tooltip true})`(membrane->plot membrane-tree format opts)Convert a PlotjeMembrane into a figure for the given format.
Dispatches on format keyword; :svg is always available.
Reads width and height from the membrane via
(membrane.ui/width m) / (membrane.ui/height m) (so any
Membrane backend can introspect the canvas size), and the title
from (:plotje/title m).
(membrane->plot (plan->membrane (plan pose)) :svg {})Convert a `PlotjeMembrane` into a figure for the given format.
Dispatches on format keyword; `:svg` is always available.
Reads width and height from the membrane via
`(membrane.ui/width m)` / `(membrane.ui/height m)` (so any
Membrane backend can introspect the canvas size), and the title
from `(:plotje/title m)`.
- `(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"`.
(membrane? x)Return true if x is a PlotjeMembrane -- the value returned by
pj/plan->membrane and pj/membrane. A PlotjeMembrane is a
Membrane UI component (implements IOrigin, IBounds,
IChildren) carrying the rendered drawables and plan-derived
width/height; the plot title rides as :plotje/title.
Return true if x is a `PlotjeMembrane` -- the value returned by `pj/plan->membrane` and `pj/membrane`. A `PlotjeMembrane` is a Membrane UI component (implements `IOrigin`, `IBounds`, `IChildren`) carrying the rendered drawables and plan-derived width/height; the plot title rides as `:plotje/title`.
(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 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 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).
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as pj/pose would, so (plan data)
works without an explicit pj/pose call.
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)`.
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as `pj/pose` would, so `(plan data)`
works without an explicit `pj/pose` call.
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 PlotjeMembrane -- a Membrane UI component
carrying the rendered drawables, plan-derived width and height,
and the plot title.
The 1-arity uses no rendering options. The 2-arity takes an
opts map with optional :tooltip, :theme, :palette, etc.
The result implements membrane.ui IOrigin, IBounds, and
IChildren, so width and height are accessible via
(membrane.ui/width m) and (membrane.ui/height m). The title,
when set, rides as :plotje/title. Future per-membrane
attributes use the same :plotje/* namespaced-keyword convention.
The shape is captured by the PlotjeMembraneSchema in
scicloj.plotje.impl.membrane.
(plan->membrane (plan fr))(plan->membrane (plan fr) {:tooltip true})Convert a plan into a `PlotjeMembrane` -- a Membrane UI component
carrying the rendered drawables, plan-derived width and height,
and the plot title.
The 1-arity uses no rendering options. The 2-arity takes an
opts map with optional `:tooltip`, `:theme`, `:palette`, etc.
The result implements `membrane.ui` `IOrigin`, `IBounds`, and
`IChildren`, so width and height are accessible via
`(membrane.ui/width m)` and `(membrane.ui/height m)`. The title,
when set, rides as `:plotje/title`. Future per-membrane
attributes use the same `:plotje/*` namespaced-keyword convention.
The shape is captured by the `PlotjeMembraneSchema` in
`scicloj.plotje.impl.membrane`.
- `(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 ride as record fields on the membrane
(accessed via membrane.ui/width/membrane.ui/height); the
title rides as :plotje/title. membrane->plot reads them from
there.
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as pj/pose would, so (plot data)
renders the inferred default instead of a blank figure.
(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 ride as record fields on the membrane
(accessed via `membrane.ui/width`/`membrane.ui/height`); the
title rides as `:plotje/title`. `membrane->plot` reads them from
there.
Raw data (a dataset or a bare collection of values) is given a
default mapping first, exactly as `pj/pose` would, so `(plot data)`
renders the inferred default instead of a blank figure.
- `(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 the file on disk is a PNG.
Arguments:
pose -- a pose, or raw data (a dataset or a bare collection of
values), which is given a default mapping first, exactly as
pj/pose would.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 written file as a java.io.File carrying :kind/image
metadata, so evaluating a pj/save call in a notebook also shows
the saved chart. The file prints as its path and compares equal to
a plain java.io.File on the same path, so (str (pj/save ...))
still gives the path string.
(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 the file on disk is a PNG.
Arguments:
- `pose` -- a pose, or raw data (a dataset or a bare collection of
values), which is given a default mapping first, exactly as
`pj/pose` would.
- `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 written file as a `java.io.File` carrying `:kind/image`
metadata, so evaluating a `pj/save` call in a notebook also shows
the saved chart. The file prints as its path and compares equal to
a plain `java.io.File` on the same path, so `(str (pj/save ...))`
still gives the path string.
- `(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, optional :breaks (explicit tick locations), optional
:labels (custom tick text paired with :breaks), and optional
:n-ticks (thin a categorical axis to about this many ticks). 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. On :shape, :values supplies the symbols to draw those
categories with, in the same order; pj/shape-symbols lists the ones
available.
:labels requires :breaks and must match it in count. Use it to
render numeric positions with custom text -- for example, days of the
week on a tile heatmap.
:n-ticks thins a crowded categorical axis to about that many
evenly-spaced tick labels (a categorical axis otherwise labels every
category). It applies to discrete axes; numeric axes control tick
density through the :tick-spacing-x / :tick-spacing-y options.
(scale pose :x :log) -- log scale on x-axis.(scale pose :x {:type :categorical :domain [...]}) -- explicit
category order.(scale pose :x {:n-ticks 8}) -- thin a crowded categorical axis to
about eight evenly-spaced tick labels.(scale pose :y {:type :linear :breaks [0 5 10]}) -- pin tick locations.(scale pose :x {:type :linear :breaks [1 2 3 4 5 6 7] :labels ["Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"]})
-- numeric positions with custom tick text.(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 pose :shape {:values [:cross :plus]}) -- pick the symbols.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`, optional `:breaks` (explicit tick locations), optional
`:labels` (custom tick text paired with `:breaks`), and optional
`:n-ticks` (thin a categorical axis to about this many ticks). 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. On `:shape`, `:values` supplies the symbols to draw those
categories with, in the same order; `pj/shape-symbols` lists the ones
available.
`:labels` requires `:breaks` and must match it in count. Use it to
render numeric positions with custom text -- for example, days of the
week on a tile heatmap.
`:n-ticks` thins a crowded categorical axis to about that many
evenly-spaced tick labels (a categorical axis otherwise labels every
category). It applies to discrete axes; numeric axes control tick
density through the `:tick-spacing-x` / `:tick-spacing-y` options.
- `(scale pose :x :log)` -- log scale on x-axis.
- `(scale pose :x {:type :categorical :domain [...]})` -- explicit
category order.
- `(scale pose :x {:n-ticks 8})` -- thin a crowded categorical axis to
about eight evenly-spaced tick labels.
- `(scale pose :y {:type :linear :breaks [0 5 10]})` -- pin tick locations.
- `(scale pose :x {:type :linear :breaks [1 2 3 4 5 6 7]
:labels ["Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"]})`
-- numeric positions with custom tick text.
- `(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 pose :shape {:values [:cross :plus]})` -- pick the symbols.(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.The marker symbols a categorical :shape mapping draws with, in the
order they are assigned to categories. A plot with more categories
than this repeats a symbol, so two categories cannot be told apart;
that warns at plan time. Pass a selection of these as :values to
(pj/scale pose :shape {:values [...]}) to choose them yourself.
The marker symbols a categorical `:shape` mapping draws with, in the
order they are assigned to categories. A plot with more categories
than this repeats a symbol, so two categories cannot be told apart;
that warns at plan time. Pass a selection of these as `:values` to
`(pj/scale pose :shape {:values [...]})` to choose them yourself.(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,
:dashed-lines, :dash-patterns, :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`, `:dashed-lines`, `:dash-patterns`, `: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).
(to-data panel data)(to-data panel cx cy)What data positions the canvas coordinates name, for one panel of
pj/frames. The inverse of pj/to-drawing. An interaction reads
this direction: which value is under the pointer, which range a
selection covers.
Throws under a coordinate system with no inverse. :polar maps x and
y together to an angle and a radius, so a canvas position there does
not name one pair of data values. A panel entry reports which case it
is in :invertible?.
(to-data panel 412.0 88.5) returns [x y] in data values(to-data panel {:x [412.0] :y [88.5]}) returns a dataset with the
same two column names, now in data valuesA continuous axis answers with numbers, so its column is :float64.
A categorical axis answers with the category whose band holds the
position, so its column holds those.
What data positions the canvas coordinates name, for one panel of
`pj/frames`. The inverse of `pj/to-drawing`. An interaction reads
this direction: which value is under the pointer, which range a
selection covers.
Throws under a coordinate system with no inverse. `:polar` maps x and
y together to an angle and a radius, so a canvas position there does
not name one pair of data values. A panel entry reports which case it
is in `:invertible?`.
- `(to-data panel 412.0 88.5)` returns `[x y]` in data values
- `(to-data panel {:x [412.0] :y [88.5]})` returns a dataset with the
same two column names, now in data values
A continuous axis answers with numbers, so its column is `:float64`.
A categorical axis answers with the category whose band holds the
position, so its column holds those.(to-drawing panel data)(to-drawing panel x y)Where data positions land on the canvas, for one panel of pj/frames.
Takes a panel entry -- an element of (:panels (frames plot)) -- and
either one x and y, or a dataset of them with :x and :y columns.
The dataset arity maps whole columns and builds the panel's scales
once, so it is the one to reach for when placing many positions.
(to-drawing panel 3.2 21.0) returns [x y] in canvas coordinates(to-drawing panel {:x [3.2 4.0] :y [21.0 18.5]}) returns a dataset
with the same two column names, now in canvas coordinatesA dataset rather than a collection of pairs because the two
coordinates of a point share one index space, which a dataset states
and two loose sequences only promise. Anything tc/dataset coerces
works.
The result is in canvas coordinates, measured from the top left of the
whole image. A {:in :drawing-area} layer measures from the drawing
area's own corner instead, so drawing these positions back means
subtracting that corner first.
Where data positions land on the canvas, for one panel of `pj/frames`.
Takes a panel entry -- an element of `(:panels (frames plot))` -- and
either one x and y, or a dataset of them with `:x` and `:y` columns.
The dataset arity maps whole columns and builds the panel's scales
once, so it is the one to reach for when placing many positions.
- `(to-drawing panel 3.2 21.0)` returns `[x y]` in canvas coordinates
- `(to-drawing panel {:x [3.2 4.0] :y [21.0 18.5]})` returns a dataset
with the same two column names, now in canvas coordinates
A dataset rather than a collection of pairs because the two
coordinates of a point share one index space, which a dataset states
and two loose sequences only promise. Anything `tc/dataset` coerces
works.
The result is in canvas coordinates, measured from the top left of the
whole image. A `{:in :drawing-area}` layer measures from the drawing
area's own corner instead, so drawing these positions back means
subtracting that corner first.(valid-membrane? membrane)Check if a membrane conforms to the Malli schema.
(valid-membrane? (membrane pose)) -- true if valid.Check if a membrane conforms to the Malli schema. - `(valid-membrane? (membrane pose))` -- true if valid.
(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 |