OCaml Scientific Computing Tutorials

Back
Table of Contents

可视化

Owl 是一个 OCaml 数值库。除了对矩阵操作提供广泛支持之外,它还具有灵活的绘图模块。Owl 的 Plot 模块旨在通过最小的编码工作帮助您创建相当复杂的图。它构建在 [Plplot 之上,但将其复杂性隐藏在用户视野之外。

由于 Plplot 调用底层图形设备驱动程序进行绘图,该模块是跨平台的。然而,根据我们的经验,Cairo 包 提供了最高质量和最准确的图形,因此我们建议安装 Cairo。实际上,本教程中的示例都是使用 Cairo PNG 驱动程序 生成的,但正如您将看到的,您可以对图形拥有完全控制,并以多种方式配置它们。

在下面的部分中,我们将通过示例演示在 Owl 中如何使用绘图模块来辅助您完成数据可视化和分析中的多项任务。

创建图

让我们从使用 Plot.create 函数创建图的标准方式开始。以下是其在 Owl_plot.mli 中的类型定义:


  val create : ?m:int -> ?n:int -> string -> handle

这是一个例子。

let f x = Maths.sin x /. x in
let h = Plot.create "plot_001.png" in

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
>- : unit = ()

对于任何图形,我们需要通过调用 create 函数获得一个句柄 h。图像的类型可以从图形文件名中自动推断出来。在这种情况下,我们想创建一个绘制正弦函数的 PNG 图像。我们可以使用 plot_fun 函数实现这一点。此外,我们还设置了 x 和 y 轴标签以及图形标题,以及字体和线条大小。您会发现,这些命令与其他绘图工具(如 Matplotlib)中的命令相似。一旦调用了 Plot.output,图形就会被“封存”并写入最终文件。生成的图形如下所示。

Basic function plot
基本函数绘图

如果这对您来说看起来太基本了,那么我们在下一部分中有一些花哨的 3D 网格图。

规格

对于 Owl 中的大多数高级绘图函数,都有一个名为 spec 的可选参数。 spec 参数接受一个规格列表,让您更精细地控制图的外观。每个函数都有一组略有不同的参数。如果您传递了某个函数无法理解的参数,它们将被简单地忽略。如果您多次传递相同的参数,则只有最后一个参数会生效。

接下来,我们将提供一些示例,以显示如何使用 spec 参数来更好地调整 Owl 的图。第一个示例展示了如何使用 ZLineContour 和其他 spec 参数配置 mesh 图。

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_020.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
>- : unit = ()
Plot specification
绘图规格

第二个示例展示了如何在绘制 3D 表面时调整 surf 绘图函数。

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_021.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
  >- : unit = ()
  
Surf plot
表面图

子图

您可能已经在上一个示例中发现了另一个功能:子图。的确,通过改变 create 函数中 mn 参数的数量,您可以改变子图布局的行数和列数。

let f p i = match i with
  | 0 -> Stats.gaussian_rvs ~mu:0. ~sigma:0.5 +. p.(1)
  | _ -> Stats.gaussian_rvs ~mu:0. ~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 "plot_002.png" 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 255 0 0;
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
>- : unit = ()
Subplots
Subplots

多条线

当然,您可以在同一页上绘制多条线(或其他类型的图)。以下是一个在同一个图中绘制正弦和余弦线的示例。

let h = Plot.create "plot_024.png" 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 [|"正弦函数"; "余弦函数"|];
  Plot.output h
  >- : unit = ()
  
绘制多条线
绘制多条线

这里是另一个示例,其中在同一图中既有直方图又有线图。

(* 生成数据 *)
  let g x = (Stats.gaussian_pdf x ~mu:0. ~sigma:1.) *. 100. in
  let y = Mat.gaussian ~mu:0. ~sigma:1. 1 1000 in
  
  (* 绘制多个数据集 *)
  let h = Plot.create "plot_025.png" 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 (-4.) 4.);
  Plot.legend_on h [|"数据"; "模型"|];
  
  Plot.output h
  >- : unit = ()
  
混合线图和直方图
混合线图和直方图

因此,只要在调用 Plot.output 之前“保持”绘图,您就可以在同一图中绘制许多数据集。

图例

通过分别调用 Plot.legend_onPlot.legend_off,可以打开和关闭图例。调用 Plot.legend_on 时,您还需要提供一个图例名称数组和图例的位置。在 Plot 中有八个默认位置:


    type legend_position =
      North | South | West | East | NorthWest | NorthEast | SouthWest | SouthEast
  

尽管它看起来很混乱,但以下示例显示了如何在 Owl 的绘图模块中使用图例。

(* 生成数据 *)
  let x = Mat.(uniform 1 20 *$ 10.) in
  let y = Mat.(uniform 1 20) in
  let z = Mat.gaussian 1 20 in
  
  (* 绘制多个数据集 *)
  let h = Plot.create "plot_026.png" 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);
  
  (* 设置图例 *)
  Plot.(legend_on h ~position:NorthEast [|"测试 1"; "测试 2"; "散点"; "柱状"; "直方图"; "区域"|]);
  Plot.output h
  >- : unit = ()
  
带有图例的图
带有图例的图

绘制图案

绘图模块支持多种线型,如下所示:

let h = Plot.create "plot_004.png" 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
    >- : unit = ()
    
绘制线条
绘制线条

同样,我们还可以使用不同的图案填充矩形,如下例所示。

let h = Plot.create "plot_005.png" 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)))
    ) |> ignore;
    
    Plot.output h
    >- : unit = ()
    
填充图案
填充图案

折线图

在了解了这些绘图元素之后,在本章的其余部分中,我们将演示一些支持的不同类型的绘图。折线图是最基本的功能。您可以在函数中指定颜色、标记和线型。

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 "plot_022.png" 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
    >- : unit = ()
    
带有自定义标记的折线图
带有自定义标记的折线图

散点图

接下来是散点图。与折线图类似,您可以指定标记类型和标记大小。下面的示例实际上显示了各种标记的模式。它们由不同的 id 引用。

let x = Mat.uniform 1 30 in
let y = Mat.uniform 1 30 in
let h = Plot.create ~m:3 ~n:3 "plot_006.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
>- : unit = ()
Scatter plot
Scatter plot

阶梯图

阶梯图也称为“阶梯图”,因为它以类似阶梯的曲线绘制给定 ndarray 中的元素。

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 "plot_007.png" 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
  >- : unit = ()
  
阶梯图
阶梯图

箱线图

箱线图通过四分位数图形地展示数值数据的分组。它常用于描述统计学。

let y1 = Mat.uniform 1 10 in
  let y2 = Mat.uniform 10 100 in
  let h = Plot.create ~m:1 ~n:2 "plot_008.png" 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
  >- : unit = ()
  
箱线图
箱线图

茎叶图

茎叶图很简单,如下代码所示。

let x = Mat.linspace 0.5 2.5 25 in
  let y = Mat.map (Stats.exponential_pdf ~lambda:0.1) x in
  let h = Plot.create ~m:1 ~n:2 "plot_009.png" 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
  >- : unit = ()
  
茎叶图
茎叶图

茎叶图常用于显示变量的自相关性,因此 Plot 模块已经包含了方便的 autocorr

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 "plot_010.png" 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
>- : unit = ()
Stem plot with autocorrelation
Stem plot with autocorrelation

面积图

面积图类似于线图,但它填充了线和 x 轴之间的空间,如下所示。

let x = Mat.linspace 0. 8. 100 in
    let y = Mat.map Maths.atan x in
    let h = Plot.create ~m:1 ~n:2 "plot_011.png" 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
    >- : unit = ()
    
面积图
面积图

直方图和累积分布函数图

直方图是数据可视化中最常用的图之一。给定一系列测量值,您可以使用 histogramecdf 绘图函数轻松绘制数据的直方图和经验累积分布。

let x = Mat.gaussian 200 1 in
    let h = Plot.create ~m:1 ~n:2 "plot_012.png" in
    Plot.subplot h 0 0;
    Plot.set_title h "直方图";
    Plot.histogram ~h ~bin:25 x;
    Plot.subplot h 0 1;
    Plot.set_title h "经验累积分布函数";
    Plot.ecdf ~h x;
    Plot.output h
    >- : unit = ()
    
直方图和累积分布函数图
直方图和累积分布函数图

对数图

在 Owl 绘图中,您可以选择在 x 轴和/或 y 轴上使用对数刻度。

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_013.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
>- : unit = ()
Change plot scale on x- and y-axis to log
Change plot scale on x- and y-axis to log

3D图

我们已经看到了上面的3D图的示例。在Plot模块中有四个与3D图相关的函数。它们是surfmeshheatmapcontour函数。首先,让我们看一下meshsurf函数。

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_014.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
    >- : unit = ()
    
3D图
3D图

使用altitudeazimuth参数轻松控制视角。下面是一个例子。

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 "plot_015.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
    >- : unit = ()
    

生成的图如下所示。

定制的3D图,例1
定制的3D图,例1

这里是另一个类似的例子,使用不同的函数。

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_016.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
>- : unit = ()
Customised 3D Plot, example 2
Customised 3D Plot, example 2

热图和等高线图

最后,让我们看一下使用与之前相同的函数的热图和等高线图的外观。

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_017.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
  >- : unit = ()
  
热图和等高线图
热图和等高线图

高级统计图

除了这些常用的基本图类型外,我们还支持几种高级统计图。例如,qqplotprobplot都是用于确定数据集是否来自某个特定分布的简单图形测试。

qqplot显示样本数据y的分位数与给定分布的理论分位数值,或样本数据x的分位数的量子-量子图。以下是一个例子。

let y = Mat.(gaussian 100 1 *$ 10.) in
let x = Mat.gaussian 200 1 in
let h = Plot.create ~m:2 ~n:2 "plot_018.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.rayleigh_ppf 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.chi2_ppf p 10.);

Plot.output h
>- : unit = ()
使用qqplot进行高级统计图
使用qqplot进行高级统计图

probplot类似于qqplot。它包含两种特殊情况:normplot用于给定的理论分布为正态分布,以及wblplot用于威布尔分布。以下是它们的示例。

let x = Mat.empty 200 1 |> Mat.map (fun _ -> Stats.weibull_rvs 1.2 1.5) in
let h = Plot.create ~m:1 ~n:2 "plot_019.png" in

Plot.subplot h 0 0;
Plot.set_title h "随机威布尔样本 vs. 标准正态分布";
Plot.set_xlabel h "样本数据";
Plot.set_ylabel h "理论正态分布";
Plot.normplot ~h x;

Plot.subplot h 0 1;
Plot.set_title h "随机威布尔样本 vs. 威布尔分布";
Plot.set_xlabel h "样本数据";
Plot.set_ylabel h "理论威布尔分布";
Plot.wblplot ~h ~lambda:1.2 ~k:1.5 x;
Plot.output h
>- : unit = ()
使用probplot进行高级统计图
使用probplot进行高级统计图

摘要

本章介绍了Owl中的绘图模块,包括如何创建、操作绘图,以及支持的不同类型的绘图。本章提供了许多示例,旨在成为您在需要可视化任务时随时查阅的手册。实际上,本书中大多数图表都基于这个模块。

本章的一个潜在问题是,我们可能没有太多考虑“颜色和谐性”。默认选择的颜色可能并不总是令人愉悦。好消息是,您可以轻松更改图表中的颜色。尝试搜索“色彩理论”,您会找到许多指南。例如,在线图中,类似颜色可能是一个不错的选择。这些颜色是12部分色轮上的任何连续三种颜色,如黄绿色、黄色和黄橙色。我们发现可视化的艺术方面通常令人愉悦。

接下来:第04章数学函数