Plot Figures ================================================= Owl is an OCaml numerical library. Besides its extensive supports to matrix operations, it also has a flexible plotting module. Owl's ``Plot`` module is designed to help you in making fairly complicated plots with minimal coding efforts. It is built atop of `Plplot `_ but hides its complexity from users. The module is cross-platform since ``Plplot`` calls the underlying graphics device driver to plot. However, based on my experience, the `Cairo Package `_ provides the best quality and most accurate figure so I recommend installing Cairo. The examples in this tutorial are generated by using ``Cairo PNG Driver``. Create Plots ------------------------------------------------- Simply put, there are two ways of plotting: 1) with a handle; 2) without a handle. You can imagine a handle is just a "pointer" to a figure. The first option is for lazy people who do not want to fine tune their figures but want to have a look at their results quickly. Most plotting functions in Owl can be called without an explicit handle passed in. E.g., the following code creates a simple line plot. .. code-block:: ocaml let f x = Maths.sin x /. x in Plot.plot_fun f 1. 15.;; .. figure:: ../figure/plot_002.png :width: 100% :align: center :alt: plot example However, in most cases, you do want to have a full control over the figure you are creating and do want to configure it a bit especially if you don't like the default red on black theme. Then, here is the standard way of creating a plot using ``Plot.create`` function. Here is its type definition in ``Owl_plot.mli`` .. code-block:: ocaml val create : ?m:int -> ?n:int -> string -> handle The first two parameters ``m`` and ``n`` are used for creating subplot, I will talk about subplot later. Now we only use the third parameter which defines the output file. Let's extend the previous example. .. code-block:: ocaml let f x = Maths.sin x /. x in let h = Plot.create "plot_003.png" in Plot.set_foreground_color h 0 0 0; Plot.set_background_color h 255 255 255; Plot.set_title h "Function: f(x) = sine x / x"; Plot.set_xlabel h "x-axis"; Plot.set_ylabel h "y-axis"; Plot.set_font_size h 8.; Plot.set_pen_size h 3.; Plot.plot_fun ~h f 1. 15.; Plot.output h;; As we can see, we first create a plot handle ``h`` and also specified the output file as ``plot_003.png`` in ``create`` function. Owl will select the suitable output device driver for you based on the file name suffix. Then we call various functions in the ``Plot`` module to configure the plot by passing in ``h``. These functions are self-explained, and you can read Owl's documentation for details. There are two thing worth mentioning here. First, you need to pass ``h`` to the plot function, i.e., ``Plot.plot_fun`` in this example. Second, the most important step is calling ``Plot.output h`` will actually write your figure to a file. .. figure:: ../figure/plot_003.png :width: 100% :align: center :alt: plot example Simple, isn't it? Let's continue to more interesting plots. Configure via Spec ------------------------------------------------- Introduce ``spec`` ... Subplots ------------------------------------------------- You use the same ``Plot.create`` function to start a subplot. E.g., the code below create a ``2 x 2`` subplot. We leave the output file name as an empty string so ``Plplot`` later will prompt a list of device drivers you can choose from, when you call ``Plot.output``. .. code-block:: ocaml let h = Plot.create ~m:2 ~n:2 "" in ... The key concept of subplot is: you need to successively call ``Plot.subplot`` to "focus" on different individual subplot to work on them. Continue the previous example, let's look at the code below. .. code-block:: ocaml let f p i = match i with | 0 -> Stats.Rnd.gaussian ~sigma:0.5 () +. p.(1) | _ -> Stats.Rnd.gaussian ~sigma:0.1 () *. p.(0) in let y = Stats.gibbs_sampling f [|0.1;0.1|] 5_000 |> Mat.of_arrays in let h = Plot.create ~m:2 ~n:2 "" in Plot.set_background_color h 255 255 255; (* focus on the subplot at 0,0 *) Plot.subplot h 0 0; Plot.set_title h "Bivariate model"; Plot.scatter ~h (Mat.col y 0) (Mat.col y 1); (* focus on the subplot at 0,1 *) Plot.subplot h 0 1; Plot.set_title h "Distribution of y"; Plot.set_xlabel h "y"; Plot.set_ylabel h "Frequency"; Plot.histogram ~h ~bin:50 (Mat.col y 1); (* focus on the subplot at 1,0 *) Plot.subplot h 1 0; Plot.set_title h "Distribution of x"; Plot.set_ylabel h "Frequency"; Plot.histogram ~h ~bin:50 (Mat.col y 0); (* focus on the subplot at 1,1 *) Plot.subplot h 1 1; Plot.set_foreground_color h 0 50 255; Plot.set_title h "Sine function"; Plot.(plot_fun ~h ~spec:[ LineStyle 2 ] Maths.sin 0. 28.); Plot.autocorr ~h (Mat.sequential 1 28); (* output your final plot *) Plot.output h;; The code will generate the following plot. You can control the configuration of each individual subplot once you have "focused" on it by calling ``Plot.subplot``. Besides the figure handle ``h``, ``Plot.subplot`` uses the two-dimensional index you pass in to locate the subplot. .. figure:: ../figure/plot_004.png :width: 100% :align: center :alt: plot example ``Plot`` module automatically calculates the suitable page size for your subplot. If you are not happy with the calculated size, you can also specify the page size by calling ``Plot.set_page_size`` function. Subplot is quite straightforward, right? Multiple (Lines) ------------------------------------------------- You can certainly plot multiple lines (or other types of plots) on the same page. Once you call ``Plot.output``, the plot will be ``sealed`` and written into the final file. Here is one example with both sine and cosine lines in one plot. .. code-block:: ocaml let h = Plot.create "" in Plot.(plot_fun ~h ~spec:[ RGB (0,0,255); Marker "#[0x2299]"; MarkerSize 8. ] Maths.sin 0. 9.); Plot.(plot_fun ~h ~spec:[ RGB (255,0,0); Marker "#[0x0394]"; MarkerSize 8. ] Maths.cos 0. 9.); Plot.legend_on h [|"Sine function"; "Cosine function"|]; Plot.output h;; .. figure:: ../figure/plot_005.png :width: 100% :align: center :alt: plot example Here is another example which has both histogram and line plot in one figure. .. code-block:: ocaml (* generate data *) let f p = Stats.Pdf.gaussian p.(0) 0.5 in let g x = Stats.Pdf.gaussian x 0.5 *. 4000. in let y = Stats.metropolis_hastings f [|0.1|] 100_000 |> Mat.of_arrays in (* plot multiple data sets *) let h = Plot.create "" in Plot.set_background_color h 255 255 255; Plot.(histogram ~h ~spec:[ RGB (255,0,50) ] ~bin:100 y); Plot.(plot_fun ~h ~spec:[ RGB (0,0,255); LineWidth 2. ] g (-2.) 2.); Plot.legend_on h [|"data"; "model"|]; Plot.output h;; .. figure:: ../figure/plot_006.png :width: 100% :align: center :alt: plot example So as long as you "hold" the plot without calling ``Plot.output``, you can plot many data sets in one figure. Legend ------------------------------------------------- Legend can be turned on and off by calling ``Plot.legend_on`` and ``Plot.legend_off`` respectively. When you call ``Plot.legend_on``, you also need to provide an array of legend names and the position of legend. There are eight default positions in ``Plot``. .. code-block:: ocaml type legend_position = North | South | West | East | NorthWest | NorthEast | SouthWest | SouthEast Despite of its messy looking, the following example shows how to use legend in Owl's plot module. .. code-block:: ocaml (* generate data *) let x = Mat.(uniform 1 20 *$ 10.) in let y = Mat.(uniform 1 20) in let z = Mat.gaussian 1 20 in (* plot multiple data sets *) let h = Plot.create "" in Plot.(plot_fun ~h ~spec:[ RGB (0,0,255); LineStyle 1; Marker "*" ] Maths.sin 1. 8.); Plot.(plot_fun ~h ~spec:[ RGB (0,255,0); LineStyle 2; Marker "+" ] Maths.cos 1. 8.); Plot.scatter ~h x y; Plot.stem ~h x z; let u = Mat.(abs(gaussian 1 10 *$ 0.3)) in Plot.(bar ~h ~spec:[ RGB (255,255,0); FillPattern 3 ] u); let v = Mat.(neg u *$ 0.3) in let u = Mat.sequential 1 10 in Plot.(area ~h ~spec:[ RGB (0,255,0); FillPattern 4 ] u v); (* set up legend *) Plot.(legend_on h ~position:NorthEast [|"test 1"; "test 2"; "scatter"; "stem"; "bar"; "area"|]); Plot.output h;; .. figure:: ../figure/plot_007.png :width: 100% :align: center :alt: plot example Drawing ------------------------------------------------- You can draw lines and rectangles in the plot. The first example actually shows different line styles in ``Plot`` by drawing multiple lines. .. code-block:: ocaml let h = Plot.create "" in Plot.set_background_color h 255 255 255; Plot.set_pen_size h 2.; Plot.(draw_line ~h ~spec:[ LineStyle 1 ] 1. 1. 9. 1.); Plot.(draw_line ~h ~spec:[ LineStyle 2 ] 1. 2. 9. 2.); Plot.(draw_line ~h ~spec:[ LineStyle 3 ] 1. 3. 9. 3.); Plot.(draw_line ~h ~spec:[ LineStyle 4 ] 1. 4. 9. 4.); Plot.(draw_line ~h ~spec:[ LineStyle 5 ] 1. 5. 9. 5.); Plot.(draw_line ~h ~spec:[ LineStyle 6 ] 1. 6. 9. 6.); Plot.(draw_line ~h ~spec:[ LineStyle 7 ] 1. 7. 9. 7.); Plot.(draw_line ~h ~spec:[ LineStyle 8 ] 1. 8. 9. 8.); Plot.set_xrange h 0. 10.; Plot.set_yrange h 0. 9.; Plot.output h;; .. figure:: ../figure/plot_008.png :width: 100% :align: center :alt: plot example Similarly, the next example shows the filling patterns in ``Plot`` by drawing rectangles. .. code-block:: ocaml let h = Plot.create "" in Array.init 9 (fun i -> let x0, y0 = 0.5, float_of_int i +. 1.0 in let x1, y1 = 4.5, float_of_int i +. 0.5 in Plot.(draw_rect ~h ~spec:[ FillPattern i ] x0 y0 x1 y1); Plot.(text ~h ~spec:[ RGB (0,255,0) ] 2.3 (y0-.0.2) ("pattern: " ^ (string_of_int i))); ); Plot.output h;; .. figure:: ../figure/plot_009.png :width: 100% :align: center :alt: plot example Various Types of Plot ------------------------------------------------- In the following, I will use several examples to illustrate how to use the basic plotting functions in Owl. Line Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Line plot is the most basic function. You can specify the colour, marker, and line style in the function. .. code-block:: ocaml let x = Mat.linspace 0. 2. 100 in let y0 = Mat.sigmoid x in let y1 = Mat.map Maths.sin x in let h = Plot.create "" in Plot.(plot ~h ~spec:[ RGB (255,0,0); LineStyle 1; Marker "#[0x2299]"; MarkerSize 8. ] x y0); Plot.(plot ~h ~spec:[ RGB (0,255,0); LineStyle 2; Marker "#[0x0394]"; MarkerSize 8. ] x y1); Plot.(legend_on h ~position:SouthEast [|"sigmoid"; "sine"|]); Plot.output h;; .. figure:: ../figure/plot_010.png :width: 100% :align: center :alt: plot example Scatter Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For scatter plot, the most important thing is the markers. You can check all the possible marker symbols on [this page](http://plplot.sourceforge.net/examples.php?demo=23), they can be passed in as a parameter to ``Plot.scatter`` function. .. code-block:: ocaml let x = Mat.uniform 1 30 in let y = Mat.uniform 1 30 in let h = Plot.create ~m:3 ~n:3 "zzz.png" in Plot.set_background_color h 255 255 255; Plot.subplot h 0 0; Plot.(scatter ~h ~spec:[ Marker "#[0x2295]"; MarkerSize 5. ] x y); Plot.subplot h 0 1; Plot.(scatter ~h ~spec:[ Marker "#[0x229a]"; MarkerSize 5. ] x y); Plot.subplot h 0 2; Plot.(scatter ~h ~spec:[ Marker "#[0x2206]"; MarkerSize 5. ] x y); Plot.subplot h 1 0; Plot.(scatter ~h ~spec:[ Marker "#[0x229e]"; MarkerSize 5. ] x y); Plot.subplot h 1 1; Plot.(scatter ~h ~spec:[ Marker "#[0x2217]"; MarkerSize 5. ] x y); Plot.subplot h 1 2; Plot.(scatter ~h ~spec:[ Marker "#[0x2296]"; MarkerSize 5. ] x y); Plot.subplot h 2 0; Plot.(scatter ~h ~spec:[ Marker "#[0x2666]"; MarkerSize 5. ] x y); Plot.subplot h 2 1; Plot.(scatter ~h ~spec:[ Marker "#[0x22a1]"; MarkerSize 5. ] x y); Plot.subplot h 2 2; Plot.(scatter ~h ~spec:[ Marker "#[0x22b9]"; MarkerSize 5. ] x y); Plot.output h;; .. figure:: ../figure/plot_011.png :width: 100% :align: center :alt: plot example Stairs Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Instead of drawing a straight line between two points, stairs plot first moves along the x-axis then y-axis while plotting the data. The following example is self-explained. .. code-block:: ocaml let x = Mat.linspace 0. 6.5 20 in let y = Mat.map Maths.sin x in let h = Plot.create ~m:1 ~n:2 "" in Plot.set_background_color h 255 255 255; Plot.subplot h 0 0; Plot.plot_fun ~h Maths.sin 0. 6.5; Plot.(stairs ~h ~spec:[ RGB (0,128,255) ] x y); Plot.subplot h 0 1; Plot.(plot ~h ~spec:[ RGB (0,0,0) ] x y); Plot.(stairs ~h ~spec:[ RGB (0,128,255) ] x y); Plot.output h;; .. figure:: ../figure/plot_019.png :width: 100% :align: center :alt: plot example Box Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Box plots here generally refer to histogram, bar chart, and Whisker plot. You already learnt how to make a histogram plot. In the following, I will show how to make the other two. Here is the example for making both bar chart and Whisker box. Just note the input to ``Plot.boxplot`` is a row-based matrix, each row represents multiple measurements of one variable, which correspond one box in the plot. .. code-block:: ocaml let y1 = Mat.uniform 1 10 in let y2 = Mat.uniform 10 100 in let h = Plot.create ~m:1 ~n:2 "" in Plot.subplot h 0 0; Plot.(bar ~h ~spec:[ RGB (0,153,51); FillPattern 3 ] y1); Plot.subplot h 0 1; Plot.(boxplot ~h ~spec:[ RGB (0,153,51) ] y2); Plot.output h;; .. figure:: ../figure/plot_012.png :width: 100% :align: center :alt: plot example Stem Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Stem plot is simple, as the following code shows. .. code-block:: ocaml let x = Mat.linspace 0.5 2.5 25 in let y = Mat.map (Stats.Pdf.exponential 0.1) x in let h = Plot.create ~m:1 ~n:2 "" in Plot.set_background_color h 255 255 255; Plot.subplot h 0 0; Plot.set_foreground_color h 0 0 0; Plot.stem ~h x y; Plot.subplot h 0 1; Plot.(stem ~h ~spec:[ Marker "#[0x2295]"; MarkerSize 5.; LineStyle 1 ] x y); Plot.output h;; .. figure:: ../figure/plot_013.png :width: 100% :align: center :alt: plot example Stem plot is often used to show the autocorrelation of a variable, therefore ``Plot`` module already includes ``autocorr`` for your convenience. .. code-block:: ocaml let x = Mat.linspace 0. 8. 30 in let y0 = Mat.map Maths.sin x in let y1 = Mat.uniform 1 30 in let h = Plot.create ~m:1 ~n:2 "" in Plot.subplot h 0 0; Plot.set_title h "Sine"; Plot.autocorr ~h y0; Plot.subplot h 0 1; Plot.set_title h "Gaussian"; Plot.autocorr ~h y1; Plot.output h;; Obviously, sine function possesses stronger self-similarity than Gaussian noise. .. figure:: ../figure/plot_014.png :width: 100% :align: center :alt: plot example Area Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Area plot is similar to line plot but also fills the space between the line and x-axis. .. code-block:: ocaml let h = Plot.create ~m:1 ~n:2 "" in let x = Mat.linspace 0. 8. 100 in let y = Mat.map Maths.atan x in Plot.subplot h 0 0; Plot.(area ~h ~spec:[ FillPattern 1 ] x y); let x = Mat.linspace 0. (2. *. 3.1416) 100 in let y = Mat.map Maths.sin x in Plot.subplot h 0 1; Plot.(area ~h ~spec:[ FillPattern 2 ] x y); Plot.output h;; .. figure:: ../figure/plot_015.png :width: 100% :align: center :alt: plot example Histogram & CDF Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Given a series of measurements, you can easily plot the histogram and empirical cumulative distribution of the data. .. code-block:: ocaml let x = Mat.gaussian 200 1 in let h = Plot.create ~m:1 ~n:2 "" in Plot.subplot h 0 0; Plot.set_title h "histogram"; Plot.histogram ~h ~bin:25 x; Plot.subplot h 0 1; Plot.set_title h "empirical cdf"; Plot.ecdf ~h x; Plot.output h;; .. figure:: ../figure/plot_020.png :width: 100% :align: center :alt: plot example Log Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Plot with log-scale on either or both x and y axis. .. code-block:: ocaml let x = Mat.logspace (-1.5) 2. 50 in let y = Mat.map Maths.exp x in let h = Plot.create ~m:2 ~n:2 "plot_027.png" in Plot.subplot h 0 0; Plot.set_xlabel h "Input Data X"; Plot.set_ylabel h "Input Data Y"; Plot.(loglog ~h ~spec:[ RGB (0,255,0); LineStyle 2; Marker "+" ] ~x:x y); Plot.subplot h 0 1; Plot.set_xlabel h "Index of Input Data Y"; Plot.set_ylabel h "Input Data Y"; Plot.(loglog ~h ~spec:[ RGB (0,0,255); LineStyle 1; Marker "*" ] y); Plot.subplot h 1 0; Plot.set_xlabel h "Input Data X"; Plot.set_ylabel h "Input Data Y"; Plot.semilogx ~h ~x:x y; Plot.subplot h 1 1; Plot.set_xlabel h "Index of Input Data Y"; Plot.set_ylabel h "Input Data Y"; Plot.semilogy ~h y; Plot.output h;; .. figure:: ../figure/plot_027.png :width: 100% :align: center :alt: plot example 3D Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ There are four functions in ``Plot`` module related to 3D plot. They are ``surf``, ``mesh``, ``heatmap``, and ``contour`` functions. Again, I will illustrate them with examples. First, let's look at ``mesh`` and ``surf`` functions. .. code-block:: ocaml let x, y = Mat.meshgrid (-2.5) 2.5 (-2.5) 2.5 100 100 in let z0 = Mat.(sin ((x **$ 2.) + (y **$ 2.))) in let z1 = Mat.(cos ((x **$ 2.) + (y **$ 2.))) in let h = Plot.create ~m:2 ~n:2 "plot_016.png" in Plot.subplot h 0 0; Plot.surf ~h x y z0; Plot.subplot h 0 1; Plot.mesh ~h x y z0; Plot.subplot h 1 0; Plot.surf ~h x y z1; Plot.subplot h 1 1; Plot.mesh ~h x y z1; Plot.output h;; .. figure:: ../figure/plot_016.png :width: 100% :align: center :alt: plot example It is easy to control the viewpoint with ``altitude`` and ``azimuth`` parameters. Here is an example. .. code-block:: ocaml 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 "test_mesh.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;; The generated figure is as below. .. figure:: ../figure/plot_022.png :width: 100% :align: center :alt: plot example Here is another similar example with different data set. .. code-block:: ocaml let x, y = Mat.meshgrid (-3.) 3. (-3.) 3. 50 50 in let z = Mat.( 3. $* ((1. $- x) **$ 2.) * exp (neg (x **$ 2.) - ((y +$ 1.) **$ 2.)) - (10. $* (x /$ 5. - (x **$ 3.) - (y **$ 5.)) * (exp (neg (x **$ 2.) - (y **$ 2.)))) - ((1./.3.) $* exp (neg ((x +$ 1.) **$ 2.) - (y **$ 2.))) ) in let h = Plot.create ~m:2 ~n:3 "plot_017.png" in Plot.subplot h 0 0; Plot.surf ~h x y z; Plot.subplot h 0 1; Plot.mesh ~h x y z; Plot.subplot h 0 2; Plot.(surf ~h ~spec:[ Contour ] x y z); Plot.subplot h 1 0; Plot.(mesh ~h ~spec:[ Contour; Azimuth 115.; NoMagColor ] x y z); Plot.subplot h 1 1; Plot.(mesh ~h ~spec:[ Azimuth 115.; ZLine X; NoMagColor; RGB (61,129,255) ] x y z); Plot.subplot h 1 2; Plot.(mesh ~h ~spec:[ Azimuth 115.; ZLine Y; NoMagColor; RGB (130,255,40) ] x y z); Plot.output h;; .. figure:: ../figure/plot_017.png :width: 100% :align: center :alt: plot example Finally, let's look at how heatmap and contour look like. .. code-block:: ocaml let x, y = Mat.meshgrid (-3.) 3. (-3.) 3. 100 100 in let z = Mat.( 3. $* ((1. $- x) **$ 2.) * exp (neg (x **$ 2.) - ((y +$ 1.) **$ 2.)) - (10. $* (x /$ 5. - (x **$ 3.) - (y **$ 5.)) * (exp (neg (x **$ 2.) - (y **$ 2.)))) - ((1./.3.) $* exp (neg ((x +$ 1.) **$ 2.) - (y **$ 2.))) ) in let h = Plot.create ~m:2 ~n:2 "plot_018.png" in Plot.subplot h 0 0; Plot.(mesh ~h ~spec:[ Contour ] x y z); Plot.subplot h 0 1; Plot.heatmap ~h x y z; Plot.subplot h 1 0; Plot.mesh ~h x y z; Plot.subplot h 1 1; Plot.contour ~h x y z; Plot.output h;; .. figure:: ../figure/plot_018.png :width: 100% :align: center :alt: plot example Advanced Statistical Plot ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Both ``qqplot`` and ``probplot`` are simple graphical tests for determining if a data set comes from a certain distribution. A ``qqplot`` displays a quantile-quantile plot of the quantiles of the sample data y versus the theoretical quantiles values from a given distribution, or the quantiles of the sample data x. Here is an example. .. code-block:: ocaml let y = Mat.(gaussian 100 1 *$ 10.) in let x = Mat.gaussian 200 1 in let h = Plot.create ~m:2 ~n:2 "plot_025.png" in Plot.subplot h 0 0; Plot.set_title h "Gaussian vs. Gaussian Sample"; Plot.set_ylabel h "Quantiles of Input Sample"; Plot.set_xlabel h "Normal Distribution Quantiles"; Plot.qqplot ~h y ~x:x; Plot.subplot h 0 1; Plot.set_title h "Gaussian vs. Default Dist"; Plot.set_ylabel h "Quantiles of Input Sample"; Plot.set_xlabel h "Normal Distribution Quantiles"; Plot.(qqplot ~h y ~spec:[RGB (0,128,255)]); Plot.subplot h 1 0; Plot.set_title h "Gaussian vs. Rayleigh Dist"; Plot.set_ylabel h "Quantiles of Input Sample"; Plot.set_xlabel h "Rayleigh Distribution (sigma=0.5) Quantiles"; Plot.qqplot ~h y ~pd:(fun p -> Stats.Cdf.rayleigh_Pinv p 0.5); Plot.subplot h 1 1; Plot.set_title h "Gaussian vs. Chi-Square Dist"; Plot.set_ylabel h "Quantiles of Input Sample"; Plot.set_xlabel h "Chi-Square Distribution (k=10) Quantiles"; Plot.qqplot ~h y ~pd:(fun p -> Stats.Cdf.chisq_Pinv p 10.); Plot.output h;; .. figure:: ../figure/plot_025.png :width: 100% :align: center :alt: plot example ``probplot`` is similar to ``qqplot``. It contains two special cases: ``normplot`` for when the given theoretical distribution is Normal distribution, and ``wblplot`` for Weibull Distribution. Here is an example of them. .. code-block:: ocaml let x = Mat.empty 200 1 |> Mat.map (fun _ -> Stats.Rnd.weibull 1.2 1.5) in let h = Plot.create ~m:1 ~n:2 "plot_026.png" in Plot.subplot h 0 0; Plot.set_title h "Random Weibull Sample vs. Std Normal Dist"; Plot.set_xlabel h "Sample Data"; Plot.set_ylabel h "Theoratical Normal Dist"; Plot.normplot ~h x; Plot.subplot h 0 1; Plot.set_title h "Random Weibull Sample vs. Weibull Dist"; Plot.set_xlabel h "Sample Data"; Plot.set_ylabel h "Theoratical Weibull Dist"; Plot.wblplot ~h ~lambda:1.2 ~k:1.5 x; Plot.output h;; .. figure:: ../figure/plot_026.png :width: 100% :align: center :alt: plot example Plot Specification ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For most high-level plotting functions in Owl, there is an optional parameter called ``spec``. ``spec`` parameter take a list of specifications to let you finer control the appearance of the plot. Every function has a set of slightly different parameters, in case you pass in some parameters that a function cannot understand, they will be simply ignored. If you pass in the same parameter multiple times, only the last one will take effects. In the following, I will provide some examples to show how to use ``spec`` parameter to finer tune Owl's plots. The first example shows how to configure the ``mesh`` plot using ``ZLine``, ``Contour``, and other ``spec`` parameters. .. code-block:: ocaml let x, y = Mat.meshgrid (-2.5) 2.5 (-2.5) 2.5 50 50 in let z = Mat.(sin ((x * x) + (y * y))) in let h = Plot.create ~m:2 ~n:3 "plot_023.png" in Plot.subplot h 0 0; Plot.(mesh ~h ~spec:[ ZLine XY ] x y z); Plot.subplot h 0 1; Plot.(mesh ~h ~spec:[ ZLine X ] x y z); Plot.subplot h 0 2; Plot.(mesh ~h ~spec:[ ZLine Y ] x y z); Plot.subplot h 1 0; Plot.(mesh ~h ~spec:[ ZLine Y; NoMagColor ] x y z); Plot.subplot h 1 1; Plot.(mesh ~h ~spec:[ ZLine Y; Contour ] x y z); Plot.subplot h 1 2; Plot.(mesh ~h ~spec:[ ZLine XY; Curtain ] x y z); Plot.output h;; .. figure:: ../figure/plot_023.png :width: 100% :align: center :alt: plot example The second example shows how to tune ``surf`` plotting function. .. code-block:: ocaml let x, y = Mat.meshgrid (-1.) 1. (-1.) 1. 50 50 in let z = Mat.(tanh ((x * x) + (y * y))) in let h = Plot.create ~m:2 ~n:3 "plot_024.png" in Plot.subplot h 0 0; Plot.(surf ~h ~spec:[ ] x y z); Plot.subplot h 0 1; Plot.(surf ~h ~spec:[ Faceted ] x y z); Plot.subplot h 0 2; Plot.(surf ~h ~spec:[ NoMagColor ] x y z); Plot.subplot h 1 0; Plot.(surf ~h ~spec:[ Contour ] x y z); Plot.subplot h 1 1; Plot.(surf ~h ~spec:[ Curtain ] x y z); Plot.subplot h 1 2; Plot.(surf ~h ~spec:[ Altitude 10.; Azimuth 125. ] x y z); Plot.output h;; .. figure:: ../figure/plot_024.png :width: 100% :align: center :alt: plot example If you have made some cool figures using Owl, please do share them with us on `Plot Gallery `_! Thanks.