4
3

More than 5 years have passed since last update.

OCamlでCSVの数値データ読み込みとPDFへの描画

Last updated at Posted at 2016-11-05

OCamlでCSVを読み込んでPDFにプロットしてみた。

まずOPAMで依存パッケージをインストールしておく。

opam install batteries csv camlpdf

以下のソースコードを作成し、ocamlbuild -pkgs camlpdf,csv,batteries main.nativeでコンパイルし、./main.nativeで実行する。手元のMacBook Air (13 inch, Mid-2011)で時間を測ると、コンパイルは1.3秒程度、実行時間は45個のCSVファイル(合計6.5 MB)の読み込み+PDF作成で2.8秒と、かなり速くて良い感じ。

main.ml
open BatList

type t = {
    x: float;
    y: float;
}

let write_pdf points path =
    let f p =
        Pdfops.Op_l (p.x *. 50.,p.y *. 1000.)
    in let ps = map f points
    in let ops =
      concat [[Pdfops.Op_cm (Pdftransform.matrix_of_transform [Pdftransform.Translate (50., 100.)]);
       Pdfops.Op_SC [0.5;0.5;0.];
       Pdfops.Op_w 1.;
       Pdfops.Op_m (0.,0.)
       ];
       ps;
       [Pdfops.Op_S]
       ]
    in
      let page =
        {(Pdfpage.blankpage Pdfpaper.a4) with
            Pdfpage.content = [Pdfops.stream_of_ops ops]}
      in
        let pdf, pageroot = Pdfpage.add_pagetree [page] (Pdf.empty ()) in
          let pdf = Pdfpage.add_root pageroot [] pdf in
            Pdfwrite.pdf_to_file pdf path

let show_points p =
    Printf.sprintf "Point {%f,%f}" p.x p.y

let read_csv path =
    let dat = Csv.load path in
    let dat = drop 13 dat in
    let a = 1 in
    let decode [x;y] =
        {x = float_of_string x; y = float_of_string y} in
    map decode dat

let () =
    let f i =
        let points = read_csv (Printf.sprintf "testdata/%02d.csv" i) in
        write_pdf points (Printf.sprintf "%02d.pdf" i) in
    iter f (range 1 `To 45);;

なお、csv, camlpdfともにドキュメントがほぼないに等しいのでソースコードを読む必要がある。

csvはCSV.loadというのがstring -> string list listという型で、ファイル名を指定するとCSVの二次元リストを返す関数。

PDFの出力については、AdobeのPDF仕様書を読みながらPdfops.Op_l(PDFの線を描画するl演算子)などの意味を紐解いていく必要があったが、PDFをいじったことのある人であればなんとかなる感じ。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3