13  Glossary

Key terms used throughout Plotje, with brief definitions and code examples. This is a reference chapter – skim or skip it on a first read through the book, and come back to look up a term when you meet it.

(ns plotje-book.glossary
  (:require
   ;; Rdatasets -- standard datasets
   [scicloj.metamorph.ml.rdatasets :as rdatasets]
   ;; Kindly -- notebook rendering protocol
   [scicloj.kindly.v4.kind :as kind]
   ;; Plotje -- composable plotting
   [scicloj.plotje.api :as pj]
   ;; clojure2d -- color palettes and gradients
   [clojure2d.color :as c2d]))

Pose

A pose is the composable value in Plotje. A leaf pose describes one plot panel; a composite pose contains other poses arranged together. Every pose-shaping function in the API (pj/pose, pj/lay-*, pj/facet, pj/arrange, pj/options, pj/scale, pj/coord) takes a pose and returns a pose. pj/->pose is the polymorphic lift (a function that wraps a value into a richer type) – it accepts raw data or a pose and returns a pose, so any of the output functions can start from a dataset directly. Poses auto-render in Kindly-compatible tools like Clay.

(def my-pose
  (-> (rdatasets/datasets-iris)
      (pj/lay-point :sepal-length :sepal-width {:color :species})
      (pj/options {:title "Iris"})))
my-pose
Irissepal widthsepal lengthspeciessetosaversicolorvirginica4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

A pose is a plain Clojure value – printed, the same value reveals its underlying map shape with :data, :mapping, :layers, and :opts:

(kind/pprint my-pose)
{:layers [{:layer-type :point, :mapping {:color :species}}],
 :data
 https://vincentarelbundock.github.io/Rdatasets/csv/datasets/iris.csv [150 6]:

| :rownames | :sepal-length | :sepal-width | :petal-length | :petal-width |  :species |
|----------:|--------------:|-------------:|--------------:|-------------:|-----------|
|         1 |           5.1 |          3.5 |           1.4 |          0.2 |    setosa |
|         2 |           4.9 |          3.0 |           1.4 |          0.2 |    setosa |
|         3 |           4.7 |          3.2 |           1.3 |          0.2 |    setosa |
|         4 |           4.6 |          3.1 |           1.5 |          0.2 |    setosa |
|         5 |           5.0 |          3.6 |           1.4 |          0.2 |    setosa |
|         6 |           5.4 |          3.9 |           1.7 |          0.4 |    setosa |
|         7 |           4.6 |          3.4 |           1.4 |          0.3 |    setosa |
|         8 |           5.0 |          3.4 |           1.5 |          0.2 |    setosa |
|         9 |           4.4 |          2.9 |           1.4 |          0.2 |    setosa |
|        10 |           4.9 |          3.1 |           1.5 |          0.1 |    setosa |
|       ... |           ... |          ... |           ... |          ... |       ... |
|       140 |           6.9 |          3.1 |           5.4 |          2.1 | virginica |
|       141 |           6.7 |          3.1 |           5.6 |          2.4 | virginica |
|       142 |           6.9 |          3.1 |           5.1 |          2.3 | virginica |
|       143 |           5.8 |          2.7 |           5.1 |          1.9 | virginica |
|       144 |           6.8 |          3.2 |           5.9 |          2.3 | virginica |
|       145 |           6.7 |          3.3 |           5.7 |          2.5 | virginica |
|       146 |           6.7 |          3.0 |           5.2 |          2.3 | virginica |
|       147 |           6.3 |          2.5 |           5.0 |          1.9 | virginica |
|       148 |           6.5 |          3.0 |           5.2 |          2.0 | virginica |
|       149 |           6.2 |          3.4 |           5.4 |          2.3 | virginica |
|       150 |           5.9 |          3.0 |           5.1 |          1.8 | virginica |
,
 :mapping {:x :sepal-length, :y :sepal-width},
 :opts {:title "Iris"}}

Leaf Pose

A leaf pose is a pose that describes a single plot panel. It carries :data, a :mapping from columns to aesthetics, and :layers – the chart-type layers attached to it. Created by pj/pose or pj/lay-*.

Composite Pose

A composite pose is a pose that contains other poses under :poses plus an optional :layout. Created by pj/arrange. Its leaves render independently and are tiled into the final plot.

Some features are not yet exposed through pj/arrange – unequal weights and nested composite cells. To use them, build the composite as a literal map; pj/pose accepts the literal form.

Arrange

pj/arrange builds a composite pose from a sequence of poses. Each input becomes one of the composite’s :poses; the composite tiles them via :layout. It accepts :cols, :title, :width, :height, and :share-scales. For features it does not yet expose – unequal weights and nested composite cells – pass a literal map to pj/pose.

Layer Type

A layer type is the bundle of mark + stat + position that determines how data becomes a visual element. It is a context-free recipe; placing it on a pose produces a layer (next entry). See the Layer Types chapter for detailed tables of all built-in layer types, marks, stats, and positions.

Layer

A layer is a layer type placed on a pose, optionally with scoped mappings. Created by pj/lay-*.

Layers attach to poses in three ways, depending on what you pass to pj/lay-*:

  • Barepj/lay-* without columns attaches the layer using the current pose’s mapping (inherited from pj/pose or a prior pj/lay-*).

  • Matching columnspj/lay-* with columns that match the most recent matching leaf reuses that leaf, so the new layer joins the existing panel.

  • Non-matching columnspj/lay-* with columns that do not match any existing leaf creates a fresh leaf pose with the layer attached.

(-> my-pose :layers first :layer-type)
:point

Mark

The mark is the visual shape shown for each data point or group. Several layer types may share the same mark – for instance, :line and :smooth both produce lines, and :area and :density both produce filled regions. See the Layer Types chapter for a table of all built-in marks.

Stat

A stat (statistical transform) processes raw data before rendering. Each stat takes data-space inputs and produces the geometry that its mark will show. See the Layer Types chapter for a table of all built-in stats.

Position

A position adjustment determines how overlapping marks are placed: kept at their data values (:identity), dodged side-by-side along a categorical band (:dodge), stacked end-to-end so bar tops sit on the previous bar’s top (:stack), or normalized to fill [0, 1] proportions (:fill). Position runs between stat computation and rendering. :stack and :fill rewrite values in data space, before the scales see them; :dodge leaves values untouched and records which slot each mark takes in its band, which becomes a position in drawing space when the mark is drawn. You can override the default position by passing :position in the layer options. When multiple layers share :position :dodge, they are coordinated together – error bars automatically align with bars. See the Layer Types chapter for a table of all built-in positions.

(def tips {:day ["Mon" "Mon" "Tue" "Tue"]
           :count [30 20 45 15]
           :meal ["lunch" "dinner" "lunch" "dinner"]})
(-> tips
    (pj/lay-bar :day :count {:color :meal :position :stack}))
countdaymeallunchdinnerMonTue0102030405060

Draft

A draft is the record produced by pj/draft. For a leaf pose, it is a LeafDraft carrying :layers (a vector of flat maps, one per applicable layer with merged pose-and-layer scope) and :opts (the pose-level options that flow into the plan stage). For a composite pose, it is a CompositeDraft carrying per-leaf drafts plus composite layout geometry. Draft layers carry all the information the plan stage needs: data, columns, mark, stat, color, grouping.

pj/draft is useful for inspecting exactly what the plan stage will consume before any domains, ticks, or coordinate math are computed.

Keys prefixed with double underscores (e.g. :__panel-idx) are internal markers used by later stages and follow the Clojure convention “do not consume.” Ignore them when reading a draft.

(-> my-pose pj/draft kind/pprint)
{:layers
 [{:x :sepal-length,
   :y :sepal-width,
   :mark :point,
   :stat :identity,
   :layer-type :point,
   :color :species,
   :data
   https://vincentarelbundock.github.io/Rdatasets/csv/datasets/iris.csv [150 6]:

| :rownames | :sepal-length | :sepal-width | :petal-length | :petal-width |  :species |
|----------:|--------------:|-------------:|--------------:|-------------:|-----------|
|         1 |           5.1 |          3.5 |           1.4 |          0.2 |    setosa |
|         2 |           4.9 |          3.0 |           1.4 |          0.2 |    setosa |
|         3 |           4.7 |          3.2 |           1.3 |          0.2 |    setosa |
|         4 |           4.6 |          3.1 |           1.5 |          0.2 |    setosa |
|         5 |           5.0 |          3.6 |           1.4 |          0.2 |    setosa |
|         6 |           5.4 |          3.9 |           1.7 |          0.4 |    setosa |
|         7 |           4.6 |          3.4 |           1.4 |          0.3 |    setosa |
|         8 |           5.0 |          3.4 |           1.5 |          0.2 |    setosa |
|         9 |           4.4 |          2.9 |           1.4 |          0.2 |    setosa |
|        10 |           4.9 |          3.1 |           1.5 |          0.1 |    setosa |
|       ... |           ... |          ... |           ... |          ... |       ... |
|       140 |           6.9 |          3.1 |           5.4 |          2.1 | virginica |
|       141 |           6.7 |          3.1 |           5.6 |          2.4 | virginica |
|       142 |           6.9 |          3.1 |           5.1 |          2.3 | virginica |
|       143 |           5.8 |          2.7 |           5.1 |          1.9 | virginica |
|       144 |           6.8 |          3.2 |           5.9 |          2.3 | virginica |
|       145 |           6.7 |          3.3 |           5.7 |          2.5 | virginica |
|       146 |           6.7 |          3.0 |           5.2 |          2.3 | virginica |
|       147 |           6.3 |          2.5 |           5.0 |          1.9 | virginica |
|       148 |           6.5 |          3.0 |           5.2 |          2.0 | virginica |
|       149 |           6.2 |          3.4 |           5.4 |          2.3 | virginica |
|       150 |           5.9 |          3.0 |           5.1 |          1.8 | virginica |
,
   :__panel-idx 0}],
 :opts {:title "Iris"}}

Draft Layer

A draft layer is one entry of a draft’s :layers vector – a single map that bundles the layer type, the merged mappings (pose + layer scopes), and the effective dataset for one (leaf, applicable-layer) pair. It is the specification of what the renderer will draw for that layer, before any geometry, domains, or ticks are computed. The plan layer (entry below) is the same idea after geometry has been resolved.

(-> my-pose pj/draft :layers first kind/pprint)
{:x :sepal-length,
 :y :sepal-width,
 :mark :point,
 :stat :identity,
 :layer-type :point,
 :color :species,
 :data
 https://vincentarelbundock.github.io/Rdatasets/csv/datasets/iris.csv [150 6]:

| :rownames | :sepal-length | :sepal-width | :petal-length | :petal-width |  :species |
|----------:|--------------:|-------------:|--------------:|-------------:|-----------|
|         1 |           5.1 |          3.5 |           1.4 |          0.2 |    setosa |
|         2 |           4.9 |          3.0 |           1.4 |          0.2 |    setosa |
|         3 |           4.7 |          3.2 |           1.3 |          0.2 |    setosa |
|         4 |           4.6 |          3.1 |           1.5 |          0.2 |    setosa |
|         5 |           5.0 |          3.6 |           1.4 |          0.2 |    setosa |
|         6 |           5.4 |          3.9 |           1.7 |          0.4 |    setosa |
|         7 |           4.6 |          3.4 |           1.4 |          0.3 |    setosa |
|         8 |           5.0 |          3.4 |           1.5 |          0.2 |    setosa |
|         9 |           4.4 |          2.9 |           1.4 |          0.2 |    setosa |
|        10 |           4.9 |          3.1 |           1.5 |          0.1 |    setosa |
|       ... |           ... |          ... |           ... |          ... |       ... |
|       140 |           6.9 |          3.1 |           5.4 |          2.1 | virginica |
|       141 |           6.7 |          3.1 |           5.6 |          2.4 | virginica |
|       142 |           6.9 |          3.1 |           5.1 |          2.3 | virginica |
|       143 |           5.8 |          2.7 |           5.1 |          1.9 | virginica |
|       144 |           6.8 |          3.2 |           5.9 |          2.3 | virginica |
|       145 |           6.7 |          3.3 |           5.7 |          2.5 | virginica |
|       146 |           6.7 |          3.0 |           5.2 |          2.3 | virginica |
|       147 |           6.3 |          2.5 |           5.0 |          1.9 | virginica |
|       148 |           6.5 |          3.0 |           5.2 |          2.0 | virginica |
|       149 |           6.2 |          3.4 |           5.4 |          2.3 | virginica |
|       150 |           5.9 |          3.0 |           5.1 |          1.8 | virginica |
,
 :__panel-idx 0}

Mapping

A mapping maps a column (or a written value) to an aesthetic. Aesthetics come in three groups:

  • Positional aesthetics (:x, :y, plus :x-end, :x-min, :x-max, :y-min, :y-max for marks that need them) place each mark.

  • Appearance aesthetics (:color, :size, :alpha, :shape, :text, :fill) shape how each mark looks.

  • Grouping aesthetic (:group) splits the data and draws nothing of its own.

A mapping can be written in full, saying which of its two readings – the column or the value – it means, and which side of the scale to read it through. {:column :species} names the column even where a value of that name could be drawn, {:value "red"} names the value even where the data carries a column called red, and a :scale false beside either draws it as it stands.

Mappings live on a pose – where they flow into every layer attached to it – or on a single layer, where they scope to that layer alone. Lower scope wins on conflict; an explicit nil cancels a mapping inherited from above.

Aesthetic

An aesthetic is a property of a mark that can be mapped to a data column or fixed to a written value. Plotje supports three groups:

Positional aesthetics – where the mark sits:

Key Controls Column type
:x Horizontal position Numerical, temporal, or categorical
:y Vertical position Numerical, temporal, or categorical
:x-end Right edge of an interval bar Same type as :x
:x-min, :x-max Edges of a vertical band No column – a written value only
:y-min, :y-max An errorbar’s bounds, or the edges of a horizontal band Same type as :y, or a written value

Appearance aesthetics – how the mark looks:

Key Controls Column type
:color Fill/stroke color Categorical or numerical
:size How large a mark is drawn – a point’s radius Numerical
:alpha Opacity Numerical
:shape Point shape Categorical
:text Label content Any
:fill Tile gradient color Numerical

Grouping aesthetic – which rows are drawn together:

Key Controls Column type
:group Splits the layer into one drawn group per value Categorical

The layer’s data decides: a value naming one of its columns is a column reference, and anything else is the value itself – "#E74C3C", "red" or :red on :color, 0.5 on :alpha – setting that aesthetic for every mark. It has to be a value the aesthetic can draw: 0.5 on :text names no column and is no label either, so it is reported rather than drawn. Two aesthetics have no reading for a value at all and say so – :fill and :group take a column and nothing else.

To say which you mean where both readings fit, write the mapping in full: {:column "red"} or {:value "red"}.

A single layer can mix the readings: positional column refs (:x, :y), an appearance column ref (:color :species, :size :petal-length), and a written appearance value (:alpha 0.7, the same opacity for every point):

(-> (rdatasets/datasets-iris)
    (pj/lay-point :sepal-length :sepal-width
                  {:color :species :size :petal-length :alpha 0.7}))
sepal widthsepal lengthspeciessetosaversicolorvirginicapetal length1234564.55.05.56.06.57.07.58.02.02.53.03.54.04.5

Group

A group is a subset of data that is processed and rendered together. Mapping :color to a categorical column automatically creates groups – one per unique value. You can also create groups without color using the :group key.

(-> (rdatasets/datasets-iris)
    (pj/lay-line :sepal-length :sepal-width {:group :species}))
sepal widthsepal length4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

Data Space

Data space is values in their original units – centimeters, dollars, dates, species names. A pose’s mappings, a stat’s inputs and outputs, and a plan’s domains and ticks are all in data space. Every stage up to and including the plan keeps its geometry there, which is why a plan is readable: the numbers in it are the numbers from the dataset.

Drawing Space

Drawing space is where the rendered output lives: positions measured in drawing units from the top left of the canvas, x rightward and y downward. A scale maps one axis from data space into drawing space and a coord decides how the two axes land there, so the crossing happens at the membrane stage. The plan holds its geometry in data space, alongside the layout dimensions – panel size, margins, label padding – which are already in drawing units.

A drawing unit is one unit of the plot’s :width and :height. In SVG output it is one user unit; in PNG output it is one Java2D unit. How much of a screen that covers depends on how the output is displayed, which is why this book does not call it a pixel. A browser scales the SVG to whatever box the page gives it, so a drawing unit becomes one CSS pixel only at the plot’s natural size – and a CSS pixel is not a screen pixel either, since a high-resolution display draws two or more screen pixels for each one, and zoom moves that ratio again.

The one place this book does say pixel is the browser interaction layer, because that is the unit a mouse event reports: the drag threshold in the Interactivity chapter is three CSS pixels, not three drawing units.

A position in drawing space is measured from the corner of some rectangle, and this book names three of them: the canvas, the panel box and the drawing area, each with its own entry below. pj/frames reports the panel box and the drawing area for every panel of a plot, and the canvas once – the canvas belongs to the plot rather than to any panel.

Canvas

The canvas is the whole output image: the rectangle the plot’s :width and :height describe, with its top left corner at the origin of drawing space. Everything else a plot draws – panels, axis labels, title, legend – sits inside it.

It is the outermost of the three frames, and the only one shared by every panel. In a composite, each cell’s panels report their rectangles against this same canvas, so all of them can be compared directly.

Panel Box

The panel box is one panel including the axis margin around it: the rectangle a panel is given in the grid, before anything is drawn inside it. In a faceted plot the panel boxes tile the grid edge to edge, one per facet variant, each offset from the last by a panel’s width or height.

A mark that draws in the margin clips to this box rather than to the drawing area. A rug tick is one: it sits outside the panel background. See Clip.

Drawing Area

The drawing area is the panel background inside the axis margin: the panel box less that margin on all four sides. Data marks are drawn here and clipped to it.

A :in :drawing-area layer measures its positions from this rectangle’s top left corner, so a note at drawing-space [12 12] lands 12 units right and 12 units down from that corner.

Nudge

A nudge shifts data coordinates by a constant offset. It is orthogonal to position – you can nudge within a dodge, or nudge at identity. Applied via :nudge-x and :nudge-y keys in the layer options.

A nudge is applied before the scales, but the axis domain is computed without it, so a nudge large enough to carry a mark past the domain leaves it clipped at the panel edge. Widen the domain with pj/scale when that happens. A nudge is therefore a shift in data units rather than a claim about where the datum belongs; ggplot2’s nudge_x and nudge_y differ here, expanding the axis range to keep the nudged mark in view.

(-> {:x [1 2 3] :y [4 5 6]}
    (pj/lay-point :x :y {:nudge-x 0.5}))
yx1.01.21.41.61.82.02.22.42.62.83.04.04.24.44.64.85.05.25.45.65.86.0

Jitter

Jitter adds random offsets in drawing units to reduce overplotting. Unlike position and nudge, jitter operates after scaling (not in data space) and is deterministic – seeded by a hash of the group’s color so repeated renders produce identical output.

On categorical x-axes, jitter is applied along the band axis only.

(-> (rdatasets/datasets-iris)
    (pj/lay-point :species :sepal-length {:jitter true}))
sepal lengthspeciessetosaversicolorvirginica4.55.05.56.06.57.07.58.0

Inference

Inference is the automatic selection of a layer type (mark + stat + position) when you bypass pj/lay-* and pass columns to pj/pose. Plotje picks a layer type based on column types: numerical x and y defaults to :point, categorical x with numerical y to :boxplot, a single numerical column to :histogram, and so on. Use :x-type / :y-type on a pose or layer to override the detected type.

(-> (rdatasets/datasets-iris)
    (pj/pose :sepal-length :sepal-width))
sepal widthsepal length4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

Plan

A plan is the fully resolved description of the plot – a plain Clojure map containing everything needed to render a plot: data-space geometry, domains, tick info, legend, layout dimensions. No membrane types, no datasets, no scale objects.

Created with pj/plan. Numeric arrays (:xs, :ys, etc.) are dtype-next buffers for efficiency – they print with their length and a small preview rather than every element.

(def my-plan (pj/plan my-pose))
(kind/pprint my-plan)
{:panels
 [{:coord :cartesian,
   :y-domain [1.88 4.5200000000000005],
   :x-scale {:type :linear},
   :x-domain [4.12 8.08],
   :x-ticks
   {:values [4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0],
    :labels ["4.5" "5.0" "5.5" "6.0" "6.5" "7.0" "7.5" "8.0"],
    :categorical? false},
   :col 0,
   :layers
   [{:mark :point,
     :style {:opacity 0.75, :radius 3.0},
     :size-scale nil,
     :alpha-scale nil,
     :size-drawn? nil,
     :alpha-drawn? nil,
     :groups
     [{:color
       [0.8941176470588236
        0.10196078431372549
        0.10980392156862745
        1.0],
       :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[5.100, 4.900, 4.700, 4.600, 5.000, 5.400, 4.600, 5.000, 4.400, 4.900, 5.400, 4.800, 4.800, 4.300, 5.800, 5.700, 5.400, 5.100, 5.700, 5.100...],
       :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.500, 3.000, 3.200, 3.100, 3.600, 3.900, 3.400, 3.400, 2.900, 3.100, 3.700, 3.400, 3.000, 3.000, 4.000, 4.400, 3.900, 3.500, 3.800, 3.800...],
       :label "setosa",
       :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19...]}
      {:color
       [0.21568627450980393
        0.49411764705882355
        0.7215686274509804
        1.0],
       :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[7.000, 6.400, 6.900, 5.500, 6.500, 5.700, 6.300, 4.900, 6.600, 5.200, 5.000, 5.900, 6.000, 6.100, 5.600, 6.700, 5.600, 5.800, 6.200, 5.600...],
       :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.200, 3.200, 3.100, 2.300, 2.800, 2.800, 3.300, 2.400, 2.900, 2.700, 2.000, 3.000, 2.200, 2.900, 2.900, 3.100, 3.000, 2.700, 2.200, 2.500...],
       :label "versicolor",
       :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69...]}
      {:color
       [0.30196078431372547 0.6862745098039216 0.2901960784313726 1.0],
       :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[6.300, 5.800, 7.100, 6.300, 6.500, 7.600, 4.900, 7.300, 6.700, 7.200, 6.500, 6.400, 6.800, 5.700, 5.800, 6.400, 6.500, 7.700, 7.700, 6.000...],
       :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.300, 2.700, 3.000, 2.900, 3.000, 3.000, 2.500, 2.900, 2.500, 3.600, 3.200, 2.700, 3.000, 2.500, 2.800, 3.200, 3.000, 3.800, 2.600, 2.200...],
       :label "virginica",
       :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119...]}],
     :y-domain [2.0 4.4],
     :x-domain [4.3 7.9]}],
   :y-scale {:type :linear},
   :y-ticks
   {:values [2.0 2.5 3.0 3.5 4.0 4.5],
    :labels ["2.0" "2.5" "3.0" "3.5" "4.0" "4.5"],
    :categorical? false},
   :row 0}],
 :width 600,
 :height 400,
 :shape-legend nil,
 :caption nil,
 :total-width 600.0,
 :legend-position :right,
 :layout-type :single,
 :layout
 {:subtitle-pad 0,
  :legend-w 102,
  :caption-pad 0,
  :y-label-pad 42.5,
  :legend-h 0.0,
  :title-pad 33,
  :strip-h 0,
  :x-label-pad 38,
  :strip-w 0.0},
 :grid {:rows 1, :cols 1},
 :legend
 {:title :species,
  :entries
  [{:label "setosa",
    :color
    [0.8941176470588236 0.10196078431372549 0.10980392156862745 1.0]}
   {:label "versicolor",
    :color
    [0.21568627450980393 0.49411764705882355 0.7215686274509804 1.0]}
   {:label "virginica",
    :color
    [0.30196078431372547 0.6862745098039216 0.2901960784313726 1.0]}]},
 :panel-height 329.0,
 :title "Iris",
 :y-label "sepal width",
 :alpha-legend nil,
 :x-label "sepal length",
 :subtitle nil,
 :panel-width 455.5,
 :size-legend nil,
 :total-height 400.0,
 :tooltip nil,
 :margin 10}

Panel

A panel is a single plotting area within a plan. It contains x/y domains, scale specs, tick info, coordinate type, and layers. A simple plot has one panel; pj/facet and pj/facet-grid produce multiple.

(kind/pprint (first (:panels my-plan)))
{:coord :cartesian,
 :y-domain [1.88 4.5200000000000005],
 :x-scale {:type :linear},
 :x-domain [4.12 8.08],
 :x-ticks
 {:values [4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0],
  :labels ["4.5" "5.0" "5.5" "6.0" "6.5" "7.0" "7.5" "8.0"],
  :categorical? false},
 :col 0,
 :layers
 [{:mark :point,
   :style {:opacity 0.75, :radius 3.0},
   :size-scale nil,
   :alpha-scale nil,
   :size-drawn? nil,
   :alpha-drawn? nil,
   :groups
   [{:color
     [0.8941176470588236 0.10196078431372549 0.10980392156862745 1.0],
     :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[5.100, 4.900, 4.700, 4.600, 5.000, 5.400, 4.600, 5.000, 4.400, 4.900, 5.400, 4.800, 4.800, 4.300, 5.800, 5.700, 5.400, 5.100, 5.700, 5.100...],
     :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.500, 3.000, 3.200, 3.100, 3.600, 3.900, 3.400, 3.400, 2.900, 3.100, 3.700, 3.400, 3.000, 3.000, 4.000, 4.400, 3.900, 3.500, 3.800, 3.800...],
     :label "setosa",
     :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19...]}
    {:color
     [0.21568627450980393 0.49411764705882355 0.7215686274509804 1.0],
     :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[7.000, 6.400, 6.900, 5.500, 6.500, 5.700, 6.300, 4.900, 6.600, 5.200, 5.000, 5.900, 6.000, 6.100, 5.600, 6.700, 5.600, 5.800, 6.200, 5.600...],
     :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.200, 3.200, 3.100, 2.300, 2.800, 2.800, 3.300, 2.400, 2.900, 2.700, 2.000, 3.000, 2.200, 2.900, 2.900, 3.100, 3.000, 2.700, 2.200, 2.500...],
     :label "versicolor",
     :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69...]}
    {:color
     [0.30196078431372547 0.6862745098039216 0.2901960784313726 1.0],
     :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[6.300, 5.800, 7.100, 6.300, 6.500, 7.600, 4.900, 7.300, 6.700, 7.200, 6.500, 6.400, 6.800, 5.700, 5.800, 6.400, 6.500, 7.700, 7.700, 6.000...],
     :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.300, 2.700, 3.000, 2.900, 3.000, 3.000, 2.500, 2.900, 2.500, 3.600, 3.200, 2.700, 3.000, 2.500, 2.800, 3.200, 3.000, 3.800, 2.600, 2.200...],
     :label "virginica",
     :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119...]}],
   :y-domain [2.0 4.4],
   :x-domain [4.3 7.9]}],
 :y-scale {:type :linear},
 :y-ticks
 {:values [2.0 2.5 3.0 3.5 4.0 4.5],
  :labels ["2.0" "2.5" "3.0" "3.5" "4.0" "4.5"],
  :categorical? false},
 :row 0}

Plan Layer

A plan layer is the resolved descriptor inside a plan panel: resolved mark type, style, and groups of data-space geometry. The user-level layer becomes the plan layer through pj/plan.

(kind/pprint (get-in my-plan [:panels 0 :layers 0]))
{:mark :point,
 :style {:opacity 0.75, :radius 3.0},
 :size-scale nil,
 :alpha-scale nil,
 :size-drawn? nil,
 :alpha-drawn? nil,
 :groups
 [{:color
   [0.8941176470588236 0.10196078431372549 0.10980392156862745 1.0],
   :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[5.100, 4.900, 4.700, 4.600, 5.000, 5.400, 4.600, 5.000, 4.400, 4.900, 5.400, 4.800, 4.800, 4.300, 5.800, 5.700, 5.400, 5.100, 5.700, 5.100...],
   :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.500, 3.000, 3.200, 3.100, 3.600, 3.900, 3.400, 3.400, 2.900, 3.100, 3.700, 3.400, 3.000, 3.000, 4.000, 4.400, 3.900, 3.500, 3.800, 3.800...],
   :label "setosa",
   :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19...]}
  {:color
   [0.21568627450980393 0.49411764705882355 0.7215686274509804 1.0],
   :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[7.000, 6.400, 6.900, 5.500, 6.500, 5.700, 6.300, 4.900, 6.600, 5.200, 5.000, 5.900, 6.000, 6.100, 5.600, 6.700, 5.600, 5.800, 6.200, 5.600...],
   :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.200, 3.200, 3.100, 2.300, 2.800, 2.800, 3.300, 2.400, 2.900, 2.700, 2.000, 3.000, 2.200, 2.900, 2.900, 3.100, 3.000, 2.700, 2.200, 2.500...],
   :label "versicolor",
   :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69...]}
  {:color
   [0.30196078431372547 0.6862745098039216 0.2901960784313726 1.0],
   :xs #tech.v3.dataset.column<float64>[50]
:sepal-length
[6.300, 5.800, 7.100, 6.300, 6.500, 7.600, 4.900, 7.300, 6.700, 7.200, 6.500, 6.400, 6.800, 5.700, 5.800, 6.400, 6.500, 7.700, 7.700, 6.000...],
   :ys #tech.v3.dataset.column<float64>[50]
:sepal-width
[3.300, 2.700, 3.000, 2.900, 3.000, 3.000, 2.500, 2.900, 2.500, 3.600, 3.200, 2.700, 3.000, 2.500, 2.800, 3.200, 3.000, 3.800, 2.600, 2.200...],
   :label "virginica",
   :row-indices #tech.v3.dataset.column<int64>[50]
:__row-idx
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119...]}],
 :y-domain [2.0 4.4],
 :x-domain [4.3 7.9]}

Dataset

A dataset is the tabular data backing a plot. Plotje uses tech.ml.dataset datasets internally – column-oriented, dtype-next-backed tables. The most convenient way to create and manipulate them is the Tablecloth API, which is a Clojure-idiomatic wrapper over tech.ml.dataset.

Raw input (a map of {column-name [values]}, a sequence of row-maps, or a CSV/URL string) is coerced via tablecloth.api/dataset at construction time. The dataset lives on a pose under :data; layers can override with their own :data, and inside a composite each pose in :poses can carry its own :data too.

Pipeline

The pipeline is the five-stage flow from user code to rendered output: pose -> draft -> plan -> membrane -> plot. A pose is what you compose; pj/draft flattens it into a draft (a LeafDraft or CompositeDraft record); pj/plan resolves geometry and layout; the membrane stage turns the plan into drawable primitives; the plot is the terminal SVG hiccup or PNG output. See the Architecture chapter for the per-stage details.

Sub-plot

A sub-plot is one resolved entry of a composite pose’s :poses, in the plan. Where a leaf pose’s plan carries :panels (one per faceted variant), a composite pose’s plan carries :sub-plots (one per inner pose), each with its own nested :plan map. The compositor reads :sub-plots and tiles their rendered membranes into the final canvas.

Resolve Tree

The resolve tree is the scope-merge walk that propagates a root pose’s :mapping, :opts, and root-attached :layers downward into every descendant leaf during plan construction. Lower (narrower) scopes override higher ones; root-attached layers reach every applicable leaf in the tree.

Domain

A domain is the extent of data values a scale reads – along an axis, or on an appearance aesthetic such as :size. It is the data side of a scale; the visible side is its range.

  • Numerical: [min max], where min/max are the raw data extent extended by 5% on each side so points do not sit on the panel edge. For my-pose above, sepal-length runs from 4.3 to 7.9 in the data; the x-domain becomes [4.12 8.08].

  • Temporal: same [min max] form, but the values are epoch-milliseconds (Plotje converts LocalDate, LocalDateTime, Instant, and java.util.Date automatically). Tick labels stay calendar-aware.

  • Categorical: a vector of distinct values in the order they first appear in the data, not alphabetical (e.g., iris gives ["setosa" "versicolor" "virginica"]).

Each panel carries its own :x-domain and :y-domain. With :scales :shared faceting, all panels share one domain pair; with :scales :free (or :free-x/:free-y), each panel computes its own.

(let [p (first (:panels my-plan))]
  {:x-domain (:x-domain p)
   :y-domain (:y-domain p)})
{:x-domain [4.12 8.08], :y-domain [1.88 4.5200000000000005]}

Clip

Clipping bounds a panel’s marks to the panel, so geometry that runs past the axis domain – a line beyond a narrowed scale, a point at the very edge – is masked at the panel boundary rather than painting outside it (and, in a multi-panel layout, into a neighbour). It is the visual counterpart of the Domain: the domain names the window, the clip enforces it. A narrowed domain therefore acts as a view window – the data is kept, only the view is bounded.

Data marks clip to the drawing area (the grey panel background); rug ticks, which sit in the axis margin by design, clip to the wider panel box – the panel rectangle including that margin. The clip is realized in the Membrane stage as a scissor (a membrane.ui/scissor-view, a Membrane primitive that masks its contents to a rectangle), so every backend that honours it clips identically. pj/svg-summary reports the clip regions as :clips – one per panel for the data marks, plus one per panel that also carries a margin mark such as rug.

(-> my-pose pj/plot pj/svg-summary :clips)
1

Tick

A tick is an axis mark with a label at a domain value. Ticks are chosen at layout time to fit the axis length in drawing units – label widths, the spacing asked for, and calendar boundaries (for temporal axes) all feed into the selection. Each panel in the plan carries its own :x-ticks and :y-ticks maps with parallel :values and :labels vectors.

(-> my-plan :panels first :x-ticks)
{:values [4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0],
 :labels ["4.5" "5.0" "5.5" "6.0" "6.5" "7.0" "7.5" "8.0"],
 :categorical? false}

Scale

A scale turns data into something visible. The axes turn data values into places in drawing units; :color, :size, :alpha, :fill and :shape turn them into a color, a radius, an opacity or a symbol. A scale is built from a domain and an output range using wadogo, so it depends on the whole column it is given and not on any one row.

Whether a mapping is read through its scale is asked one mapping at a time, with the :scale key:

  • {:color {:column :hex :scale false}} draws the column’s values as they stand. They inform no domain and earn no legend, since a legend explains a scale.

  • {:color {:value "Model A" :scale true}} sends a written value through the scale as though it were a column of one distinct value, which is how a whole layer is labelled as a named series.

Omitting :scale leaves the choice to the conventions: a column is read through its scale, and a written value is drawn as it stands on the appearance aesthetics and read through the scale on :x and :y.

The same key says which scale, as a type or a whole spec: {:size {:column :weight :scale :log}} reads that one mapping logarithmically, whatever pj/scale says on the pose around it. pj/scale and a mapping’s :scale take the same spec. On :x and :y a panel carries one scale per axis, so two layers naming different ones are refused.

Two aesthetics have no scale at all – :text, which draws a label as it stands, and :group, which draws nothing of its own – so both report a :scale rather than accepting one.

Type Use
:linear Numerical data (default)
:log Orders-of-magnitude data
:categorical Distinct categories (band scale)

Scales are created at render time, not stored in the plan. The plan stores scale specs: :type and :domain, which every scale has, and the keys each aesthetic reads beside them. pj/aesthetic-scales publishes which those are, aesthetic by aesthetic, and Scales prints the table.

Temporal columns (LocalDate, LocalDateTime, Instant, java.util.Date) are detected automatically and converted to epoch-milliseconds – one number per value – before any scale is built. The axis is then an ordinary :linear scale over those numbers, and the domain the plan carries is a pair of epoch-millisecond numbers. That is all “treated as numerical” means: it describes the scaling, not the display. The tick labels are written as dates or times, in a format that follows the span the axis covers. See Inference Rules for the conversion and the tick formats, worked through.

Coord

A coord (coordinate system) defines how data-space maps to drawing units.

Type Behavior
:cartesian Standard: x rightward, y upward
:flip Swap x and y axes
:polar Radial: x as angle, y as radius
:fixed Equal aspect ratio: 1 data unit = 1 data unit
(-> (rdatasets/datasets-iris)
    (pj/lay-bar :species)
    (pj/coord :flip))
species05101520253035404550setosaversicolorvirginica

Facet

A facet splits data into multiple panels by a categorical column. Each panel shows a subset of the data.

  • pj/facet creates a row or column of panels
  • pj/facet-grid creates a row-by-column grid from two columns

By default all panels share the same x and y domains, derived from the full dataset (:scales :shared). To let each panel use its own data range, set {:scales :free} (or :free-x/:free-y) in pj/options.

(-> (rdatasets/datasets-iris)
    (pj/lay-point :sepal-length :sepal-width)
    (pj/facet :species))
sepal widthsepal length682.02.53.03.54.04.56868setosaversicolorvirginica

Annotation

An annotation is a mark layered on a plot to explain it rather than to show data: a reference line, a shaded region, a note, a leader line, a caption. Their positions are given as values or measured on the panel, not read from a column for every row.

Two ways to place one:

  • In data space, so the annotation moves with the axis. Reference lines and bands have their own layer types; a note is a text layer whose :x and :y are values.

  • On the panel, with :in :drawing-area, so the annotation is positioned in drawing units from the corner of the panel background and the axis domains are unaffected. See Drawing Area.

Annotations are regular layers, so they attach under the same three cases as any lay-*: bare call sits on the pose, matching columns join the most recent matching leaf, non-matching columns create a new leaf.

Constructor What
pj/lay-rule-v Vertical line at x = x-intercept
pj/lay-rule-h Horizontal line at y = y-intercept
pj/lay-band-v Vertical shaded region from x = x-min to x = x-max
pj/lay-band-h Horizontal shaded region from y = y-min to y = y-max
pj/lay-text, pj/lay-label A note, at a value or on the panel

The four rule and band constructors take their positions in the layer’s :mapping slot (:y-intercept or :x-intercept for rules; :y-min/:y-max or :x-min/:x-max for bands) as written values rather than column references, and each draws at exactly one place. {:value 1.5} says the same thing at more length; a {:column ...} there is reported, since these read no column. Column-mapped intercepts, producing one mark per row like ggplot2’s geom_hline(aes(yintercept = ...)), are planned but not yet implemented.

Those four are also the only ones the plan keeps apart: a panel carries them in an :annotations slot of its own rather than among its :layers, which matters when walking a plan but not when writing a pose. A text note is an ordinary layer. See the Extensibility chapter.

(def annotated
  (-> (rdatasets/datasets-iris)
      (pj/lay-point :sepal-length :sepal-width)
      (pj/lay-rule-h {:y-intercept 3.0})))
annotated
sepal widthsepal length4.55.05.56.06.57.07.58.02.02.53.03.54.04.5
(kind/pprint (nth (:layers annotated) 1))
{:layer-type :rule-h, :mapping {:y-intercept 3.0}}

Legend

A legend is the key drawn beside the plot that explains a scale: which color stands for which category, which radius for which number. It is generated automatically, and what it explains is the scale rather than the mapping – so a legend appears exactly where a scale was applied.

That means a column read through its scale earns one, and a written value read through its scale earns a one-entry legend naming the value. A mapping given {:scale false} earns none, since its values were drawn as they stand and nothing was decided that a reader would need explaining. Neither does an aesthetic the mark cannot vary from row to row: :size on pj/lay-line draws one width for the whole layer, so a legend pairing values with radii would explain an encoding the panel does not carry.

A legend appears in the plan under the key named for its aesthetic – :legend for color, holding entries with labels and colors, and :size-legend, :alpha-legend, :shape-legend for the others. One column driving both color and shape produces a single merged legend under :legend, whose entries carry a :shape too. Where it sits is controlled via {:legend-position :bottom} in options.

(kind/pprint (:legend my-plan))
{:title :species,
 :entries
 [{:label "setosa",
   :color
   [0.8941176470588236 0.10196078431372549 0.10980392156862745 1.0]}
  {:label "versicolor",
   :color
   [0.21568627450980393 0.49411764705882355 0.7215686274509804 1.0]}
  {:label "virginica",
   :color
   [0.30196078431372547 0.6862745098039216 0.2901960784313726 1.0]}]}

Theme

A theme controls the visual appearance of non-data elements. It is a nested map under :theme with three keys:

Key Controls
:bg Panel background color
:grid Gridline color
:font-size Base font size in drawing units

Passed as {:theme {...}} via pj/options, pj/with-config, or pj/set-config!. Other visual settings (margins, legend width, tick spacing) are top-level configuration keys, not theme entries – see pj/config-key-docs.

(-> (rdatasets/datasets-iris)
    (pj/lay-point :sepal-length :sepal-width {:color :species})
    (pj/options {:theme {:bg "#2d2d2d" :grid "#444444" :font-size 10}}))
sepal widthsepal lengthspeciessetosaversicolorvirginica4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

Membrane

A membrane is a PlotjeMembrane – a record carrying a tree of layout and drawing primitives (Translate, WithColor, RoundedRectangle, Label, etc.) sized to a complete plot canvas. The record itself implements the Membrane library’s UI protocols (IOrigin, IBounds, IChildren), so it composes with other Membrane elements and any Membrane consumer can use it without special handling.

Plotje produces a membrane via pj/plan->membrane (single-step transition from a plan) or pj/membrane (composition shortcut from a pose). The record carries :width and :height as fields (read via (membrane.ui/width m)/(membrane.ui/height m)), and the title as :plotje/title. Direct renderers (e.g., Plotly) skip the membrane entirely. The Membranes chapter walks the stage in depth.

(def my-membrane (pj/plan->membrane my-plan))

A complete membrane is large – one drawable per data point on top of axes, gridlines, ticks, and labels. The record’s children (the underlying drawable tree) for my-plan:

(kind/pprint my-membrane)
{:drawables
 [{:x 270.25,
   :y 14,
   :drawable
   {:color [0.2 0.2 0.2 1.0],
    :drawables
    ({:text "Iris",
      :font {:name nil, :size 15, :weight nil, :width nil, :slant nil},
      :text-anchor "middle"})}}
  {:x 12,
   :y 197.5,
   :drawable
   {:degrees -90,
    :drawable
    {:color [0.2 0.2 0.2 1.0],
     :drawables
     ({:text "sepal width",
       :font
       {:name nil, :size 13, :weight nil, :width nil, :slant nil},
       :text-anchor "middle"})}}}
  {:x 270.25,
   :y 382.0,
   :drawable
   {:color [0.2 0.2 0.2 1.0],
    :drawables
    ({:text "sepal length",
      :font {:name nil, :size 13, :weight nil, :width nil, :slant nil},
      :text-anchor "middle"})}}
  {:x 508.0,
   :y 35,
   :drawable
   {:color [0.2 0.2 0.2 1.0],
    :drawables
    ({:text "species",
      :font
      {:name nil, :size 11, :weight nil, :width nil, :slant nil}})},
   :legend true}
  {:x 508.0,
   :y 53,
   :drawable
   [{:x 0,
     :y 0,
     :drawable
     {:color
      [0.8941176470588236 0.10196078431372549 0.10980392156862745 1.0],
      :drawables
      ({:style :membrane.ui/style-fill,
        :drawables [{:width 8, :height 8, :border-radius 4.0}]})}}
    {:x 12,
     :y 0,
     :drawable
     {:color [0.2 0.2 0.2 1.0],
      :drawables
      ({:text "setosa",
        :font
        {:name nil,
         :size 10,
         :weight nil,
         :width nil,
         :slant nil}})}}],
   :legend true}
  {:x 508.0,
   :y 69,
   :drawable
   [{:x 0,
     :y 0,
     :drawable
     {:color
      [0.21568627450980393 0.49411764705882355 0.7215686274509804 1.0],
      :drawables
      ({:style :membrane.ui/style-fill,
        :drawables [{:width 8, :height 8, :border-radius 4.0}]})}}
    {:x 12,
     :y 0,
     :drawable
     {:color [0.2 0.2 0.2 1.0],
      :drawables
      ({:text "versicolor",
        :font
        {:name nil,
         :size 10,
         :weight nil,
         :width nil,
         :slant nil}})}}],
   :legend true}
  {:x 508.0,
   :y 85,
   :drawable
   [{:x 0,
     :y 0,
     :drawable
     {:color
      [0.30196078431372547 0.6862745098039216 0.2901960784313726 1.0],
      :drawables
      ({:style :membrane.ui/style-fill,
        :drawables [{:width 8, :height 8, :border-radius 4.0}]})}}
    {:x 12,
     :y 0,
     :drawable
     {:color [0.2 0.2 0.2 1.0],
      :drawables
      ({:text "virginica",
        :font
        {:name nil,
         :size 10,
         :weight nil,
         :width nil,
         :slant nil}})}}],
   :legend true}
  {:x 52.5,
   :y 43.0,
   :drawable
   {:color
    [0.9098039215686274 0.9098039215686274 0.9098039215686274 1.0],
    :drawables
    ({:style :membrane.ui/style-fill,
      :drawables [{:width 435.5, :height 309.0}]})}}
  {:x 42.5,
   :y 33.0,
   :drawable
   [{:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([51.790404040404034 10] [51.790404040404034 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([106.77777777777777 10] [106.77777777777777 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([161.7651515151515 10] [161.7651515151515 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([216.75252525252526 10] [216.75252525252526 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([271.73989898989896 10] [271.73989898989896 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([326.72727272727275 10] [326.72727272727275 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([381.7146464646464 10] [381.7146464646464 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([436.7020202020202 10] [436.7020202020202 319.0])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([10 304.95454545454544] [445.5 304.95454545454544])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([10 246.4318181818182] [445.5 246.4318181818182])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([10 187.90909090909093] [445.5 187.90909090909093])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([10 129.38636363636365] [445.5 129.38636363636365])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([10 70.8636363636364] [445.5 70.8636363636364])}]}]})}
    {:color
     [0.9607843137254902 0.9607843137254902 0.9607843137254902 1.0],
     :drawables
     ({:stroke-width 0.6,
       :drawables
       [{:style :membrane.ui/style-stroke,
         :drawables
         [{:points
           ([10 12.340909090909179] [445.5 12.340909090909179])}]}]})}
    {:offset [10 10],
     :bounds [435.5 309.0],
     :drawable
     [{:x 114.77525252525247,
       :y 126.38636363636365,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 0}
      {:x 92.78030303030306,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 1}
      {:x 70.78535353535355,
       :y 161.5,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 2}
      {:x 59.78787878787873,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 3}
      {:x 103.77777777777777,
       :y 114.68181818181819,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 4}
      {:x 147.76767676767682,
       :y 79.56818181818187,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 5}
      {:x 59.78787878787873,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 6}
      {:x 103.77777777777777,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 7}
      {:x 37.79292929292932,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 8}
      {:x 92.78030303030306,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 9}
      {:x 147.76767676767682,
       :y 102.97727272727275,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 10}
      {:x 81.78282828282826,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 11}
      {:x 81.78282828282826,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 12}
      {:x 26.795454545454515,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 13}
      {:x 191.75757575757575,
       :y 67.8636363636364,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 14}
      {:x 180.760101010101,
       :y 21.04545454545456,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 15}
      {:x 147.76767676767682,
       :y 79.56818181818187,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 16}
      {:x 114.77525252525247,
       :y 126.38636363636365,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 17}
      {:x 180.760101010101,
       :y 91.27272727272734,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 18}
      {:x 114.77525252525247,
       :y 91.27272727272734,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 19}
      {:x 147.76767676767682,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 20}
      {:x 114.77525252525247,
       :y 102.97727272727275,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 21}
      {:x 59.78787878787873,
       :y 114.68181818181819,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 22}
      {:x 114.77525252525247,
       :y 149.7954545454546,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 23}
      {:x 81.78282828282826,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 24}
      {:x 103.77777777777777,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 25}
      {:x 103.77777777777777,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 26}
      {:x 125.77272727272731,
       :y 126.38636363636365,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 27}
      {:x 125.77272727272731,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 28}
      {:x 70.78535353535355,
       :y 161.5,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 29}
      {:x 81.78282828282826,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 30}
      {:x 147.76767676767682,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 31}
      {:x 125.77272727272731,
       :y 56.15909090909099,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 32}
      {:x 158.7651515151515,
       :y 44.454545454545496,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 33}
      {:x 92.78030303030306,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 34}
      {:x 103.77777777777777,
       :y 161.5,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 35}
      {:x 158.7651515151515,
       :y 126.38636363636365,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 36}
      {:x 92.78030303030306,
       :y 114.68181818181819,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 37}
      {:x 37.79292929292932,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 38}
      {:x 114.77525252525247,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 39}
      {:x 103.77777777777777,
       :y 126.38636363636365,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 40}
      {:x 48.790404040404034,
       :y 266.8409090909091,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 41}
      {:x 37.79292929292932,
       :y 161.5,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 42}
      {:x 103.77777777777777,
       :y 126.38636363636365,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 43}
      {:x 114.77525252525247,
       :y 91.27272727272734,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 44}
      {:x 81.78282828282826,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 45}
      {:x 114.77525252525247,
       :y 91.27272727272734,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 46}
      {:x 59.78787878787873,
       :y 161.5,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 47}
      {:x 136.770202020202,
       :y 102.97727272727275,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 48}
      {:x 103.77777777777777,
       :y 149.7954545454546,
       :drawable
       [{:color
         [0.8941176470588236
          0.10196078431372549
          0.10980392156862745
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 49}
      {:x 323.72727272727275,
       :y 161.5,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 50}
      {:x 257.74242424242425,
       :y 161.5,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 51}
      {:x 312.72979797979804,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 52}
      {:x 158.7651515151515,
       :y 266.8409090909091,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 53}
      {:x 268.73989898989896,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 54}
      {:x 180.760101010101,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 55}
      {:x 246.74494949494945,
       :y 149.7954545454546,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 56}
      {:x 92.78030303030306,
       :y 255.13636363636363,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 57}
      {:x 279.73737373737373,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 58}
      {:x 125.77272727272731,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 59}
      {:x 103.77777777777777,
       :y 301.95454545454544,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 60}
      {:x 202.75505050505052,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 61}
      {:x 213.75252525252526,
       :y 278.5454545454545,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 62}
      {:x 224.74999999999994,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 63}
      {:x 169.7626262626262,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 64}
      {:x 290.7348484848485,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 65}
      {:x 169.7626262626262,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 66}
      {:x 191.75757575757575,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 67}
      {:x 235.74747474747477,
       :y 278.5454545454545,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 68}
      {:x 169.7626262626262,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 69}
      {:x 202.75505050505052,
       :y 161.5,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 70}
      {:x 224.74999999999994,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 71}
      {:x 246.74494949494945,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 72}
      {:x 224.74999999999994,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 73}
      {:x 257.74242424242425,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 74}
      {:x 279.73737373737373,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 75}
      {:x 301.7323232323232,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 76}
      {:x 290.7348484848485,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 77}
      {:x 213.75252525252526,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 78}
      {:x 180.760101010101,
       :y 231.72727272727272,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 79}
      {:x 158.7651515151515,
       :y 255.13636363636363,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 80}
      {:x 158.7651515151515,
       :y 255.13636363636363,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 81}
      {:x 191.75757575757575,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 82}
      {:x 213.75252525252526,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 83}
      {:x 147.76767676767682,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 84}
      {:x 213.75252525252526,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 85}
      {:x 290.7348484848485,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 86}
      {:x 246.74494949494945,
       :y 266.8409090909091,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 87}
      {:x 169.7626262626262,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 88}
      {:x 158.7651515151515,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 89}
      {:x 158.7651515151515,
       :y 231.72727272727272,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 90}
      {:x 224.74999999999994,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 91}
      {:x 191.75757575757575,
       :y 231.72727272727272,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 92}
      {:x 103.77777777777777,
       :y 266.8409090909091,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 93}
      {:x 169.7626262626262,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 94}
      {:x 180.760101010101,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 95}
      {:x 180.760101010101,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 96}
      {:x 235.74747474747477,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 97}
      {:x 114.77525252525247,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 98}
      {:x 180.760101010101,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.21568627450980393
          0.49411764705882355
          0.7215686274509804
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 99}
      {:x 246.74494949494945,
       :y 149.7954545454546,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 100}
      {:x 191.75757575757575,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 101}
      {:x 334.7247474747474,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 102}
      {:x 246.74494949494945,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 103}
      {:x 268.73989898989896,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 104}
      {:x 389.7121212121212,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 105}
      {:x 92.78030303030306,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 106}
      {:x 356.71969696969694,
       :y 196.61363636363637,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 107}
      {:x 290.7348484848485,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 108}
      {:x 345.72222222222223,
       :y 114.68181818181819,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 109}
      {:x 268.73989898989896,
       :y 161.5,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 110}
      {:x 257.74242424242425,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 111}
      {:x 301.7323232323232,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 112}
      {:x 180.760101010101,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 113}
      {:x 191.75757575757575,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 114}
      {:x 257.74242424242425,
       :y 161.5,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 115}
      {:x 268.73989898989896,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 116}
      {:x 400.70959595959596,
       :y 91.27272727272734,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 117}
      {:x 400.70959595959596,
       :y 231.72727272727272,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 118}
      {:x 213.75252525252526,
       :y 278.5454545454545,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 119}
      {:x 312.72979797979804,
       :y 161.5,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 120}
      {:x 169.7626262626262,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 121}
      {:x 400.70959595959596,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 122}
      {:x 246.74494949494945,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 123}
      {:x 290.7348484848485,
       :y 149.7954545454546,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 124}
      {:x 345.72222222222223,
       :y 161.5,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 125}
      {:x 235.74747474747477,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 126}
      {:x 224.74999999999994,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 127}
      {:x 257.74242424242425,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 128}
      {:x 345.72222222222223,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 129}
      {:x 367.71717171717177,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 130}
      {:x 422.7045454545455,
       :y 91.27272727272734,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 131}
      {:x 257.74242424242425,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 132}
      {:x 246.74494949494945,
       :y 208.31818181818184,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 133}
      {:x 224.74999999999994,
       :y 231.72727272727272,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 134}
      {:x 400.70959595959596,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 135}
      {:x 246.74494949494945,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 136}
      {:x 257.74242424242425,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 137}
      {:x 213.75252525252526,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 138}
      {:x 312.72979797979804,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 139}
      {:x 290.7348484848485,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 140}
      {:x 312.72979797979804,
       :y 173.20454545454547,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 141}
      {:x 191.75757575757575,
       :y 220.02272727272725,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 142}
      {:x 301.7323232323232,
       :y 161.5,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 143}
      {:x 290.7348484848485,
       :y 149.7954545454546,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 144}
      {:x 290.7348484848485,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 145}
      {:x 246.74494949494945,
       :y 243.4318181818182,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 146}
      {:x 268.73989898989896,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 147}
      {:x 235.74747474747477,
       :y 138.09090909090912,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 148}
      {:x 202.75505050505052,
       :y 184.90909090909093,
       :drawable
       [{:color
         [0.30196078431372547
          0.6862745098039216
          0.2901960784313726
          0.75],
         :drawables
         ({:style :membrane.ui/style-fill,
           :drawables
           [{:width 6.0, :height 6.0, :border-radius 3.0}]})}
        nil],
       :row-idx 149}]}
    {:x 51.790404040404034,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "4.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 106.77777777777777,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "5.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 161.7651515151515,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "5.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 216.75252525252526,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "6.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 271.73989898989896,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "6.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 326.72727272727275,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "7.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 381.7146464646464,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "7.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 436.7020202020202,
     :y 331.0,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "8.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "middle"})}}
    {:x 7.0,
     :y 299.45454545454544,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "2.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "end"})}}
    {:x 7.0,
     :y 240.9318181818182,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "2.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "end"})}}
    {:x 7.0,
     :y 182.40909090909093,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "3.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "end"})}}
    {:x 7.0,
     :y 123.88636363636365,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "3.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "end"})}}
    {:x 7.0,
     :y 65.3636363636364,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "4.0",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "end"})}}
    {:x 7.0,
     :y 6.840909090909179,
     :drawable
     {:color [0.4 0.4 0.4 1.0],
      :drawables
      ({:text "4.5",
        :font
        {:name nil, :size 11, :weight nil, :width nil, :slant nil},
        :text-anchor "end"})}}]}],
 :width 600,
 :height 400,
 :plotje/title "Iris"}

Plot

A plot is the final rendered output – the result of rendering a plan to a specific format. For SVG, the plot is hiccup markup wrapped in kind/hiccup.

Created by pj/plot or by auto-rendering a pose.

(def my-plot (pj/plan->plot my-plan :svg {}))

The plot is hiccup – a vector starting with :svg followed by an attribute map and the plot’s drawable elements. Wrapped in kind/hiccup, it renders as the same picture we saw at the top of this chapter:

(kind/hiccup my-plot)
Irissepal widthsepal lengthspeciessetosaversicolorvirginica4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

Palette

A palette is an ordered set of colors used for categorical aesthetics. When :color maps to a categorical column, colors are assigned from the active palette in order.

Plotje uses clojure2d for palettes. Set with :values in a :color scale spec, or with the :color-values option one scope further out:

(-> (rdatasets/datasets-iris)
    (pj/lay-point :sepal-length :sepal-width {:color :species})
    (pj/scale :color {:values :set2}))
sepal widthsepal lengthspeciessetosaversicolorvirginica4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

clojure2d provides thousands of named palettes – the count below is the size of the catalogue:

(count (c2d/find-palette #".*"))
7024

Gradient

A gradient (or color scale) maps a continuous numeric range to a smooth color ramp. Used when :color maps to a numerical column.

Common gradients: :viridis, :inferno, :plasma, :magma. Diverging gradients center on a :midpoint value. Set with :range in a :color scale spec, or with the :color-range option one scope further out:

(-> {:x (range 50) :y (range 50) :c (range 50)}
    (pj/lay-point :x :y {:color :c})
    (pj/scale :color {:range :inferno}))
yxc0490102030405005101520253035404550

Configuration

Configuration controls rendering behavior – dimensions, theme, palette, color scale, margins, and more. It is one of three option scopes – the others are plot options and layer options. Configuration follows a precedence chain:

plot options > pj/with-config > pj/set-config! > plotje.edn > library defaults

plotje.edn is an optional file in your project root that provides project-level defaults (e.g., a consistent palette or theme across all plots).

See the Configuration chapter for details. The active configuration is itself a Clojure map – pj/config returns a snapshot:

(select-keys (pj/config) [:width :height :theme :color-values :color-range])
{:width 600,
 :height 400,
 :theme {:bg "#E8E8E8", :grid "#F5F5F5", :font-size 11}}

Plot Options

Plot options are per-plot settings passed to pj/options, pj/plan, or pj/plot. They include text content (title, subtitle, caption, axis labels) and a nested :config override. Unlike configuration keys, plot options are inherently per-plot – a title does not make sense as a global default.

See pj/plot-option-docs for the full list, or the Configuration chapter for usage examples.

(sort (keys pj/plot-option-docs))
(:alpha-label
 :caption
 :color-label
 :config
 :fill-label
 :panel-height
 :panel-width
 :scales
 :shape-label
 :share-scales
 :size-label
 :subtitle
 :title
 :x-label
 :y-label)

Layer Options

Layer options are per-layer settings passed in the options map of layer functions (pj/lay-point, pj/lay-histogram, etc.). They control aesthetics (:color, :size, :alpha, :shape), grouping (:group), position adjustment (:position), and layer-type-specific parameters (:bandwidth, :confidence-band, :normalize, etc.).

Four keys are universal – accepted by every layer – and each layer type may accept additional keys. The Layer Types chapter lists which options each layer type accepts. See also pj/layer-option-docs for descriptions, or inspect a specific layer type with pj/layer-type-lookup.

(sort (keys pj/layer-option-docs))
(:align-x
 :align-y
 :alpha
 :bandwidth
 :bar-width
 :bins
 :binwidth
 :bootstrap-resamples
 :box
 :box-width
 :cap-width
 :color
 :color-type
 :confidence-band
 :data
 :density-2d-grid
 :fill
 :font-size
 :font-style
 :font-weight
 :group
 :in
 :interval-thickness
 :jitter
 :length
 :level
 :levels
 :mark
 :normalize
 :nudge-x
 :nudge-y
 :offset-x
 :offset-y
 :position
 :shape
 :side
 :size
 :stat
 :stroke
 :stroke-dash
 :stroke-width
 :text
 :trim
 :x
 :x-end
 :x-intercept
 :x-max
 :x-min
 :x-type
 :y
 :y-intercept
 :y-max
 :y-min
 :y-type)

Tooltip and Brush

A tooltip shows data values on hover. A brush enables click-and-drag selection that highlights a rectangular region. Both are JavaScript-based interactions added to the SVG output.

Enabled via {:tooltip true} and {:brush true} in options:

(-> (rdatasets/datasets-iris)
    (pj/lay-point :sepal-length :sepal-width {:color :species})
    (pj/options {:tooltip true :brush true}))
sepal widthsepal lengthspeciessetosaversicolorvirginica4.55.05.56.06.57.07.58.02.02.53.03.54.04.5

Summary Table

Term What Key functions
Pose Composable value: data + mapping + layers (+ inner poses) All pj/ functions return poses
Leaf pose Pose describing one plot panel pj/pose, pj/lay-* with columns
Composite pose Pose containing other poses (in :poses) and a layout pj/arrange
Mapping Column-to-aesthetic association on a pose or layer pj/pose mapping, pj/lay-* options
Layer Layer type attached to a pose, optionally with scoped mappings pj/lay-*
Dataset Tabular data backing a plot – a tech.ml.dataset, conveniently built and manipulated via the Tablecloth API :data slot, pj/with-data
Pipeline Five-stage flow pose -> draft -> plan -> membrane -> plot Architecture chapter
Sub-plot One resolved entry of a composite pose’s :poses, in the plan :sub-plots in plan
Resolve tree Scope-merge walk: root mappings propagate to every leaf Internal to pj/plan
Draft LeafDraft or CompositeDraft record carrying merged layer maps and pose-level options pj/draft, automatic during pj/plan
Draft layer One element of a draft: layer type + merged mappings + data Element of pj/draft output
Layer type Mark + stat + position bundle pj/layer-type-lookup, pj/lay-*
Mark Visual shape: point, line, bar, area, … Key in layer-type map
Stat Data transform: identity, bin, count, linear-model, density, … Key in layer-type map
Position How overlapping marks are placed: identity, dodge, stack, fill Key in layer-type map
Inference Auto-choosing mark/stat from column types When pj/lay-* is omitted
Aesthetic Mark property bindable to a column: positional (x, y, …) or appearance (color, size, alpha, …) Key in mapping or layer
Group Subset of data rendered together From :color or :group
Plan Fully resolved plot description pj/plan
Panel One plotting area (domain, ticks, layers) One or more per plan
Plan layer Resolved geometry + style for one mark Inside plan panels
Domain Data range on an axis Part of panel
Tick Axis mark with label at a domain value Part of panel
Data space Values in their original units – what mappings, stats, domains, and ticks hold Every stage up to the plan
Drawing space Positions in drawing units on the output canvas Membrane and plot stages
Canvas The whole output image, and the origin of drawing space :width / :height; pj/frames
Panel box One panel including its axis margin pj/frames
Drawing area The panel background inside that margin, where data marks clip pj/frames; :in :drawing-area
Scale Data-to-drawing-units mapping (linear, log, categorical) pj/scale, or :scale in a mapping
Coord Coordinate system (cartesian, flip, polar, fixed) pj/coord
Facet Split into panels by a categorical column pj/facet, pj/facet-grid
Arrange Compose multiple poses into a grid pj/arrange
Share scales Make sibling poses of a composite share data ranges across named axes :share-scales in composite :opts
Annotation Reference marks (rules, bands); positions in :mapping as written values today, data-driven planned pj/lay-rule-*, pj/lay-band-*
Legend Color/size/alpha key from aesthetic mappings Automatic in plan
Plot options Title, subtitle, caption, labels, dimensions pj/options
Layer options Per-layer aesthetics and layer-type parameters pj/lay-* options map
Theme Visual styling: background, grid, fonts :theme in pj/options
Palette Ordered color set for categorical aesthetics :values in a :color scale spec
Gradient Continuous color ramp for numerical mappings :range in a :color scale spec
Configuration Global rendering defaults pj/config, pj/set-config!, pj/with-config
Membrane PlotjeMembrane record – a Membrane UI component carrying the drawable tree, plan-derived dimensions, and :plotje/title pj/membrane, pj/plan->membrane
Plot Final output (SVG hiccup) pj/plot, pj/save
Tooltip / Brush JavaScript hover and selection interactions {:tooltip true} in options
source: notebooks/plotje_book/glossary.clj