Liking cljdoc? Tell your friends :D

scicloj.plotje.impl.pose

Pose substrate -- the recursive plain-map type that is the library's spec vocabulary. This namespace holds the pure tree operations (resolve, layout, shared-scale injection) and the leaf->draft emitter that feeds plan.clj.

Shape of a pose: {:data ? dataset (inherited from ancestor if absent) :mapping ? aesthetic mappings (merges with ancestors) :layers ? layers at this level (accumulate into leaves) :poses ? sub-poses; absence = leaf :layout ? {:direction :horizontal|:vertical :weights [pos-num ...]} :opts ? plot options (inheritable) :share-scales ? #{:x :y} for composites}

Pose substrate -- the recursive plain-map type that is the
library's spec vocabulary. This namespace holds the pure tree
operations (resolve, layout, shared-scale injection) and the
leaf->draft emitter that feeds plan.clj.

Shape of a pose:
  {:data         ?  dataset (inherited from ancestor if absent)
   :mapping      ?  aesthetic mappings (merges with ancestors)
   :layers       ?  layers at this level (accumulate into leaves)
   :poses       ?  sub-poses; absence = leaf
   :layout       ?  {:direction :horizontal|:vertical
                     :weights   [pos-num ...]}
   :opts         ?  plot options (inheritable)
   :share-scales ?  #{:x :y}  for composites}
raw docstring

*blank-notes*clj

Bound to an atom by compositor/composite-pose->draft while it drafts the cells of an arrangement: leaf->draft collects there the Note for a cell that draws nothing, in place of printing it. A blank cell beside cells that draw is left to the Note lay-* prints when it adds a layer on a cell of its own; the Note is printed where no cell draws.

Bound to an atom by `compositor/composite-pose->draft` while it drafts
the cells of an arrangement: `leaf->draft` collects there the Note for
a cell that draws nothing, in place of printing it. A blank cell beside
cells that draw is left to the Note `lay-*` prints when it adds a layer
on a cell of its own; the Note is printed where no cell draws.
sourceraw docstring

*where-warnings*clj

Within one elaborate, the row-filter warnings already printed: a composite's filter reaches every cell, and a value it misspells is reported once rather than once per cell.

Within one `elaborate`, the row-filter warnings already printed: a
composite's filter reaches every cell, and a value it misspells is
reported once rather than once per cell.
sourceraw docstring

apply-track-weightsclj

(apply-track-weights pose)

The composite with its :col-weights and :row-weights written as the :weights of its layout, at every depth: the rows of cells a vertical composite holds take the column weights, and the composite the row weights. A horizontal composite is one row, and a vertical one of single cells one column. The keys are then removed from the options, so no cell reads them.

The cells are laid out in these proportions, and the composite is aligned (compositor/drawing-tracks), so its drawing areas keep them once the tick labels have taken their room.

The composite with its `:col-weights` and `:row-weights` written as
the `:weights` of its layout, at every depth: the rows of cells a
vertical composite holds take the column weights, and the composite
the row weights. A horizontal composite is one row, and a vertical
one of single cells one column. The keys are then removed from the
options, so no cell reads them.

The cells are laid out in these proportions, and the composite is
aligned (`compositor/drawing-tracks`), so its drawing areas keep
them once the tick labels have taken their room.
sourceraw docstring

apply-whereclj

(apply-where pose)

A pose whose written row filter, :where, is applied to its data: {:where {:species "setosa"}} keeps the rows whose :species is "setosa". Several keys must all match; a set is any of its values. The filter is consumed, so the result carries the filtered data and no :where. A pose with no data keeps its filter for the data it is given later.

Numbers compare by value (same-value?). A value that appears nowhere in its column is reported -- a misspelling, or a category the data does not hold -- since it selects no rows; a cell generated from the data never names one.

A cell generated from a category keeps the full data and writes its filter, so the listed pose says that its cells split one dataset. The spelling :where is provisional.

A pose whose written row filter, `:where`, is applied to its data:
`{:where {:species "setosa"}}` keeps the rows whose `:species` is
"setosa". Several keys must all match; a set is any of its values.
The filter is consumed, so the result carries the filtered data and
no `:where`. A pose with no data keeps its filter for the data it
is given later.

Numbers compare by value (`same-value?`). A value that appears
nowhere in its column is reported -- a misspelling, or a category the
data does not hold -- since it selects no rows; a cell generated from
the data never names one.

A cell generated from a category keeps the full data and writes its
filter, so the listed pose says that its cells split one dataset.
The spelling `:where` is provisional.
sourceraw docstring

check-explicit-mapping!clj

(check-explicit-mapping! k v)

Throw when an explicit mapping is malformed. Nothing here reads the layer's data, which is what lets api run it at the pj/pose or lay-* call rather than at pj/draft: a mistyped key inside the map is a mistake about the form, and the form is fully visible where it is written. The checks that need the data -- whether the column is there, whether the value is one the aesthetic can draw -- stay in validate-columns.

Called both from the call site and from normalize-explicit-mapping, so a pose built by hand and threaded straight to pj/draft is held to the same rules.

Throw when an explicit mapping is malformed. Nothing here reads the
layer's data, which is what lets `api` run it at the `pj/pose` or
`lay-*` call rather than at `pj/draft`: a mistyped key inside the
map is a mistake about the form, and the form is fully visible
where it is written. The checks that need the data -- whether the
column is there, whether the value is one the aesthetic can draw --
stay in `validate-columns`.

Called both from the call site and from
`normalize-explicit-mapping`, so a pose built by hand and threaded
straight to `pj/draft` is held to the same rules.
sourceraw docstring

check-panel-domain!clj

(check-panel-domain! k v spec)

Throw unless spec, the :scale of a panel aesthetic, is a map holding a :domain of categories and nothing else.

:col and :row draw nothing through a scale, so they take no scale type, range or breaks. What they share with a categorical axis and a categorical legend is an order of categories, and the :domain that orders those two orders the panels: the listed categories first, the others after, in the order of the data. Called from the mapping check and from pj/scale, so the two refuse the same things.

Throw unless `spec`, the `:scale` of a panel aesthetic, is a map
holding a `:domain` of categories and nothing else.

`:col` and `:row` draw nothing through a scale, so they take no scale
type, range or breaks. What they share with a categorical axis and a
categorical legend is an order of categories, and the `:domain` that
orders those two orders the panels: the listed categories first, the
others after, in the order of the data. Called from the mapping check
and from `pj/scale`, so the two refuse the same things.
sourceraw docstring

check-panel-domain-key!clj

(check-panel-domain-key! k col domain)

Throw where a :domain is specified for a panel aesthetic that reads several columns as a compound key. A :domain lists the categories of one column, and a compound key has a panel for each combination of values the data holds, so the list has nothing to be matched against. Called where the two are written together (check-panel-mapping!) and where the panels are made (panel-order), since a pj/scale on an outer pose meets the facet of an inner one only there.

Throw where a `:domain` is specified for a panel aesthetic that
reads several columns as a compound key. A `:domain` lists the
categories of one column, and a compound key has a panel for each
combination of values the data holds, so the list has nothing to be
matched against. Called where the two are written together
(`check-panel-mapping!`) and where the panels are made
(`panel-order`), since a `pj/scale` on an outer pose meets the
facet of an inner one only there.
sourceraw docstring

check-panel-mapping!clj

(check-panel-mapping! k v)

Throw where v, a mapping value written for the panel aesthetic k in full, cannot be read: a :scale that is not a :domain alone (check-panel-domain!), or a :domain beside a compound key (check-panel-domain-key!). Called from the mapping check, from pj/facet and from pj/scale, so the three refuse the same things.

Throw where `v`, a mapping value written for the panel aesthetic `k`
in full, cannot be read: a `:scale` that is not a `:domain` alone
(`check-panel-domain!`), or a `:domain` beside a compound key
(`check-panel-domain-key!`). Called from the mapping check, from
`pj/facet` and from `pj/scale`, so the three refuse the same
things.
sourceraw docstring

check-series!clj

(check-series! caller data m)

Throw where the series written in mapping m cannot be pivoted out of data -- the checks the pivot makes, without pivoting. Run by a lay-* call that has the data, so the error names the call, and by the draft before it pivots.

Throw where the series written in mapping `m` cannot be pivoted out
of `data` -- the checks the pivot makes, without pivoting. Run by a
`lay-*` call that has the data, so the error names the call, and by
the draft before it pivots.
sourceraw docstring

check-series-leaf!clj

(check-series-leaf! leaf)

Throw where the series on a leaf cannot be pivoted together with the rest of it: two series pivoting one dataset (see leaf-series), or the pose's own mapping naming a column the pivot consumes -- that aesthetic would apply to the pivoted rows, which no longer hold the column. A layer naming such a column is not refused: it reads the data as written, before the pivot (pivot-leaf-series). Run by every lay-* call on a leaf, so the call that makes the conflict is the one that reports it, and by the draft.

Throw where the series on a leaf cannot be pivoted together with the
rest of it: two series pivoting one dataset (see `leaf-series`), or
the pose's own mapping naming a column the pivot consumes -- that
aesthetic would apply to the pivoted rows, which no longer hold the
column. A layer naming such a column is not refused: it reads the
data as written, before the pivot (`pivot-leaf-series`). Run by every
`lay-*` call on a leaf, so the call that makes the conflict is the
one that reports it, and by the draft.
sourceraw docstring

check-shared-panel!clj

(check-shared-panel! leaf)

Report layers of a leaf that share its one panel and disagree about what an axis holds.

The layers of a pose share its panel, so each axis is one scale for all of them. Columns of different kinds on one axis -- a category beside a number -- cannot be placed on one scale, and drawing them anyway placed the numbers as category places: an error, naming the layers and the two ways to separate panels. A count or a density beside a column on :y can be placed, and so can a count beside a density, but the axis then reads in two units: a Note, with the same advice. Numeric columns of very different size can be placed too, and one of them is then drawn flat: a Note (note-columns-of-different-size!).

Report layers of a leaf that share its one panel and disagree about
what an axis holds.

The layers of a pose share its panel, so each axis is one scale for
all of them. Columns of different kinds on one axis -- a category
beside a number -- cannot be placed on one scale, and drawing them
anyway placed the numbers as category places: an error, naming the
layers and the two ways to separate panels. A count or a density
beside a column on `:y` can be placed, and so can a count beside a
density, but the axis then reads in two units: a Note, with the same
advice. Numeric columns of very different
size can be placed too, and one of them is then drawn flat: a Note
(`note-columns-of-different-size!`).
sourceraw docstring

check-track-weights!clj

(check-track-weights! k weights n what)

Report a weight vector that is not one positive number for each of the n columns or rows (what) it shares out.

Report a weight vector that is not one positive number for each of
the `n` columns or rows (`what`) it shares out.
sourceraw docstring

coerce-data-in-treeclj

(coerce-data-in-tree pose)

A pose with the :data of every pose in it a dataset. pj/pose coerces the data it is given; a pose written as a map may hold a plain map or rows, and the sharing of axes reads columns from :data as a dataset -- on a plain map it found no column, and cells asked to share an axis kept their own, with no message.

A pose with the `:data` of every pose in it a dataset. `pj/pose`
coerces the data it is given; a pose written as a map may hold a
plain map or rows, and the sharing of axes reads columns from
`:data` as a dataset -- on a plain map it found no column, and cells
asked to share an axis kept their own, with no message.
sourceraw docstring

collapse-regular-splitclj

(collapse-regular-split pose)

A composite whose cells are a regular split of its data, as the faceted leaf that draws it in one plan; any other pose as it is.

Regular: the composite holds the data and writes no strips or axis titles of its own; each cell carries only a :where of single values; and the cells keep exactly the values the data holds for the facet columns, in the order the data holds them -- one row of cells by :col, one column by :row, or a grid by both, with every combination present, as expand-variation writes it. A written :share-scales is kept in the faceted leaf's options, where the facet plan reads it.

A composite whose cells are a regular split of its data, as the
faceted leaf that draws it in one plan; any other pose as it is.

Regular: the composite holds the data and writes no strips or axis
titles of its own; each cell carries only a `:where` of single
values; and the cells keep exactly the values the data holds for the
facet columns, in the order the data holds them -- one row of cells
by `:col`, one column by `:row`, or a grid by both, with every
combination present, as `expand-variation` writes it. A written
`:share-scales` is kept in the faceted leaf's options, where the
facet plan reads it.
sourceraw docstring

combine-scalesclj

(combine-scales outer inner)

Combine an outer scale statement with an inner one.

Scale settings accumulate down the scope chain: where both name a spec the two merge key by key, so a pose that sets a range and a layer that names a type give a plot with both. The innermost wins per key.

true and false are not specs and do not merge. false says the value passes through no scale at all, so it replaces whatever was set above; true says it does pass through one without saying which, so it leaves an outer spec standing.

Combine an outer scale statement with an inner one.

Scale settings accumulate down the scope chain: where both name a
spec the two merge key by key, so a pose that sets a range and a
layer that names a type give a plot with both. The innermost wins
per key.

`true` and `false` are not specs and do not merge. `false` says the
value passes through no scale at all, so it replaces whatever was
set above; `true` says it does pass through one without saying
which, so it leaves an outer spec standing.
sourceraw docstring

composite?clj

(composite? f)

A composite pose has at least one sub-pose.

A composite pose has at least one sub-pose.
sourceraw docstring

compute-layoutclj

(compute-layout pose rect)
(compute-layout pose [x y w h] path)

Walk the pose tree and assign a pixel rectangle to each leaf. Returns a map of path -> [x y w h].

Composite :layout is {:direction :horizontal|:vertical|:matrix :weights [pos-num ...]}. Defaults: :direction :horizontal :weights (repeat n 1) (equal share)

Matrix layout (:direction :matrix) places leaves on a grid derived from their :x / :y mappings -- distinct x-cols become grid columns, distinct y-cols become grid rows, leaves land at their (x, y) intersection cell. Duplicate (x, y) pairs stack into new rows in DFS order. Empty cells get no entry. See matrix-axes for the full algorithm and the corresponding strip-label derivation. :weights are ignored under :matrix.

Rectangle arithmetic is in doubles; callers that need integer pixels should coerce at the render boundary (see pj/plot's width/height coercion).

Walk the pose tree and assign a pixel rectangle to each leaf.
Returns a map of path -> [x y w h].

Composite :layout is {:direction :horizontal|:vertical|:matrix
                      :weights   [pos-num ...]}. Defaults:
  :direction :horizontal
  :weights   (repeat n 1)  (equal share)

Matrix layout (`:direction :matrix`) places leaves on a grid
derived from their :x / :y mappings -- distinct x-cols become
grid columns, distinct y-cols become grid rows, leaves land at
their (x, y) intersection cell. Duplicate (x, y) pairs stack
into new rows in DFS order. Empty cells get no entry. See
`matrix-axes` for the full algorithm and the corresponding
strip-label derivation. :weights are ignored under :matrix.

Rectangle arithmetic is in doubles; callers that need integer
pixels should coerce at the render boundary (see pj/plot's
width/height coercion).
sourceraw docstring

data-category-orderclj

(data-category-order data cols)

The values the columns cols of data hold, each once, in the order of the rows -- the order a categorical axis and a categorical legend list them in, whichever panel a row is drawn in. Nil where data holds none of the columns.

The values are the data's own, which is what a legend's categories are matched against; an axis is matched against display labels, so its callers map defaults/fmt-category-label over the answer. One function for the panels of a facet (leaf->draft), the cells of an arrangement (shared-axis-groups) and the legend they share (compositor/unify-legend-scales), because the three ask one question.

The values the columns `cols` of `data` hold, each once, in the order
of the rows -- the order a categorical axis and a categorical legend
list them in, whichever panel a row is drawn in. Nil where `data`
holds none of the columns.

The values are the data's own, which is what a legend's categories
are matched against; an axis is matched against display labels, so
its callers map `defaults/fmt-category-label` over the answer. One
function for the panels of a facet (`leaf->draft`), the cells of an
arrangement (`shared-axis-groups`) and the legend they share
(`compositor/unify-legend-scales`), because the three ask one
question.
sourceraw docstring

default-mappingclj

(default-mapping d)

The mapping raw data gets when nothing names a column: the first 1-3 columns, as :x, :y and :color. Nil for 0 or 4+ columns.

The mapping raw data gets when nothing names a column: the first
1-3 columns, as `:x`, `:y` and `:color`. Nil for 0 or 4+ columns.
sourceraw docstring

default-series-labelclj

The name the key column a series invents takes when the writer does not give one. It titles the legend, so it is a word a reader can read there.

The name the key column a series invents takes when the writer does
not give one. It titles the legend, so it is a word a reader can read
there.
sourceraw docstring

default-share-axesclj

(default-share-axes composite)

The axes the cells of a composite do share by default -- two or more cells draw one column there (or count one column), and the cells of each bucket agree on the kind of scale. Sharing is by column, so cells reading different columns on an axis keep their own extents, and an axis where every cell draws a column of its own is not in the default: written out, the default changes nothing and draws no message (warn-share-scales-without-effect!). An axis the cells cannot share is left alone, with no message: the writer did not ask for it.

The axes the cells of a composite do share by default -- two or more
cells draw one column there (or count one column), and the cells of
each bucket agree on the kind of scale. Sharing is
by column, so cells reading different columns on an axis keep their
own extents, and an axis where every cell draws a column of its own
is not in the default: written out, the default changes nothing and
draws no message (`warn-share-scales-without-effect!`). An axis the
cells cannot share is left alone, with no message: the writer did
not ask for it.
sourceraw docstring

elaborateclj

(elaborate pose)
(elaborate pose parent-ctx)

elaborate-leaf on every leaf of a pose, each read with the context its ancestors give it, and each leaf's choices written back onto that leaf. An ancestor's :infer layer, which reaches several leaves, is left to the plan.

`elaborate-leaf` on every leaf of a pose, each read with the context
its ancestors give it, and each leaf's choices written back onto that
leaf. An ancestor's `:infer` layer, which reaches several leaves, is
left to the plan.
sourceraw docstring

elaborate-leafclj

(elaborate-leaf leaf)

A leaf with the draft's choices written in. leaf carries its full context -- a top-level leaf, or one resolve-tree resolved.

  • The row filter applied -- see apply-where.
  • Series pivoted -- see pivot-leaf-series.
  • The data's default mapping, where the leaf needs one -- see infer-default-mapping.
  • A leaf with a place and no layers draws one layer, of the type the data chooses.
  • A column the leaf's own mapping names is drawn by the layers that name no column on that axis, and by no other: where every layer names its own, as in (-> data (pj/pose :a :b) (pj/lay-point :c :d)), the leaf draws c-against-d alone and report-unread-positions! warns that :a and :b are not drawn (teaching: pose_rules.clj, "Note on leaf-input with other columns").
  • A layer holds the panel's columns it reads, where it names none or names one and its layer type needs two -- see read-panel-columns.
  • A layer written as :infer takes the type the data chooses for the place it draws at.

Idempotent: a second call finds nothing left to choose.

A leaf with the draft's choices written in. `leaf` carries its full
context -- a top-level leaf, or one `resolve-tree` resolved.

- The row filter applied -- see `apply-where`.
- Series pivoted -- see `pivot-leaf-series`.
- The data's default mapping, where the leaf needs one -- see
  `infer-default-mapping`.
- A leaf with a place and no layers draws one layer, of the type the
  data chooses.
- A column the leaf's own mapping names is drawn by the layers that
  name no column on that axis, and by no other: where every layer
  names its own, as in
  `(-> data (pj/pose :a :b) (pj/lay-point :c :d))`, the leaf draws
  c-against-d alone and `report-unread-positions!` warns that
  `:a` and `:b` are not drawn (teaching: `pose_rules.clj`, "Note on
  leaf-input with other columns").
- A layer holds the panel's columns it reads, where it names none
  or names one and its layer type needs two -- see
  `read-panel-columns`.
- A layer written as `:infer` takes the type the data chooses for
  the place it draws at.

Idempotent: a second call finds nothing left to choose.
sourceraw docstring

expand-facet-nodeclj

(expand-facet-node pose panel-mapping)

A leaf holding a :facet node, as the listed pose it expands to; any other pose as it is. A part over columns of :y alone stacks its cells down, so they share the :x axis; any other single part runs across; :col and :row make a grid. The leaf's series is pivoted first, as for a facet over categories.

panel-mapping is what the pose and the poses above it map :col and :row to. An order of panels specified there with no column -- (pj/scale pose :col {:domain [..]}) written before the facet, or on a pose above -- orders the categories of that part of the node, where the part specifies no order of its own.

A leaf holding a `:facet` node, as the listed pose it expands to;
any other pose as it is. A part over columns of `:y` alone stacks its
cells down, so they share the `:x` axis; any other single part runs
across; `:col` and `:row` make a grid. The leaf's series is pivoted
first, as for a facet over categories.

`panel-mapping` is what the pose and the poses above it map `:col`
and `:row` to. An order of panels specified there with no column --
`(pj/scale pose :col {:domain [..]})` written before the facet, or
on a pose above -- orders the categories of that part of the node,
where the part specifies no order of its own.
sourceraw docstring

expand-facet-nodesclj

(expand-facet-nodes pose)
(expand-facet-nodes pose inherited)
(expand-facet-nodes pose inherited panel-mapping)

expand-facet-node on every pose of a tree that holds a :facet node, so a pose faceted over columns draws the same panels as a cell of an arrangement as it does alone. A faceted cell with no data of its own is expanded with the data it inherits, which the expansion reads to pivot a series and to list a category's values. A series faceted by its own key is such a pose (series-key-facet).

`expand-facet-node` on every pose of a tree that holds a `:facet`
node, so a pose faceted over columns draws the same panels as a cell
of an arrangement as it does alone. A faceted cell with no data of
its own is expanded with the data it inherits, which the expansion
reads to pivot a series and to list a category's values. A series
faceted by its own key is such a pose (`series-key-facet`).
sourceraw docstring

expand-facetsclj

(expand-facets pose)

A leaf whose mapping writes :col or :row, as the listed pose its facet expands to: :col alone is a row of cells, :row alone a column of them, both a grid with an empty cell for each combination the data does not hold. The facet's :share-scales stays where it is, on the listed pose. Any other pose is returned as it is -- a composite, a leaf with no data of its own, a grid naming one column on both sides, and a facet wrapped by :grid-cols or :grid-rows, which needs a strip over each cell.

A leaf whose mapping writes `:col` or `:row`, as the listed pose its
facet expands to: `:col` alone is a row of cells, `:row` alone a
column of them, both a grid with an empty cell for each combination
the data does not hold. The facet's
`:share-scales` stays where it is, on the listed pose. Any other
pose is returned as it is -- a composite, a leaf with no data of its
own, a grid naming one column on both sides, and a facet wrapped by
`:grid-cols` or `:grid-rows`, which needs a strip over each cell.
sourceraw docstring

expand-variationclj

(expand-variation pose variation)

A pose with cells generated from a variation, written as the listed pose they expand to. Provisional prototype (step 7 of the PR #61 plan; the verb and whether this is published are open).

  • A column of the data -- :species -- is a category: one cell per value the column holds, in the order the data holds them, each the full data with a written row filter, {:where {:species v}}.
  • {:x [:a :b]} or {:y [...]} names columns: one cell per column, each writing its column on that axis, as pj/pose would.
  • {:col c :row r} crosses two categories into a grid, a row per value of r; a combination the data does not hold is a filter that keeps no rows, which draws as an empty cell.

The cells inherit the pose's data, mapping and layers, as cells of a composite do, so they are the parts of one declared split: they share each axis they can, and an axis they share on one column is ticked and titled once, and each is labelled in a strip by the value its filter keeps (share-axes, infer-chrome), as cells written by hand would be. The expansion adds only one drawing area for the cells.

A pose with cells generated from a variation, written as the listed
pose they expand to. Provisional prototype (step 7 of the PR #61
plan; the verb and whether this is published are open).

- A column of the data -- `:species` -- is a category: one cell per
  value the column holds, in the order the data holds them, each the
  full data with a written row filter, `{:where {:species v}}`.
- `{:x [:a :b]}` or `{:y [...]}` names columns: one cell per column,
  each writing its column on that axis, as `pj/pose` would.
- `{:col c :row r}` crosses two categories into a grid, a row per
  value of `r`; a combination the data does not hold is a filter that
  keeps no rows, which draws as an empty cell.

The cells inherit the pose's data, mapping and layers, as cells of a
composite do, so they are the parts of one declared split: they share
each axis they can, and an axis they share on one column is ticked
and titled once, and each is labelled in a strip by the value its
filter keeps (`share-axes`, `infer-chrome`), as cells written by
hand would be. The expansion adds only one drawing area for the cells.
sourceraw docstring

explicit-mapping-keysclj

The keys an explicit mapping map may carry: one source, and optionally the scale to read it through.

The keys an explicit mapping map may carry: one source, and
optionally the scale to read it through.
sourceraw docstring

explicit-mapping?clj

(explicit-mapping? v)

True of a mapping value written in the explicit form -- a map naming its source, as {:column :species} or {:value "red" :scale true}, or naming only a scale, as pj/scale writes.

A map is unambiguous here because no aesthetic takes one as a value: a color is a string or a keyword, a size is a number, a shape is a symbol from a fixed list.

True of a mapping value written in the explicit form -- a map naming
its source, as `{:column :species}` or `{:value "red" :scale true}`,
or naming only a scale, as `pj/scale` writes.

A map is unambiguous here because no aesthetic takes one as a value:
a color is a string or a keyword, a size is a number, a shape is a
symbol from a fixed list.
sourceraw docstring

facet-columns-directionclj

(facet-columns-direction node)

The direction a facet over columns with no direction of its own places its panels in: down for columns of :y alone, so they share the :x axis, and across otherwise.

The direction a facet over columns with no direction of its own
places its panels in: down for columns of `:y` alone, so they share
the `:x` axis, and across otherwise.
sourceraw docstring

facet-label-separatorclj

What joins the parts of a compound facet label. A panel faceted by several columns is labelled by each column's value in turn, and this is what stands between them.

What joins the parts of a compound facet label. A panel faceted by
several columns is labelled by each column's value in turn, and this
is what stands between them.
sourceraw docstring

facet-node-directionsclj

(facet-node-directions node)

The directions a facet node holds a part in, nil parts left out: [] for a facet over columns with no direction of its own.

The directions a facet node holds a part in, `nil` parts left out:
`[]` for a facet over columns with no direction of its own.
sourceraw docstring

fit-layersclj

(fit-layers pose)
(fit-layers pose inherited)
(fit-layers pose inherited data)

A composite whose layers are fitted to its cells, as above. Returned unchanged where every layer fits every cell it reaches.

A layer that fits no cell because it names a column on an axis where every cell names another (columns-no-cell-has) reports an error where it leaves some cell with no layer drawing that cell's own columns: the facet's column would be drawn nowhere. Beside layers that fit every cell it is drawn in every cell, as a column shown in each panel for comparison.

A composite whose layers are fitted to its cells, as above. Returned
unchanged where every layer fits every cell it reaches.

A layer that fits no cell because it names a column on an axis where
every cell names another (`columns-no-cell-has`) reports an error
where it leaves some cell with no layer drawing that cell's own
columns: the facet's column would be drawn nowhere. Beside layers
that fit every cell it is drawn in every cell, as a column shown in
each panel for comparison.
sourceraw docstring

fold-facet-categoriesclj

(fold-facet-categories node cats)

A facet node with the categories cats -- a map from :col or :row to the mapping value a pose, or a pose above it, writes there -- crossed into it, as the grid they draw together. Columns with no direction of their own take the direction the categories leave. Categories in a direction the node holds, or in both directions beside columns with none, report an error: the panels have no direction left for them.

Categories are kept in the mapping, where they follow the scope rules, and meet the facet over columns here, when the pose is drawn -- so a facet over categories written on an arrangement crosses a cell's facet over columns as it crosses the cell's own.

A facet node with the categories `cats` -- a map from `:col` or
`:row` to the mapping value a pose, or a pose above it, writes there
-- crossed into it, as the grid they draw together. Columns with no
direction of their own take the direction the categories leave.
Categories in a direction the node holds, or in both directions
beside columns with none, report an error: the panels have no
direction left for them.

Categories are kept in the mapping, where they follow the scope
rules, and meet the facet over columns here, when the pose is drawn
-- so a facet over categories written on an arrangement crosses a
cell's facet over columns as it crosses the cell's own.
sourceraw docstring

infer-chromeclj

(infer-chrome composite)
(infer-chrome composite strip-mode)

An elaborated composite with its chrome written in, where its cells are the parts of one declared split: the once-only axis titles and ticks (infer-axis-chrome) and the strips naming each cell's part of the data (infer-strips); where its cells are asked to share an axis with :share-scales, the axis titles and ticks. Anything written is kept. strip-mode is :strip-labels (defaults/strip-text).

An elaborated composite with its chrome written in, where its cells
are the parts of one declared split: the once-only axis titles and
ticks (`infer-axis-chrome`) and the strips naming each cell's part
of the data (`infer-strips`); where its cells are asked to share an
axis with `:share-scales`, the axis titles and ticks. Anything
written is kept. `strip-mode` is `:strip-labels` (`defaults/strip-text`).
sourceraw docstring

infer-default-mappingclj

(infer-default-mapping leaf)

A leaf with the columns it draws filled in where nothing names them, from data of 1-3 columns.

  • Where neither the leaf's mapping nor any layer names an :x or a :y column, the data's default-mapping is written under the leaf's own mapping, so a scale it already carries reads the default column.
  • The same where the first layer reads the leaf's data and names no column, and the leaf's mapping names none, whatever the layers after the first name. A layer added to a pose leaves the layers before it as they were drawn: on data of three columns (-> data pj/lay-point) colours by the third, and so do (-> data pj/lay-point (pj/lay-smooth :a :b)) and (-> data pj/lay-point (pj/lay-smooth :b :a)), where the smooth keeps the columns it names and is drawn on the points' panel. (-> data (pj/lay-point :a :b) pj/lay-smooth) reads no colour, as (-> data (pj/lay-point :a :b)) reads none.
  • Where a :y is named and no :x is, and a layer's type draws only from two columns (layer-type/column-counts lacks 1), the leaf's :x is the first column nothing names, so (pj/lay-point data {:y :a}) draws :a against the column before it. A leaf with no layer, or whose layers can draw from one column, keeps :y alone and is drawn on its side -- see side-on -- so (pj/pose data {:y :a}) draws the same on data of any width. A :y is never filled in: whether a layer needs one depends on its type, and (pj/lay-bar data :x) counts.

An axis a facet over columns names columns on counts as named, and its columns as used: {:col {:x [:a :b]} :row {:y [:a :b]}} on data of three columns draws :a and :b and no colour, as (pj/pose data {:x :a :y :b}) does.

Returns the leaf unchanged otherwise, so it is idempotent.

A leaf with the columns it draws filled in where nothing names them,
from data of 1-3 columns.

- Where neither the leaf's mapping nor any layer names an `:x` or a
  `:y` column, the data's `default-mapping` is written under the
  leaf's own mapping, so a scale it already carries reads the
  default column.
- The same where the first layer reads the leaf's data and names no
  column, and the leaf's mapping names none, whatever the layers
  after the first name. A layer added to a pose leaves the layers
  before it as they were drawn: on data of three columns
  `(-> data pj/lay-point)` colours by the third, and so do
  `(-> data pj/lay-point (pj/lay-smooth :a :b))` and
  `(-> data pj/lay-point (pj/lay-smooth :b :a))`, where the smooth
  keeps the columns it names and is drawn on the points' panel.
  `(-> data (pj/lay-point :a :b) pj/lay-smooth)` reads no colour,
  as `(-> data (pj/lay-point :a :b))` reads none.
- Where a `:y` is named and no `:x` is, and a layer's type draws
  only from two columns (`layer-type/column-counts` lacks 1), the
  leaf's `:x` is the first column nothing names, so
  `(pj/lay-point data {:y :a})` draws `:a` against the column before
  it. A leaf with no layer, or whose layers can draw from one
  column, keeps `:y` alone and is drawn on its side -- see
  `side-on` -- so `(pj/pose data {:y :a})` draws the same on data of
  any width. A `:y` is never filled in: whether a layer needs one
  depends on its type, and `(pj/lay-bar data :x)` counts.

An axis a facet over columns names columns on counts as named, and
its columns as used: `{:col {:x [:a :b]} :row {:y [:a :b]}}` on data
of three columns draws `:a` and `:b` and no colour, as
`(pj/pose data {:x :a :y :b})` does.

Returns the leaf unchanged otherwise, so it is idempotent.
sourceraw docstring

infer-nested-chromeclj

(infer-nested-chrome composite)
(infer-nested-chrome composite strip-mode)

composite with the chrome of each composite nested below its root written in as infer-chrome writes the root's -- a facet over columns placed as a cell of an arrangement is drawn as it is drawn alone: its axis titles once, its ticks on the outer cells, its strips. A nested composite's strips and axis titles are drawn in bands beside its block (compositor/strip-nested-titles). The cells whose y tick labels it drops are recorded on the root (:plotje/y-ticks-inferred-off), by their paths from the root.

`composite` with the chrome of each composite nested below its root
written in as `infer-chrome` writes the root's -- a facet over
columns placed as a cell of an arrangement is drawn as it is drawn
alone: its axis titles once, its ticks on the outer cells, its
strips. A nested composite's strips and axis titles are drawn in
bands beside its block (`compositor/strip-nested-titles`). The cells
whose y tick labels it drops are recorded on the root
(`:plotje/y-ticks-inferred-off`), by their paths from the root.
sourceraw docstring

last-leaf-pathclj

(last-leaf-path pose)

Return the path vector of the last leaf visited in left-to-right depth-first order. Nil if the pose is itself a leaf with no path context (the caller is the root leaf).

Return the path vector of the last leaf visited in left-to-right
depth-first order. Nil if the pose is itself a leaf with no path
context (the caller is the root leaf).
sourceraw docstring

last-matching-leaf-pathclj

(last-matching-leaf-path pose position-mapping)

Walk pose in left-to-right DFS order. Return the :path of the last leaf whose panel's columns (leaf-place, read after the ancestors' :mapping is merged in) match position-mapping. Matching is strict equality: :x and "x" are different column references. Returns nil if no leaf matches.

position-mapping may carry either or both of :x and :y; a nil value matches a leaf whose panel has no column on that axis.

The panel's columns are the leaf's own, and on an axis its mapping names none, those of its first layer naming one: a lay-* call keeps its columns on its layer, so a cell built by lay-* alone names them only there.

What a mapping names decides the match, not how it is written: a column carrying a scale names the same column as the plain form, and a mapping that names only a scale names no column at all.

Walk `pose` in left-to-right DFS order. Return the `:path` of the
last leaf whose panel's columns (`leaf-place`, read after the
ancestors' `:mapping` is merged in) match `position-mapping`.
Matching is strict equality: `:x` and `"x"` are different column
references. Returns `nil` if no leaf matches.

`position-mapping` may carry either or both of `:x` and `:y`; a
`nil` value matches a leaf whose panel has no column on that axis.

The panel's columns are the leaf's own, and on an axis its mapping
names none, those of its first layer naming one: a `lay-*` call
keeps its columns on its layer, so a cell built by `lay-*` alone
names them only there.

What a mapping names decides the match, not how it is written: a
column carrying a scale names the same column as the plain form, and
a mapping that names only a scale names no column at all.
sourceraw docstring

layer-position-keyclj

(layer-position-key leaf-mapping layer data)

The place a layer draws at, as [x-source y-source] -- what decides which panel it lands on. Nil where the layer names no place of its own, which is what makes it draw on every panel.

Whether the layer names a place is read from its own :mapping: a layer that names none is not choosing the leaf's, it is declining to choose, and the two answers place it differently. The place itself is read from the leaf's mapping merged with the layer's, so that a layer naming one axis draws at the same place as one naming both.

The place a layer draws at, as `[x-source y-source]` -- what decides
which panel it lands on. Nil where the layer names no place of its
own, which is what makes it draw on every panel.

Whether the layer names a place is read from its own `:mapping`: a
layer that names none is not choosing the leaf's, it is declining to
choose, and the two answers place it differently. The place itself is
read from the leaf's mapping merged with the layer's, so that a layer
naming one axis draws at the same place as one naming both.
sourceraw docstring

leaf->draftclj

(leaf->draft leaf)

Emit a draft vector from a leaf pose. A draft has one entry per applicable layer; each entry is a flat map carrying the merged aesthetic mapping (pose < layer-type-info < layer), the layer's :stat/:position/:mark as first-class siblings, each aesthetic's resolved scale spec under its own key, and plot-level :coord stamped from :opts. The scales come from the mapping, which is where pj/scale writes them; only :coord is still an option.

If the leaf's :opts carry :facet-col or :facet-row, the draft is multiplied over distinct facet values. Each variant carries a filtered :data plus :facet-col / :facet-row labels that plan.clj detects to build the facet grid.

The leaf's :opts is passed through to plan/draft->plan; in particular the compositor uses :suppress-legend on grid cells.

An empty :layers vector yields one {:mark :infer ...} placeholder so downstream inference can still choose a layer type from the data.

Data precedence: layer :data > leaf :data.

:__panel-idx is the panel a draft entry belongs to, which plan.clj groups by. A leaf draws one panel -- its layers share it -- and faceting multiplies it, so the index is the facet variant.

Emit a draft vector from a leaf pose. A draft has one entry per
applicable layer; each entry is a flat map carrying the merged
aesthetic mapping (pose < layer-type-info < layer), the layer's
:stat/:position/:mark as first-class siblings, each aesthetic's
resolved scale spec under its own key, and plot-level :coord
stamped from :opts. The scales come from the mapping, which is
where `pj/scale` writes them; only :coord is still an option.

If the leaf's :opts carry :facet-col or :facet-row, the draft is
multiplied over distinct facet values. Each variant carries a
filtered :data plus :facet-col / :facet-row labels that plan.clj
detects to build the facet grid.

The leaf's :opts is passed through to plan/draft->plan; in
particular the compositor uses :suppress-legend on grid cells.

An empty :layers vector yields one {:mark :infer ...} placeholder so
downstream inference can still choose a layer type from the data.

Data precedence: layer :data > leaf :data.

:__panel-idx is the panel a draft entry belongs to, which plan.clj
groups by. A leaf draws one panel -- its layers share it -- and
faceting multiplies it, so the index is the facet variant.
sourceraw docstring

leaf-atclj

(leaf-at pose path)

Fetch the leaf at path in pose. Returns nil if the path does not land on a leaf.

Fetch the leaf at `path` in `pose`. Returns nil if the path does
not land on a leaf.
sourceraw docstring

leaf-columnsclj

(leaf-columns leaf)

The columns a leaf draws on :x and :y on its first panel, as {:x source :y source} with the axes it does not name left out. The leaf's own mapping where it names an axis, and otherwise the columns its layers name: a lay-* call keeps its columns on its layer, so a pose built by lay-* alone names them only there.

The columns a leaf draws on `:x` and `:y` on its first panel, as
`{:x source :y source}` with the axes it does not name left out. The
leaf's own mapping where it names an axis, and otherwise the columns
its layers name: a `lay-*` call keeps its columns on its layer, so a
pose built by `lay-*` alone names them only there.
sourceraw docstring

leaf-placeclj

(leaf-place leaf)

The place a leaf draws at -- the panel's columns -- as [x-source y-source], or nil where neither it nor any layer names one. Decided axis by axis: the leaf's own column, and where its mapping names none on that axis, that of the first layer naming one there. A lay-* call keeps its columns on its layer, so a pose built by lay-* alone names them only there. The layers of a leaf share this one panel; separate panels come from a split or from pj/arrange.

The place a leaf draws at -- the panel's columns -- as
`[x-source y-source]`, or nil where neither it nor any layer names
one. Decided axis by axis: the leaf's own column, and where its
mapping names none on that axis, that of the first layer naming one
there. A `lay-*` call keeps its columns on its layer, so a pose built
by `lay-*` alone names them only there. The layers of a leaf share
this one panel; separate panels come from a split or from
`pj/arrange`.
sourceraw docstring

leaf?clj

(leaf? f)

A leaf pose has no sub-poses. (An empty :poses vector also counts as leaf because it has nothing to tile.)

A leaf pose has no sub-poses. (An empty :poses vector also
counts as leaf because it has nothing to tile.)
sourceraw docstring

mapping-sourceclj

(mapping-source v)

What a mapping value names, with the full form unwrapped: the :column, the :value or the :from. A mapping that names only a scale names no source, and answers nil.

Identity is decided on this rather than on the written value, so that {:x {:from :a :scale ...}} and a plain {:x :a} are the same position -- which they are, since pj/scale produces the first from the second.

What a mapping value names, with the full form unwrapped: the
`:column`, the `:value` or the `:from`. A mapping that names only a
scale names no source, and answers nil.

Identity is decided on this rather than on the written value, so
that `{:x {:from :a :scale ...}}` and a plain `{:x :a}` are the same
position -- which they are, since `pj/scale` produces the first from
the second.
sourceraw docstring

matrix-axesclj

(matrix-axes composite)

For a composite whose layout is :matrix, walk its leaves in DFS order and compute the grid axes:

  • col-key per leaf: the leaf's :x mapping. Two leaves sharing (x, y) keep the same col-key.
  • row-key per leaf: the leaf's :y mapping, with a DFS-occurrence discriminator when (x, y) repeats. The first (a, b) gets row b; the second (a, b) gets row [b 1]; the third [b 2]; etc. Same column, new row in DFS order.
  • col-keys / row-keys: distinct keys in order of first appearance.
  • col-labels / row-labels: human-readable strings via defaults/fmt-name; nil when only one column or one row exists so we don't render a redundant strip header.

Univariate leaves (missing :x or :y) use the no-x-key / no-y-key sentinels so they get their own grid lane.

Returns {:col-keys [...] :row-keys [...] :col-labels [...|nil] :row-labels [...|nil] :positions {path -> [col-idx row-idx]} :x-vars [...] :y-vars [...]}.

The compositor consumes :positions for rect math and the labels for strip rendering; :x-vars / :y-vars surface in plan introspection.

For a composite whose layout is `:matrix`, walk its leaves in
DFS order and compute the grid axes:

- col-key per leaf: the leaf's :x mapping. Two leaves sharing
  (x, y) keep the same col-key.
- row-key per leaf: the leaf's :y mapping, with a DFS-occurrence
  discriminator when (x, y) repeats. The first (a, b) gets row
  b; the second (a, b) gets row [b 1]; the third [b 2]; etc.
  Same column, new row in DFS order.
- col-keys / row-keys: distinct keys in order of first appearance.
- col-labels / row-labels: human-readable strings via
  defaults/fmt-name; nil when only one column or one row exists
  so we don't render a redundant strip header.

Univariate leaves (missing :x or :y) use the no-x-key / no-y-key
sentinels so they get their own grid lane.

Returns {:col-keys [...] :row-keys [...]
         :col-labels [...|nil] :row-labels [...|nil]
         :positions {path -> [col-idx row-idx]}
         :x-vars [...] :y-vars [...]}.

The compositor consumes :positions for rect math and the labels
for strip rendering; :x-vars / :y-vars surface in plan introspection.
sourceraw docstring

merge-mappingsclj

(merge-mappings outer inner)

Merge an outer mapping into an inner one, the way pose mappings have always merged -- the inner value wins -- except for the scale, which accumulates. See merge-mapping-value.

Merge an outer mapping into an inner one, the way pose mappings have
always merged -- the inner value wins -- except for the scale, which
accumulates. See `merge-mapping-value`.
sourceraw docstring

overlay-labelsclj

(overlay-labels leaf)

The column each layer of a panel draws where its layers disagree, as a vector aligned with (:layers leaf), or nil where they all draw one place.

Read for two things, which do not depend on one another. The axis is titled by every column drawn on it, so each labelled layer is marked for the title. And the label is the default for a layer's :color: a layer with no :color specified takes its label as a colour and a legend entry (default-color-layers).

Layers that disagree about a column take a panel each, and the panels name the columns. Overlaid, they share a panel and nothing names them: the marks are drawn in one colour under an axis titled after whichever layer came first, which is a picture that shows less than the writer asked for and says nothing about it.

The label is the column a layer draws where the layers disagree. Answered nil where nothing distinguishes them, which is the ordinary case of layers drawing one place.

The column each layer of a panel draws where its layers disagree, as
a vector aligned with `(:layers leaf)`, or nil where they all draw
one place.

Read for two things, which do not depend on one another. The axis is
titled by every column drawn on it, so each labelled layer is marked
for the title. And the label is the default for a layer's `:color`:
a layer with no `:color` specified takes its label as a colour and a
legend entry (`default-color-layers`).

Layers that disagree about a column take a panel each, and the
panels name the columns. Overlaid, they share a panel and nothing
names them: the marks are drawn in one colour under an axis titled
after whichever layer came first, which is a picture that shows
less than the writer asked for and says nothing about it.

The label is the column a layer draws where the layers disagree.
Answered nil where nothing distinguishes them, which is the ordinary
case of layers drawing one place.
sourceraw docstring

panel-domainclj

(panel-domain v)

The :domain specified for a panel aesthetic in a mapping value, or nil where none is.

The `:domain` specified for a panel aesthetic in a mapping value, or
nil where none is.
sourceraw docstring

panel-facet-callclj

(panel-facet-call k v)

The pj/facet call that writes panel aesthetic k -- :col or :row, or the retired :facet-col / :facet-row -- with v, as a message shows it: (pj/facet pose :drv) across, (pj/facet pose {:row :drv}) down. One form for both messages that report a panel aesthetic written on a layer.

The `pj/facet` call that writes panel aesthetic `k` -- `:col` or
`:row`, or the retired `:facet-col` / `:facet-row` -- with `v`, as a
message shows it: `(pj/facet pose :drv)` across,
`(pj/facet pose {:row :drv})` down. One form for both messages that
report a panel aesthetic written on a layer.
sourceraw docstring

path->update-in-pathclj

(path->update-in-path path)

Translate a leaf path like [0 1] into the get-in / update-in navigation [:poses 0 :poses 1]. A root path [] translates to [].

Translate a leaf path like [0 1] into the get-in / update-in navigation
[:poses 0 :poses 1]. A root path [] translates to [].
sourceraw docstring

pivot-leaf-seriesclj

(pivot-leaf-series leaf)

A leaf whose series are pivoted: the columns a series reads become a key column and a value column, and the mapping that wrote the series names those two instead -- the key column on :color, or on :group where that mapping writes :color itself, so the series stay separate marks either way.

A series on the leaf's mapping is read by every layer below it; a series on a layer is that layer's. The pivoted data replaces the data the series was read from: the leaf's, or the layer's own :data. Checked first by check-series-leaf!.

A layer with no data or series of its own that names a column the series consumes -- points on :revenue beside lines for [:revenue :cost] -- reads that column's rows of the series, in the series' colour (read-series-column).

leaf carries its full context, as elaborate-leaf receives it. Idempotent: a pivoted leaf names no series.

A leaf whose series are pivoted: the columns a series reads become a
key column and a value column, and the mapping that wrote the series
names those two instead -- the key column on `:color`, or on `:group`
where that mapping writes `:color` itself, so the series stay
separate marks either way.

A series on the leaf's mapping is read by every layer below it; a
series on a layer is that layer's. The pivoted data replaces the data
the series was read from: the leaf's, or the layer's own `:data`.
Checked first by `check-series-leaf!`.

A layer with no data or series of its own that names a column the
series consumes -- points on `:revenue` beside lines for `[:revenue
:cost]` -- reads that column's rows of the series, in the series'
colour (`read-series-column`).

`leaf` carries its full context, as `elaborate-leaf` receives it.
Idempotent: a pivoted leaf names no series.
sourceraw docstring

pivoted-series-titleclj

(pivoted-series-title column scale)

The title a series pivot wrote for the value column it invented -- the written columns joined, as "revenue, cost", or the writer's own :label -- where column is that invented column and scale the scale spec carried beside it; nil otherwise.

A message that prints a layer's columns prints this instead: the writer never wrote the invented column, and the data holds no column of that name. Read from the title until the pivot keeps the mapping as written (the transforms plan, step C).

The title a series pivot wrote for the value column it invented --
the written columns joined, as "revenue, cost", or the writer's
own `:label` -- where `column` is that invented column and `scale` the
scale spec carried beside it; nil otherwise.

A message that prints a layer's columns prints this instead: the
writer never wrote the invented column, and the data holds no column
of that name. Read from the title until the pivot keeps the mapping
as written (the transforms plan, step C).
sourceraw docstring

pose?clj

(pose? x)

True if x looks pose-shaped: a map carrying :layers, :poses, or a map-valued :mapping. Permissive by design -- schema-level validation lives in impl.pose-schema.

A pose carrying only a mapping draws, a layer being inferred for it, and is completed later by api/with-data. Read as data instead -- which is what a map with none of these keys is -- it became a dataset whose columns were :mapping and :data, and drew that.

The :mapping value is tested rather than the key, because a dataset written as a map of columns may hold a column called :mapping. Its value is then the column, a sequence, and not a mapping.

True if x looks pose-shaped: a map carrying :layers, :poses, or a
map-valued :mapping. Permissive by design -- schema-level
validation lives in impl.pose-schema.

A pose carrying only a mapping draws, a layer being inferred for
it, and is completed later by `api/with-data`. Read as data instead
-- which is what a map with none of these keys is -- it became a
dataset whose columns were :mapping and :data, and drew that.

The :mapping value is tested rather than the key, because a dataset
written as a map of columns may hold a column called :mapping. Its
value is then the column, a sequence, and not a mapping.
sourceraw docstring

position-mapping-keyclj

(position-mapping-key m)

A mapping's place, as [x-source y-source], or nil where it names neither.

A mapping's place, as `[x-source y-source]`, or nil where it names
neither.
sourceraw docstring

put-scaleclj

(put-scale mapping aesthetic spec)

Write a scale spec into mapping for aesthetic -- what pj/scale does.

A scale lives with the mapping it reads, so this is an update of the mapping rather than of the pose's options. Where the aesthetic is mapped plainly there is no room for a scale, so the value is rewritten in the full form under :from, which says the same thing: ask the data. Where it is not mapped here at all, the scale is written on its own and applies to whatever source is named below.

A mapping cancelled with nil stays cancelled: an aesthetic that draws nothing has nothing to scale. A mapping that says :scale false on this same pose is refused rather than overridden: one pose cannot both draw a value as it stands and read it through a scale.

Write a scale spec into `mapping` for `aesthetic` -- what `pj/scale`
does.

A scale lives with the mapping it reads, so this is an update of the
mapping rather than of the pose's options. Where the aesthetic is
mapped plainly there is no room for a scale, so the value is
rewritten in the full form under `:from`, which says the same thing:
ask the data. Where it is not mapped here at all, the scale is
written on its own and applies to whatever source is named below.

A mapping cancelled with `nil` stays cancelled: an aesthetic that
draws nothing has nothing to scale. A mapping that says `:scale
false` on this same pose is refused rather than overridden: one pose
cannot both draw a value as it stands and read it through a scale.
sourceraw docstring

report-panel-aesthetic-on-layerclj

(report-panel-aesthetic-on-layer layer-mapping)

Report a panel aesthetic written on a layer.

:row and :col send a distinction to panels, and a facet multiplies the whole leaf rather than one layer of it, so a panel aesthetic on a layer names a division the draft cannot build. It is reported here rather than dropped, which is what a mapping key with no reading used to do.

Report a panel aesthetic written on a layer.

`:row` and `:col` send a distinction to panels, and a facet
multiplies the whole leaf rather than one layer of it, so a panel
aesthetic on a layer names a division the draft cannot build. It is
reported here rather than dropped, which is what a mapping key with
no reading used to do.
sourceraw docstring

report-unread-positions!clj

(report-unread-positions! pose which)

Warn about an :x or :y written on a composite that no cell reads. pj/pose writes the composite's own mapping, and a cell that maps its own :x or :y overrides it, so without this the write changes nothing and says nothing. The same for a leaf whose layers each name another column there.

which is :composites or :leaves. The two are asked at different moments: a composite once its facets are expanded, because an expansion makes composites; a leaf as it was written, before that, because the cells an expansion makes each hold the layers of the whole pose, and fit-layers reports a layer that fits no cell.

Warn about an `:x` or `:y` written on a composite that no cell reads.
`pj/pose` writes the composite's own mapping, and a cell that maps its
own `:x` or `:y` overrides it, so without this the write changes
nothing and says nothing. The same for a leaf whose layers each name
another column there.

`which` is `:composites` or `:leaves`. The two are asked at different
moments: a composite once its facets are expanded, because an
expansion makes composites; a leaf as it was written, before that,
because the cells an expansion makes each hold the layers of the
whole pose, and `fit-layers` reports a layer that fits no cell.
sourceraw docstring

resolve-treeclj

(resolve-tree pose)
(resolve-tree pose parent-ctx path)

Walk the pose tree top-down, merging parent context into each descendant. Returns a vector of resolved leaves; each leaf carries merged :data, :mapping, :layers, :opts, and a :path vector of indices describing its position in the tree.

Context inheritance rules:

  • :data -- nearest ancestor wins (child overrides parent).
  • :mapping -- merged, with child keys overriding parent keys, and scale settings accumulating (see merge-mappings).
  • :layers -- concatenated (ancestor layers distribute down, then the leaf's own layers append).
  • :opts -- combined (defaults/combine-options: child overrides on key collision, and a :theme combines key by key). So a :share-scales written on a composite reaches a faceted leaf below that writes none, in place of the facet's own default: under an outer {:x :all} the facet's panels share :x only. A facet that writes its own keeps it.

Extra keys on a leaf (anything not in #{:data :mapping :layers :poses :layout :opts :share-scales}) pass through to the resolved leaf so callers can attach metadata like :path-labels from facet-style generators.

Walk the pose tree top-down, merging parent context into each
descendant. Returns a vector of resolved leaves; each leaf carries
merged :data, :mapping, :layers, :opts, and a :path vector of
indices describing its position in the tree.

Context inheritance rules:
- :data     -- nearest ancestor wins (child overrides parent).
- :mapping  -- merged, with child keys overriding parent keys, and
               scale settings accumulating (see `merge-mappings`).
- :layers   -- concatenated (ancestor layers distribute down, then
               the leaf's own layers append).
- :opts     -- combined (`defaults/combine-options`: child overrides on key
               collision, and a `:theme` combines key by key). So a
               `:share-scales` written on a composite reaches a
               faceted leaf below that writes none, in place of
               the facet's own default: under an outer
               `{:x :all}` the facet's panels share `:x` only. A
               facet that writes its own keeps it.

Extra keys on a leaf (anything not in
#{:data :mapping :layers :poses :layout :opts :share-scales})
pass through to the resolved leaf so callers can attach metadata
like :path-labels from facet-style generators.
sourceraw docstring

scale-only-mapping?clj

(scale-only-mapping? v)

True of a mapping value that names a scale and no source -- what pj/scale writes for an aesthetic this pose does not map. It says how to read whatever source is named elsewhere, and where none is, nothing is drawn and the scale is inert.

True of a mapping value that names a scale and no source -- what
`pj/scale` writes for an aesthetic this pose does not map. It says
how to read whatever source is named elsewhere, and where none is,
nothing is drawn and the scale is inert.
sourceraw docstring

series-aestheticsclj

The aesthetics a series may be written under. A series names the columns a mark is drawn from, so it belongs where a column goes on an axis; on an appearance aesthetic there would be nothing for the pivot to draw.

The aesthetics a series may be written under. A series names the
columns a mark is drawn from, so it belongs where a column goes on
an axis; on an appearance aesthetic there would be nothing for the
pivot to draw.
sourceraw docstring

series-clashesclj

(series-clashes cols label column-names)

The columns a series reading cols, with its key column named label, would write over in data whose columns are column-names, as {:key <label or nil> :value <value column or nil>}.

The pivot drops the columns it reads and writes the two it invents, so only the columns it leaves are at risk. One rule for both places that ask: api/pivot-series reports a clash, and report-panel-split offers a series only where there is none -- offering it where the pivot would then refuse sent a writer from one message straight into another.

The columns a series reading `cols`, with its key column named
`label`, would write over in data whose columns are `column-names`,
as `{:key <label or nil> :value <value column or nil>}`.

The pivot drops the columns it reads and writes the two it invents,
so only the columns it leaves are at risk. One rule for both places
that ask: `api/pivot-series` reports a clash, and
`report-panel-split` offers a series only where there is none --
offering it where the pivot would then refuse sent a writer from one
message straight into another.
sourceraw docstring

series-mappingclj

(series-mapping v)

The series a mapping value asks for, as {:cols [...] :as label}, or nil where it asks for none.

Two spellings, one meaning. A vector of columns on a positional aesthetic is the short one; {:series [...] :as :measure} is the same thing written out, and the only reason to write it is to name the key column the pivot invents.

A vector of pairs is not a series -- pj/pose reports it, naming pj/arrange -- so a vector whose elements are themselves sequential answers nil and is left to it.

The series a mapping value asks for, as `{:cols [...] :as label}`, or
nil where it asks for none.

Two spellings, one meaning. A vector of columns on a positional
aesthetic is the short one; `{:series [...] :as :measure}` is the
same thing written out, and the only reason to write it is to name
the key column the pivot invents.

A vector of pairs is not a series -- `pj/pose` reports it, naming
`pj/arrange` -- so a vector whose elements are themselves
sequential answers nil and is left to it.
sourceraw docstring

series-pair-value-columnsclj

The names the two value columns take where a series on :x and a series on :y are pivoted together as pairs. Each titles its axis, which :x-label and :y-label rename.

The names the two value columns take where a series on `:x` and a
series on `:y` are pivoted together as pairs. Each titles its axis,
which `:x-label` and `:y-label` rename.
sourceraw docstring

series-value-columnclj

The name the value column a series invents takes. It titles the value axis, which :x-label and :y-label already rename, so it needs no second spelling of its own.

The name the value column a series invents takes. It titles the
value axis, which `:x-label` and `:y-label` already rename, so it
needs no second spelling of its own.
sourceraw docstring

series-value-columnsclj

(series-value-columns)

The columns a series pivot invents to hold the values: one for a series, one per axis for series in pairs.

The columns a series pivot invents to hold the values: one for a
series, one per axis for series in pairs.
sourceraw docstring

share-axesclj

(share-axes pose)

The axes a composite's cells share in some way -- the axes share-spec names.

The axes a composite's cells share in some way -- the axes
`share-spec` names.
sourceraw docstring

share-bucketsclj

source

share-specclj

(share-spec pose)

How a composite's cells share each axis, as the map defaults/share-scales-spec describes: the written :share-scales (in :opts, or at the top of a hand-built composite), or -- where none is written and the cells are the parts of one declared split -- every axis they can share, each column on its own. Read by shared-axis-groups and by infer-chrome, so the domains and the chrome agree.

How a composite's cells share each axis, as the map
`defaults/share-scales-spec` describes: the written `:share-scales`
(in `:opts`, or at the top of a hand-built composite), or -- where
none is written and the cells are the parts of one declared split --
every axis they can share, each column on its own. Read by
`shared-axis-groups` and by `infer-chrome`, so the domains and the
chrome agree.
sourceraw docstring

shared-axis-groupsclj

(shared-axis-groups root)

Which cells of a pose tree share an axis with which, as {path {axis {:group id :order [category ...]}}} for every leaf in a group of two or more. axis there is the leaf's own -- the axis of its mapping -- while :share-scales names the axis as drawn (data-axis).

Each composite with a :share-scales -- written in (:opts pose) or at the top of a hand-built composite, or inferred where its cells are the parts of one declared split (share-spec) -- links the cells of each of its buckets (share-buckets). Links chain: a cell whose layers draw :a and :b on one panel is in both columns' buckets, and a cell linked by an outer composite and by an inner one joins the two sets, so sharing is one relation over the whole tree and every cell of a group ends on the same domain.

A flipped cell and an upright one drawing a column along the same direction of the page are in one bucket: a marginal on the right names the panel's :y column on its own :x under a flip, and follows whatever the panel's layers draw there.

:order is given where every cell of a group reads the dataset of the composite that links it, whole or in part, and the columns the group draws hold categories: it lists them in the order of that dataset's rows, which is the order a shared categorical axis then takes (plan/order-categories), as the same plot unsplit does.

The checks and warnings about a :share-scales are raised here.

Which cells of a pose tree share an axis with which, as
`{path {axis {:group id :order [category ...]}}}` for every leaf in
a group of two or more. `axis` there is the leaf's own -- the axis
of its mapping -- while `:share-scales` names the axis as drawn
(`data-axis`).

Each composite with a `:share-scales` -- written in `(:opts pose)` or
at the top of a hand-built composite, or inferred where its cells are
the parts of one declared split (`share-spec`) -- links the cells of
each of its buckets (`share-buckets`). Links chain: a cell whose
layers draw `:a` and `:b` on one panel is in both columns' buckets,
and a cell linked by an outer composite and by an inner one joins
the two sets, so sharing is one relation over the whole tree and
every cell of a group ends on the same domain.

A flipped cell and an upright one drawing a column along the same
direction of the page are in one bucket: a marginal on the right
names the panel's `:y` column on its own `:x` under a flip, and
follows whatever the panel's layers draw there.

`:order` is given where every cell of a group reads the dataset of
the composite that links it, whole or in part, and the columns the
group draws hold categories: it lists them in the order of that
dataset's rows, which is the order a shared categorical axis then
takes (`plan/order-categories`), as the same plot unsplit does.

The checks and warnings about a `:share-scales` are raised here.
sourceraw docstring

source-keysclj

The three ways an explicit mapping can name its source.

:column reads the value from the layer's data and :value is the value itself; :from is the plain reading spelled out -- ask the data, and take whichever answer it gives, exactly as a mapping written plainly does. :from is what lets a plain mapping carry a :scale, since a bare :size :weight has no room for one.

The three ways an explicit mapping can name its source.

`:column` reads the value from the layer's data and `:value` is the
value itself; `:from` is the plain reading spelled out -- ask the
data, and take whichever answer it gives, exactly as a mapping
written plainly does. `:from` is what lets a plain mapping carry a
`:scale`, since a bare `:size :weight` has no room for one.
sourceraw docstring

track-countsclj

(track-counts pose)

How many columns and rows of cells a composite lays out: {:n-cols :n-rows :row-lengths :rows? :direction}. A vertical composite of rows -- as pj/arrange and a facet over columns build them -- has a row per child; a horizontal one is one row, and a vertical one of single cells one column.

How many columns and rows of cells a composite lays out:
`{:n-cols :n-rows :row-lengths :rows? :direction}`. A vertical
composite of rows -- as `pj/arrange` and a facet over columns build
them -- has a row per child; a horizontal one is one row, and a
vertical one of single cells one column.
sourceraw docstring

track-weight-keysclj

The plot options that share out a composite's columns and rows of panels. Each is read on the composite it is written on and reaches none of its cells (apply-track-weights).

The plot options that share out a composite's columns and rows of
panels. Each is read on the composite it is written on and reaches
none of its cells (`apply-track-weights`).
sourceraw docstring

unanimous-columnclj

(unanimous-column leaves axis)

The column every cell of leaves draws along axis of the page, or nil where they do not all draw the same one. Cells left empty do not vote. Read along the page (data-axis), as the sharing is, because the title it decides is drawn there: under a flip the column on a cell's :y is titled along the bottom.

The column every cell of `leaves` draws along `axis` of the page, or
nil where they do not all draw the same one. Cells left empty do not
vote. Read along the page (`data-axis`), as the sharing is, because
the title it decides is drawn there: under a flip the column on a
cell's `:y` is titled along the bottom.
sourceraw docstring

unread-positionsclj

(unread-positions pose)

The :x and :y that a composite in pose's tree writes in its own :mapping and that no leaf below reads, because each leaf, or a pose between, writes its own -- on its mapping, or on every one of its layers, which is where a lay-* call naming columns keeps them. Returns [[path k] ...], path the composite's :poses indices from the root.

The `:x` and `:y` that a composite in `pose`'s tree writes in its own
`:mapping` and that no leaf below reads, because each leaf, or a pose
between, writes its own -- on its mapping, or on every one of its
layers, which is where a `lay-*` call naming columns keeps them.
Returns `[[path k] ...]`, `path` the composite's `:poses` indices from
the root.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close