3  Plotly API reference πŸ“–

This chapter is a detailed refernce of Tableplot’s Plotly API. For diverse examples, see the Plotly API Walkthrough.

3.1 Setup πŸ”¨

In this tutorial, we use:

  • The Tableplot plotly API namepace scicloj.tableplot.v1.plotly
  • Tablecloth for dataset processing and column processing
  • dtype-next’s tensor namespace for tensor examples
  • dtype-next’s buffered image namespace for image representation
  • Kindly (to specify how certain values should be visualized)
  • the datasets defined in the Datasets chapter

We require a few aditional namespaces which are used internally to generate this reference.

(ns tableplot-book.plotly-reference
  (:require [scicloj.tableplot.v1.plotly :as plotly]
            [tablecloth.api :as tc]
            [tablecloth.column.api :as tcc]
            [tech.v3.tensor :as tensor]
            [scicloj.kindly.v4.kind :as kind]
            [scicloj.kindly.v4.api :as kindly]
            [scicloj.tableplot.v1.dag :as dag]
            [scicloj.metamorph.ml.rdatasets :as rdatasets]
            [clojure.string :as str]
            [aerial.hanami.common :as hc]
            [aerial.hanami.templates :as ht]
            [clojure.math :as math]))

3.2 Overview 🐦

The Tableplot Plotly API allows the user to write functional pipelines that create and process templates of plots, that can eventually be realized as Plotly.js specifications.

The data is assumed to be held in datasets defined by tech.ml.dataset (which can conveniently be used using Tablecloth).

The templates are an adapted version of Hanami Templates. Hanami transforms templates by recursively applying a simple set of rules. The rules are based on looking up substitution keys according to standard defaults as well as user substitutions overriding those defaults. Tableplot uses a slighly adapted version of Hanami’s template transformations, which makes sure not to recurse into datasets.

For example, the layer-point function generates a template with some specified substitutions. Let us apply this function to a dataset with some user substitutions. As you can see below, all the substitution keys are keywords beginning with =. E.g., :=color-type. This is just a convention that helps distinguish their role from other keys.

By default, this template is annotated by the Kindly standared so that tools supporting Kindly (such as Clay) will display by realizing it and using it as a Plotly.js specification.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 10}))

Test: template has dataset

Test: layer has correct x and y mappings

Test: realized spec produces scatter type traces

To inspect it, let us use Kindly to request that this template would rather be pretty-printed as a data structure.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 10})
    kind/pprint)
{:data :=traces,
 :layout :=layout,
 :aerial.hanami.templates/defaults
 {:=textfont :com.rpl.specter.impl/NONE,
  :=x0 :com.rpl.specter.impl/NONE,
  :=y-type #function[clojure.lang.AFunction/1],
  :=coordinates :2d,
  :=boxmode :com.rpl.specter.impl/NONE,
  :=x0-after-stat :=x0,
  :=z-after-stat :=z,
  :=splom-traces #function[clojure.lang.AFunction/1],
  :=zmax :com.rpl.specter.impl/NONE,
  :=layers
  [{:y :=y-after-stat,
    :trace-base
    {:mode :=mode,
     :type :=type,
     :opacity :=mark-opacity,
     :textfont :=textfont},
    :colorscale :=colorscale,
    :color-type :=color-type,
    :r :=r,
    :coordinates :=coordinates,
    :group :=group,
    :color :=color,
    :meanline-visible :=meanline-visible,
    :mark :=mark,
    :x-title :=x-title,
    :symbol :=symbol,
    :name :=name,
    :fill :=mark-fill,
    :y1 :=y1-after-stat,
    :bar-width :=bar-width,
    :boxmode :=boxmode,
    :size-range :=size-range,
    :theta :=theta,
    :size :=size,
    :size-type :=size-type,
    :z :=z-after-stat,
    :lon :=lon,
    :aerial.hanami.templates/defaults
    {:=textfont :com.rpl.specter.impl/NONE,
     :=x0 :com.rpl.specter.impl/NONE,
     :=y-type #function[clojure.lang.AFunction/1],
     :=coordinates :2d,
     :=boxmode :com.rpl.specter.impl/NONE,
     :=x0-after-stat :=x0,
     :=z-after-stat :=z,
     :=splom-traces #function[clojure.lang.AFunction/1],
     :=zmax :com.rpl.specter.impl/NONE,
     :=layers [],
     :=mark-fill :com.rpl.specter.impl/NONE,
     :=x1 :com.rpl.specter.impl/NONE,
     :=title :com.rpl.specter.impl/NONE,
     :=annotations :com.rpl.specter.impl/NONE,
     :=z-type #function[clojure.lang.AFunction/1],
     :=y1 :com.rpl.specter.impl/NONE,
     :=y-type-after-stat #function[clojure.lang.AFunction/1],
     :=height 400,
     :=box-visible :com.rpl.specter.impl/NONE,
     :=mark-symbol :com.rpl.specter.impl/NONE,
     :=name :com.rpl.specter.impl/NONE,
     :=mark-opacity :com.rpl.specter.impl/NONE,
     :=inferred-group #function[clojure.lang.AFunction/1],
     :=y-showgrid true,
     :=density-bandwidth :com.rpl.specter.impl/NONE,
     :=mode #function[clojure.lang.AFunction/1],
     :=splom-layout #function[clojure.lang.AFunction/1],
     :=y-title :com.rpl.specter.impl/NONE,
     :=z-type-after-stat #function[clojure.lang.AFunction/1],
     :=size :com.rpl.specter.impl/NONE,
     :=model-options {:model-type :metamorph.ml/ols},
     :=group :=inferred-group,
     :=y0 :com.rpl.specter.impl/NONE,
     :=mark-size 10,
     :=violinmode :com.rpl.specter.impl/NONE,
     :=design-matrix #function[clojure.lang.AFunction/1],
     :=size-type #function[clojure.lang.AFunction/1],
     :=zmin :com.rpl.specter.impl/NONE,
     :=x-showgrid true,
     :=r :com.rpl.specter.impl/NONE,
     :=color :species,
     :=mark-color :com.rpl.specter.impl/NONE,
     :=bar-width :com.rpl.specter.impl/NONE,
     :=y1-after-stat :=y1,
     :=x :sepal-width,
     :=symbol :com.rpl.specter.impl/NONE,
     :=x-after-stat :=x,
     :=yaxis-gridcolor "rgb(255,255,255)",
     :=lon :com.rpl.specter.impl/NONE,
     :=text :com.rpl.specter.impl/NONE,
     :=type #function[clojure.lang.AFunction/1],
     :=x-type-after-stat #function[clojure.lang.AFunction/1],
     :=traces #function[clojure.lang.AFunction/1],
     :=x-type #function[clojure.lang.AFunction/1],
     :=histogram-nbins 10,
     :=automargin false,
     :=stat :=dataset,
     :=z :z,
     :=width 500,
     :=lat :com.rpl.specter.impl/NONE,
     :=margin {:t 25},
     :=color-type #function[clojure.lang.AFunction/1],
     :=xaxis-gridcolor "rgb(255,255,255)",
     :=mark :point,
     :=size-range [10 30],
     :=x-title :com.rpl.specter.impl/NONE,
     :=colorscale :com.rpl.specter.impl/NONE,
     :=layout #function[clojure.lang.AFunction/1],
     :=colnames #function[clojure.lang.AFunction/1],
     :=y :sepal-length,
     :=x1-after-stat :=x1,
     :=dataset
     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 |
,
     :=background "rgb(235,235,235)",
     :=theta :com.rpl.specter.impl/NONE,
     :=y0-after-stat :=y0,
     :=y-after-stat :=y,
     :=predictors [:=x],
     :=marker-size-key #function[clojure.lang.AFunction/1],
     :=meanline-visible :com.rpl.specter.impl/NONE},
    :lat :=lat,
    :y0 :=y0-after-stat,
    :zmax :=zmax,
    :annotations :=annotations,
    :inferred-group :=inferred-group,
    :marker-override
    {:color :=mark-color,
     :=marker-size-key :=mark-size,
     :symbol :=mark-symbol,
     :colorscale :=colorscale},
    :x :=x-after-stat,
    :x1 :=x1-after-stat,
    :x0 :=x0-after-stat,
    :zmin :=zmin,
    :y-title :=y-title,
    :box-visible :=box-visible,
    :dataset :=stat,
    :violinmode :=violinmode,
    :text :=text}],
  :=mark-fill :com.rpl.specter.impl/NONE,
  :=x1 :com.rpl.specter.impl/NONE,
  :=title :com.rpl.specter.impl/NONE,
  :=annotations :com.rpl.specter.impl/NONE,
  :=z-type #function[clojure.lang.AFunction/1],
  :=y1 :com.rpl.specter.impl/NONE,
  :=y-type-after-stat #function[clojure.lang.AFunction/1],
  :=height 400,
  :=box-visible :com.rpl.specter.impl/NONE,
  :=mark-symbol :com.rpl.specter.impl/NONE,
  :=name :com.rpl.specter.impl/NONE,
  :=mark-opacity :com.rpl.specter.impl/NONE,
  :=inferred-group #function[clojure.lang.AFunction/1],
  :=y-showgrid true,
  :=density-bandwidth :com.rpl.specter.impl/NONE,
  :=mode #function[clojure.lang.AFunction/1],
  :=splom-layout #function[clojure.lang.AFunction/1],
  :=y-title :com.rpl.specter.impl/NONE,
  :=z-type-after-stat #function[clojure.lang.AFunction/1],
  :=size :com.rpl.specter.impl/NONE,
  :=model-options {:model-type :metamorph.ml/ols},
  :=group :=inferred-group,
  :=y0 :com.rpl.specter.impl/NONE,
  :=mark-size :com.rpl.specter.impl/NONE,
  :=violinmode :com.rpl.specter.impl/NONE,
  :=design-matrix #function[clojure.lang.AFunction/1],
  :=size-type #function[clojure.lang.AFunction/1],
  :=zmin :com.rpl.specter.impl/NONE,
  :=x-showgrid true,
  :=r :com.rpl.specter.impl/NONE,
  :=color :com.rpl.specter.impl/NONE,
  :=mark-color :com.rpl.specter.impl/NONE,
  :=bar-width :com.rpl.specter.impl/NONE,
  :=y1-after-stat :=y1,
  :=x :x,
  :=symbol :com.rpl.specter.impl/NONE,
  :=x-after-stat :=x,
  :=yaxis-gridcolor "rgb(255,255,255)",
  :=lon :com.rpl.specter.impl/NONE,
  :=text :com.rpl.specter.impl/NONE,
  :=type #function[clojure.lang.AFunction/1],
  :=x-type-after-stat #function[clojure.lang.AFunction/1],
  :=traces #function[clojure.lang.AFunction/1],
  :=x-type #function[clojure.lang.AFunction/1],
  :=histogram-nbins 10,
  :=automargin false,
  :=stat :=dataset,
  :=z :z,
  :=width 500,
  :=lat :com.rpl.specter.impl/NONE,
  :=margin {:t 25},
  :=color-type #function[clojure.lang.AFunction/1],
  :=xaxis-gridcolor "rgb(255,255,255)",
  :=mark :point,
  :=size-range [10 30],
  :=x-title :com.rpl.specter.impl/NONE,
  :=colorscale :com.rpl.specter.impl/NONE,
  :=layout #function[clojure.lang.AFunction/1],
  :=colnames #function[clojure.lang.AFunction/1],
  :=y :y,
  :=x1-after-stat :=x1,
  :=dataset
  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 |
,
  :=background "rgb(235,235,235)",
  :=theta :com.rpl.specter.impl/NONE,
  :=y0-after-stat :=y0,
  :=y-after-stat :=y,
  :=predictors [:=x],
  :=marker-size-key #function[clojure.lang.AFunction/1],
  :=meanline-visible :com.rpl.specter.impl/NONE},
 :kindly/f #'scicloj.tableplot.v1.plotly/plotly-xform}

For now, you are not supposed to make sense of this data representation. As a user, you usually do not need to think about it.

If you wish to see the actual Plotly.js specification, you can use the plot function:

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 10})
    plotly/plot
    kind/pprint)
{:data
 [{:y
   [5.1
    4.9
    4.7
    4.6
    5.0
    5.4
    4.6
    5.0
    4.4
    4.9
    5.4
    4.8
    4.8
    4.3
    5.8
    5.7
    5.4
    5.1
    5.7
    5.1
    5.4
    5.1
    4.6
    5.1
    4.8
    5.0
    5.0
    5.2
    5.2
    4.7
    4.8
    5.4
    5.2
    5.5
    4.9
    5.0
    5.5
    4.9
    4.4
    5.1
    5.0
    4.5
    4.4
    5.0
    5.1
    4.8
    5.1
    4.6
    5.3
    5.0],
   :r nil,
   :name "setosa",
   :marker {:color "#1B9E77", :size 10},
   :fill nil,
   :mode :markers,
   :width nil,
   :type "scatter",
   :theta nil,
   :z nil,
   :lon nil,
   :lat nil,
   :x
   [3.5
    3.0
    3.2
    3.1
    3.6
    3.9
    3.4
    3.4
    2.9
    3.1
    3.7
    3.4
    3.0
    3.0
    4.0
    4.4
    3.9
    3.5
    3.8
    3.8
    3.4
    3.7
    3.6
    3.3
    3.4
    3.0
    3.4
    3.5
    3.4
    3.2
    3.1
    3.4
    4.1
    4.2
    3.1
    3.2
    3.5
    3.6
    3.0
    3.4
    3.5
    2.3
    3.2
    3.5
    3.8
    3.0
    3.8
    3.2
    3.7
    3.3],
   :text nil}
  {:y
   [7.0
    6.4
    6.9
    5.5
    6.5
    5.7
    6.3
    4.9
    6.6
    5.2
    5.0
    5.9
    6.0
    6.1
    5.6
    6.7
    5.6
    5.8
    6.2
    5.6
    5.9
    6.1
    6.3
    6.1
    6.4
    6.6
    6.8
    6.7
    6.0
    5.7
    5.5
    5.5
    5.8
    6.0
    5.4
    6.0
    6.7
    6.3
    5.6
    5.5
    5.5
    6.1
    5.8
    5.0
    5.6
    5.7
    5.7
    6.2
    5.1
    5.7],
   :r nil,
   :name "versicolor",
   :marker {:color "#D95F02", :size 10},
   :fill nil,
   :mode :markers,
   :width nil,
   :type "scatter",
   :theta nil,
   :z nil,
   :lon nil,
   :lat nil,
   :x
   [3.2
    3.2
    3.1
    2.3
    2.8
    2.8
    3.3
    2.4
    2.9
    2.7
    2.0
    3.0
    2.2
    2.9
    2.9
    3.1
    3.0
    2.7
    2.2
    2.5
    3.2
    2.8
    2.5
    2.8
    2.9
    3.0
    2.8
    3.0
    2.9
    2.6
    2.4
    2.4
    2.7
    2.7
    3.0
    3.4
    3.1
    2.3
    3.0
    2.5
    2.6
    3.0
    2.6
    2.3
    2.7
    3.0
    2.9
    2.9
    2.5
    2.8],
   :text nil}
  {:y
   [6.3
    5.8
    7.1
    6.3
    6.5
    7.6
    4.9
    7.3
    6.7
    7.2
    6.5
    6.4
    6.8
    5.7
    5.8
    6.4
    6.5
    7.7
    7.7
    6.0
    6.9
    5.6
    7.7
    6.3
    6.7
    7.2
    6.2
    6.1
    6.4
    7.2
    7.4
    7.9
    6.4
    6.3
    6.1
    7.7
    6.3
    6.4
    6.0
    6.9
    6.7
    6.9
    5.8
    6.8
    6.7
    6.7
    6.3
    6.5
    6.2
    5.9],
   :r nil,
   :name "virginica",
   :marker {:color "#7570B3", :size 10},
   :fill nil,
   :mode :markers,
   :width nil,
   :type "scatter",
   :theta nil,
   :z nil,
   :lon nil,
   :lat nil,
   :x
   [3.3
    2.7
    3.0
    2.9
    3.0
    3.0
    2.5
    2.9
    2.5
    3.6
    3.2
    2.7
    3.0
    2.5
    2.8
    3.2
    3.0
    3.8
    2.6
    2.2
    3.2
    2.8
    2.8
    2.7
    3.3
    3.2
    2.8
    3.0
    2.8
    3.0
    2.8
    3.8
    2.8
    2.8
    2.6
    3.0
    3.4
    3.1
    3.0
    3.1
    3.1
    3.1
    2.7
    3.2
    3.3
    3.0
    2.5
    3.0
    3.4
    3.0],
   :text nil}],
 :layout
 {:width 500,
  :height 400,
  :margin {:t 25},
  :automargin false,
  :plot_bgcolor "rgb(235,235,235)",
  :xaxis
  {:gridcolor "rgb(255,255,255)", :title :sepal-width, :showgrid true},
  :yaxis
  {:gridcolor "rgb(255,255,255)",
   :title :sepal-length,
   :showgrid true},
  :title nil}}

We may also inspect it with Portal:

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 10})
    plotly/plot
    kind/portal)

This is useful for debugging, and also when one wishes to edit the Plotly.js spec directly.

In the remainder of this chapter, we will offer a detailed reference to the API functions, the way layers are defined, the substitution keys, and the relationships among them.

3.3 Debugging πŸ›

Throughout this notebook, we will sometimes use the debug function that allows one to look into the value of a given substitution key in a given context.

For example, here we learn about the :=background key for background color. In this example, we kept it grey, which is its default.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 10})
    (plotly/debug :=background))
"rgb(235,235,235)"

3.4 Raw Plotly specifications ✏

Before beginning the exploration of Tableplot’s Plotly API, let us remember we may also use the raw format supported by Plotly.js. We simply use plain Clojuree data structures to represent the JSON format expected by Plotly.js and annotate it as kind/plotly, so that our Clojure tooling knows to treat it as such when displaying it.

For example, let us reproduce one of its Bubble Chart Examples.

The original Javascript code looks like this:

var trace1 = {
              x: [1, 2, 3, 4],
              y: [10, 11, 12, 13],
              text: ['A<br>size: 40', 'B<br>size: 60', 'C<br>size: 80', 'D<br>size: 100'],
              mode: 'markers',
              marker: {
                       color: ['rgb(93, 164, 214)', 'rgb(255, 144, 14)',  'rgb(44, 160, 101)', 'rgb(255, 65, 54)'],
                       size: [40, 60, 80, 100]
                       }
              };

var data = [trace1];

var layout = {
              title: {
                      text: 'Bubble Chart Hover Text'
                      },
              showlegend: false,
              height: 600,
              width: 600
              };

Plotly.newPlot('myDiv', data, layout);

Here is how we represent that in Clojure:

(plotly/plot
 {:data [{:x [1 2 3 4]
          :y [10 11 12 13]
          :text ["A<br>size: 40" "B<br>size: 60" "C<br>size: 80" "D<br>size: 100"]
          :mode :markers
          :marker {:color ["rgb(93, 164, 214)", "rgb(255, 144, 14)", "rgb(44, 160, 101)", "rgb(255, 65, 54)"]
                   :size [40 60 80 100]}}]
  :layout {:title {:text "Bubble Chart Hover Text"}
           :showlegend false
           :height 600
           :width 600}})

Sometimes, this raw way is all we need; but in common situations, Tableplot makes things easier.

3.5 Concepts πŸ’‘

3.5.1 Plotly.js traces

Traces are a core concept in Plotly.js. They specify separate parts of the plots which can be drawn on the same canvas but may vary in their visual nature.

For example, here is a raw Plotly.js spec with two traces.

(plotly/plot
 {:data [{:x [1 2 3 4]
          :y [10 15 12 13]
          :color "blue"
          :mode :markers
          :marker {:size [40 60 80 100]
                   :color ["blue" "brown" "red" "green"]}}
         {:x [1 2 3 4]
          :y [15 21 17 18]
          :mode :markers
          :color "grey"
          :marker {:size 50
                   :color "grey"}}]})

In Tableplot, we often do not need to think about traces, as they are drawn for us. But it is helpful to know about them if we wish to understand the specs generated by Tableplot.

3.5.2 Layers

Layers are a higher-level concept. We introduce them in Tableplot following ggplot2’s layered grammar of graphics. Plotly bindings in other languages have similar concepts.

Like traces, layers are also parts of the plot that can be drawn on the same canvas, but they are a slightly higher-level concept, that makes it easier to bind our data to parts of the plot.

Layers are themselves templates, so they can have their own substitutions.

For example:

(-> (rdatasets/datasets-iris)
    (tc/random 10 {:seed 1})
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 20})
    (plotly/layer-text {:=text :species}))

This plot has two layers: one for points, and one for text (which is visible on hover).

Let us see that using debug:

(-> (rdatasets/datasets-iris)
    (tc/random 10 {:seed 1})
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 20})
    (plotly/layer-text {:=text :species})
    (plotly/debug :=layers)
    kind/pprint)
[{:y :sepal-length,
  :trace-base {:mode :markers, :type "scatter"},
  :color-type :nominal,
  :coordinates :2d,
  :group (:species),
  :color :species,
  :mark :point,
  :size-range [10 30],
  :z :z,
  :inferred-group (:species),
  :marker-override {:size 20},
  :x :sepal-width,
  :dataset
  https://vincentarelbundock.github.io/Rdatasets/csv/datasets/iris.csv [10 6]:

| :rownames | :sepal-length | :sepal-width | :petal-length | :petal-width |   :species |
|----------:|--------------:|-------------:|--------------:|-------------:|------------|
|        27 |           5.0 |          3.4 |           1.6 |          0.4 |     setosa |
|        97 |           5.7 |          2.9 |           4.2 |          1.3 | versicolor |
|       127 |           6.2 |          2.8 |           4.8 |          1.8 |  virginica |
|        92 |           6.1 |          3.0 |           4.6 |          1.4 | versicolor |
|         7 |           4.6 |          3.4 |           1.4 |          0.3 |     setosa |
|        95 |           5.6 |          2.7 |           4.2 |          1.3 | versicolor |
|       125 |           6.7 |          3.3 |           5.7 |          2.1 |  virginica |
|        61 |           5.0 |          2.0 |           3.5 |          1.0 | versicolor |
|        73 |           6.3 |          2.5 |           4.9 |          1.5 | versicolor |
|        42 |           4.5 |          2.3 |           1.3 |          0.3 |     setosa |
}
 {:y :y,
  :trace-base {:mode :text, :type "scatter"},
  :coordinates :2d,
  :mark :text,
  :size-range [10 30],
  :z :z,
  :x :x,
  :dataset
  https://vincentarelbundock.github.io/Rdatasets/csv/datasets/iris.csv [10 6]:

| :rownames | :sepal-length | :sepal-width | :petal-length | :petal-width |   :species |
|----------:|--------------:|-------------:|--------------:|-------------:|------------|
|        27 |           5.0 |          3.4 |           1.6 |          0.4 |     setosa |
|        97 |           5.7 |          2.9 |           4.2 |          1.3 | versicolor |
|       127 |           6.2 |          2.8 |           4.8 |          1.8 |  virginica |
|        92 |           6.1 |          3.0 |           4.6 |          1.4 | versicolor |
|         7 |           4.6 |          3.4 |           1.4 |          0.3 |     setosa |
|        95 |           5.6 |          2.7 |           4.2 |          1.3 | versicolor |
|       125 |           6.7 |          3.3 |           5.7 |          2.1 |  virginica |
|        61 |           5.0 |          2.0 |           3.5 |          1.0 | versicolor |
|        73 |           6.3 |          2.5 |           4.9 |          1.5 | versicolor |
|        42 |           4.5 |          2.3 |           1.3 |          0.3 |     setosa |
,
  :text :species}]

You see, a layer is an intermediate data representation of Tableplot that takes care of the details necessary to generate traces.

In our example, the two layers are realized as four traces: since the point layer is colored by species, it is realized as three traces.

Let us see that using debug:

(-> (rdatasets/datasets-iris)
    (tc/random 10 {:seed 1})
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 20})
    (plotly/layer-text {:=text :species})
    (plotly/debug :=traces)
    kind/pprint)
[{:y [5.0 4.6 4.5],
  :r nil,
  :name "setosa",
  :marker {:color "#1B9E77", :size 20},
  :fill nil,
  :mode :markers,
  :width nil,
  :type "scatter",
  :theta nil,
  :z nil,
  :lon nil,
  :lat nil,
  :x [3.4 3.4 2.3],
  :text nil}
 {:y [5.7 6.1 5.6 5.0 6.3],
  :r nil,
  :name "versicolor",
  :marker {:color "#D95F02", :size 20},
  :fill nil,
  :mode :markers,
  :width nil,
  :type "scatter",
  :theta nil,
  :z nil,
  :lon nil,
  :lat nil,
  :x [2.9 3.0 2.7 2.0 2.5],
  :text nil}
 {:y [6.2 6.7],
  :r nil,
  :name "virginica",
  :marker {:color "#7570B3", :size 20},
  :fill nil,
  :mode :markers,
  :width nil,
  :type "scatter",
  :theta nil,
  :z nil,
  :lon nil,
  :lat nil,
  :x [2.8 3.3],
  :text nil}
 {:r nil,
  :name "",
  :fill nil,
  :mode :text,
  :width nil,
  :type "scatter",
  :theta nil,
  :z nil,
  :lon nil,
  :lat nil,
  :text
  ["setosa"
   "versicolor"
   "virginica"
   "versicolor"
   "setosa"
   "versicolor"
   "virginica"
   "versicolor"
   "versicolor"
   "setosa"]}]

3.5.3 Mark

Mark is a Tableplot notion that is used to distinguish different types of layers, e.g. point-layer vs line-layer. It is similar to the ggplot notion of β€˜geom’.

Its possible values are:

[:point :text :line :box :violin :bar :segment]

Here, :box means boxplot, and :violin means Violin plot.

3.5.4 Coordinates

Coordinates are a Tableplot notion that defines how marks are eventually mapped over to the cranvas, similar to ggplot’s notion.

We currently support the following:

[:2d :3d :polar :geo]

Here, 2d and 3d mean Eucledian coordinates of the corresponding dimensions, and :geo means latitude and longitude.

For example:

3.5.4.1 geo

Inspired by Plotly’s tutorial for Scatter Plots on Maps in JavaScript:

(-> {:lat [45.5, 43.4, 49.13, 51.1, 53.34, 45.24,
           44.64, 48.25, 49.89, 50.45]
     :lon [-73.57, -79.24, -123.06, -114.1, -113.28,
           -75.43, -63.57, -123.21, -97.13, -104.6]
     :text ["Montreal", "Toronto", "Vancouver", "Calgary", "Edmonton",
            "Ottawa", "Halifax", "Victoria", "Winnepeg", "Regina"]}
    tc/dataset
    (plotly/base {:=coordinates :geo
                  :=lat :lat
                  :=lon :lon})
    (plotly/layer-point {:=mark-opacity 0.8
                         :=mark-color ["#bebada", "#fdb462", "#fb8072", "#d9d9d9", "#bc80bd",
                                       "#b3de69", "#8dd3c7", "#80b1d3", "#fccde5", "#ffffb3"]
                         :=mark-size 20
                         :=name "Canadian cities"})
    (plotly/layer-text {:=text :text
                        :=textfont {:size 7
                                    :color :purple}})
    plotly/plot
    (assoc-in [:layout :geo]
              {:scope "north america"
               :resolution 10
               :lonaxis {:range [-130 -55]}
               :lataxis {:range [40 60]}
               :countrywidth 1.5
               :showland true
               :showlakes true
               :showrivers true}))

3.5.4.2 3d

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=z :petal-length
                         :=color :petal-width
                         :=coordinates :3d}))

Test: 3d coordinates are configured correctly

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=z :petal-length
                         :=color :species
                         :=coordinates :3d}))

3.5.4.3 polar

Monthly rain amounts - polar bar-chart

(def rain-data
  (tc/dataset
   {:month [:Jan :Feb :Mar :Apr
            :May :Jun :Jul :Aug
            :Sep :Oct :Nov :Dec]
    :rain (repeatedly #(rand-int 200))}))
(-> rain-data
    (plotly/layer-bar
     {:=r :rain
      :=theta :month
      :=coordinates :polar
      :=mark-size 20
      :=mark-opacity 0.6}))

Test: polar coordinates are configured correctly

Controlling the polar layout (by manipulating the raw Plotly.js spec):

(-> rain-data
    (plotly/base
     {})
    (plotly/layer-bar
     {:=r :rain
      :=theta :month
      :=coordinates :polar
      :=mark-size 20
      :=mark-opacity 0.6})
    plotly/plot
    (assoc-in [:layout :polar]
              {:angularaxis {:tickfont {:size 16}
                             :rotation 90
                             :direction "counterclockwise"}
               :sector [0 180]}))

A polar random walk - polar line-chart

(let [n 50]
  (-> {:r (->> (repeatedly n #(- (rand) 0.5))
               (reductions +))
       :theta (->> (repeatedly n #(* 10 (rand)))
                   (reductions +)
                   (map #(rem % 360)))
       :color (range n)}
      tc/dataset
      (plotly/layer-point
       {:=r :r
        :=theta :theta
        :=coordinates :polar
        :=mark-size 10
        :=mark-opacity 0.6})
      (plotly/layer-line
       {:=r :r
        :=theta :theta
        :=coordinates :polar
        :=mark-size 3
        :=mark-opacity 0.6})))

3.5.5 Plotly.js mode and type

Mode and type are Plotly.js notions that are used to distinguish diffetent types of traces.

Combinations of Tableplot’s mark and coordinates are mapped onto combinations of Plotly.js mode and type, but currently we do not use all the meaningful combinations supported by Plotly.js.

Mode is derived from mark as follows:

_unnamed [8 2]:

:mark :mode
:point :markers
:text :text
:line :lines
:box
:bar
:segment :lines
:heatmap
:surface

Type is defined as the concatenation of a mark-based string: ("box","violin","bar","heatmap","surface" if that is the mark, and "scatter" otherwise) with a coordinates-based string ("3d", "polar", or "geo" if we have such coordinates, nil otherwise).

Thus, for example, if the mark is :point and the coordinates are :polar, then the type is "scatterpolar".

3.5.6 Field types

Looking into the data in the columns, we may classify them into the following types:

  • :quantitative - numerical columns
  • :temporal - date-time columns
  • :nominal - all other column types (e.g., Strings, keywords)

In certain situations, the types of data in relevant columns determines the way things should be plotted.

For example, when a column is used for coloring a plot, we should use gradient colors when it is quantitative but more distinct colors when it is nominal.

Colorin gby a nominal column:

(-> (rdatasets/datasets-iris)
    (plotly/layer-point
     {:=x :sepal-width
      :=y :sepal-length
      :=color :species
      :=mark-size 20}))

Coloring by a Quantitative column:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=color :cyl
      :=mark-size 20}))

Overriding a quantitative column to be considered nominal by the :=color-type key:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=color :cyl
      :=color-type :nominal
      :=mark-size 20}))

Test: color-type can be explicitly set to nominal

3.5.7 Stat

A stat is a statistical transformation that takes the substitution context and returns a new dataset. Stats such as smooth-stat, histogram-stat, and density-stat are used in a few of the layer functions, such as layer-smooth, layer-histogram, and layer-density.

The user will typically not need to think about them, but they are a useful concept in extending Tableplot.

3.6 API functions βš™

3.6.1 base

[dataset-or-template]

[dataset-or-template submap]

[dataset template submap]

The base function can be used to create the basis template to which we can add layers. It can be used to set up some substitution keys to be shared by the various layers. It can also be used to set up some general substitution keys, which affect the layout rather than any specific layer.

The return value is always a template which is set up to be visualized as Plotly.js.

In the full case of three arguments (dataset template submap), dataset is added to template as the value substituted for the :=dataset key, and the substitution map submap is added as well.

In the other cases, if the template is not passed missing, it is replaced by a minimal base template to be carried along the pipeline. If the dataset or submap parts are not passed, they are simply not substituted into the template.

If the first argument is a dataset, it is converted to a very basic template where it is substituted at the :=dataset key.

We typically use base with other layers added to it. The base substitutions are shared between layers, and the layers can override them and add substitutions of their own.

πŸ”‘ Main useful keys:

  • the keys which are useful for layer
  • the keys that affect :=layout

3.6.1.1 For example

Setting layout options:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=background "floralwhite"
                  :=height 300
                  :=width 400})
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species
                         :=mark-size 10
                         :=mark-opacity 0.6}))

Test: layout settings (background, height, width) are applied

Setting properties which are shared between layers.

(-> (rdatasets/datasets-iris)
    (plotly/base {:=x :sepal-width
                  :=y :sepal-length
                  :=mark-size 10})
    (plotly/layer-point {:=mark-color "grey"
                         :=mark-size 20
                         :=mark-opacity 0.3})
    (plotly/layer-point {:=color :species}))

Test: base with multiple layers creates 2 layers

Test: base sets shared x and y defaults

3.6.2 layer

[dataset-or-template layer-template submap]

The layer function is typically not used on the user side. It is a generic way to create more specific functions to add layers such as layer-point.

If dataset-or-template is a dataset, it is converted to a basic template where it is substituted at the :=dataset key.

Otherwise, it is already template and can be processed further. The layer-template template is added as an additional layer to our template. The submap substitution map is added as additional substitutions to that layer.

The var layer-base is typicall used as the layer-template.

πŸ”‘ Main useful keys:

  • :=mark
  • The keys that are useful for the layer-* functions.

3.6.2.1 For example

We could write someting like:

(-> (rdatasets/datasets-iris)
    (plotly/layer plotly/layer-base
                  {:=mark :point
                   :=x :sepal-width
                   :=y :sepal-length}))

Of course, this can also be expressed more succinctly using layer-point.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length}))

3.6.3 layer-point

[dataset-or-template]

[dataset-or-template submap]

Add a point layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=dataset :=mark :=x :=y :=color :=size :=size-range :=symbol :=color-type :=size-type :=mark-color :=mark-size :=mark-symbol :=mark-opacity

3.6.3.1 For example

Customizing mark size:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=mark-size 20}))

Test: mark size appears in realized spec

Customizing mark symbol:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=mark-symbol :diamond}))

Test: mark symbol appears in realized spec

Customizing mark color:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=mark-color "darkred"}))

Test: mark color appears in realized spec

Customizing mark opacity:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=mark-opacity 0.5}))

Test: mark opacity appears in realized spec (at trace level, not marker)

Coloring by :cyl (considered :quantitative as it is a numerical column).

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=color :cyl
      :=mark-size 20}))

Test: quantitative color creates vector of color values in marker

Coloring by :cyl and overriding :=colorscale:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=color :cyl
      :=colorscale :Greens
      :=mark-size 20}))

Test: custom colorscale appears in spec

Coloring by :cyl, and marking it as :nominal:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=color :cyl
      :=color-type :nominal
      :=mark-size 20}))

Test: nominal color creates multiple traces (one per group)

Determining mark size by :cyl:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=size :cyl}))

Test: size mapping creates vector of sizes in spec

Determining mark size by :cyl and specifying the :=size-range:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=size :cyl
      :=size-range [5 15]}))

Test: size-range constrains marker sizes

Determining mark size by :cyl, and marking :=size-type as :nominal:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=size :cyl
      :=size-type :nominal}))

Determining mark symbol by :cyl:

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-point
     {:=x :mpg
      :=y :disp
      :=symbol :cyl
      :=mark-size 20
      :=mark-color "darkred"}))

Test: symbol mapping creates marker with symbol key

Using the fact that :=x and :=y default to :x and :y:

(-> {:x (range 29)
     :y (reductions + (repeatedly 29 rand))}
    tc/dataset
    plotly/layer-point)

String columns, varying size and color:

(-> {"x" [1 2 3 4]
     "y" [1 4 9 16]
     "z" [:A :B :A :B]
     "w" [:C :C :D :D]}
    tc/dataset
    (plotly/layer-point {:=x "x"
                         :=y "y"
                         :=color "z"
                         :=size "w"}))

String columns, varying symbol and color:

(-> {"x" [1 2 3 4]
     "y" [1 4 9 16]
     "z" [:A :B :A :B]
     "w" [:C :C :D :D]}
    tc/dataset
    (plotly/layer-point {:=x "x"
                         :=y "y"
                         :=color "z"
                         :=symbol "w"
                         :=mark-size 20}))

Using 3d coordinates:

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=z :petal-length
                         :=color :petal-width
                         :=coordinates :3d}))

Test: 3d coordinates produce scatter3d trace type

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=z :petal-length
                         :=color :species
                         :=coordinates :3d}))

3.6.4 layer-line

[dataset-or-template]

[dataset-or-template submap]

Add a line layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=dataset :=x :=y :=color :=size :=siz-range :=color-type :=size-type :=mark-color :=mark-size :=mark-opacity

3.6.4.1 For example

(-> (rdatasets/ggplot2-economics_long)
    (tc/select-rows #(-> % :variable (= "unemploy")))
    (plotly/layer-line
     {:=x :date
      :=y :value
      :=mark-color "purple"}))

Test: layer-line produces lines mode traces

Test: line color appears in realized spec

3.6.5 layer-bar

[dataset-or-template]

[dataset-or-template submap]

Add a bar layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=bar-width :=dataset :=x :=y :=color :=size :=color-type :=size-type :=mark-color :=mark-size :=mark-opacity

3.6.5.1 For example

(-> (rdatasets/datasets-mtcars)
    (tc/group-by [:cyl])
    (tc/aggregate {:total-disp #(-> % :disp tcc/sum)})
    (tc/add-column :bar-width 0.5)
    (plotly/layer-bar
     {:=x :cyl
      :=bar-width :bar-width
      :=y :total-disp}))

Test: bar chart produces correct trace type

Test: bar chart has x and y data arrays

3.6.6 layer-boxplot

[dataset-or-template]

[dataset-or-template submap]

Add a boxplot layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=boxmode :=dataset :=x :=y :=color :=size :=color-type :=size-type :=mark-color :=mark-size :=mark-opacity

3.6.6.1 For example

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-boxplot
     {:=x :cyl
      :=y :disp}))

Test: boxplot produces box trace type

Test: boxplot has x and y data

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-boxplot
     {:=x :cyl
      :=y :disp
      :=color :am
      :=color-type :nominal}))

Test: boxplot with nominal color creates multiple traces

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-boxplot
     {:=x :cyl
      :=y :disp
      :=color :am
      :=color-type :nominal
      :=boxmode :group}))

3.6.7 layer-violin

[dataset-or-template]

[dataset-or-template submap]

Add a Violin plot layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=violinmode :=box-visible :=meanline-visible :=dataset :=x :=y :=color :=size :=color-type :=size-type :=mark-color :=mark-size :=mark-opacity

3.6.7.1 For example

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-violin
     {:=x :cyl
      :=y :disp}))

Test: violin produces violin trace type

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-violin
     {:=x :cyl
      :=y :disp
      :=box-visible true}))

Test: violin with box-visible option is configured correctly

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-violin
     {:=x :cyl
      :=y :disp
      :=meanline-visible true}))

Test: meanline-visible option is configured

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-violin
     {:=x :cyl
      :=y :disp
      :=color :am
      :=color-type :nominal}))
(-> (rdatasets/datasets-mtcars)
    (plotly/layer-violin
     {:=x :cyl
      :=y :disp
      :=color :am
      :=color-type :nominal
      :=violinmode :group}))

Test: violinmode option is configured

3.6.8 layer-segment

[dataset-or-template]

[dataset-or-template submap]

Add a segment layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=dataset :=x0 :=y0 :=x1 :=y1 :=color :=size :=color-type :=size-type :=mark-color :=mark-size :=mark-opacity

3.6.8.1 For example

(-> (rdatasets/datasets-iris)
    (plotly/layer-segment
     {:=x0 :sepal-width
      :=y0 :sepal-length
      :=x1 :petal-width
      :=y1 :petal-length
      :=mark-opacity 0.4
      :=mark-size 3
      :=color :species}))

Test: segment produces scatter traces with lines mode

3.6.9 layer-text

[dataset-or-template]

[dataset-or-template submap]

Add a text layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=text :=textfont :=dataset :=x :=y :=color :=size :=color-type :=size-type :=mark-color :=mark-size :=mark-opacity

3.6.9.1 For example

(-> (rdatasets/datasets-mtcars)
    (plotly/layer-text
     {:=x :mpg
      :=y :disp
      :=text :cyl
      :=textfont {:family "Courier New, monospace"
                  :size 16
                  :color :purple}
      :=mark-size 20}))

Test: text layer produces text mode traces

Test: textfont configuration is applied

3.6.10 layer-histogram

[context]

[context submap]

Add a histogram layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

histogram-stat is used internally as :=stat.

The histogram’s binning and counting are computed using Fastmath.

The :=histogram-nbins key controls the number of bins.

If a list of grouping columns :=group is specified, e.g., when the plot is colored by a nominal type, then the data is grouped by this column, and overlapping histograms are generated.

πŸ”‘ Main useful keys: :=histogram-nbins :=dataset :=x :=color :=color-type :=mark-color :=mark-size :=mark-opacity

3.6.10.1 Examples:

(-> (rdatasets/datasets-iris)
    (plotly/layer-histogram {:=x :sepal-width}))

Test: histogram produces bar trace type

Test: histogram has x and y data (bins and counts)

(-> (rdatasets/datasets-iris)
    (plotly/layer-histogram {:=x :sepal-width
                             :=histogram-nbins 30}))

Test: histogram layer has correct nbins configuration

Test: histogram with 30 bins produces approximately 30 bins

(-> (rdatasets/datasets-iris)
    (plotly/layer-histogram {:=x :sepal-width
                             :=color :species
                             :=mark-opacity 0.5}))

Test: histogram with grouping creates 3 traces (one per species)

3.6.11 layer-histogram2d

[context]

[context submap]

Given columns =x,=y, add a corresponding 2d histogram heatmap layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

See also: layer-heatmap.

πŸ”‘ Main useful keys: :=dataset :=x :=y :=histogram-nbins :=colorscale

(experimental)

3.6.11.1 Examples:

Currently, the number of bins is determined by :histogram-nbins. We are exploring various rules of thumbs to determine it automatically.

(-> (rdatasets/datasets-iris)
    (plotly/layer-histogram2d {:=x :sepal-width
                               :=y :sepal-length}))

Test: histogram2d produces heatmap trace type

(-> (rdatasets/datasets-iris)
    (plotly/layer-histogram2d {:=x :sepal-width
                               :=y :sepal-length
                               :=colorscale :Portland}))
(-> (rdatasets/datasets-iris)
    (plotly/layer-histogram2d {:=x :sepal-width
                               :=y :sepal-length
                               :=histogram-nbins 100}))
(let [n 10000]
  (-> {:x (repeatedly n rand)}
      tc/dataset
      (tc/add-column :y #(tcc/* (repeatedly n rand)
                                (:x %)
                                (:x %)))
      (plotly/layer-histogram2d {:=histogram-nbins 250})))

3.6.12 layer-density

[context]

[context submap]

(experimental)

Add an estimated density layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

density-stat is used internally as :=stat.

The density is estimated by Gaussian kernel density estimation using Fastmath.

The :=density-bandwidth can controls the bandwidth. Otherwise, it is determined by a rule of thumb.

If a list of grouping columns :=group is specified, e.g., when the plot is colored by a nominal type, then the data is grouped by this column, and overlapping densities are generated.

πŸ”‘ Main useful keys: :=dataset :=x :=y :=predictors :=design-matrix :=model-options :=group :=mark-color :=mark-size :=mark-opacity

3.6.12.1 Examples:

(-> (rdatasets/datasets-iris)
    (plotly/layer-density {:=x :sepal-width}))

Test: density produces scatter trace with line mode and tozeroy fill

Test: density curve has many points (smooth curve)

Test: density y-values are non-negative

(-> (rdatasets/datasets-iris)
    (plotly/layer-density {:=x :sepal-width
                           :=density-bandwidth 0.05}))

Test: density bandwidth is configured correctly

(-> (rdatasets/datasets-iris)
    (plotly/layer-density {:=x :sepal-width
                           :=density-bandwidth 1}))
(-> (rdatasets/datasets-iris)
    (plotly/layer-density {:=x :sepal-width
                           :=color :species}))

Test: density with color grouping creates 3 traces

Witn no substitution keys, we can rely on the default for :=x being the :x column:

(-> {:x (repeatedly 9999 rand)}
    tc/dataset
    plotly/layer-density)

3.6.13 layer-smooth

[context]

[context submap]

Add a smoothed layer layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

Statistical regression methods are applied to the dataset to model it as a smooth shape. It is inspired by ggplot’s geom_smooth.

smooth-stat is used internally as :=stat.

By default, the regression is computed with only one predictor variable, which is :=x. This can be overriden using the :=predictors key, which allows computing a regression with more than one predictor.

One can also specify the predictor columns as expressions through the :=design-matrix key. Here, we use the design matrix functionality of Metamorph.ml.

One can also provide the regression model details through :=model-options and use any regression model and parameters registered by Metamorph.ml.

The regressions computed are done on a group level, where the grouping can be inferred as :=inferred-group but can also be user-overridden through :=group.

3.6.13.1 Examples:

Simple linear regression of :=y by :=x:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=x :sepal-width
                  :=y :sepal-length})
    (plotly/layer-point {:=mark-color "green"
                         :=name "Actual"})
    (plotly/layer-smooth {:=mark-color "orange"
                          :=name "Predicted"}))

Test: multi-layer plot has 2 layers

Test: realized plot has 2 traces

Test: traces have correct names

Test: smooth trace has predicted y-values

Test: smooth line color appears in spec

Multiple linear regression of :=y by :=predictors:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=x :sepal-width
                  :=y :sepal-length})
    (plotly/layer-point {:=mark-color "green"
                         :=name "Actual"})
    (plotly/layer-smooth {:=predictors [:petal-width
                                        :petal-length]
                          :=mark-opacity 0.5
                          :=name "Predicted"}))

Test: smooth layer with predictors is configured correctly

Polynomial regression of :=y by :=design-matrix:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=x :sepal-width
                  :=y :sepal-length})
    (plotly/layer-point {:=mark-color "green"
                         :=name "Actual"})
    (plotly/layer-smooth {:=design-matrix [[:sepal-width '(identity :sepal-width)]
                                           [:sepal-width-2 '(* :sepal-width
                                                               :sepal-width)]]
                          :=mark-opacity 0.5
                          :=name "Predicted"}))

Test: smooth layer with design-matrix is configured

Custom regression defined by :=model-options:

(require 'scicloj.ml.tribuo)
(def regression-tree-options
  {:model-type :scicloj.ml.tribuo/regression
   :tribuo-components [{:name "cart"
                        :type "org.tribuo.regression.rtree.CARTRegressionTrainer"
                        :properties {:maxDepth "8"
                                     :fractionFeaturesInSplit "1.0"
                                     :seed "12345"
                                     :impurity "mse"}}
                       {:name "mse"
                        :type "org.tribuo.regression.rtree.impurity.MeanSquaredError"}]
   :tribuo-trainer-name "cart"})
(-> (rdatasets/datasets-iris)
    (plotly/base {:=x :sepal-width
                  :=y :sepal-length})
    (plotly/layer-point {:=mark-color "green"
                         :=name "Actual"})
    (plotly/layer-smooth {:=model-options regression-tree-options
                          :=mark-opacity 0.5
                          :=name "Predicted"}))

Grouped regression where :=inferred-group is influenced by :color since :=color-type is :nominal:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=title "dummy"
                  :=color :species
                  :=x :sepal-width
                  :=y :sepal-length})
    plotly/layer-point
    plotly/layer-smooth)

Regression where grouping is avoiding using through :=group:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=title "dummy"
                  :=color :species
                  :=group []
                  :=x :sepal-width
                  :=y :sepal-length})
    plotly/layer-point
    (plotly/layer-smooth {:=mark-color "red"}))

Test: group can be set to empty array to override grouping

An simpler way to achieve this – the color is only defined for the point layer:

(-> (rdatasets/datasets-iris)
    (plotly/base {:=title "dummy"
                  :=x :sepal-width
                  :=y :sepal-length})
    (plotly/layer-point {:=color :species})
    plotly/layer-smooth)

3.6.14 layer-heatmap

[dataset-or-template]

[dataset-or-template submap]

Add a heatmap layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=dataset :=x :=y :=z :=zmin :=zmax :=colorscale

3.6.14.1 For example

Numerical x,y axes:

(Note we are using the fact that :=x,:=y,:=z default to :x,:y,:z.)

(-> {:x (range 100)
     :y (range 200)
     :z (for [i (range 200)]
          (for [j (range 100)]
            (+ (* (math/sin (/ i 5)) i)
               (* (math/sin (/ j 5)) j))))}
    tc/dataset
    plotly/layer-heatmap)

Test: heatmap produces heatmap trace type

Test: heatmap has x, y, and z data

Test: heatmap z is a 2D matrix (vector of seqs)

Mixed Categorical and numerical x,y axes:

(-> {:x [:A :B]
     :y (range 3)
     :z (for [i (range 3)]
          (for [j (range 2)]
            (+ i j)))}
    tc/dataset
    plotly/layer-heatmap)

Controling the z range:

(-> {:x [:A :B]
     :y (range 3)
     :z (for [i (range 3)]
          (for [j (range 2)]
            (+ i j)))}
    tc/dataset
    (plotly/layer-heatmap
     {:=zmin 0
      :=zmax 5}))

Referring to data elements by name:

(-> {:site [:A :B]
     :time (range 3)
     :temperature (for [i (range 3)]
                    (for [j (range 2)]
                      (+ i j)))}
    tc/dataset
    (plotly/layer-heatmap {:=x :site
                           :=y :time
                           :=z :temperature}))

Customizing color scales:

(-> {:x (range 100)
     :y (range 200)
     :z (for [i (range 200)]
          (for [j (range 100)]
            (+ (* (math/sin (/ i 5)) i)
               (* (math/sin (/ j 5)) j))))}
    tc/dataset
    (plotly/layer-heatmap {:=colorscale :Greys}))

3.6.15 layer-correlation

[context]

[context submap]

Add a correlation heatmap layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

See also: layer-heatmap.

πŸ”‘ Main useful keys: :=dataset :=zmin :=zmax :=colorscale

3.6.15.1 For example

Correlations of a few columns:

(let [n 99]
  (-> {:u (repeatedly n rand)
       :v (repeatedly n rand)
       :w (repeatedly n rand)}
      tc/dataset
      (tc/add-columns {:x #(tcc/+ (:u %) (:v %))
                       :y #(tcc/- (:w %) (tcc/+ (:u %) (:v %)))})
      plotly/layer-correlation))

Test: correlation produces heatmap trace type

Test: correlation matrix is square

Test: correlation values are in valid range [-1, 1]

Correlations of a few columns with a different color scale and zmin-zmax range that is mapped into colors:

(let [n 99]
  (-> {:u (repeatedly n rand)
       :v (repeatedly n rand)
       :w (repeatedly n rand)}
      tc/dataset
      (tc/add-columns {:x #(tcc/+ (:u %) (:v %))})
      (plotly/layer-correlation {:=zmin 0
                                 :=zmax 1
                                 :=colorscale :hot})))

Correlations of many columns:

Let us visualize the correlations of an autoregressive random process at different time shifts.

(let [autoregression (->> (repeatedly 1000 rand)
                          (reductions (fn [x noise]
                                        (+ (* 0.8 x)
                                           (* 0.2 noise)))))
      shifts-dataset (->> (for [shift (range 50)]
                            [(str "shift" shift)
                             (drop shift autoregression)])
                          (apply concat)
                          (apply array-map)
                          tc/dataset)]
  (-> shifts-dataset
      (plotly/layer-correlation {:=zmin 0
                                 :=zmax 1
                                 :=colorscale :hot})))

3.6.16 layer-surface

[dataset-or-template]

[dataset-or-template submap]

Add a surface layer to the given dataset-or-template, with possible additional substitutions if submap is provided.

πŸ”‘ Main useful keys: :=dataset :=z

3.6.16.1 For example

(-> {:z (for [i (range 100)]
          (for [j (range 100)]
            (-> (tcc/- [i j]
                       [30 60])
                (tcc// [20 50])
                tcc/sq
                tcc/sum
                -
                math/exp)))}
    tc/dataset
    plotly/layer-surface)

Combining a 3d scatterplot with a surface:

(let [xy->z (fn [x y]
              (-> [y x]
                  tcc/sq
                  tcc/sum
                  -
                  math/exp))
      n 30]
  (-> {:x (repeatedly n rand)
       :y (repeatedly n rand)}
      tc/dataset
      (tc/map-columns :z
                      [:x :y]
                      (fn [x y]
                        (+ (xy->z x y)
                           (* 0.1 (rand)))))
      (plotly/layer-point {:=coordinates :3d})
      (plotly/layer-surface {:=dataset (let [xs (range 0 1 0.1)
                                             ys (range 0 1 0.1)]
                                         (tc/dataset
                                          {:x xs
                                           :y ys
                                           :z (for [y ys]
                                                (for [x xs]
                                                  (xy->z x y)))}))
                             :=mark-opacity 0.5})))

3.6.17 surface

[surface]

Show a given surface, represented as a matrix of z values, in 3d.

3.6.17.1 For example

(plotly/surface
 (for [i (range 100)]
   (for [j (range 100)]
     (-> (tcc/- [i j]
                [30 60])
         (tcc// [20 50])
         tcc/sq
         tcc/sum
         -
         math/exp))))

Test: surface function produces surface trace type

Test: surface has z data as 2D matrix (vector of seqs)

3.6.18 imshow

[image]

Show a given image - either a java.awt.image.BufferedImage object or a two dimensional matrix of RGB triples.

Imshow uses dtype-next’s BufferedImage support to figure out the right order of color channels, etc.

So, it can handle plain vectors of vectors, dtype next tensors, and actual Java BufferedImage objects.

3.6.18.1 For example

(plotly/imshow
 (for [i (range 10)]
   (for [j (range 10)]
     [(* 10 i) ; Red
      (* 10 j) ; Green
      (* 10 (+ i j)) ; Blue
      ])))

Test: imshow produces image trace type

Test: imshow has image data in z

(plotly/imshow
 (tensor/compute-tensor
  [100 100 3]
  (fn [i j k]
    (case k
      0 i ; Red
      1 j ; Green
      2 (+ i j) ; Blue
      ))
  :uint8))
(defonce Crab-Nebula-image
  (-> "https://scicloj.github.io/sci-cloj-logo-transparent.png"
      (java.net.URL.)
      (javax.imageio.ImageIO/read)))
(plotly/imshow Crab-Nebula-image)

3.6.19 splom

[dataset submap]

Show a SPLOM (ScatterPLOt Matrix) of given dimensions of a dataset.

πŸ”‘ Main useful keys: :=dataset :=colnames :=color :=color-type :=symbol and the other keys that affect :=layout, especially :=height and :=width.

3.6.19.1 For example

(-> (rdatasets/datasets-iris)
    (plotly/splom {:=colnames [:sepal-width
                               :sepal-length
                               :petal-width
                               :petal-length]
                   :=height 600
                   :=width 600}))

Test: splom produces splom trace type

Test: splom has dimensions configured for each column

(-> (rdatasets/datasets-iris)
    (plotly/splom {:=colnames [:sepal-width
                               :sepal-length
                               :petal-width
                               :petal-length]
                   :=color :species
                   :=height 600
                   :=width 600}))

Test: splom with color grouping creates multiple traces

(-> (rdatasets/datasets-iris)
    (plotly/splom {:=colnames [:sepal-width
                               :sepal-length
                               :petal-width
                               :petal-length]
                   :=symbol :species
                   :=height 600
                   :=width 600}))

By default, all columns participate in a SPLOM:

(-> (rdatasets/datasets-iris)
    (tc/select-columns [:sepal-width
                        :sepal-length
                        :petal-width
                        :petal-length])
    (plotly/splom {:=height 600
                   :=width 600}))

3.6.20 plot

[template]

The plot function realizes a template as a Plotly.js specification.

3.6.20.1 For example

(-> (rdatasets/datasets-iris)
    tc/head
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length})
    plotly/plot
    kind/pprint)
{:data
 [{:y [5.1 4.9 4.7 4.6 5.0],
   :r nil,
   :name "",
   :fill nil,
   :mode :markers,
   :width nil,
   :type "scatter",
   :theta nil,
   :z nil,
   :lon nil,
   :lat nil,
   :x [3.5 3.0 3.2 3.1 3.6],
   :text nil}],
 :layout
 {:width 500,
  :height 400,
  :margin {:t 25},
  :automargin false,
  :plot_bgcolor "rgb(235,235,235)",
  :xaxis
  {:gridcolor "rgb(255,255,255)", :title :sepal-width, :showgrid true},
  :yaxis
  {:gridcolor "rgb(255,255,255)",
   :title :sepal-length,
   :showgrid true},
  :title nil}}

This can be useful for editing the plot as a raw Plotly.js specification. For example:

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length})
    plotly/plot
    (assoc-in [:layout :plot_bgcolor] "floralwhite"))

3.6.21 debug

[template result]

[template layer-idx result]

(experimental)

Given a template and a result structure involving substitution keys, find out what value result would receive when realizing the template.

Given a template, a layer-idx integer, and a result structure involving substitution keys, find out what value result would receive when realizing the layer-idxth layer in the template.

3.6.21.1 For example

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species}))

Let us verify that :=background is deterimined to be grey.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species})
    (plotly/debug :=background))
"rgb(235,235,235)"

Here, let us verify :=color-type for the 0th layer is deterimined to be :nominal.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species})
    (plotly/debug 0 :=color-type))
:nominal

Here, let us check both :=color and :=color-type for the 0th layer.

(-> (rdatasets/datasets-iris)
    (plotly/layer-point {:=x :sepal-width
                         :=y :sepal-length
                         :=color :species})
    (plotly/debug 0 {:color :=color
                     :color-type :=color-type}))
{:color :species, :color-type :nominal}

3.7 Stats πŸ–©

3.7.1 histogram-stat

Compute a dataset representing the histogram of the :=x column in :=dataset.

The histogram’s binning and counting are computed using Fastmath.

The number of bins is specified by :histogram-nbins.

If the grouping list of columns :=group is specified, then the histogram is computed in groups.

by default depends on: :=dataset :=group :=x :=histogram-nbins

3.7.2 density-stat

Compute a dataset representing the approximated density of the :=x column in :=dataset.

The density is estimated by Gaussian kernel density estimation using Fastmath.

The :=density-bandwidth can controls the bandwidth. Otherwise, it is determined by a rule of thumb.

If the grouping list of columns :=group is specified, then the density is estimated in groups.

πŸ”‘ Main useful keys: :=density-bandwidth :=dataset :=x :=color :=color-type :=mark-color :=mark-size :=mark-opacity

by default depends on: :=dataset :=group :=x :=density-bandwidth

3.7.3 smooth-stat

Compute a dataset with the :=y column in :=dataset replaced with its value predicted by regression, and with the results ordered by the :=x column.

The predictor columns are specified by :=design-matrix

and the regression model is specified by :=model-options.

If the grouping list of columns :=group is specified, then the regression is computed in groups.

by default depends on: :=dataset :=x :=y :=predictors :=group :=design-matrix :=model-options

3.7.4 correlation-stat

Compute a dataset representing the correlations of the columns in :=dataset.

by default depends on: :=dataset

3.8 Substitution Keys πŸ”‘

3.8.1 :=stat

role: The data resulting from a possible statistical transformation.

default: :=dataset

3.8.2 :=dataset

role: The data to be plotted.

default: NONE

3.8.3 :=x

role: The column for the x axis.

default: :x

3.8.4 :=x-after-stat

role: The column for the x axis to be used after :=stat.

default: :=x

3.8.5 :=y

role: The column for the y axis.

default: :y

3.8.6 :=y-after-stat

role: The column for the y axis to be used after :=stat.

default: :=y

3.8.7 :=z

role: The column for the z axis.

default: :z

3.8.8 :=z-after-stat

role: The column for the z axis to be used after :=stat.

default: :=z

3.8.9 :=x0

role: The column for the first x axis value, in cases where pairs are needed, e.g. segment layers.

default: NONE

3.8.10 :=x0-after-stat

role: The column for the first x axis value after :=stat, in cases where pairs are needed, e.g. segment layers.

default: :=x0

3.8.11 :=y0

role: The column for the first y axis value, in cases where pairs are needed, e.g. segment layers.

default: NONE

3.8.12 :=y0-after-stat

role: The column for the first y axis value after :=stat, in cases where pairs are needed, e.g. segment layers.

default: :=y0

3.8.13 :=x1

role: The column for the second x axis value, in cases where pairs are needed, e.g. segment layers.

default: NONE

3.8.14 :=x1-after-stat

role: The column for the second x axis value after :=stat, in cases where pairs are needed, e.g. segment layers.

default: :=x1

3.8.15 :=y1

role: The column for the second y axis value, in cases where pairs are needed, e.g. segment layers.

default: NONE

3.8.16 :=y1-after-stat

role: The column for the second y axis value after :=stat, in cases where pairs are needed, e.g. segment layers.

default: :=y1

3.8.17 :=bar-width

role: The column to determine the bar width in bar layers.

default: NONE

3.8.18 :=color

role: The column to determine the color of marks.

default: NONE

3.8.19 :=size

role: The column to determine the size of marks.

default: NONE

3.8.20 :=size-range

role: The desired range of values for the marker sizes when sizing by a quantitative variable.

default: [10 30]

3.8.21 :=symbol

role: The column to determine the symbol of marks.

default: NONE

3.8.22 :=x-type

role: The field type of the column used to determine the x axis.

default: Check the field type of the column specified by :=x after :=stat.

  • :quantitative - numerical columns
  • :temporal - date-time columns
  • :nominal - all other column types (e.g., Strings, keywords)

by default depends on: :=x :=dataset

3.8.23 :=x-type-after-stat

role: The field type of the column used to determine the x axis after :=stat.

default:

by default depends on: :=x-after-stat :=x :=x-type :=stat

3.8.24 :=y-type

role: The field type of the column used to determine the y axis.

default: Check the field type of the column specified by :=y after :=stat.

  • :quantitative - numerical columns
  • :temporal - date-time columns
  • :nominal - all other column types (e.g., Strings, keywords)

by default depends on: :=y :=dataset

3.8.25 :=y-type-after-stat

role: The field type of the column used to determine the y axis after :=stat.

default:

by default depends on: :=y-after-stat :=y :=y-type :=stat

3.8.26 :=z-type

role: The field type of the column used to determine the z axis.

default: Check the field type of the column specified by :=z after :=stat.

  • :quantitative - numerical columns
  • :temporal - date-time columns
  • :nominal - all other column types (e.g., Strings, keywords)

by default depends on: :=z :=dataset

3.8.27 :=z-type-after-stat

role: The field type of the column used to determine the z axis after :=stat.

default:

by default depends on: :=z-after-stat :=z :=z-type :=stat

3.8.28 :=r

role: The column for the radius in polar coordinates.

default: NONE

3.8.29 :=theta

role: The column for the angle in polar coordinates.

default: NONE

3.8.30 :=lat

role: The column for the latitude in geo coordinates.

default: NONE

3.8.31 :=lon

role: The column for the longitude in geo coordinates.

default: NONE

3.8.32 :=color-type

role: The field type of the column used to determine mark color.

default: Check the field type of the column specified by :=color after :=stat.

  • :quantitative - numerical columns
  • :temporal - date-time columns
  • :nominal - all other column types (e.g., Strings, keywords)

by default depends on: :=color :=dataset

3.8.33 :=size-type

role: The field type of the column used to determine mark size

default: Check the field type of the column specified by :=size after :=stat.

  • :quantitative - numerical columns
  • :temporal - date-time columns
  • :nominal - all other column types (e.g., Strings, keywords)

by default depends on: :=size :=dataset

3.8.34 :=mark-color

role: A fixed color specification for marks.

default: NONE

3.8.35 :=mark-size

role: A fixed size specification for marks.

default: NONE

3.8.36 :=marker-size-key

role: What key does Plotly.js use to hold the marker size?

default: Determine which Plotly.js key should be used to specify the mark size. For lines, it is :width. Otherwise, it is :size.

by default depends on: :=mode :=type

3.8.37 :=mark-symbol

role: A fixed symbol specification for marks

default: NONE

3.8.38 :=mark-fill

role: A fixed fill specification for marks.

default: NONE

3.8.39 :=mark-opacity

role: A fixed opacity specification for marks.

default: NONE

3.8.40 :=text

role: The column to determine the text of marks (relevant for text layer).

default: NONE

3.8.41 :=textfont

role: Text font specification as defined in Plotly.js. See Text and oFnt Styling.

default: NONE

3.8.42 :=mark

role: The mark used for a layer (a Tablepot concept).

default: :point

3.8.43 :=mode

role: The Plotly.js mode used in a trace.

default: Determine the Plotly.js mode for a trace.

by default depends on: :=mark

3.8.44 :=type

role: The Plotly.js type used in a trace.

default: Determine the Plotly.js type for a trace.

by default depends on: :=mark :=coordinates

3.8.45 :=name

role: The layer name (which affects the Plotly.js traces names and appears in the legend).

default: NONE

3.8.46 :=layers

role: A vector of all lyaers in the plot (an inermediate Tableplot representation before converting to Plotly.js traces).

default: []

3.8.47 :=traces

role: A vector of all Plotly.js traces in the plot.

default: Create the Plotly.js traces from the Tableplot layers.

by default depends on: :=layers

3.8.48 :=layout

role: The layout part of the resulting Plotly.js specification.

default: Create the layout part of the Plotly.js specification.

by default depends on: :=width :=height :=margin :=automargin :=background :=title :=xaxis-gridcolor :=yaxis-gridcolor :=x-after-stat :=y-after-stat :=x-title :=y-title :=x-showgrid :=y-showgrid :=boxmode :=violinmode :=annotations :=layers

3.8.49 :=inferred-group

role: A list of columns to be used for grouping of statistical computations, inferred from other keys and data (e.g., :=color).

default: Infer the relevant grouping for statistical layers such as layer-smooth. The :=color column affects the grouing if and only if :=color-type is :nominal. The :=size column affects the grouing if and only if :=size-type is :nominal. The :=symbol column affects the grouping.

by default depends on: :=color :=color-type :=size :=size-type :=symbol

3.8.50 :=group

role: A list of columns to be used for grouping of statisticsl computations, a possible user override of :=inerred-group.

default: :=inferred-group

3.8.51 :=predictors

role: The list of predictors to be used in regression (layer-smooth).

default: [:=x]

3.8.52 :=design-matrix

role: The design matrix definition to be used in regression (layer-smooth).

default: Determine a trivial design matrix specifiation from a set of :=predictors columns. The design matrix simply uses these columns without any additional transformation.

by default depends on: :=predictors

3.8.53 :=model-options

role: The optional specification of a model for regression (layer-smooth).

default: {:model-type :metamorph.ml/ols}

3.8.54 :=histogram-nbins

role: The number of bins for layer-histogram.

default: 10

3.8.55 :=density-bandwidth

role: The bandwidth of density estimation for layer-density.

default: NONE

3.8.56 :=box-visible

role: Should the boxplot be visible in Violin plots? (boolean)

default: NONE

3.8.57 :=meanline-visible

role: Should the mean line be visible in Violin plots? (boolean)

default: NONE

3.8.58 :=boxmode

role: How to show a group of box plots? The default is nil, which means overlay. The alternative is :group.

default: NONE

3.8.59 :=violinmode

role: How to show a group of violin plots? The default is nil, which means overlay. The alternative is :group.

default: NONE

3.8.60 :=coordinates

role: The coordinates to use: :2d/:3d/:polar/:geo.

default: :2d

3.8.61 :=height

role: The plot’s height.

default: 400

3.8.62 :=width

role: The plot’s width.

default: 500

3.8.63 :=margin

role: Plotly.js margin specification. See Setting Graph Size in Javaspcrit.

default: {:t 25}

3.8.64 :=automargin

role: Should Plotly.js margins be automatically adjusted? See Setting Graph Size in Javaspcrit.

default: false

3.8.65 :=x-title

role: The title for x axis.

default: NONE

3.8.66 :=y-title

role: The title for y axis.

default: NONE

3.8.67 :=title

role: The plot title.

default: NONE

3.8.68 :=x-showgrid

role: Should we show the grid for the x axis?

default: true

3.8.69 :=y-showgrid

role: Should we show the grid for the y axis?

default: true

3.8.70 :=background

role: The plot background color.

default: "rgb(235,235,235)"

3.8.71 :=xaxis-gridcolor

role: The color for the x axis grid lines.

default: "rgb(255,255,255)"

3.8.72 :=yaxis-gridcolor

role: The color for the y axis grid lines.

default: "rgb(255,255,255)"

3.8.73 :=colnames

role: Column names for a SPLOM plot. The default is all columns of the dataset.

default: Extract all column names of the dataset.

by default depends on: :=dataset

3.8.74 :=splom-layout

role: The layout for a SPLOM plot.

default: Create the layout for a SPLOM plot.

by default depends on: :=layout :=colnames

3.8.75 :=splom-traces

role: The trace for a SPLOM plot.

default: Create the trace for a SPLOM plot.

by default depends on: :=dataset :=colnames :=color :=color-type :=symbol :=splom-colnames

3.8.76 :=zmin

role: Minimal z range value for heatmap.

default: NONE

3.8.77 :=zmax

role: Maximal z range value for heatmap.

default: NONE

3.8.78 :=colorscale

role: Color scale for heatmap and scatterplots.

default: NONE

3.8.79 :=annotations

role: Plot annotations.

default: NONE

source: notebooks/tableplot_book/plotly_reference.clj