Skip to content

Commit

Permalink
Add histogram plots.
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurentMazare committed May 12, 2019
1 parent f98dcb6 commit 61943bd
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 10 deletions.
27 changes: 23 additions & 4 deletions examples/fig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,36 @@
open Base
open Matplotlib

let () =
let left_graph ax =
let xs = List.init 120 ~f:Float.of_int in
let ys1 = List.map xs ~f:(fun i -> Float.sin (i /. 20.)) in
let ys2 = List.map xs ~f:(fun i -> Float.cos (i /. 12.)) in
let xs = Array.of_list xs in
let ys1 = Array.of_list ys1 in
let ys2 = Array.of_list ys2 in
let _fig, ax = Fig.create_with_ax () in
Ax.set_title ax "left ax";
Ax.set_xlabel ax "x label";
Ax.set_ylabel ax "sin(x)";
Ax.grid ax true;
Ax.plot ax ~color:Red ~xs ys1;
Ax.plot ax ~color:Green ~linestyle:Dotted ~linewidth:2. ~xs ys2;
Ax.plot ax ~label:"sin1" ~color:Red ~xs ys1;
Ax.plot ax ~label:"sin2" ~color:Green ~linestyle:Dotted ~linewidth:2. ~xs ys2;
Ax.legend ax

let right_graph ax =
let rnds =
Array.init 5000 ~f:(fun _ ->
let u1 = Random.float 1. in
let u2 = Random.float 1. in
Float.cos (2. *. 3.1415 *. u1) *. Float.sqrt (-. 2. *. Float.log u2))
in
Ax.hist ax rnds ~bins:50;
Ax.set_title ax "hist";
Ax.set_xlabel ax "Sample values";
Ax.set_ylabel ax "Frequency"

let () =
let fig, ax1, ax2 = Fig.create_with_two_axes `horizontal in
left_graph ax1;
right_graph ax2;
Fig.suptitle fig "the figure suptitle";
Mpl.show ()
39 changes: 37 additions & 2 deletions src/matplotlib/fig_ax.ml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,32 @@ module Ax = struct
in
ignore (Py.Module.get_function_with_keywords t "grid" [||] keywords)

let plot t ?color ?linewidth ?linestyle ?xs ys =
Mpl.plot t ?color ?linewidth ?linestyle ?xs ys
let legend ?loc t =
let keywords =
let loc =
Option.map loc ~f:(fun loc ->
let loc =
match loc with
| `best -> "best"
| `upper_right -> "upper right"
| `upper_left -> "upper left"
| `lower_left -> "lower left"
| `lower_right -> "lower right"
| `right -> "right"
| `center_left -> "center left"
| `center_right -> "center right"
| `lower_center -> "lower center"
| `upper_center -> "upper center"
| `center -> "center"
in
"loc", Py.String.of_string loc)
in
List.filter_opt [ loc ]
in
ignore (Py.Module.get_function_with_keywords t "legend" [||] keywords)

let plot = Mpl.plot
let hist = Mpl.hist
end

module Fig = struct
Expand All @@ -68,6 +92,17 @@ module Fig = struct
let ax = add_subplot t ~nrows:1 ~ncols:1 ~index:1 in
t, ax

let create_with_two_axes ?figsize orientation =
let t = create ?figsize () in
let nrows, ncols =
match orientation with
| `horizontal -> 1, 2
| `vertical -> 2, 1
in
let ax1 = add_subplot t ~nrows ~ncols ~index:1 in
let ax2 = add_subplot t ~nrows ~ncols ~index:2 in
t, ax1, ax2

let suptitle t title =
ignore (t.&("suptitle")[| Py.String.of_string title |])
end
29 changes: 29 additions & 0 deletions src/matplotlib/fig_ax.mli
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,42 @@ module Ax : sig
val set_xlabel : t -> string -> unit
val set_ylabel : t -> string -> unit
val grid : t -> ?which:[`major|`minor|`both] -> ?axis:[`both|`x|`y] -> bool -> unit
val legend
: ?loc:
[`best
|`upper_right
|`upper_left
|`lower_left
|`lower_right
|`right
|`center_left
|`center_right
|`lower_center
|`upper_center
|`center]
-> t
-> unit

val plot
: t
-> ?label:string
-> ?color:Mpl.Color.t
-> ?linewidth:float
-> ?linestyle:Mpl.Linestyle.t
-> ?xs:float array
-> float array
-> unit

val hist
: t
-> ?label:string
-> ?color:Mpl.Color.t
-> ?bins:int
-> ?orientation:[ `horizontal | `vertical ]
-> ?histtype:[ `bar | `barstacked | `step | `stepfilled ]
-> ?xs:float array list
-> float array
-> unit
end

module Fig : sig
Expand All @@ -30,5 +57,7 @@ module Fig : sig

val create_with_ax : ?figsize:(float * float) -> unit -> t * Ax.t

val create_with_two_axes : ?figsize:(float * float) -> [`horizontal|`vertical] -> t * Ax.t * Ax.t

val suptitle : t -> string -> unit
end
34 changes: 33 additions & 1 deletion src/matplotlib/mpl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,13 @@ end
let float_array_to_python xs =
Py.List.of_array_map Py.Float.of_float xs

let plot p ?color ?linewidth ?linestyle ?xs ys =
let plot p ?label ?color ?linewidth ?linestyle ?xs ys =
let keywords =
List.filter_opt
[ Option.map color ~f:(fun color -> "color", Color.to_pyobject color)
; Option.map linewidth ~f:(fun lw -> "linewidth", Py.Float.of_float lw)
; Option.map linestyle ~f:(fun ls -> "linestyle", Linestyle.to_pyobject ls)
; Option.map label ~f:(fun l -> "label", Py.String.of_string l)
]
in
let args =
Expand All @@ -139,3 +140,34 @@ let plot p ?color ?linewidth ?linestyle ?xs ys =
| None -> [| float_array_to_python ys |]
in
ignore (Py.Module.get_function_with_keywords p "plot" args keywords)

let hist p ?label ?color ?bins ?orientation ?histtype ?xs ys =
let keywords =
List.filter_opt
[ Option.map color ~f:(fun color -> "color", Color.to_pyobject color)
; Option.map label ~f:(fun l -> "label", Py.String.of_string l)
; Option.map bins ~f:(fun b -> "bins", Py.Int.of_int b)
; Option.map orientation ~f:(fun o ->
let o =
match o with
| `horizontal -> "horizontal"
| `vertical -> "vertical"
in
"orientation", Py.String.of_string o)
; Option.map histtype ~f:(fun h ->
let h =
match h with
| `bar -> "bar"
| `barstacked -> "barstacked"
| `step -> "step"
| `stepfilled -> "stepfilled"
in
"histtype", Py.String.of_string h)
]
in
let args =
match xs with
| Some xs -> [| List.map (ys::xs) ~f:float_array_to_python |> Py.List.of_list |]
| None -> [| float_array_to_python ys |]
in
ignore (Py.Module.get_function_with_keywords p "hist" args keywords)
12 changes: 12 additions & 0 deletions src/matplotlib/mpl.mli
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,21 @@ end
(* Only internal functions below. *)
val plot
: Py.Object.t
-> ?label:string
-> ?color:Color.t
-> ?linewidth:float
-> ?linestyle:Linestyle.t
-> ?xs:float array
-> float array
-> unit

val hist
: Py.Object.t
-> ?label:string
-> ?color:Color.t
-> ?bins:int
-> ?orientation:[ `horizontal | `vertical ]
-> ?histtype:[ `bar | `barstacked | `step | `stepfilled ]
-> ?xs:float array list
-> float array
-> unit
8 changes: 6 additions & 2 deletions src/matplotlib/pyplot.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ let grid b =
let p = Mpl.pyplot_module () in
ignore (p.&("grid")[| Py.Bool.of_bool b |])

let plot ?color ?linewidth ?linestyle ?xs ys =
let plot ?label ?color ?linewidth ?linestyle ?xs ys =
let p = Mpl.pyplot_module () in
Mpl.plot p ?color ?linewidth ?linestyle ?xs ys
Mpl.plot p ?label ?color ?linewidth ?linestyle ?xs ys

let hist ?label ?color ?bins ?orientation ?histtype ?xs ys =
let p = Mpl.pyplot_module () in
Mpl.hist p ?label ?color ?bins ?orientation ?histtype ?xs ys
13 changes: 12 additions & 1 deletion src/matplotlib/pyplot.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@ val grid : bool -> unit
val title : string -> unit

val plot
: ?color:Mpl.Color.t
: ?label:string
-> ?color:Mpl.Color.t
-> ?linewidth:float
-> ?linestyle:Mpl.Linestyle.t
-> ?xs:float array
-> float array
-> unit

val hist
: ?label:string
-> ?color:Mpl.Color.t
-> ?bins:int
-> ?orientation:[ `horizontal | `vertical ]
-> ?histtype:[ `bar | `barstacked | `step | `stepfilled ]
-> ?xs:float array list
-> float array
-> unit

0 comments on commit 61943bd

Please sign in to comment.