Module Mavryk_benchmark.Plot

prbnmcn-gnuplot: a self-contained interface to Gnuplot.

Introduction

We give an introduction to the library by giving some examples. These examples can be run by performing

> dune exec ./test/example.exe

in the root of the library.

Let's assume throughout we've access to some sampler for the standard normal distribution:

val normal : Random.State.t -> float

Data: 1d, 2d, 3d

The library encapsulates 1d, 2d and 3d data points using the types Plot.r1, Plot.r2 and Plot.r3. Similarly named functions allow to inject floating-point values into these types.

As an example, we can write samplers for 2d and 3d normal variates with specified means:

(** [st] is the random state *)
let normal2 (mu_x, mu_y)
  st = Plot.r2 (normal st +. mu_x) (normal st +. mu_y)

Scatter plot example

Let's plot some clouds of points using normal2. For 2d scatter plots, we use Plot.Scatter.points_2d. We need to feed this function with a value of type r2 Plot.Data.t. For instance, the following function specifies a 2d scatter plot with 100 random normally distributed points with mean mu.

let scatter ~mu st =
  Plot.Scatter.points_2d
    ~points:(Plot.Data.of_array (Array.init 100 (fun _ -> normal2 mu st)))
    ()

Let's produce a plot with two clouds around (3, 2) and (10, 8) and display it using the Plot.plot2 function.

let st = Random.State.make_self_init ()

let scatter2d_example =
  Plot.plot2
    ~xaxis:"x"
    ~yaxis:"y"
    ~title:"Clouds"
    [scatter ~mu:(3., 2.) st; scatter ~mu:(10., 8.) st]

Finally, we can produce the plot and save it, say to a .png file.

let () =
  let target = Plot.png ~pixel_size:(1024, 1024) ~png_file:"scatter.png" () in
  Plot.(run ~plot:scatter2d_example ~target exec)

3d plots work similarly, using the Plot.Scatter.points_3d function.

Line plot example

The library also handles line plots, through the functions exposed in Plot.Line. The API works similarly. Functions must be discretized before being plotted: for the sake of the example, let's introduce the following function.

let discretize f =
  Array.init 100 (fun i ->
      let x = float_of_int i *. 0.1 in
      let y = f x in
      Plot.r2 x y)

We prepare a fancy plot for the discretized sine function as follows.

let sine_with_points =
  let open Plot in
  Line.line_2d
    ~points:(Data.of_array (discretize sin))
    ~style:
      Style.(default |> set_color Color.red |> set_point ~ptyp:Pointtype.box)
    ~with_points:true
    ()

We display it similarly as in the scatter plot case.

let line2d_example =
  Plot.plot2 ~xaxis:"x" ~yaxis:"y" ~title:"Lines" [sine_with_points]

let () =
  let target = Plot.png ~pixel_size:(1024, 1024) ~png_file:"lines.png" () in
  Plot.(run ~plot:line2d_example ~target exec)

Histogram example

Finally, the library allows to prepare histograms.

let gaussian =
  let open Plot in
  Histogram.hist
    ~points:(Data.of_array (Array.init 100 (fun _ -> r1 @@ normal st)))
    ()

let histogram_example =
  Plot.plot2 ~xaxis:"x" ~yaxis:"freq" ~title:"Histogram" [gaussian]

let () =
  let target = Plot.png ~pixel_size:(1024, 1024) ~png_file:"histogram.png" () in
  Plot.(run ~plot:histogram_example ~target exec)

The binning is performed automatically by Gnuplot: currently, the API does not provide any functionality for manually specifed box plots.

API

Raw data

type r1

r1, r2, r3 encode elements of R^n for n equal to 1, 2 or 3.

type r2
type r3
val r1 : float -> r1

r1, r2, r3 are injections into their respective types.

val r2 : float -> float -> r2
val r3 : float -> float -> float -> r3
val tup_r2 : (float * float) -> r2

tup_r2, tup_r3 proceed on tuples.

val tup_r3 : (float * float * float) -> r3

Colors, styles, etc

module Color : sig ... end

Colors

module Pointtype : sig ... end

Pointtypes

module Fill : sig ... end

Filling shapes.

module Style : sig ... end

Styles

module Tics : sig ... end

Tics. See the gnuplot documentation for the xtics command for the meaning of these options.

Datasets

module Data : sig ... end

Datasets

Plot specifications

type 'dim spec

'dim spec is the type of a declarative plot specification for data of type 'dim.

Scatter plots

module Scatter : sig ... end

Preparing scatter plots.

Line plots

module Line : sig ... end

Preparing line plots.

Histograms

module Histogram : sig ... end

Preparing histograms.

module Bar : sig ... end

Plot rendering

type plot

A plot consists of

  • a choice of axes (2d or 3d, with a name for each axis)
  • a list of plot specs consistent with the dimension of the axes
  • a title
val plot2 : xaxis:string -> yaxis:string -> ?xtics:Tics.t -> ?ytics:Tics.t -> ?title:string -> r2 spec list -> plot

plot2 ~xaxis ~yaxis ?xtics ?ytics ?title specs construct a 2d plot. The plots specs are stacked together in the same figure. All the plots share the same 2d axis system, with names xaxis and yaxis.

val plot3 : xaxis:string -> yaxis:string -> zaxis:string -> ?xtics:Tics.t -> ?ytics:Tics.t -> ?ztics:Tics.t -> ?title:string -> r3 spec list -> plot

plot3 ~xaxis ~yaxis ~zaxis ~title specs construct a 3d plot. The plots specs are stacked together in the same figure. All the plots share the same 3d axis system, with names xaxis, yaxis and zaxis.

type target

Plot target. Note that the Qt and X11 targets do not work well with multiple ("matrix") plots on some tiling window managers or generally when resizing windows. In this case, it is recommended to use the Pdf or Png targets and use a third-party visualizer.

val pdf : ?cm_size:(float * float) -> pdf_file:string -> unit -> target

pdf ?cm_size ~pdf_file () specifies that the plot should be written to the file pdf_file using the pdf format. The optional argument ?cm_size specifies the width and height of the figure in cm. If not specified, Gnuplot will select the aspect ratio and size automatically.

val png : ?pixel_size:(int * int) -> png_file:string -> unit -> target

png ?pixel_size ~png_file () specifies that the plot should be written to the file png_file using the PNG format. The optional argument ?pixel_size specifies the width and height of the figure in pixels. If not specified, Gnuplot will select the aspect ratio and size automatically.

val x11 : target

The X11 target. This target is interactive (it will open a window).

val qt : ?pixel_size:(int * int) -> unit -> target

The qt target. This target is interactive (it will open a window). The optional argument ?pixel_size specifies the width and height of the figure in cm. If not specified, Gnuplot will select the aspect ratio and size automatically.

val get_targets : ?path:string -> unit -> string list option

get_targets () returns a list of all available targets (called 'terminals' by gnuplot). Returns None if the list of targets could not be obtained.

val run : ?path:string -> ?detach:bool -> ?filename:string -> ?exec:bool -> target:target -> plot -> unit

run ?path ?detach ?filename ?exec ~target plot performs plotting of plot using target.

  • path : The path of Gnuplot, defaults to "gnuplot"
  • detach : If true, Gnuplot process does not block the main process. The default is false.
  • filename : If specified, the plot script is saved to this file.
  • exec : If false, execution of Gnuplot is skipped. The default is true.
val run_matrix : ?path:string -> ?detach:bool -> ?filename:string -> ?exec:bool -> target:target -> ?title:string -> plot option array array -> unit

run_matrix ?path ?detach ?filename ?exec ~target ?title plots performs plotting of plots using target.

  • path : The path of Gnuplot, defaults to "gnuplot"
  • detach : If true, Gnuplot process does not block the main process. The default is false.
  • filename : If specified, the plot script is saved to this file.
  • exec : If false, execution of Gnuplot is skipped. The default is true.
  • title : The title of the plots. The default is ""