Skip to content

Latest commit

 

History

History
126 lines (97 loc) · 3.31 KB

README.md

File metadata and controls

126 lines (97 loc) · 3.31 KB

Plot your data with aplomb!

Aplomb is a plotting package for OCaml based on Vega-Lite.

Status: pre-release, expect breaking changes.

Overview

Aplomb makes it simple to create Vega-Lite visualization specs from datasets, then view the specs as plots.

  • Package aplomb.browser shows plots in browser tabs.
  • aplomb.webview shows them in webviews.
  • aplomb.iocaml shows them in Iocaml notebooks. See examples/bar.ipynb.

Usage example

(*
  To run interactively:

  utop -require aplomb,aplomb.browser -init examples/bar.ml
*)
let data = [
  ("a", `String [| "A"; "B"; "C"; "D"; "E"; "F"; "G"; "H"; "I" |]);
  ("b", `Int [| 28; 55; 43; 91; 81; 53; 19; 87; 52 |])
]

let spec =
  Aplomb.Dynamic.(simple ~data ~description:"A simple bar chart with embedded data." (`Mark `Bar)
    |> x "a" ~typ:`Ordinal
    |> y "b" ~typ:`Quantitative
    |> finish)

let _ = AplombBrowser.show spec

Usage example with static datatypes

(*
  To run interactively:

  utop -require aplomb.ppx_deriving,aplomb,ppx_deriving_yojson,yojson,aplomb.browser -init examples/bar_static.ml
*)
type row = {
    a : string [@typ `Ordinal];
    b : int [@typ `Quantitative]
  } [@@deriving yojson,aplomb]

let data =
  [|
    {a = "A"; b = 28};
    {a = "B"; b = 55};
    {a = "C"; b = 43};
    {a = "D"; b = 91};
    {a = "E"; b = 81};
    {a = "F"; b = 53};
    {a = "G"; b = 19};
    {a = "H"; b = 87};
    {a = "I"; b = 52}
  |]

let spec =
  Plot_row.(simple ~data ~description:"A simple bar chart with embedded data." (`Mark `Bar)
    |> x `a
    |> y `b
    |> finish)

let _ = AplombBrowser.show spec

Storing your data in a custom type

If your data isn't stored in an association list or in a type that aplomb.ppx_deriving understands, you can still create a plotting module for it using the Aplomb.Make functor. First, write a module of type Aplomb.DataS around your data type:

module type DataS = sig

  (** The type that holds the dataset. *)
  type t

  (**
  The type of references to fields (columns) in the dataset. If the dataset is a
  map, this should be the key type. If this module is generated from a record type
  by ppx_deriving_aplomb, this will be a variant type whose values correspond to
  field names of the record.
  *)

  type field

  (** A function that maps the dataset to a list of Yojson objects. This *)
  val inline : t -> Yojson.Safe.json list

  (**
  A function that evaluates to the name of a field as a string. This name should
  correspond to the keys in the Yojson spec generated by 'inline'.
  *)
  val fieldName : field -> string

  (**
  A function that evaluates to the Vega-Lite type of a field. This may be one of
  `Ordinal, `Nominal, `Temporal or `Quantitative. It may be overridden when
  generating plots.
  *)
  val defaultTyp : field -> VegaLite.V2.Type.t
end

Then create and use your plotting module:

module Data = struct
  (* Of type DataS *)
  ...
end
module PlotData = Aplomb.Make(Data)

let spec = PlotData.(simple ... () |> toplevel)

Hopefully one day soon OCaml will grow a proper data frame, and this functor will make it easy to derive plotting modules for that!