Skip to content
Marshall Abrams edited this page Aug 5, 2017 · 25 revisions

This Wiki is open to the public and everyone can edit it. I encourage people to share their plot examples as well as the corresponding code. Each example should have a title to briefly describe it and an unique increasing identifier. Please use the example #0 as the template.

#0 Surface plot with different altitude and azimuth

let x, y = Mat.meshgrid (-2.5) 2.5 (-2.5) 2.5 100 100 in
let z = Mat.(sin ((x * x) + (y * y))) in
let h = Plot.create ~m:1 ~n:3 "gallery_000.png" in
Plot.subplot h 0 0;
Plot.(mesh ~h ~spec:[ Altitude 50.; Azimuth 120. ] x y z);
Plot.subplot h 0 1;
Plot.(mesh ~h ~spec:[ Altitude 65.; Azimuth 120. ] x y z);
Plot.subplot h 0 2;
Plot.(mesh ~h ~spec:[ Altitude 80.; Azimuth 120. ] x y z);
Plot.output h;;

#1 Visualise the sparsity of matrices

let x = Mat.bernoulli ~p:0.1 40 40 in
let y = Mat.bernoulli ~p:0.2 40 40 in
let z = Mat.bernoulli ~p:0.3 40 40 in
let h = Plot.create ~m:1 ~n:3 "gallery_001.png" in
Plot.subplot h 0 0;
Plot.spy ~h x;
Plot.subplot h 0 1;
Plot.spy ~h y;
Plot.subplot h 0 2;
Plot.spy ~h z;
Plot.output h;;

#2 Using mesh plot to display 2D curves in different planes

For large sets of 2D plots, there are too few distinguishable colors to differentiate curves by color, but giving each curve its own plot produces too many plots for convenient viewing. It's sometimes useful to look at such curves both overlaid on one 2D plot, and also laid out as if in three dimensions, with each 2D plot seeming to be in its its own plane. Whether this is useful depends on the curves. If it works, it can be especially helpful when you want to compare related families of curves. In the example below, notice that overlapping curves make the 2D plots confusing in some regions. The 3D plots to the right of each 2D plot present exactly the same data, with each curve in a separate plane. This representation clarifies the patterns in each family of curves. (There are nevertheless relationships that can be seen more precisely in the 2D plots, so it's useful to display plots of both kinds for each family of curves.) The code is rather long, so I'll display the plots first:

2x2 array of four plots, 2D on left, 3D on right

Here's the code. The trick that makes the mesh function display the curves without surfaces between them--so it looks like there are separate 2D curves in different planes--is Zline X in the spec parameter list for mesh. Notice that the values in the zs and zs' matrices--i.e. the heights of the curves--are displayed as y values in the 2D plots but as z values in the 3D plots. These are values of the functions at coordinates given in the xs matrix. Those coordinates are the same in every row of xs. The values in the ys matrix have no real meaning; they are the same in every column and are arbitrary integers that index the 2D curves.)

(* Generate some contrived data that will illustrate utility of 2D/3D plotting.
   This will require several lines. *)
let num_points = 500 in
let num_plots = 25 in
let gauss mean sd x = Owl.Stats.Pdf.gaussian (x +. mean) sd in
let idx_to_mean idx =
  let i = float (num_plots - idx) in
  if idx <= num_plots/3 then i /. 8. else (i /. 8.) +. 1.  in
let idx_to_sd idx = 
  let i = float (num_plots - idx) in
  if idx <= num_plots/2 then i /. 10. else (i /. 7.) in
let xs, ys = Mat.meshgrid (-9.) 4. 1. (float num_plots) num_points num_plots in
(* xs: Each row (with the same values) will be input to a different function.
   ys: Each column simply contains (ignored) indexes to different functions. *)
let zs = Mat.mapi (fun i j e -> gauss (idx_to_mean i) (idx_to_sd i) e) xs in
let shifts = Mat.(repeat ~axis:1 ((sequential num_plots 1) /$ 5.) num_points) in
let zs' = Mat.(zs + shifts) in

(* Plot families of 2D curves in both two (left) and three (right) dimensions *)
let open Plot in
(* configuration specifications: *)
let line_color = RGB (0,25,200) in
let mesh_spec = [NoMagColor; line_color; (* plot line color in 3D plots *)
                 ZLine X]    (* make disconnected 2D curves in 3D plots *)
let plot_spec = [line_color] in           (* plot-line color in 2D plots*)
let font_size = 3.25 in

(* create page and add plots: *)
let h = create ~m:2 ~n:2 "2D3Dexample.png" in (* 2x2 layout of plots *)
set_background_color h 255 255 255;
set_pen_size h 0.5;    (* smaller lines are easier to see on the 3D plots *)

(* first family of curves, using zs: *)
subplot h 0 0;
set_font_size h font_size;
set_foreground_color h 90 0 20; (* gray grid and tick marks *)
plot ~h ~spec:plot_spec xs zs;  (* note zs, not ys, gives the y-axis values *)
subplot h 0 1;
set_font_size h font_size;
set_foreground_color h 90 0 20;
mesh ~h ~spec:(mesh_spec @ [Azimuth 25.; Altitude 40.] xs ys zs; (* zs = z-axis *)

(* second family of curves, using zs': *)
subplot h 1 0;
set_font_size h font_size;
set_foreground_color h 90 0 20;
plot ~h ~spec:plot_spec xs zs';
subplot h 1 1;
set_font_size h font_size;
set_foreground_color h 90 0 20;
mesh ~h ~spec:(mesh_spec @ [Azimuth 15.; Altitude 15.]) xs ys zs';

output h;;

-mars0i