Skip to content

apatil/aplomb

Repository files navigation

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!

About

Data visualization and plotting for OCaml

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published