ocaml-gnuplot-0.8.3/0000755000175000017500000000000011163720161012763 5ustar trchtrchocaml-gnuplot-0.8.3/gnuplot_macos.ml0000644000175000017500000000546011163137466016206 0ustar trchtrch(* File: gnuplot_macos.ml Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_macos.ml,v 1.5 2007-11-27 23:07:22 chris_77 Exp $ *) (* * Configuration ***********************************************************************) (* The gnuplot program. *) let gnuplot = "gnuplot" (* If one wants the 'aqua' terminal instead of the X11 one on MacOS X. *) let macosX_aqua = true (***********************************************************************) open Printf open Gnuplot_dir let macosX = match Sys.os_type with | "Unix" -> true | "MacOS" -> false | _ -> output_string stderr "Configure PLATFORM in Makefile.conf"; exit 1 type t = { dir : string; file : bool; mutable no : int; (* temporary file number *) } let temp_dir = if macosX then try Unix.getenv "TMPDIR" with Not_found -> "/tmp" else try Sys.getenv "TempFolder" with Not_found -> ":" let open_gnuplot_out = fun persist ?pos xsize ysize color -> let pos = match pos with | None -> "" | Some (x,y) -> sprintf "%+i%+i" x y in let pgm = sprintf "%s -noraise -geometry %.0fx%.0f%s %s %s" gnuplot xsize ysize pos (if persist then "-persist" else "") (if color then "" else "-gray") in let gp = Unix.open_process_out pgm in (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = false; no = 0 }) let open_file_out fname = let gp = open_out fname in (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = true; no = 0 }) let close_out gp t = if t.file then close_out gp else match Unix.close_process_out gp with | Unix.WEXITED 0 -> remove_rec_dir t.dir | _ -> raise (Sys_error "Gnuplot ended with an error") let set_terminal_X = if macosX_aqua then begin let pgmname = Filename.basename Sys.argv.(0) in fun g xsize ysize color -> fprintf g "set terminal aqua title \"%s\" size %.0f %.0f\n" pgmname xsize ysize end else (* X11 gnuplot under MacOS X *) let pgmname = Filename.basename Sys.argv.(0) in fun g _ _ _ -> fprintf g "set terminal x11 title \"OCaml Gnuplot: %s\"\n" pgmname let open_temp_file t = t.no <- t.no + 1; let fname = Filename.concat t.dir (string_of_int t.no ^ ".dat") in (fname, open_out fname) ocaml-gnuplot-0.8.3/gnuplot_unix.ml0000644000175000017500000000507611163137466016072 0ustar trchtrch(* File: gnuplot_unix.ml Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_unix.ml,v 1.4 2004-11-28 23:49:39 chris_77 Exp $ *) (* * Configuration ***********************************************************************) (* The gnuplot program. The default should be fine for most people. *) let gnuplot = "gnuplot" (***********************************************************************) open Gnuplot_dir type t = { dir : string; file : bool; mutable no : int; (* temporary file number *) } let temp_dir = try Unix.getenv "TMPDIR" with Not_found -> "/tmp" let open_gnuplot_out persist ?pos xsize ysize color = (* The -geometry,... options have no influence if the terminal is not X11 (so no need to take special care about X11). *) let pos = match pos with | None -> "" | Some (x,y) -> Printf.sprintf "%+i%+i" x y in let pgm = Printf.sprintf "%s -noraise -geometry %.0fx%.0f%s %s %s" gnuplot xsize ysize pos (if persist then "-persist" else "") (if color then "" else "-gray") in let gp = Unix.open_process_out pgm in (* On sucessful opening of a pipe to gnuplot, create a temp dir to hold data files. *) (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = false; no = 0 }) let open_file_out fname = let gp = open_out fname in (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = true; no = 0 }) let close_out gp t = if t.file then (* If we were writing the commands to a file, the data files must be kept -- otherwise the file is unusable. *) close_out gp else match Unix.close_process_out gp with | Unix.WEXITED 0 -> remove_rec_dir t.dir | _ -> raise (Sys_error "Gnuplot ended with an error") let set_terminal_X = let pgmname = Filename.basename Sys.argv.(0) in fun g _ _ _ -> Printf.fprintf g "set terminal x11 title \"OCaml Gnuplot: %s\"\n" pgmname let open_temp_file t = t.no <- t.no + 1; let fname = Filename.concat t.dir (string_of_int t.no ^ ".dat") in (fname, open_out fname) ocaml-gnuplot-0.8.3/META.in0000644000175000017500000000033111163163052014036 0ustar trchtrch# Specifications for the Gnuplot module -*-conf-unix-*- name="gnuplot" description="OCaml Gnuplot Interface" requires = "unix bigarray" archive(byte) = "gnuplot.cma" archive(native) = "gnuplot.cmxa" ocaml-gnuplot-0.8.3/make_array.ml0000644000175000017500000000716311163437022015440 0ustar trchtrch(* File: make_array.ml This "script" will generate "gnuplot_bigarray*.ml" and "gnuplot_array.ml" from "gnuplot_generic.ml". It naive and no more general that it needs to be. Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: make_array.ml,v 1.4 2004-11-28 23:51:11 chris_77 Exp $ *) let arg = "\\([^()]+\\)" let re_arr = Str.regexp_string "ARRAY" and re_vec = Str.regexp_string "VEC" and re_mat = Str.regexp_string "MAT" and re_lower = Str.regexp_string "LOWER" and re_upper = Str.regexp ("UPPER *(" ^ arg ^ ")") and re_get = Str.regexp ("GET *(" ^ arg ^ "," ^ arg ^ ")") and re_get2 = Str.regexp ("GET2 *(" ^ arg ^ "," ^ arg ^ "," ^ arg ^ ")") type subst = { mod_name : string; (* module name *) header : string; (* header of the new file *) vec : string; (* type for vectors -- VEC *) mat : string; (* type for matrices -- MAT *) lower : string; (* lower bound for vectors -- LOWER *) upper : string; (* upper bound for vectors -- UPPER(\1) *) get : string; (* get function -- GET(\1,\2) *) get2 : string (* get function for arrays -- GET2(\1,\2,\3) *) } let subtitute infile outfile subst = (try Sys.remove outfile with _ -> ()); (* ignore errors *) let fh0 = open_in infile in let fh1 = open_out outfile in Printf.fprintf fh1 "(* Automatically generated from %S. *)\n%s\n" infile subst.header; try while true do let l = input_line fh0 in let l = Str.global_replace re_arr subst.mod_name l in let l = Str.global_replace re_vec subst.vec l in let l = Str.global_replace re_mat subst.mat l in let l = Str.global_replace re_lower subst.lower l in let l = Str.global_replace re_upper subst.upper l in let l = Str.global_replace re_get subst.get l in let l = Str.global_replace re_get2 subst.get2 l in output_string fh1 l; output_string fh1 "\n"; done with End_of_file -> (); close_in fh0; close_out fh1; Unix.chmod outfile 0o444 (* to prevent accidental modification *) let () = let src_file = "gnuplot_arr_ba.ml" in subtitute src_file "gnuplot_array.ml" { mod_name = "Array"; header = "include Gnuplot_common_ type vec = float array type mat = float array array "; vec = "vec"; mat = "mat"; lower = "0"; upper = "Array.length(\\1) - 1"; get = "Array.unsafe_get(\\1)(\\2)"; get2 = "Array.unsafe_get (Array.unsafe_get(\\1)(\\2))(\\3)"; }; subtitute src_file "gnuplot_ba_c.ml" { mod_name = "Bigarray"; header = "open Gnuplot_common_ open Bigarray"; vec = "(float, float64_elt, c_layout) Array1.t"; mat = "(float, float64_elt, c_layout) Array2.t"; lower = "0"; upper = "Array1.dim(\\1) - 1"; get = "\\1.{\\2}"; get2 = "\\1.{\\2,\\3}"; }; subtitute src_file "gnuplot_ba_f.ml" { mod_name = "Bigarray"; header = "open Gnuplot_common_ open Bigarray"; vec = "(float, float64_elt, fortran_layout) Array1.t"; mat = "(float, float64_elt, fortran_layout) Array2.t"; lower = "1"; upper = "Array1.dim(\\1)"; get = "\\1.{\\2}"; get2 = "\\1.{\\2,\\3}"; } ocaml-gnuplot-0.8.3/gnuplot_arr_ba.ml0000644000175000017500000001577211163252135016330 0ustar trchtrch(* File: gnuplot_arr_ba.ml These are the functions that will be specialized for bigarray and array by the program "gnuplot_make.ml". Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_arr_ba.ml,v 1.6 2004-11-28 23:49:39 chris_77 Exp $ *) open Printf (* Specialized for efficiency *) let min (x:int) y = if x < y then x else y let min4 (x:int) y z t = min (min x y) (min z t) let data_of_float x = if is_finite x then string_of_float x else "?" (* * 2D Plots **********************************************************************) let x g ?(tag=system_tag) ?(style=Lines) ?(label="") ?(n0=LOWER) ?(ofsx=LOWER) ?(incx=1) (xvec:VEC) = if g.closed then failwith "Gnuplot.ARRAY.x: handle closed"; if ofsx < LOWER || ofsx > UPPER(xvec) then invalid_arg "Gnuplot.x: ofsx invalid"; if incx < 1 then invalid_arg "Gnuplot.x: incx < 1"; let rec loop i n out = if i <= UPPER(xvec) then begin out (string_of_int n ^ " " ^ data_of_float(GET(xvec,i)) ^ "\n"); loop (i + incx) (n + 1) out end in plot_data g ~inline_if:(1 + (UPPER(xvec) - ofsx) / incx <= g.max_inline) (loop ofsx n0) ~axes ~label ~style:(with_style g style) ~tag let xy g ?(tag=system_tag) ?(style=Lines) ?(label="") ?(ofsx=LOWER) ?(incx=1) (xvec:VEC) ?(ofsy=LOWER) ?(incy=1) (yvec:VEC) = if g.closed then failwith "Gnuplot.ARRAY.xy: handle closed"; if ofsx < LOWER || ofsx > UPPER(xvec) || incx < 1 || ofsy < LOWER || ofsy > UPPER(yvec) || incy < 1 then invalid_arg "Gnuplot.xy: ofsx, incx, ofxy, or incy invalid"; let rec loop i j out = if i <= UPPER(xvec) && j <= UPPER(yvec) then begin out (data_of_float(GET(xvec,i)) ^ " " ^ data_of_float(GET(yvec,i)) ^ "\n"); loop (i + incx) (j + incy) out end in let nlines = 1 + min ((UPPER(xvec) - ofsx) / incx) ((UPPER(yvec) - ofsy) / incy) in plot_data g ~inline_if:(nlines <= g.max_inline) (loop ofsx ofsy) ~axes ~label ~style:(with_style g style) ~tag let bin g ?(tag=system_tag) ?(label="") ?(center=true) ?(ofsx=LOWER) ?(incx=1) (xvec:VEC) ?(ofsy=LOWER) ?(incy=1) (yvec:VEC) = if g.closed then failwith "Gnuplot.ARRAY.bin"; if ofsx < LOWER || ofsx + incx > UPPER(xvec) (* >= 2 points *) || incx < 1 || ofsy < LOWER || ofsy > UPPER(yvec) || incy < 1 then invalid_arg "Gnuplot.bin"; if center then begin let rec loop i j out = if i <= UPPER(xvec) && j <= UPPER(yvec) then begin let xlow = if i = ofsx then 0.5 *. (3. *. GET(xvec,ofsx) -. GET(xvec,ofsx + incx)) else 0.5 *. (GET(xvec,i - incx) +. GET(xvec,i)) and xup = if i + incx > UPPER(xvec) then 0.5 *. (3. *. GET(xvec,i) -. GET(xvec,i - incx)) else 0.5 *. (GET(xvec,i) +. GET(xvec,i + incx)) and yi = GET(yvec,j) in if is_finite xlow && is_finite xup && is_finite yi then let b0 = string_of_float xlow and b1 = string_of_float xup and y = string_of_float yi in out(sprintf "%s 0.\n%s %s\n%s %s\n%s 0.\n" b0 b0 y b1 y b1) else out "? ?\n"; loop (i + incx) (j + incy) out end in let nbin = 1 + min ((UPPER(xvec) - ofsx) / incx) ((UPPER(yvec) - ofsy) / incy) in plot_data g ~inline_if:(4 * nbin <= g.max_inline) (loop ofsx ofsy) ~axes ~label ~style:(with_style g Lines) ~tag end else begin let rec loop is_finite_xi sxi i1 j out = if i1 <= UPPER(xvec) && j <= UPPER(yvec) then begin let xi1 = GET(xvec,i1) and yi = GET(yvec,j) in let is_finite_xi1 = is_finite xi1 and sxi1 = string_of_float xi1 in if is_finite_xi && is_finite_xi1 && is_finite yi then let syi = string_of_float yi in out(sprintf "%s 0.\n%s %s\n%s %s\n%s 0.\n" sxi sxi syi sxi1 syi sxi1) else out "? ?\n"; loop is_finite_xi1 sxi1 (i1 + incx) (j + incy) out end in let x0 = GET(xvec,ofsx) in let nbin = 1 + min ((UPPER(xvec) - ofsx - incx) / incx) ((UPPER(yvec) - ofsy) / incy) in plot_data g ~inline_if:(4 * nbin <= g.max_inline) (loop (is_finite x0) (string_of_float x0) (ofsx + incx) ofsy) ~axes ~label ~style:(with_style g Lines) ~tag end let vector g ?(tag=system_tag) ?(label="") ?(ofsx=LOWER) ?(incx=1) (xvec:VEC) ?(ofsy=LOWER) ?(incy=1) (yvec:VEC) ?(ofsdx=LOWER) ?(incdx=1) (dxvec:VEC) ?(ofsdy=LOWER) ?(incdy=1) (dyvec:VEC) = if g.closed then failwith "Gnuplot.ARRAY.vector"; if ofsx < LOWER || ofsx > UPPER(xvec) || incx < 1 || ofsy < LOWER || ofsy > UPPER(yvec) || incy < 1 || ofsdx < LOWER || ofsdx > UPPER(dxvec) || incdx < 1 || ofsdy < LOWER || ofsdy > UPPER(dyvec) || incdy < 1 then invalid_arg "Gnuplot.vector"; let rec loop i j i' j' out = if i <= UPPER(xvec) && i <= UPPER(yvec) && i' <= UPPER(dxvec) && j' <= UPPER(dyvec) then begin let xi = GET(xvec,i) and yi = GET(yvec,j) and dxi = GET(dxvec,i') and dyi = GET(dyvec,j') in if is_finite xi && is_finite yi && is_finite dxi && is_finite dyi then out (sprintf "%F %F %F %F\n" xi yi dxi dyi) else out "? ? ? ?\n"; loop (i + incx) (j + incy) (i' + incdx) (j' + incdy) out end in let nlines = 1 + min4 ((UPPER(xvec) - ofsx) / incx) ((UPPER(yvec) - ofsy) / incy) ((UPPER(dxvec) - ofsdx) / incdx) ((UPPER(dyvec) - ofsdy) / incdy) in plot_data g ~inline_if:(nlines <= g.max_inline) (loop ofsx ofsy ofsdx ofsdy) ~axes ~label ~style:with_vector ~tag let err g ?(tag=system_tag) ?(xerr:VEC option) (xvec:VEC) ?(yerr:VEC option) (yvec:VEC) = if g.closed then failwith "Gnuplot.ARRAY.err"; failwith "Gnuplot.err not yet implemented" (* * 3D Plots **********************************************************************) let xyz g ?(tag=system_tag) ?(style=Lines) ?(label="") (xvec:VEC) (yvec:VEC) (zmat:MAT) = if g.closed then failwith "Gnuplot.ARRAY.xyz"; let loop out = for i = LOWER to UPPER(xvec) do let xi = GET(xvec,i) in if is_finite xi then begin for j = LOWER to UPPER(yvec) do let yi = GET(yvec,j) in let zij = GET2(zmat,i,j) in if is_finite yi && is_finite zij then out (sprintf "%F %F %F\n" xi yi zij) else out "? ? ?\n" done end else out "? ? ?\n" done in let nlines = (1 + UPPER(xvec) - LOWER) * (1 + UPPER(yvec) - LOWER) in plot_data g ~inline_if:(nlines <= g.max_inline) loop ~axes:no_axes ~label ~style:(with_style g style) ~tag ocaml-gnuplot-0.8.3/gnuplot.ml0000644000175000017500000000147011163137466015021 0ustar trchtrch(* Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot.ml,v 1.4 2005-09-27 17:35:21 chris_77 Exp $ *) include Gnuplot_common_ module Bigarray = Gnuplot_bigarray module Array = Gnuplot_array include Gnuplot_functor ocaml-gnuplot-0.8.3/LICENSE0000644000175000017500000006534511163137466014017 0ustar trchtrchThis Library is distributed under the terms of the GNU Lesser General Public License version 2.1 (included below). As a special exception to the GNU Lesser General Public License, you may link, statically or dynamically, a "work that uses the Library" with a publicly distributed version of the Library to produce an executable file containing portions of the Library, and distribute that executable file under terms of your choice, without any of the additional requirements listed in clause 6 of the GNU Lesser General Public License. By "a publicly distributed version of the Library", we mean either the unmodified Library as distributed, or a modified version of the Library that is distributed under the conditions defined in clause 3 of the GNU Library General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Lesser General Public License. GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ocaml-gnuplot-0.8.3/demos/0000755000175000017500000000000011163715774014110 5ustar trchtrchocaml-gnuplot-0.8.3/demos/parse_args.ml0000644000175000017500000000174511163240171016557 0ustar trchtrch(* Parsing the command line arguments for all examples *) (* $Id: parse_args.ml,v 1.3 2004-11-22 19:54:26 chris_77 Exp $ *) let ext = ref "" let want_offline = ref false let () = let args = [ ("-dev", Arg.Set_string ext, "extension of the file in which to save the drawing.\n " ^ " If no file is provided, the drawing will be done on the screen."); ("-o", Arg.Set want_offline, " To write the commands to a file instead of sending them to gnuplot."); ] in let anon _ = raise (Arg.Bad "No anonymous argument") in Arg.parse args anon "Usage:" let base = Filename.chop_extension Sys.argv.(0) let pgmname = Filename.basename base let device i = try let fname = Printf.sprintf "%s-%i.%s" base i !ext in let g = Gnuplot.device_of_filename fname in Printf.printf "%-4s: Device %2i --> file %S\n" pgmname i fname; g with Failure _ -> Gnuplot.Wxt let offline i = if !want_offline then Some(Printf.sprintf "%s-%i.plt" base i) else None ocaml-gnuplot-0.8.3/demos/ex7.ml0000644000175000017500000000053011163137466015137 0ustar trchtrch(* $Id: ex7.ml,v 1.3 2004-11-22 19:54:26 chris_77 Exp $ *) (* Test the plotting of an empty data set but with a box. *) module P = Gnuplot open Parse_args let () = let g = P.init ?offline:(offline 1) (device 1) in P.env g ~xgrid:true (-2.) 2. (-1.) 1.; try P.close g with Failure _ -> print_endline "*** Gnuplot had a problem! ***" ocaml-gnuplot-0.8.3/demos/ex2.ml0000644000175000017500000000427311163240375015134 0ustar trchtrch(* $Id: ex2.ml,v 1.4 2004-11-22 19:54:26 chris_77 Exp $ *) open Printf open Parse_args module P = Gnuplot.Array let pi = 4. *. atan 1. (* Angle in degrees of the vector (x,y) with the x axis *) let deg_angle x y = 180. /. pi *. atan2 y x let () = (* Log plot with different scales. *) let n = 101 in let freq = Array.make n 0. and ampl = Array.make n 0. and phase = Array.make n 0. in for i = 0 to n - 1 do freq.(i) <- 10.**(-2. +. float i /. 20.); ampl.(i) <- 20. *. log10(1. /. sqrt(1. +. freq.(i) *. freq.(i))); phase.(i) <- -180. /. pi *. atan freq.(i) done; let g = P.init ?offline:(offline 1) (device 1) in P.title g "Single Pole Low-Pass filter"; P.xlabel g "Frequency"; (* 1st plot *) P.env g ~xlog:true (1.E-2) (1.E3) (-80.) 0.; P.pen g 1; P.ylabel g "Amplitude (dB)"; P.xy g freq ampl; P.text g (10.**1.6) (-30.) ~rotate:(-40.) "-20 dB/decade"; (* 2nd plot -- we use the second y axis *) P.win g (1.E-2) (1.E3) (-100.) 0.; P.box g ~x:[] ~y:[P.tics ~which:[2] ~step:10. (); P.labels ~which:[2] ()]; P.pen g 2; P.ylabel g "Phase shift (degrees)"; P.xy g freq phase; P.close g module G = Gnuplot.Bigarray open Bigarray let () = (* Histogram of binomial distribution. (Illustrate how to plot Bigarrays.) *) let p = 0.2 (* probability of success of a single trial *) and n = 15 (* number of trials *) in let x = Array1.create float64 c_layout (n+1) and y = Array1.create float64 c_layout (n+1) in let nf = float n in let mean = nf *. p and sigma = sqrt(nf *. p *. (1. -. p)) and nchooseu = ref 1. in for i = 0 to n do let u = float i in x.{i} <- (u -. mean) /. sigma; y.{i} <- sigma *. !nchooseu *. p**u *. (1. -. p)**(nf -. u); nchooseu := !nchooseu *. (nf -. u) /. (u +. 1.); done; let pi = 4. *. atan 1. in let gauss x = 1. /. sqrt(2. *. pi) *. exp(-.(x**2.)/.2.) in let a = (nf -. mean) /. sigma in (* You can mix freely calls to functions of [Gnuplot.Bigarray] and of [Gnuplot.Array]*) let g = P.init (device 2) in P.box g; P.title g (sprintf "Bin(p=%g,n=%i) --> Gauss" p n); P.pen g 1; P.pen_width g 2.; G.bin g x y; G.pen g 3; G.fx g gauss (-. a) a; G.close g ocaml-gnuplot-0.8.3/demos/ex9.ml0000644000175000017500000000074511163137466015151 0ustar trchtrch(* $Id: ex9.ml,v 1.3 2004-11-22 19:54:26 chris_77 Exp $ *) (* Font and color demonstration *) module P = Gnuplot open Printf open Parse_args let () = let g = P.init ?offline:(offline 1) (device 1) in P.pen g 3; (* P.font g "Helvetica"; *) P.env g (-1.) 1. (-1.) 1.; (* FIXME: different colors for xy *) P.show g; for i = 1 to 20 do P.font_size g i; let p = i mod 6 in P.pen g p; P.text g 0. (float i) (sprintf "Size %i, pen %i" i p) done; P.close g ocaml-gnuplot-0.8.3/demos/ex1.ml0000644000175000017500000000157711163254622015137 0ustar trchtrch(* $Id: ex1.ml,v 1.2 2004-07-30 19:45:32 chris_77 Exp $ *) (* From the Matlab plotting examples at http://www.indiana.edu/~statmath/math/matlab/plotting/ *) module P = Gnuplot open Parse_args let red = 0xFF0000 let green = 0x00AA00 let blue = 0x0000FF let () = let g = P.init ?offline:(offline 1) ~xsize:500. ~ysize:300. (device 1) in P.box g; P.title g "sinus"; P.color g red; P.fx g sin (-10.) 10.; P.close g let () = let a = -6. and b = 6. in let g = P.init ?offline:(offline 2) (device 2) in P.env g a b (-2.) 2.; P.color g red; P.fx g cos a b; P.color g green; P.fx g (fun x -> 1. -. x**2. /. 2.) a b; P.color g blue; P.fx g (fun x -> 1. -. x**2. /. 2. +. x**4. /. 24.) a b; P.close g let () = let g = P.init ?offline:(offline 3) (device 3) in P.box g; P.color g blue; P.xy_param g (fun t -> (t *. cos t, t *. sin t)) 0. 10.; P.close g ocaml-gnuplot-0.8.3/demos/ex8.ml0000644000175000017500000000147511163137466015151 0ustar trchtrch(* $Id: ex8.ml,v 1.2 2004-11-22 19:54:26 chris_77 Exp $ *) (* Functor and text demonstration *) open Parse_args (* Data structure *) module Data = struct type vec = (float * string) list let iter f vec = List.iter (fun (x,_) -> f x) vec type vec2 = (float * float * string) list let iter2 f vec2 = List.iter (fun (x,y,_) -> f x y) vec2 type vec4 = unit type mat = unit let iter4 _ = failwith "Data.iter4" let iter_mat _ = failwith "Data.iter_mat" end module P = Gnuplot.Make(Data) let labelled_xy = [ (1., 4., "hello"); (2., 0., "Bonjour"); ] let () = let g = P.init ?offline:(offline 1) (device 1) in P.box g; P.pen g 1; P.point g 3; P.point_width g 2.; List.iter (fun (x,y,t) -> P.text g x y t ) labelled_xy; P.xy g labelled_xy ~style:P.Points; P.close g ocaml-gnuplot-0.8.3/demos/.depend0000644000175000017500000000000011163137466015332 0ustar trchtrchocaml-gnuplot-0.8.3/demos/ex4.ml0000644000175000017500000000220511163137466015135 0ustar trchtrch(* $Id: ex4.ml,v 1.2 2004-11-22 19:54:26 chris_77 Exp $ *) (* Illustrate a simple animation displaying the Taylor expansion of sin *) module P = Gnuplot open Parse_args let usleep t = ignore(Unix.select [] [] [] t) let tsin d = (* Compute the Taylor expansion of sin of order 2d+1 *) let d = max d 0 in let fac = ref 1. and s = ref 1. in let p = Array.init (d+1) (fun i -> let c = !s /. !fac in let i2 = 2. *. float(i+1) in let () = fac := !fac *. i2 *. (i2 +. 1.); s := -. !s in c) in fun x -> (* Horner eval of the poly *) let x2 = x *. x and y = ref 0. in for i = d downto 0 do y := p.(i) +. !y *. x2 done; !y *. x let () = let device = device 1 in let g = P.init ?offline:(offline 1) device in let b = 9. in let f = Array.init 10 tsin in P.env g ~xgrid:true 0. b (-2.) 2.; P.pen g 2; P.pen_width g 3.; P.fx g sin 0. b; P.pen g 1; P.pen_width g 1.; for i = 0 to Array.length f - 1 do P.fx g f.(i) 0. b; usleep 0.5; done; if device = P.X then usleep 2.; P.close g ocaml-gnuplot-0.8.3/demos/ex10.ml0000644000175000017500000000112311163137466015210 0ustar trchtrch(* $Id: ex10.ml,v 1.3 2004-11-22 19:54:25 chris_77 Exp $ *) (* 3D hidden trials *) module P = Gnuplot open Parse_args let is_finite x = match classify_float x with | FP_infinite | FP_nan -> false | _ -> true let () = let sphere x y = sqrt(1. -. (x*.x +. y*.y)) and sphere0 x y = let z = sqrt(1. -. (x*.x +. y*.y)) in if is_finite z then z else 0. in let g = P.init ?offline:(offline 1) (device 1) in P.env3 g (-1.5) 1.5 (-1.5) 1.5 0. 1.5; P.pen g 1; P.fxy g sphere0 (-1.5) 1.5 (-1.5) 1.5; P.pen g 3; P.xyz_ft g (fun t -> (cos t, sin t, 0.)) 0. 7.; P.close g ocaml-gnuplot-0.8.3/demos/ex3.ml0000644000175000017500000000240211163137466015133 0ustar trchtrch(* $Id: ex3.ml,v 1.2 2004-11-22 19:54:26 chris_77 Exp $ *) module P = Gnuplot open Parse_args let sleep t = ignore(Unix.select [] [] [] t) let () = let device = device 1 in let g = P.init ~nxsub:2 ~nysub:2 device ?offline:(offline 1) in P.pen_width g 1.; P.box g; P.pen g 1; P.fx g ~style:P.Impulses (fun x -> x) 0. 1.; P.pen g 2; P.fx g ~style:P.Linespoints (fun x -> x**2.) 0. 1.; P.adv g; P.pen g 0; P.box g; P.pen g 3; P.pen_width g 2.; P.title g "Spiral"; P.xy_param g (fun t -> let r = 0.1 *. t in (r *. cos t, r *. sin t)) 0. 13.; P.adv g; P.pen g 0; P.env g 0. 10. ~ylog:true ~ygrid:true 1e-5 10.; P.pen g 1; P.fx g (fun x -> exp(-. x)) 0.01 10.; P.adv g; P.pen g 0; P.env g ~xgrid:true 0. 1. ~ygrid:true 0. 1.; P.pen g (-1); (* border color *) P.show ~tag:1 g; (* Set tag 1 to be shown -- by default new tags are not displayed; a [show] command must be issued. *) List.iter (fun e -> P.fx ~tag:1 g (fun x -> x**e) 0. 1.; if device = P.X then sleep 0.5; ) [0.1; 0.25; 0.5; 1.; 2.; 4.; 10.]; sleep 1.; (* Hide them all *) P.hide ~tag:1 ~immediately:true g; sleep 2.; (* Show them all again *) P.show ~tag:1 g; P.close g ocaml-gnuplot-0.8.3/demos/parse_args.mli0000644000175000017500000000077511163137466016746 0ustar trchtrch(* File: parse_args.mli *) (* $Id: parse_args.mli,v 1.2 2004-07-30 22:48:33 chris_77 Exp $ *) (** Parse command line arguments and build accordingly the following values. *) val device : int -> Gnuplot.device (** [device i] returns a device for the plot number [i]. *) val offline : int -> string option (** [offline i] returns [Some ] if the user desires to save the commands into a file (the name of which will be constructed from the program name and [i]) and [None] otherwise. *) ocaml-gnuplot-0.8.3/demos/ex6.ml0000644000175000017500000000245111163137466015142 0ustar trchtrch(* $Id: ex6.ml,v 1.3 2004-11-22 19:54:26 chris_77 Exp $ *) module P = Gnuplot open Parse_args let () = let re_sq u v = (u *. u -. v *. v, 2. *. u *. v, u) in let im_sq u v = (u *. u -. v *. v, 2. *. u *. v, v) in let g = P.init ~xsize:800. ~ysize:400. ~nxsub:2 (device 1) ?offline:(offline 1) in P.box3 g; P.pen g 1; P.fxy_param g re_sq (-3.) 3. (-3.) 3.; P.adv g; P.box3 g; P.fxy_param g im_sq (-3.) 3. (-3.) 3.; P.close g let pi = 4. *. atan 1. let () = let torus x0 y0 z0 r0 r1 u v = let r = r0 -. r1 *. cos(v) in (x0 +. r *. cos(u), y0 +. r *. sin(u), z0 +. r1 *. sin(v)) in let torus2 x0 y0 z0 r0 r1 u v = let r = r0 -. r1 *. cos(v) in (x0 +. r1 *. sin(v), y0 +. r *. cos(u), z0 +. r *. sin(u)) in let g = P.init ~xsize:800. ~ysize:400. ~nxsub:2 (device 2) ?offline:(offline 2) in P.box3 g; P.pen g 1; P.fxy_param g (torus 0. 0. 0. 1. 0.3) 0. (2.*.pi) 0. (2.*.pi); P.fxy_param g (torus 2. 0. 0. 1. 0.3) 0. (2.*.pi) 0. (2.*.pi); P.pen g 2; P.fxy_param g (torus2 0. 1. 0. 1. 0.2) 0. (2.*.pi) 0. (2.*.pi); P.adv g; let moebius u v = let r = 2. -. v *. sin(u/.2.) in (r *. sin(u), r *. cos(u), v *. cos(0.5 *. u)) in P.pen g 0; P.box3 g; P.pen g 1; P.fxy_param g moebius 0. (2. *. pi) (-0.25) 0.25; P.close g ocaml-gnuplot-0.8.3/demos/Makefile0000644000175000017500000000312711163137466015547 0ustar trchtrch# $Id: Makefile,v 1.8 2007-11-27 23:07:22 chris_77 Exp $ # ocaml-gnuplot/demos # Copyright (C) Christophe TROESTLER include ../Makefile.conf OCAMLFLAGS = -I ../ OCAMLOPTFLAGS = -I ../ WEBDIR = ../../webpublishing WEBDIRDOC = $(WEBDIR)/Gnuplot DEMOS_LIBS = parse_args.ml DEMOS = $(wildcard ex*.ml) PKGS = $(shell grep "requires" ../META.in | \ sed -e "s/.*\"\([^\"]*\)\".*/\1/") PKGS += gnuplot PKGS_CMA = $(addsuffix .cma, $(PKGS)) .PHONY: demos byte opt demos: byte byte: $(DEMOS:.ml=.exe) opt: $(DEMOS:.ml=.com) ex%.exe: ex%.ml ../gnuplot.cma $(DEMOS_LIBS:.ml=.cmo) $(OCAMLC) -o $@ $(OCAMLFLAGS) $(PKGS_CMA) $(DEMOS_LIBS:.ml=.cmo) $< ex%.com: ex%.ml ../gnuplot.cmxa $(DEMOS_LIBS:.ml=.cmx) $(OCAMLOPT) -o $@ $(OCAMLOPTFLAGS) $(PKGS_CMA:.cma=.cmxa) \ $(DEMOS_LIBS:.ml=.cmx) $< parse_args.cmi: parse_args.mli ../gnuplot.cmi parse_args.cmo: parse_args.ml parse_args.cmi ../gnuplot.cma parse_args.cmx: parse_args.ml parse_args.cmi ../gnuplot.cmxa # Caml general dependencies .SUFFIXES: .ml .mli .cmo .cmi .cmx %.cmi: %.mli $(OCAMLC) $(OCAMLFLAGS) -c $< %.cmo: %.ml $(OCAMLC) $(OCAMLFLAGS) -c $< %.cma: %.cmo $(OCAMLC) $(OCAMLFLAGS) -a -o $@ $^ %.cmx: %.ml $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $< %.cmxa: %.cmx $(OCAMLOPT) $(OCAMLOPTFLAGS) -a -o $@ $^ .PHONY: depend depend: .depend .depend: $(SOURCES) $(wildcard *.mli) $(OCAMLDEP) $^ > .depend include .depend ######################################################################## .PHONY: clean dist-clean clean: @ rm -f *~ .*~ *.{o,a} *.cm[aiox] *.cmxa *.annot *.exe *.com @ rm -f ex*-*.{png,plt,eps,ps,dat} dist-clean: clean rm .depend ocaml-gnuplot-0.8.3/demos/ex5.ml0000644000175000017500000000120111163137466015131 0ustar trchtrch(* $Id: ex5.ml,v 1.2 2004-11-22 19:54:26 chris_77 Exp $ *) module P = Gnuplot open Parse_args let () = let f u v = let r = sqrt(u *. u +. v *. v) in sin(r) /. r in let g = P.init ?offline:(offline 1) (device 1) in P.box3 g; P.fxy g f (-10.) 10. (-10.) 10.; P.close g let () = let sq t = t *. t in let f x y = let x2 = x *. x and y2 = y *. y in 3. *. sq(1. -. x) *. exp(-. x2 -. sq(y +. 1.)) -. 10. *. (x/.5. -. x**3. -. y**5.) *. exp(-. x2 -. y2) -. exp(-. sq(x+.1.) -. y2) /. 3. in let g = P.init ?offline:(offline 2) (device 2) in P.box3 g; P.fxy g f (-2.5) 2.5 (-2.5) 2.5; P.close g ocaml-gnuplot-0.8.3/gnuplot_functor.ml0000644000175000017500000001175311163137466016566 0ustar trchtrch(* File: gnuplot_functor.ml Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_functor.ml,v 1.6 2004-11-28 23:49:39 chris_77 Exp $ *) open Printf open Bigarray (*********************************************************************** * * FUNCTORIAL INTERFACE * ***********************************************************************) module type DATA = sig type vec val iter : (float -> unit) -> vec -> unit type vec2 val iter2 : (float -> float -> unit) -> vec2 -> unit type vec4 val iter4 : (float -> float -> float -> float -> unit) -> vec4 -> unit type mat val iter_mat : (float -> float -> float -> unit) -> vec -> vec -> mat -> unit end module type PLOT_DATA = sig type vec type vec2 type vec4 type mat include Gnuplot_common.T val x : handle -> ?tag:int -> ?style:style -> ?label:string -> ?n0:int -> vec -> unit val xy : handle -> ?tag:int -> ?style:style -> ?label:string -> vec2 -> unit val bin : handle -> ?tag:int -> ?label:string -> vec2 -> unit val vector : handle -> ?tag:int -> ?label:string -> vec4 -> unit val err : handle -> ?tag:int -> vec4 -> unit val xyz : handle -> ?tag:int -> ?style:style -> ?label:string -> vec -> vec -> mat -> unit end module Make(D : DATA) = struct type vec = D.vec type vec2 = D.vec2 type vec4 = D.vec4 type mat = D.mat include Gnuplot_common_ let data_of_float x = if is_finite x then string_of_float x else "?" let x g ?(tag=system_tag) ?(style=Lines) ?(label="") ?(n0=0) xvec = if g.closed then failwith "Gnuplot.Make().x"; let save_data out = let n = ref n0 in D.iter (fun x -> out (string_of_int !n ^ " " ^ data_of_float x ^ "\n"); incr n) xvec in let nlines = 0 (* FIXME *)in plot_data g ~inline_if:(nlines <= g.max_inline) save_data ~axes ~label ~style:(with_style g style) ~tag let xy g ?(tag=system_tag) ?(style=Lines) ?(label="") vec2 = if g.closed then failwith "Gnuplot.Make().xy"; let save_data out = D.iter2 (fun x y -> out (data_of_float x ^ " " ^ data_of_float y ^ "\n")) vec2 in let nlines = 0 (* FIXME *)in plot_data g ~inline_if:(nlines <= g.max_inline) save_data ~axes ~label ~style:(with_style g style) ~tag let bin g ?(tag=system_tag) ?(label="") vec2 = if g.closed then failwith "Gnuplot.Make().bin"; let box out xlow xup y = if is_finite xlow && is_finite xup && is_finite y then let b0 = string_of_float xlow and b1 = string_of_float xup and y = string_of_float y in out(sprintf "%s 0.\n%s %s\n%s %s\n%s 0.\n" b0 b0 y b1 y b1) else out "? ?\n" in let save_data out = let first_data = ref true and second_data = ref true and x_1 = ref neg_infinity and x0 = ref neg_infinity and y0 = ref 0. in let make_box x y = if !first_data then (first_data := false; x_1 := x; y0 := y) else if !second_data then begin second_data := false; box out (0.5 *. (3. *. !x_1 -. x)) (0.5 *. (!x_1 +. x)) !y0; x0 := x; y0 := y end else begin box out (0.5 *. (!x_1 +. !x0)) (0.5 *. (!x0 +. x)) !y0; x_1 := !x0; x0 := x; y0 := y; end in D.iter2 make_box vec2; (* Last box *) box out (0.5 *. (!x_1 +. !x0)) (0.5 *. (3. *. !x0 -. !x_1)) !y0 in let nbins = 0 (* FIXME *)in let filledcurves = (* FIXME: active axes *) "with filledcurves y1 = 0 lw " ^ string_of_float g.pen_width ^ " lt " in plot_data g ~inline_if:(4 * nbins <= g.max_inline) save_data ~axes ~label ~style:filledcurves ~tag let vector g ?(tag=system_tag) ?(label="") vec4 = if g.closed then failwith "Gnuplot.Make().vector"; let save_data out = D.iter4 (fun x y dx dy -> if is_finite x && is_finite y && is_finite dx && is_finite dy then out (sprintf "%F %F %F %F\n" x y dx dy) else out "? ? ? ?\n" ) vec4 in let nlines = 0 (* FIXME *)in plot_data g ~inline_if:(nlines <= g.max_inline) save_data ~axes ~label ~style:with_vector ~tag let err g ?(tag=system_tag) vec4 = if g.closed then failwith "Gnuplot.Make().err"; failwith "Make().err not yet implemented" let xyz g ?(tag=system_tag) ?(style=Lines) ?(label="") = if g.closed then failwith "Gnuplot.Make().xyz"; failwith "Make().xyz not yet implemented" end ocaml-gnuplot-0.8.3/gnuplot_win32.ml0000644000175000017500000001202311163137466016037 0ustar trchtrch(* File: gnuplot_win32.ml Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_win32.ml,v 1.6 2007-11-27 23:07:22 chris_77 Exp $ *) (* * Configuration ***********************************************************************) (* The gnuplot executable. You may want to set the full path to pgnuplot in [win32_gnuplot] if it isn't in your PATH. *) let gnuplot = "pgnuplot.exe" let gnuplot = "C:\\Program Files\\gnuplot\\bin\\pgnuplot.exe\\pgnuplot.exe" (* let gnuplot = "gnuplot" (* Cygwin gnuplot *) *) (* let gnuplot = "h:/anum/gp400win32/bin/pgnuplot.exe" *) (* Set to [true] if you want to use the win32 (as opposed to the X11) gnuplot program under cygwin. *) let cygwin_win32_gnuplot = true let wgnuplot_ini = "C:\\WINDOWS\\WGNUPLOT.INI" (***********************************************************************) open Printf open Gnuplot_dir (* [is_cygwin] just says if we are under cygwin. [prefix] is to be added to cygwin temp files for the win32 gnuplot to find them. *) let is_cygwin, prefix, temp_dir = match Sys.os_type with | "Win32" -> (false, "", (try Sys.getenv "TEMP" with Not_found -> ".")) | "Cygwin" -> let cygroot = if cygwin_win32_gnuplot then begin let p = Unix.open_process_in "cygpath -w /" in let root = String.escaped(input_line p) in match Unix.close_process_in p with | Unix.WEXITED 0 -> root | _ -> failwith "Gnuplot_win32: \"cygpath\" returned an error code!" end else "" in (true, cygroot, (try Sys.getenv "TMPDIR" with Not_found -> "/tmp")) | _ -> output_string stderr "Configure PLATFORM in Makefile.conf"; exit 1 let win32_gnuplot = not is_cygwin || cygwin_win32_gnuplot (* Modify WGNUPLOT.INI in the windows dirextory if possible and backup the old one. The name of the backup is returned ("" on failure). *) let change_gnuplot_ini ?pos xsize ysize color = if Sys.file_exists wgnuplot_ini then begin let (backup, fh) = Filename.open_temp_file "gp" ".ini" in let fh = open_out wgnuplot_ini in output_string fh "[WGNUPLOT]\n"; (match pos with | Some (x,y) when x >= 0 && y >= 0 -> fprintf fh "GraphOrigin=%i %i\n" x y | _ -> ()); fprintf fh "GraphSize=%.0f %.0f\n" xsize ysize; output_string fh (if color then "GraphColor=1\n" else "GraphColor=0\n"); output_string fh "GraphBackground=255 255 255\n"; output_string fh "Border=0 0 0 0 0\n"; close_out fh; backup end else begin (* Backup *) "" end let restore_gnuplot_ini backup = if backup <> "" then begin end type t = { dir : string; file : bool; mutable no : int; } let open_gnuplot_out = if win32_gnuplot then begin (* Win32 gnuplot *) fun persist ?pos xsize ysize color -> let backup = change_gnuplot_ini ?pos xsize ysize color in let gp = Unix.open_process_out (if persist then gnuplot ^ " -" else gnuplot) in restore_gnuplot_ini backup; (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = false; no = 0 }) end else begin (* Cygwin X11 gnuplot *) fun persist ?pos xsize ysize color -> let pos = match pos with | None -> "" | Some (x,y) -> Printf.sprintf "%+i%+i" x y in let pgm = Printf.sprintf "%s -noraise -geometry %.0fx%.0f%s %s %s" gnuplot xsize ysize pos (if persist then "-persist" else "") (if color then "" else "-gray") in let gp = Unix.open_process_out pgm in (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = false; no = 0 }) end let open_file_out fname = let gp = open_out fname in (gp, { dir = mk_temp_dir temp_dir "gp" ".dir"; file = true; no = 0 }) let close_out gp t = if t.file then close_out gp else match Unix.close_process_out gp with | Unix.WEXITED 0 -> remove_rec_dir t.dir | _ -> raise (Sys_error "Gnuplot ended with an error") let set_terminal_X = if win32_gnuplot then begin (* Win32 gnuplot *) fun g _ _ color -> if color then output_string g "set terminal windows color\n" else output_string g "set terminal windows monochrome\n" end else begin (* Cygwin X11 gnuplot *) let pgmname = Filename.basename Sys.argv.(0) in fun g _ _ _ -> Printf.fprintf g "set terminal x11 title \"OCaml Gnuplot: %s\"\n" pgmname end let open_temp_file t = t.no <- t.no + 1; let fname = Filename.concat t.dir (string_of_int t.no ^ ".dat") in (prefix ^ fname, open_out fname) ocaml-gnuplot-0.8.3/gnuplot_dir.ml0000644000175000017500000000373311163137466015663 0ustar trchtrch(* File: gnuplot_dir.ml Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_dir.ml,v 1.3 2004-11-28 23:49:39 chris_77 Exp $ *) open Printf let prng = Random.State.make_self_init () let mk_temp_dir temp_dir prefix suffix = let rec try_name counter = if counter >= 1000 then invalid_arg (sprintf "Gnuplot.mk_temp_dir: %S dir nonexistent or full" temp_dir); let rnd = (Random.State.bits prng) land 0xFFFFFF in let name = Filename.concat temp_dir (sprintf "%s%06x%s" prefix rnd suffix) in try Unix.mkdir name 0o700; name with Unix.Unix_error _ -> try_name (counter + 1) in try_name 0 (* [remove_rec_dir d] remove recursively the dir (or file) [d]. Errors are ignored. *) let remove_rec_dir = let rec rm dirname = match (Unix.stat dirname).Unix.st_kind with | Unix.S_DIR -> (* Remove the content of the dir recursively *) let d = Unix.opendir dirname in begin try while true do match Unix.readdir d with | "." | ".." -> () | f -> rm (Filename.concat dirname f) done with End_of_file -> () end; Unix.closedir d; Unix.rmdir dirname | _ -> Unix.unlink dirname in fun dirname -> try rm dirname with _ -> () (* let remove_rec_dir d = Printf.eprintf "temp dir = %S\n" d (\* DEBUG *\) *) ocaml-gnuplot-0.8.3/gnuplot_bigarray.ml0000644000175000017500000000622611163137466016705 0ustar trchtrch(* File: gnuplot_bigarray.ml Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_bigarray.ml,v 1.4 2007-11-27 23:07:22 chris_77 Exp $ *) open Bigarray include Gnuplot_common_ (*********************************************************************** * * BIGARRAY INTERFACE * ***********************************************************************) type 'a vec = (float, float64_elt, 'a) Array1.t type 'a mat = (float, float64_elt, 'a) Array2.t (* 2D Plots *) let is_c_layout v = Array1.layout v = (Obj.magic c_layout : 'a Bigarray.layout) let x g ?tag ?style ?label ?n0 ?ofsx ?incx (xvec:'a vec) = if is_c_layout xvec then Gnuplot_ba_c.x g ?tag ?style ?label ?n0 ?ofsx ?incx (Obj.magic xvec) else Gnuplot_ba_f.x g ?tag ?style ?label ?n0 ?ofsx ?incx (Obj.magic xvec) let xy g ?tag ?style ?label ?ofsx ?incx (xvec:'a vec) ?ofsy ?incy (yvec:'a vec) = if is_c_layout xvec then Gnuplot_ba_c.xy g ?tag ?style ?label ?ofsx ?incx (Obj.magic xvec) ?ofsy ?incy (Obj.magic yvec) else Gnuplot_ba_f.xy g ?tag ?style ?label ?ofsx ?incx (Obj.magic xvec) ?ofsy ?incy (Obj.magic yvec) let bin g ?tag ?label ?center ?ofsx ?incx (xvec:'a vec) ?ofsy ?incy (yvec:'a vec) = if is_c_layout xvec then Gnuplot_ba_c.bin g ?tag ?label ?center ?ofsx ?incx (Obj.magic xvec) ?ofsy ?incy (Obj.magic yvec) else Gnuplot_ba_f.bin g ?tag ?label ?center ?ofsx ?incx (Obj.magic xvec) ?ofsy ?incy (Obj.magic yvec) let vector g ?tag ?label ?ofsx ?incx (xvec:'a vec) ?ofsy ?incy (yvec:'a vec) ?ofsdx ?incdx (dxvec:'a vec) ?ofsdy ?incdy (dyvec:'a vec) = if is_c_layout xvec then Gnuplot_ba_c.vector g ?tag ?label ?ofsx ?incx (Obj.magic xvec) ?ofsy ?incy (Obj.magic yvec) ?ofsdx ?incdx (Obj.magic dxvec) ?ofsdy ?incdy (Obj.magic dyvec) else Gnuplot_ba_f.vector g ?tag ?label ?ofsx ?incx (Obj.magic xvec) ?ofsy ?incy (Obj.magic yvec) ?ofsdx ?incdx (Obj.magic dxvec) ?ofsdy ?incdy (Obj.magic dyvec) let err g ?tag ?(xerr:'a vec option) (xvec:'a vec) ?(yerr:'a vec option) (yvec:'a vec) = if is_c_layout xvec then Gnuplot_ba_c.err g ?tag ?xerr:(Obj.magic xerr) (Obj.magic xvec) ?yerr:(Obj.magic yerr) (Obj.magic yvec) else Gnuplot_ba_f.err g ?tag ?xerr:(Obj.magic xerr) (Obj.magic xvec) ?yerr:(Obj.magic yerr) (Obj.magic yvec) (* 3D Plots *) let xyz g ?tag ?style ?label (xvec:'a vec) (yvec:'a vec) (zmat:'a mat) = if is_c_layout xvec then Gnuplot_ba_c.xyz g ?tag ?style ?label (Obj.magic xvec) (Obj.magic yvec) (Obj.magic zmat) else Gnuplot_ba_f.xyz g ?tag ?style ?label (Obj.magic xvec) (Obj.magic yvec) (Obj.magic zmat) ocaml-gnuplot-0.8.3/gnuplot.mli0000644000175000017500000001366611163715234015177 0ustar trchtrch(* Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (** Library for scientific plotting using gnuplot. This library implements a simple interface to the gnuplot program. All functions talk to gnuplot through a pipe, so crude animations are possible. @author Christophe Troestler (chris_77\@sourceforge.net) @version 0.8.3 *) (** {2 Common functions} *) include Gnuplot_common.T (** {2 Bigarray interface} *) module Bigarray : sig include Gnuplot_common.T type 'a vec = (float, Bigarray.float64_elt, 'a) Bigarray.Array1.t type 'a mat = (float, Bigarray.float64_elt, 'a) Bigarray.Array2.t (** {3 2D Plots } *) (* FIXME: doc needs updating *) val x : handle -> ?tag:int -> ?style:style -> ?label:string -> ?n0:int -> ?ofsx:int -> ?incx:int -> 'a vec -> unit (** [x g ?style ?label ?n0 xvec] draws the points ([n0 + i], [xvec.{i}]) for [0 <= i < Array1.dim xvec] according to the style chosen. Infinite and NaN values will be shown as discontinuities (i.e., no line will join the points before and after such values). @param style style of the graph (default = [Lines]) @param label label for this graph (default: none) @param n0 x-coordinate of the first elements in [xvec] (default = index of the first element of [xvec]) *) val xy : handle -> ?tag:int -> ?style:style -> ?label:string -> ?ofsx:int -> ?incx:int -> 'a vec -> ?ofsy:int -> ?incy:int -> 'a vec -> unit (** [xy g ?style ?label xvec yvec] draws the points ([xvec.{i}], [yvec.{i}]) for [0 <= i < min(Array1.dim xvec)(Array1.dim yvec)] according to the style chosen. @param style style of the graph (default = [Lines]) @param label label for this graph (default: none) *) val bin : handle -> ?tag:int -> ?label:string -> ?center:bool -> ?ofsx:int -> ?incx:int -> 'a vec -> ?ofsy:int -> ?incy:int -> 'a vec -> unit val vector : handle -> ?tag:int -> ?label:string -> ?ofsx:int -> ?incx:int -> 'a vec -> ?ofsy:int -> ?incy:int -> 'a vec -> ?ofsdx:int -> ?incdx:int -> 'a vec -> ?ofsdy:int -> ?incdy:int -> 'a vec -> unit val err : handle -> ?tag:int -> ?xerr:'a vec -> 'a vec -> ?yerr:'a vec -> 'a vec -> unit (** {3 3D Plots} *) val xyz : handle -> ?tag:int -> ?style:style -> ?label:string -> 'a vec -> 'a vec -> 'a mat -> unit (** [xyz g ?style ?label x y z] *) (* val contour : handle -> *) end (** {2 Array interface} *) module Array : sig include Gnuplot_common.T type vec = float array type mat = float array array (** {3 2D Plots } *) val x : handle -> ?tag:int -> ?style:style -> ?label:string -> ?n0:int -> ?ofsx:int -> ?incx:int -> vec -> unit (** See {!Gnuplot.Bigarray.x} *) val xy : handle -> ?tag:int -> ?style:style -> ?label:string -> ?ofsx:int -> ?incx:int -> vec -> ?ofsy:int -> ?incy:int -> vec -> unit (** See {!Gnuplot.Bigarray.xy} *) val bin : handle -> ?tag:int -> ?label:string -> ?center:bool -> ?ofsx:int -> ?incx:int -> vec -> ?ofsy:int -> ?incy:int -> vec -> unit (** See {!Gnuplot.Bigarray.bin} *) val vector : handle -> ?tag:int -> ?label:string -> ?ofsx:int -> ?incx:int -> vec -> ?ofsy:int -> ?incy:int -> vec -> ?ofsdx:int -> ?incdx:int -> vec -> ?ofsdy:int -> ?incdy:int -> vec -> unit (** See {!Gnuplot.Bigarray.vector} *) val err : handle -> ?tag:int -> ?xerr:vec -> vec -> ?yerr:vec -> vec -> unit (** See {!Gnuplot.Bigarray.err} *) (** {3 3D Plots} *) val xyz : handle -> ?tag:int -> ?style:style -> ?label:string -> vec -> vec -> mat -> unit (** See {!Gnuplot.Bigarray.xyz} *) end (** {2 Functorial interface} *) (** REMARK: This interface should not be used if performance is crucial. *) module type DATA = sig type vec (** 1D vectors, y coordinate only *) val iter : (float -> unit) -> vec -> unit type vec2 (** 2D vectors, x and y coordinates *) val iter2 : (float -> float -> unit) -> vec2 -> unit type vec4 (** 2D vectors with additional info, x and y coordinates plus two more fields (for vector coordinates, errors,...). *) val iter4 : (float -> float -> float -> float -> unit) -> vec4 -> unit type mat (** Matrix type *) val iter_mat : (float -> float -> float -> unit) -> vec -> vec -> mat -> unit end (** The vector and matrix types together with their iterators. *) module type PLOT_DATA = sig include Gnuplot_common.T type vec type vec2 type vec4 type mat val x : handle -> ?tag:int -> ?style:style -> ?label:string -> ?n0:int -> vec -> unit (** See {!Gnuplot.Bigarray.x} *) val xy : handle -> ?tag:int -> ?style:style -> ?label:string -> vec2 -> unit (** See {!Gnuplot.Bigarray.xy} *) val bin : handle -> ?tag:int -> ?label:string -> vec2 -> unit (** See {!Gnuplot.Bigarray.bin} *) val vector : handle -> ?tag:int -> ?label:string -> vec4 -> unit (** See {!Gnuplot.Bigarray.vector} *) val err : handle -> ?tag:int -> vec4 -> unit (** See {!Gnuplot.Bigarray.err} *) val xyz : handle -> ?tag:int -> ?style:style -> ?label:string -> vec -> vec -> mat -> unit (** See {!Gnuplot.Bigarray.xyz} *) end (** The module type returned by functorial interface. *) module Make(D : DATA) : (PLOT_DATA with type vec = D.vec and type vec2 = D.vec2 and type vec4 = D.vec4 and type mat = D.mat) (** Functor building a module to plot the data types described in [D]. *) ocaml-gnuplot-0.8.3/INSTALL0000644000175000017500000000163611163170410014016 0ustar trchtrch0. Perquisites You will need * Ocaml (>= 3.07) * gnuplot (>= 4.0), unless you only want to use the "offline" feature (see the [init] function). 1. Configuration Review the variables in "Makefile.conf" to adapt them to your system. Depending on the values you chose for PLATFORM, further configuration possibilities depending on your plartform are available at the beginning of "gnuplot_unix.ml", "gnuplot_win32.ml", or "gnuplot_macos.ml". 2. Compilation make byte for the bytecode library make opt for the native code library make for both 3. Installation This step requires findlib (http://projects.camlcity.org/projects/findlib.html). make install install the library. 4. Documentation make html build the documentation in the html sudirectory The documentation is in the files "gnuplot.mli" and "gnuplot_common_export.mli". ocaml-gnuplot-0.8.3/AUTHORS0000644000175000017500000000131611163137466014046 0ustar trchtrchAuthor Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ The development of this library benefited from the help of several people: * Henri Dubois-Ferriere pushed the addition of a module for Arrays. * Alexsandro Soares fixed an escaping bug on windows. * Oleg Trott prompted me to finish the Bigarray submodule for both C and FORTRAN layouts. * José Francisco Castelo Branco asked me to make possible to select fonts. * Viktor Tron with whom I had a lot of discussions, especially regarding the file/pipe issue, animations and tags. ocaml-gnuplot-0.8.3/Makefile.conf0000644000175000017500000000164111163163661015357 0ustar trchtrch# Ocaml-Gnuplot configuration -*- Makefile -*- # Copyright (C) Christophe TROESTLER # # $(PKGNAME) and $(PKGVERSION) are defined. # The platform this library is compiled on. See also # gnuplot_$(PLATFORM).ml for further configuration. MacOSX is # considered as a unix system. # PLATFORM = unix #PLATFORM = win32 #PLATFORM = macos # OCAMLC, OCAMLOPT, OCAMLDEP, OCAMLDOC # The location of the OCaml compiler and tools. The defaults should be OK. # OCAMLC = ocamlc OCAMLOPT = ocamlopt OCAMLDEP = ocamldep OCAMLDOC = ocamldoc OCAMLFIND = ocamlfind #PREFIX=/usr/local PREFIX=/usr/local/stow/ocaml-$(PKGNAME)-$(PKGVERSION) # OCAMLLIBDIR: location of OCaml's library files. The default should be OK. # OCAMLLIBDIR = $(PREFIX)/lib/ocaml/$(shell ocamlc -version) # DOCDIR: where we will install the documentation. # DOCDIR = $(PREFIX)/doc/$(PKGNAME)-$(PKGVERSION) # Utilities # COPY = cp #COPY = copy ocaml-gnuplot-0.8.3/gnuplot_sys.mli0000644000175000017500000000377011163137466016075 0ustar trchtrch(* File: gnuplot_unix.mli Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_sys.mli,v 1.4 2007-11-27 23:07:22 chris_77 Exp $ *) type t (** Abstract type to hold additional information for the gnuplot process handler. This information is specific to an instance of gnuplot. *) val open_gnuplot_out : bool -> ?pos:int * int -> float -> float -> bool -> out_channel * t (** [open_gnuplot_out persist ?xpos ?ypos xsize ysize color] opens a gnuplot process. The arguments [xsize], [ysize], and [color] are only relevant for "X" terminals. *) val open_file_out : string -> out_channel * t (** [open_file_out fname] opens the file [fname] for writing. Returns a channel to write and the necessary information to be able to close it with [close_out] -- so the return value is indistinguishable from the one of [open_gnuplot_out]. *) val close_out : out_channel -> t -> unit (** [close_out g t] closes the gnuplot process and free the associated ressources. @raise Sys_error if a problem occurs when closing. *) val set_terminal_X : out_channel -> float -> float -> bool -> unit (** [open_out g xsize ysize color] set the terminal according to the platform. *) val open_temp_file : t -> string * out_channel (** [open_temp_file t] creates a temporary file and open it for writing according to the information in [t]. Returns its name and an output channel to it. *) ocaml-gnuplot-0.8.3/gnuplot_common_.ml0000644000175000017500000015413611163673007016534 0ustar trchtrch(* Copyright (C) 2001-2009 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (********************************************************************** * * Data structures & basic functions * **********************************************************************) open Printf type color = int exception Exit of Unix.process_status let is_finite x = match classify_float x with | FP_infinite | FP_nan -> false | _ -> true (* [force_show gp] force the drawing of axes, tics,... by plotting an "empty" file. That will only work IF the RANGES have been SET. Beware that, unless multiplot mode is on, this will also erase all the plots. (Note that the missing symbol must be declared as "?".) *) let force_show gp = output_string gp "plot '-' title \"\"\n? ?\ne;\n" (* * Plot history **********************************************************************) (* Plots will be grouped by tags. When no tag is provided, the system one will be assigned -- which implies that by default the plots will be managed automatically by the system. *) type tag = int module Tags = Map.Make(struct type t = tag let compare (x:tag) y = compare x y end) type tag_state = | Managed (* Visible and the system determines if replot is needed *) | Visible (* Set visible by user -- only reploted if the user ask for it *) | Hidden (* Erased, not on display anymore *) | To_show (* scheduled to make Visible -- by [show] or a plot command *) | To_hide (* scheduled to erase *) (* Experiments show that passing the data through the pipe to gnuplot is not efficient unless there are very few lines of data. *) type data = | Inlined of string (* data in the form "line1\nline2\n...\ne\n" *) | File of string (* filename containing the data *) type plot = string * float * int * color * data (* [(cmd, lw, lt, color, data)] where [cmd] is something like ["\"datafile\" axes x1y2 title \"\" with pt 1 ps 2"], [lw] is the line width, and [lt] the value of the linetype of the plot. The gnuplot command to show such a plot is therefore [sprintf "plot %s lw %F lt %i" cmd lw lt]. If the [data] is inlined, one must follow the command "plot..." with the data in the same order than the '-'. *) type text = string * int (* [(cmd, gp_tag)] where [cmd] is something like ["set label \"...\" ... tc lt 2"] and [gp_tag] is the gnuplot tag (NOT the tag of this library) and we will subsequently refer to it as the label number. *) type plots = { mutable state : tag_state; plots : plot Queue.t; texts : text Queue.t; } (* [string_of_queue init q] will add to [init] (assumed to end with ",") the instructions to plot all data in the queue [q]. *) let string_of_queue init q = Queue.fold (fun cmd (s, lw, lt, color, _) -> sprintf "%s%s lw %F lt %i %s," cmd s lw lt (if color >= 0 then sprintf "lc rgb \"#%X\"" color else "") ) init q.plots (* NOTE: The border linewidth (-1) is by default twice as fat as the other ones. Scale appropriately when erasing. *) let string_of_queue_hide init q = Queue.fold (fun cmd (s, lw, lt, color, _) -> let lw = if color >= 0 && lt = -1 then 2. *. lw else lw in sprintf "%s%s lw %F lt -2," cmd s lw) init q.plots let ouput_texts gp q = Queue.iter (fun (cmd, _) -> output_string gp cmd; output_char gp '\n') q.texts (* [show_plot_queue s_of_q plot gp q] send to [gp] the command to plot all the graphs in the queue [q]. [plot] is either "plot " or "splot " (note the trailing space). REMARK: the linetype "-2" has the color of the background. *) let show_or_hide_plot_queue s_of_q plot gp q= if Queue.is_empty q.plots then force_show gp else begin let cmd = s_of_q plot q in cmd.[String.length cmd - 1] <- '\n'; output_string gp cmd; (* Inline data *) Queue.iter (function | (_, _, _, _, Inlined d) -> output_string gp d | _ -> ()) q.plots end let show_plot_queue = show_or_hide_plot_queue string_of_queue let hide_plot_queue = show_or_hide_plot_queue string_of_queue_hide (* [empty_plot_queue q] frees all data and temp files for queue [q]. *) let empty_plot_queue q = Queue.iter (function | (_, _, _, _, File f) -> (try Unix.unlink f with _ -> ()) | _ -> ()) q.plots; Queue.clear q.plots type plot_history = plots Tags.t (* [show_plots_all_tags plots gp sp] will send the command to the channel [gp] to redraw all the (visible) plots of the subpages [sp] starting with no plots. As we may be in autoscale mode, one must group all plots into a _single_ plot instruction to ensure Gnuplot sets the ranges correctly (otherwise, several ranges may superimpose). *) let show_plots_all_tags = let add_queue init q = match q.state with | Managed | Visible -> string_of_queue init q | To_show -> (q.state <- Visible; string_of_queue init q) | Hidden -> init | To_hide -> (q.state <- Hidden; init) in fun plot gp history -> let cmd = Tags.fold (fun _ q cmd -> add_queue cmd q) history "" in if cmd = "" then force_show gp (* FIXME: does not work if ranges are not set (see update_show) *) else begin cmd.[String.length cmd - 1] <- '\n'; output_string gp plot; output_string gp cmd; (* Inline data *) Tags.iter (fun _ q -> Queue.iter (function | (_, _, _, _, Inlined d) -> output_string gp d | _ -> ()) q.plots ) history end (* Maximum number of lines of data for it to be inlined; if the data has more than [max_inline] lines, a temporary file is created. The following value has been determined experimentally. *) let max_inline = 6 (* The tag for system managed plots. It will stay in the state [Managed] and not be accessible to the user. *) let system_tag = 0 (* Axes **********************************************************************) (* Axis of a box. Each axis is independent of the others and consists of the following characteristics: *) type axis = { mutable draw : bool; (* whether to draw the border *) mutable draw_top : bool;(* whether to draw the top border (3D) *) mutable zero : bool; (* whether to draw the zero axis *) mutable min : float; (* [min:max] interval for that axis *) mutable max : float; (* +- infty means autoscale *) mutable tics : bool; (* whether to draw major tics *) (* FIXME: tics on zeroaxis??? *) mutable tics_step : float; (* <= 0 means automatic *) mutable mtics : int; (* how many minor tics *) mutable format : string;(* tics labels format; "" = no label *) mutable format_rot : bool; (* true if rotate the label *) mutable format_font : string; (* font of tics labels, ex: ["Arial,12"] *) mutable format_lt : int; (* gnuplot linetype; color of tics labels *) mutable format_color : color; (* color (if >=0, supersedes _lt) *) mutable grid : bool; (* whether a grid is drawn at each major tic *) mutable mgrid : bool; (* whether a grid is drawn at each minor tic *) mutable logscale : bool;(* whether to put label logarithmically *) mutable active : bool; (* whether the axis is "active" -- labelled by the *last* [box] command *) mutable label : string; (* label for that axis with style (except color), e.g. ["\"x\" font \"Helvetica,default\""] ("\"\"" = none) *) mutable label_lt : int; (* the integer is the linetype (gives the color of the text). *) mutable label_color : color; (* color of the label; supersede [label_lt]. *) mutable label_nlines : int; (* number of lines of the label *) mutable label_shown : bool; (* Whether the label has been displayed (i.e. set + plot) *) mutable label_old : string; (* The currently _displayed_ label to erase (and to replace with [label]). "" means nothing to erase. *) } (* Subpages parameters & basic funtions **********************************************************************) (* Each subpage determines an area where the plotting takes place. Unfortunately Gnuplot makes it impossible to correctly set a viewport ("box" where the graphs are plotted). First, margins units are chars width and heights (that could be worked around) but more importantly they do not obey to fractional sizes (e.g. set bmargin 1.4). As a consequence, one has to let Gnuplot choose the viewport. That implies one must be careful when to redraw the entire graph: indeed, each plot command will redraw the box,... according to the current parameters -- we must therefore keep the entire history. *) type subpage = { set_subpage : string; (* gnuplot cmd to set the position of the subpage *) subpage_xmin : float; (* The coordinates of the subpage; *) subpage_ymin : float; (* the dims are hold in the handle since they are the same for all subpages. *) mutable redraw : bool; (* This flag indicates whether the entire plot must be redrawn. *) mutable xmin : float; (* Since the range is set with [win] before [box] *) mutable xmax : float; (* can set the active axes, we need a way to store *) mutable ymin : float; (* the current coordinates. +-infty = autoscale *) mutable ymax : float; x1 : axis; (* bottom *) x2 : axis; (* top *) y1 : axis; (* left *) y2 : axis; (* right *) mutable tics_outwards : bool; (* whether tics are drawn outward. This is global under gnuplot. *) mutable title : string; (* title -- see [label] above. *) mutable title_nlines : int; mutable title_lt : int; mutable title_color: color; (* RGB color, if >=0, supersede title_lt *) mutable title_shown : bool; mutable title_old : string; mutable text_number : int; (* the next text number to use for gnuplot in "set label ..." commands. *) mutable tags : plot_history; (* history of plotting commands *) mutable plot3D : bool; (* says whether the current plot is 3D *) mutable zmin : float; mutable zmax : float; z1 : axis; (* vertical direction for 3D *) z2 : axis; (* "front" vertical direction (not everything is used) *) } (* [add_plot_with_tag sp t plot] add the plot [plot] to the tag [t] in the subpage [sp]. The queue is returned for possible further processing. The tag is created with [Hidden] state if necessary. The reasoning for the default state [Hidden] is that tagging plots is often used to group them, hence the display should take place after all the plots have been tagged. *) let add_plot_with_tag sp t plot = try let q = Tags.find t sp.tags in Queue.add plot q.plots; q with Not_found -> let pl = Queue.create() in Queue.add plot pl; let q = { state = Hidden; plots = pl; texts = Queue.create() } in sp.tags <- Tags.add t q sp.tags; q (* [add_text_with_tag sp t text] does the same as [add_plot_with_tag] but for text instead of plots. *) let add_text_with_tag sp t text = try let q = Tags.find t sp.tags in Queue.add text q.texts; q with Not_found -> let txt = Queue.create() in Queue.add text txt; let q = { state = Hidden; plots = Queue.create(); texts = txt } in sp.tags <- Tags.add t q sp.tags; q (* [update_labels gp sp] sends the Gnuplot commands through [gp] to carefully erase (immediately) the old the labels and title and set the new ones. This will in 2D and 3D but only work if the ranges are set and border, tics,... are unchanged. *) let update_labels = let erz_label gp modif xy a = if a.label_old <> "" then begin fprintf gp "set %slabel %s tc lt -2;" xy a.label_old; modif := true end in let new_label gp xy a = if a.label_old <> "" then begin fprintf gp "set %slabel %s tc %s;" xy a.label (if a.label_color >= 0 then sprintf "rgb \"#%X\"" a.label_color else sprintf "lt %i" a.label_lt); a.label_old <- "" end in fun gp sp -> (* Erase old labels *) let modif = ref false in erz_label gp modif "x" sp.x1; erz_label gp modif "x2" sp.x2; erz_label gp modif "y" sp.y1; erz_label gp modif "y2" sp.y2; erz_label gp modif "z" sp.z1; if sp.title_old <> "" then begin fprintf gp "set title %s tc lt -2;\n" sp.title_old; modif := true end; if !modif then begin force_show gp; (* force erasing only if modif to do *) (* Set new labels -- for those erased only *) new_label gp "x" sp.x1; new_label gp "x2" sp.x2; new_label gp "y" sp.y1; new_label gp "y2" sp.y2; new_label gp "z" sp.z1; if sp.title_old <> "" then begin fprintf gp "set title %s tc %s;\n" sp.title (if sp.title_color >= 0 then sprintf "rgb \"#%X\"" sp.title_color else sprintf "lt %i" sp.title_lt); sp.title_old <- "" end end let range_of_float f = if is_finite f then string_of_float f else "*" (* [set_box2D gp sp] sends the Gnuplot commands to [gp] to set the box, axes, and title according to the information in the subpage [sp]. Only the labels that are UNCHANGED are set, the other ones will be set after the old ones are deleted. This information needs to be resent to Gnuplot when one changes subpages for example. *) let set_box2D gp sp = output_string gp (if sp.tics_outwards then "set tics out;" else "set tics in;"); let borders = (if sp.x1.draw then 1 else 0) + (if sp.x2.draw then 4 else 0) + (if sp.y1.draw then 2 else 0) + (if sp.y2.draw then 8 else 0) in output_string gp ("set border " ^ (string_of_int borders) ^ ";\n"); let axis xy a = let setxy = "set " ^ xy and unsetxy = "unset " ^ xy in output_string gp ((if a.zero then setxy else unsetxy) ^ "zeroaxis;"); fprintf gp "set %srange [%s:%s];" xy (range_of_float a.min) (range_of_float a.max); if a.tics then fprintf gp "set %stics border nomirror %srotate %s font \"%s\" tc %s;" xy (if a.format_rot then "" else "no") (if a.tics_step <= 0. then "" else string_of_float a.tics_step) a.format_font (if a.format_color >= 0 then sprintf "rgb \"#%X\"" a.format_color else sprintf "lt %i" a.format_lt) else output_string gp (unsetxy ^ "tics;"); if a.mtics > 0 then fprintf gp "set m%stics %i;" xy a.mtics else fprintf gp "unset m%stics;\n" xy; fprintf gp "set format %s %S;\n" xy a.format; fprintf gp "set grid %s%stics %sm%stics front;" (if a.grid then "" else "no") xy (if a.mgrid then "" else "no") xy; output_string gp ((if a.logscale then "set logscale " else "unset logscale ") ^ xy ^ ";"); if a.label_old = "" then begin fprintf gp "set %slabel %s tc %s;\n" xy a.label (if a.label_color >= 0 then sprintf "rgb \"#%X\"" a.label_color else sprintf "lt %i" a.label_lt); a.label_shown <- true end in axis "x" sp.x1; axis "x2" sp.x2; axis "y" sp.y1; axis "y2" sp.y2; if sp.title_old = "" then fprintf gp "set title %s tc %s;\n" sp.title (if sp.title_color >= 0 then sprintf "rgb \"#%X\"" sp.title_color else sprintf "lt %i" sp.title_lt) (* [set_box3D gp sp] is the same as [set_box2D] but for 3D plots. *) let set_box3D gp sp = output_string gp (if sp.tics_outwards then "set tics out;" else "set tics in;"); (* BEWARE: the borders are not linked to axes but to the view; set a view so that they initially correspond. *) output_string gp "set view 56,43;"; let borders = (if sp.x1.draw then 1 else 0) + (if sp.x2.draw then 8 else 0) + (if sp.y1.draw then 2 else 0) + (if sp.y2.draw then 4 else 0) + (if sp.x1.draw_top then 1024 else 0) + (if sp.x2.draw_top then 512 else 0) + (if sp.y1.draw_top then 256 else 0) + (if sp.y2.draw_top then 2048 else 0) + (if sp.z1.draw then 16 else 0) + (if sp.z1.draw_top then 128 else 0) + (if sp.z2.draw then 32 else 0) + (if sp.z2.draw_top then 64 else 0) in output_string gp ("set border " ^ (string_of_int borders) ^ ";\n"); let axis xy a a2 = (* let setxy = "set " ^ xy in *) let unsetxy = "unset" ^ xy in fprintf gp "set %srange [%s:%s];" xy (range_of_float a.min) (range_of_float a.max); if a.tics then fprintf gp "set %stics border %smirror %s font \"%s\" tc %s;" xy (if a2.tics then "" else "no") (if a.tics_step <= 0. then "" else string_of_float a.tics_step) a.format_font (if a.format_color >= 0 then sprintf "rgb \"#%X\"" a.format_color else sprintf "lt %i" a.format_lt) else output_string gp (unsetxy ^ "tics;"); if a.mtics > 0 then fprintf gp "set m%stics %i;" xy a.mtics else fprintf gp "unset m%stics;" xy; fprintf gp "set format %s %S;" xy a.format; fprintf gp "set grid %s%stics %sm%stics front;" (if a.grid then "" else "no") xy (if a.mgrid then "" else "no") xy; output_string gp ((if a.logscale then "set logscale " else "unset logscale ") ^ xy ^ ";"); if a.label_old = "" then begin fprintf gp "set %slabel %s tc %s;\n" xy a.label (if a.label_color >= 0 then sprintf "rgb \"#%X\"" a.label_color else sprintf "lt %i" a.label_lt); a.label_shown <- true end in axis "x" sp.x1 sp.x2; axis "y" sp.y1 sp.y2; axis "z" sp.z1 sp.z2; if sp.title_old = "" then fprintf gp "set title %s tc %s;\n" sp.title (if sp.title_color >= 0 then sprintf "rgb \"#%X\"" sp.title_color else sprintf "lt %i" sp.title_lt) (* [is_autoscaled2D sp] says whether an axis is autoscaled. This is important to know whether the entire plot must be redrawn. *) let is_autoscaled2D = let axis a = is_finite a.min && is_finite a.max in fun sp -> not(axis sp.x1 && axis sp.x2 && axis sp.y1 && axis sp.y2) let is_autoscaled3D = let axis a = is_finite a.min && is_finite a.max in fun sp -> not(axis sp.x1 && axis sp.x2 && axis sp.y1 && axis sp.y2 && axis sp.z1) (* [moveto_subpage gp sp] sends the Gnuplot commands through [gp] to define the subpage [sp] "area" and reset its parameters -- but does NOT clear it; this is the task of the plotting command. *) let moveto_subpage gp sp = output_string gp sp.set_subpage; if sp.plot3D then set_box3D gp sp else set_box2D gp sp; (* Set subpage labels that must be visible -- the [To_show] will be updated later. *) output_string gp "unset label;\n"; Tags.iter (fun _ q -> match q.state with | Managed | Visible -> ouput_texts gp q | _ -> ()) sp.tags (* Gnuplot handle **********************************************************************) type handle = { to_gplot : out_channel; (* channel to send commands to gnuplot *) gp_extra : Gnuplot_sys.t; mutable closed : bool; (* says whether the handle is closed. FIXME: Every function should check this first. *) interactive : bool; (* if true, the commands are issued immediately to gnuplot. *) max_inline : int; (* maximum of lines that are inlined (sent through the pipe); if there are more lines, a temp file is created. *) buf_inline : Buffer.t; (* buffer to hold the plot loop -- 1 per session *) newpage : string; (* gnuplot cmd to be issued to start a new page FIXME: reevaluate whether it is needed. *) nxsub : int; nysub : int; (* number of subpages in x and y directions *) subw : float; subh : float; (* width and height of subpages *) mutable sub : int; (* current subpage number: 0,..., nxsub*nysub - 1 *) subpage : subpage array; (* of length nxsub*nysub *) mutable pen : int; (* Current pen *) mutable color : color; (* Current active color (if >=0, otherwise use pen) *) mutable pen_width : float; (* Current pen width *) mutable point : int; (* Current point type *) mutable point_width : float; (* Current point width *) mutable font : string; (* Current font ("" = default) *) mutable font_size : int; (* Current font size *) } let string_of_font g = g.font ^ (if g.font_size <= 0 then "" else "," ^ string_of_int g.font_size) (* * Output devices **********************************************************************) type device = | X | Wxt | PS of string (* Postscript *) | EPS of string (* Encapsulated PostScript *) | EPSLaTeX of string (* picture environment including a PS file *) | FIG of string (* Xfig format *) | PNG of string (* Portable Network Graphics *) | MP of string (* Metapost *) | MF of string (* Metafont *) | SVG of string (* Scalable Vector Graphics *) let device_of_filename file = let suffix_is = Filename.check_suffix file in if suffix_is ".ps" then PS(file) else if suffix_is ".eps" then EPS(file) else if suffix_is ".tex" then EPSLaTeX(file) else if suffix_is ".fig" then FIG(file) else if suffix_is ".png" then PNG(file) else if suffix_is ".mp" then MP(file) else if suffix_is ".mf" then MF(file) else if suffix_is ".svg" then SVG(file) else failwith "Gnuplot.device_of_filename" (* * Plots management **********************************************************************) (* See [update_show] for a description. This function implements the main logic for updating plots, labels,... *) let update_show_generic sp ~plot_cmd ~redraw ~set_box ?add_plot g = (* If we are not in interactive mode, the plots are made at newpages so there is never anything to update. *) if g.interactive then begin if redraw sp then begin sp.redraw <- false; (* Clear *) if g.nxsub = 1 && g.nysub = 1 then output_string g.to_gplot g.newpage else output_string g.to_gplot "clear;\n"; (* All labels and plots have just been erased; mark them as such. Redraw box and all [Managed], [Visible], [To_show] plots. We need to redraw them as a single plot command to avoid superimposing (multiplot) multiple ranges (autoscale) on the same plot. *) sp.x1.label_old <- ""; sp.x2.label_old <- ""; sp.y1.label_old <- ""; sp.y2.label_old <- ""; sp.z1.label_old <- ""; sp.title_old <- ""; begin match add_plot with | Some(t,plot) -> ignore(add_plot_with_tag sp t plot); | None -> () end; set_box g.to_gplot sp; show_plots_all_tags plot_cmd g.to_gplot sp.tags; flush g.to_gplot end else begin (* Erase carefully labels and plots *) update_labels g.to_gplot sp; let del_sth = Tags.fold (fun _ q del -> match q.state with | To_hide -> hide_plot_queue plot_cmd g.to_gplot q; q.state <- Hidden; true | _ -> del) sp.tags false in (* Redraw managed plots (in case erasing destroyed them). *) if del_sth then Tags.iter (fun _ q -> match q.state with | Managed -> show_plot_queue plot_cmd g.to_gplot q | _ -> ()) sp.tags; (* Add the new plot (if any) and possibly show it. *) begin match add_plot with | Some(t, ((s, lw, lt, color, data) as plot)) -> let q = add_plot_with_tag sp t plot in begin match q.state with | Managed | Visible -> fprintf g.to_gplot "%s %s lw %F lt %i%s;\n" plot_cmd s lw lt (if color >= 0 then sprintf "lc rgb \"#%X\"" color else ""); (match data with | Inlined d -> output_string g.to_gplot d | _ -> ()) | _ -> () end | None -> () end; (* We also need to process any waiting plots. However, we do not replot the [Visible] plots, they are under user's control. *) Tags.iter (fun _ q -> match q.state with | To_show -> show_plot_queue plot_cmd g.to_gplot q; q.state <- Visible | _ -> ()) sp.tags; flush g.to_gplot end end else begin (* Not interactive mode, just add the plot *) match add_plot with | Some(t,plot) -> ignore(add_plot_with_tag sp t plot); | None -> () end (* [update_show ?add_plot g] will update the display of the plots. That is any plot waiting to be erased or to be shown will be. Managed plots may be re-plotted if needed. @param add_plot must be a couple (tag, plot). If present, the plot will be added to the tag (the latter will be created if necessary) and displayed according to the state of the tag. *) let update_show ?add_plot g = let sp = g.subpage.(g.sub) in if sp.plot3D then update_show_generic sp ?add_plot g ~plot_cmd:"splot" ~redraw:(fun sp -> sp.redraw || is_autoscaled3D sp) ~set_box:set_box3D else update_show_generic sp ?add_plot g ~plot_cmd:"plot" ~redraw:(fun sp -> sp.redraw || is_autoscaled2D sp) ~set_box:set_box2D (* * Gnuplot initializing, closing and (sub)pages **********************************************************************) let inches_per_mm = 1. /. 25.4 let string_of_current_time () = let t = Unix.localtime(Unix.time()) in sprintf "%4i-%02i-%02i %i:%02i:%02i" (1900 + t.Unix.tm_year) (1 + t.Unix.tm_mon) t.Unix.tm_mday t.Unix.tm_hour t.Unix.tm_min t.Unix.tm_sec let init ?offline ?(max_inline=max_inline) ?(persist=true) ?(color=true) ?(nxsub=1) ?(nysub=1) ?xsize ?ysize ?(aspect=1.) dev = (* Get the sizes *) let (xsize, ysize) = match xsize, ysize with | Some(x), Some(y) -> if x <= 0. then invalid_arg "Gnuplot.init: xsize <= 0" else if y <= 0. then invalid_arg "Gnuplot.init: ysize <= 0" else (x,y) | Some(x), None -> if x <= 0. then invalid_arg "Gnuplot.init: xsize <= 0" else if aspect <= 0. then invalid_arg "Gnuplot.init: aspect <= 0" else (x, aspect *. x) | None, Some(y) -> if aspect <= 0. then invalid_arg "Gnuplot.init: aspect <= 0" else if y <= 0. then invalid_arg "Gnuplot.init: ysize <= 0" else (y /. aspect, y) | None, None -> let x = match dev with | X | Wxt | PNG _ | SVG _ -> 550. (* pixels *) | PS _ | EPS _ | EPSLaTeX _ | MP _ | MF _ | FIG _ -> 100. (* milimeters *) in if aspect <= 0. then invalid_arg "Gnuplot.init: aspect <= 0" else (x, aspect *. x) in (* Open a pipe to gnuplot *) let (gp, extra), offline = match offline with | None -> Gnuplot_sys.open_gnuplot_out persist xsize ysize color, false | Some(plt) -> Gnuplot_sys.open_file_out plt, true in (* Global settings *) if offline then fprintf gp "# Generated by OCaml Gnuplot module on %s.\n" (string_of_current_time()); output_string gp "set locale \"C\";\n"; output_string gp "set encoding iso_8859_1;\n"; output_string gp "set decimalsign '.';\n"; output_string gp "set datafile missing \"?\";\n"; output_string gp "set zero 0.0;\n"; output_string gp "set hidden3d;\n"; (* FIXME: must be more subtle *) (* Set device, output and size *) let scolor = if color then "color" else "monochrome" in let set_output s = fprintf gp "set output %S;\n" s in let w, h, default_font = match dev with | X -> (* Not setting the terminal amounts to select the default one which is what we want for offline output to be able to (e.g.) play on windows a script made on Unix. *) if not offline then Gnuplot_sys.set_terminal_X gp xsize ysize color; (* no need to set output *) (1., 1., "default") | Wxt -> let pgmname = Filename.basename Sys.argv.(0) in fprintf gp "set term wxt title \"OCaml Gnuplot: %s\" enhanced \ %spersist noraise;\n" pgmname (if persist then "" else "no"); (1., 1., "default") | PS(s) -> if xsize >= ysize then begin fprintf gp "set terminal postscript landscape enhanced %s;\n" scolor; set_output s; (* default size 10x7 inches *) (xsize /. 10. *. inches_per_mm, ysize /. 7. *. inches_per_mm, "Helvetica") end else begin fprintf gp "set terminal postscript portrait enhanced %s;\n" scolor; set_output s; (* default size 7x10 inches *) (xsize /. 7. *. inches_per_mm, ysize /. 10. *. inches_per_mm, "Helvetica") end | EPS(s) -> fprintf gp "set terminal postscript eps enhanced %s;\n" scolor; set_output s; (xsize /. 10. *. inches_per_mm, ysize /. 7. *. inches_per_mm, "Helvetica") | EPSLaTeX (tex) -> let eps = (Filename.chop_suffix tex ".tex") ^ ".eps" in fprintf gp "set terminal epslatex %s dashed;\n" scolor; set_output eps; (* default size 5x3 inches *) (xsize /. 5. *. inches_per_mm, ysize /. 3. *. inches_per_mm, "default") | FIG(s) -> fprintf gp "set terminal fig %s size %.15g %.15g metric dashed \ textnormal depth 50;\n" scolor (xsize /. 10.) (ysize /. 10.); (* fig: size in centimeters *) set_output s; (1., 1., "default") | PNG(s) -> fprintf gp "set terminal png transparent medium size %.0f,%0.f enhanced;\n" xsize ysize; set_output s; (1., 1., "medium") | MP(s) -> fprintf gp "set terminal mp %s dashed tex;\n" scolor; set_output s; (* default size 5x3 inches *) (xsize /. 5. *. inches_per_mm, ysize /. 3. *. inches_per_mm, "cmr10") | MF(s) -> fprintf gp "set terminal mf;\n"; set_output s; (* default size 5x3 inches *) (xsize /. 5. *. inches_per_mm, ysize /. 3. *. inches_per_mm, "cmr10") | SVG(s) -> fprintf gp "set terminal svg size %F %F dynamic enhanced;\n" xsize ysize; set_output s; (1., 1., "Arial") in fprintf gp "set size %.15g,%.15g;\n" w h; (* Several plots per page ? *) let nxsub = max nxsub 1 and nysub = max nysub 1 in let nsub = nxsub * nysub and subw = w /. float nxsub and subh = h /. float nysub in let begin_new_page = sprintf "set multiplot;%sset size %.15g,%.15g;\n" (match dev with | MP _ | MF _ -> (* Get the size of the output right even if all the subpages are not used. *) sprintf "set size %.15g,%.15g; clear;" w h | _ -> "") subw subh in let make_axis () = (* BEWARE: this a a mutable structure, so one must create a different instance of it for each axis. *) { draw = false; (* must explicitely ask for axes *) draw_top = false; zero = false; min = neg_infinity; max = infinity; (* autoscale *) tics = false; tics_step = 0.; mtics = 0; format = ""; format_rot = false; format_font = default_font; (* no font size <==> default size *) format_lt = -1; (* border color *) format_color = -1; (* invalid color (as long as "lt" is possible) *) grid = false; mgrid = false; logscale = false; active = true; label = "\"\""; (* empty label <==> none *) label_nlines = 0; label_lt = -1; (* border color *) label_color = -1; (* invalid color (as long as "lt" is possible) *) label_shown = false; label_old = ""; (* nothing to erase *) } in let make_subpage i = (* The subpages are counted horizontally, the top left one having number [i=0]. *) let xmin = float (i mod nxsub) *. subw and ymin = float (nysub - 1 - i / nxsub) *. subh in { subpage_xmin = xmin; subpage_ymin = ymin; set_subpage = sprintf "set origin %.15g,%.15g;\n" xmin ymin; redraw = false; xmin = neg_infinity; xmax = infinity; ymin = neg_infinity; ymax = infinity; x1 = make_axis(); x2 = make_axis(); y1 = make_axis(); y2 = make_axis(); tics_outwards = false; title = "\"\""; (* empty title <==> no title *) title_nlines = 0; title_lt = -1; (* color of border *) title_color = -1; (* invalid color (as long as "lt" is possible) *) title_shown = false; title_old = ""; (* no previous title *) text_number = 1; (* The lower "label tag" number accepted by gnuplot *) tags = Tags.add system_tag { state = Managed; plots = Queue.create(); texts = Queue.create(); } Tags.empty; (* default queue only *) plot3D = false; zmin = neg_infinity; zmax = infinity; z1 = make_axis(); z2 = make_axis(); } in let handle = { to_gplot = gp; gp_extra = extra; closed = false; interactive = (dev = X || dev = Wxt); max_inline = if offline then max_int else max_inline; buf_inline = Buffer.create (max_inline * 34); newpage = "unset multiplot;\n" ^ begin_new_page; (* subpages *) nxsub = nxsub; nysub = nysub; subw = subw; subh = subh; sub = 0; subpage = Array.init nsub make_subpage; (* Pen & fonts defaults *) pen = -1; (* border color *) color = -1; (* invalid color, must be >=0 to be active *) pen_width = 1.; point = 1; point_width = 1.; font = default_font; font_size = 0; (* ==> default *) } in (* Initialize 1st page *) output_string gp begin_new_page; (* Prepare the 1st subpage if interactive *) if handle.interactive then begin moveto_subpage gp handle.subpage.(handle.sub); flush gp; end; (* Return handle *) handle let close g = if not g.closed then begin g.closed <- true; if g.interactive then update_show g else (* Issue the plotting commands for the last page now *) Array.iter (fun sp -> moveto_subpage g.to_gplot sp; show_plots_all_tags (if sp.plot3D then "splot " else "plot ") g.to_gplot sp.tags) g.subpage; output_string g.to_gplot "unset multiplot;\n"; flush g.to_gplot; try Gnuplot_sys.close_out g.to_gplot g.gp_extra (* This also removes the temp dir containing the data files. *) with Sys_error _ -> failwith "Gnuplot.close" end let adv ?sub g = if g.closed then failwith "Gnuplot.adv"; let nsub = g.nxsub * g.nysub in let sub = match sub with | None -> g.sub + 1 | Some i -> if i < 1 then nsub else i - 1 in if sub >= nsub then begin (* Start a fresh new page at the first subpage *) if not g.interactive then (* Issue the plotting commands for the current page now *) Array.iter (fun sp -> moveto_subpage g.to_gplot sp; show_plots_all_tags (if sp.plot3D then "splot " else "plot ") g.to_gplot sp.tags) g.subpage; output_string g.to_gplot g.newpage; (* We start with a blank page, so everything is erased. *) (* FIXME: restore instead to default (init) state? *) Array.iter (fun sp -> sp.x1.label_old <- ""; sp.x2.label_old <- ""; sp.y1.label_old <- ""; sp.y2.label_old <- ""; sp.z1.label_old <- ""; sp.title_old <- ""; Tags.iter (fun _ q -> match q.state with | Managed | To_hide -> empty_plot_queue q; q.state <- Hidden (* FIXME: One may want to replot tagged plots so keep them ? *) | _ -> ()) sp.tags; ) g.subpage; g.sub <- 0; end else g.sub <- sub; if g.interactive then (* Go to the subpage [sub] and re-set its parameters. *) moveto_subpage g.to_gplot g.subpage.(g.sub) let clear g = if g.closed then failwith "Gnuplot.clear"; if g.interactive then begin output_string g.to_gplot "clear;\n"; flush g.to_gplot end; let sp = g.subpage.(g.sub) in (* All plots in the system_queue are destroyed. *) let q = Tags.find system_tag sp.tags in empty_plot_queue q; (* Update [To_hide] status to [Hidden] *) Tags.iter (fun _ q -> match q.state with | To_hide -> q.state <- Hidden | _ -> ()) sp.tags (* * Tag management **********************************************************************) let tag_manage g fn_name ?tag immediately ~state = if g.closed then failwith fn_name; begin match tag with | None -> () | Some t -> if t = system_tag then invalid_arg (fn_name ^ ": cannot change the system tag"); (* Set the tag to the proper To_* state *) let sp = g.subpage.(g.sub) in try let q = Tags.find t sp.tags in q.state <- state with Not_found -> sp.tags <- Tags.add t { state = state; plots = Queue.create(); texts = Queue.create(); } sp.tags end; (* Update display -- and possibly process the given tag *) if immediately then update_show g let show ?(immediately=true) ?tag g = tag_manage g "Gnuplot.show" ?tag immediately ~state:To_show let hide ?(immediately=false) ?tag g = tag_manage g "Gnuplot.hide" ?tag immediately ~state:To_hide let auto ~tag g = tag_manage g "Gnuplot.auto" ~tag false ~state:Managed let free ~tag g = if g.closed then failwith "Gnuplot.free"; if tag = system_tag then invalid_arg "Gnuplot.free: cannot change the system tag"; try let q = Tags.find tag g.subpage.(g.sub).tags in empty_plot_queue q with Not_found -> () (* no tag [t], ignore *) (* * Pens, colors and fonts **********************************************************************) let pen g i = if g.closed then failwith "Gnuplot.pen: handle closed"; g.pen <- i let color g c = if g.closed then failwith "Gnuplot.color: handle closed"; if c < 0 || c > 0xFFFFFF then invalid_arg "Gnuplot.color"; g.color <- c let pen_width g w = if g.closed then failwith "Gnuplot.pen_width"; g.pen_width <- w let point g i = if g.closed then failwith "Gnuplot.point"; g.point <- i let point_width g w = if g.closed then failwith "Gnuplot.point_width"; g.point_width <- w let font g fn = if g.closed then failwith "Gnuplot.font"; g.font <- fn let font_size g sz = if g.closed then failwith "Gnuplot.font_size"; g.font_size <- sz (* * Text **********************************************************************) (* [number_of_lines s] returns the number of lines of [s] as seen by Gnuplot for the positioning of the box. Here are the (a bit odd) Gnuplot rules for this. -- Any number of "\n" at the beginning is ignored for the frame but pushes the title down (possibly in the plot area); -- After the first character, all "\n" count, two consecutive "\n" or an "\n" as last character imply an empty line; -- "" (and thus "\n\n...\n") is equivalent to no title, so 0 lines. The rule is therefore the following: ignore newlines at beginning, if what remains is "" this count as 0 lines, otherwise you got 1 line and add one for each newline that follows. *) let number_of_lines = let rec skip_nl s i = if i >= String.length s || String.unsafe_get s i <> '\n' then i else skip_nl s (i + 1) in let rec count_nl s i acc = if i >= String.length s then acc else let acc = if String.unsafe_get s i = '\n' then acc + 1 else acc in count_nl s (i + 1) acc in fun s -> let i0 = skip_nl s 0 in if i0 = String.length s then 0 else count_nl s (i0 + 1) 1 let change_label g a1 a2 new_label = let change a = if a.label_shown then begin a.label_old <- a.label; a.label_shown <- false; end; let new_nlines = number_of_lines new_label in if new_nlines <> a.label_nlines then g.subpage.(g.sub).redraw <- true; a.label <- sprintf "%S font \"%s\"" new_label (string_of_font g); a.label_lt <- g.pen; a.label_color <- g.color; a.label_nlines <- new_nlines in match a1.active, a2.active with | false, true -> change a2 | _ -> change a1 let xlabel g new_label = if g.closed then failwith "Gnuplot.xlabel: handle closed"; let sp = g.subpage.(g.sub) in change_label g sp.x1 sp.x2 new_label let ylabel g new_label = if g.closed then failwith "Gnuplot.ylabel: handle closed"; let sp = g.subpage.(g.sub) in change_label g sp.y1 sp.y2 new_label let title g new_title = if g.closed then failwith "Gnuplot.title: handle closed"; let sp = g.subpage.(g.sub) in if sp.title_shown then begin sp.title_old <- sp.title; sp.title_shown <- false; end; let new_nlines = number_of_lines new_title in if new_nlines <> sp.title_nlines then sp.redraw <- true; sp.title <- sprintf "%S font \"%s\"" new_title (string_of_font g); sp.title_lt <- g.pen; sp.title_color <- g.color; sp.title_nlines <- new_nlines type coord = Graph | Viewport | Subpage | World (* FIXME: allow to choose which coordinates *) (* FIXME: text is the same as a plot. same treatment. *) let text g ?(tag=system_tag) ?(frame=0.) ?(rotate=0.) ?(coord=Graph) x y s = if g.closed then failwith "Gnuplot.text"; let sp = g.subpage.(g.sub) in let pos = match coord with | Graph -> (* Use the active coordinate system *) sprintf "%s %F,%s %F" (if sp.x2.active && not sp.x1.active then "second" else "first") x (if sp.y2.active && not sp.y1.active then "second" else "first") y | Viewport -> sprintf "graph %F,graph %F" x y | Subpage -> sprintf "screen %F,screen %F" (sp.subpage_xmin +. x *. g.subw) (sp.subpage_ymin +. y *. g.subh) | World -> sprintf "screen %F,screen %F" x y in let text = sprintf "set label %i %S at %s rotate by %F font \"%s\" tc %s;\n" sp.text_number s pos rotate (string_of_font g) (if g.color >= 0 then sprintf "rgb \"#%X\"" g.color else sprintf "lt %i" g.pen) in let q = add_text_with_tag sp tag (text, sp.text_number) in begin match q.state with | Managed | Visible -> output_string g.to_gplot text; | _ -> () end; sp.text_number <- sp.text_number + 1 (* * 2D: world coordinates, axes,... **********************************************************************) (* FIXME: aspect ratio? here? *) (* FIXME: What about aspect ratio? Do we try to detect it automatically or let it be chosen by the user? *) let win g xmin xmax ymin ymax = if g.closed then failwith "Gnuplot.win"; let sp = g.subpage.(g.sub) in sp.xmin <- xmin; sp.xmax <- xmax; sp.ymin <- ymin; sp.ymax <- ymax; sp.redraw <- true (* schedule for redrawing which will reissue ranges *) (* let aspect = abs_float( ((ymax -. ymin) *. g.subw) *) (* /. ((xmax -. xmin)*. g.subh) ) in *) (* if 0.95 <= aspect && aspect <= 1.05 then *) (* cmd_issue_and_hist g p "set size ratio -1\n"; (\* FIXME: not ideal *\) *) type axis_opt = handle -> subpage -> float -> float -> axis -> axis -> unit type border_loc = int list let axis ?(which=[1]) () _ _ _ _ a1 a2 = if List.mem 1 which then a1.zero <- true; if List.mem 2 which then a2.zero <- true let border ?(which=[1;2]) () _ _ _ _ a1 a2 = if List.mem 1 which then a1.draw <- true; if List.mem 2 which then a2.draw <- true; if List.mem 3 which then a1.draw_top <- true; if List.mem 4 which then a2.draw_top <- true let tics ?(which=[1;2]) ?(outward=false) ?(grid=false) ?(minor=0) ?(minor_grid=false) ?(log=false) ?(step=0.) () = let set a min max = a.min <- min; a.max <- max; a.tics <- true; a.tics_step <- step; (* 0. = auto *) a.mtics <- minor; a.grid <- grid; a.mgrid <- minor_grid; if log && (min <= 0. || max <= 0.) then invalid_arg "Gnuplot.tics"; a.logscale <- log in fun _ sp min max a1 a2 -> if List.mem 1 which then set a1 min max; if List.mem 2 which then set a2 min max; sp.tics_outwards <- outward (* FIXME: allows an easy way to put our own label, e.g. dates. *) let labels ?(which=[1]) ?prec ?(rotate=false) () g _ _ _ a1 a2 = let font = string_of_font g in let set a = a.format <- (match prec with | None -> "%g" | Some p -> "%." ^ (string_of_int p) ^ "g"); a.format_rot <- rotate; a.format_font <- font; a.format_lt <- g.pen; a.format_color <- g.color; a.active <- true in if List.mem 1 which then set a1 else a1.active <- false; if List.mem 2 which then set a2 else a2.active <- false let default_opt = [border(); tics(); labels()] (* REMARK: The default linetype is 1. When axis labels are given this color, gnuplot will in fact display them with border color. This is a bit strange but does not really interfere -- may be surprising to the user though. [box] cannot reset the axes to a default state before applying the options because we want incremental changes to be possible. FIXME: need a way to reset these parameters (e.g. labels, once set cannot be unset). Do it in [clear] ? *) let box ?(x=default_opt) ?(y=default_opt) g = if g.closed then failwith "Gnuplot.box"; let sp = g.subpage.(g.sub) in List.iter (fun prop -> prop g sp sp.xmin sp.xmax sp.x1 sp.x2) x; List.iter (fun prop -> prop g sp sp.ymin sp.ymax sp.y1 sp.y2) y; sp.redraw <- true (* only matters for interactive mode *) let env g ?(xaxis=false) ?(xgrid=false) ?(xlog=false) xmin xmax ?(yaxis=false) ?(ygrid=false) ?(ylog=false) ymin ymax = if g.closed then failwith "Gnuplot.env"; win g xmin xmax ymin ymax; let x = [border(); tics ~grid:xgrid ~log:xlog (); labels()] in let x = if xaxis then axis() :: x else x in let y = [border(); tics ~grid:ygrid ~log:ylog (); labels()] in let y = if yaxis then axis() :: y else y in box g ~x ~y (* * Generic plotting functions **********************************************************************) type style = Lines | Linespoints | Points | Dots | Impulses let with_style g = function | Lines -> "with lines" | Linespoints -> sprintf "with linespoints pt %i ps %F" g.point g.point_width | Points -> sprintf "with points pt %i ps %g" g.point g.point_width | Dots -> "with dots" | Impulses -> "with impulses" let with_vector = "with vector" (* Active axes for 'plot' *) let axes g = let sp = g.subpage.(g.sub) in "axes " ^ (if sp.x2.active && not sp.x1.active then "x2" else "x1") ^ (if sp.y2.active && not sp.y1.active then "y2 " else "y1 ") (* 'splot' does not support 'axes' *) let no_axes _ = "" (* REMARK: the callback, calling [loop] with the output command as argument, is even a bit faster than the loop with this command inlined! *) let plot_data g ?(tag=system_tag) ~inline_if loop ~axes ~label ~style = (* The border linetype (-1) is twice as thick as the other ones. So scale the size appropriately for visual homogeneity. *) let lw = (if g.color < 0 && g.pen = -1 then 0.5 *. g.pen_width else g.pen_width) in let plot = if inline_if then begin Buffer.reset g.buf_inline; try let () = loop(Buffer.add_string g.buf_inline) in Buffer.add_string g.buf_inline "e\n"; let data = Buffer.contents g.buf_inline in (* Plot command *) let cmd = sprintf "'-' %s title %S %s" (axes g) label style in (cmd, lw, g.pen, g.color, Inlined(data)) with e -> Buffer.reset g.buf_inline; raise e end else begin let (fname, fh) = Gnuplot_sys.open_temp_file g.gp_extra in try loop(output_string fh); close_out fh; (* Plot command *) let cmd = sprintf "%S %s title %S %s" fname (axes g) label style in (cmd, lw, g.pen, g.color, File fname) with e -> close_out fh; (try Unix.unlink fname with _ -> ()); raise e end in (* Add plot and possibly display it *) update_show g ~add_plot:(tag, plot) (* * 2D Plots **********************************************************************) let fx g ?tag ?(style=Lines) ?(label="") ?(nsamples=100) f a b = if g.closed then failwith "Gnuplot.fx"; if not(is_finite a) || not(is_finite b) || nsamples <= 1 then invalid_arg "Gnuplot.fx"; let loop out = let nsamples = nsamples - 1 in let h = (b -. a) /. float nsamples in for i = 0 to nsamples do let x = a +. float i *. h in let y = f x in if is_finite y then out(string_of_float x ^ " " ^ string_of_float y ^ "\n") else out "? ?\n" done in plot_data g ~inline_if:(nsamples <= g.max_inline) loop ?tag ~axes ~label ~style:(with_style g style) let xy_param g ?tag ?(style=Lines) ?(label="") ?(nsamples=100) f a b = if g.closed then failwith "Gnuplot.xy_param"; if nsamples <= 1 then invalid_arg "Gnuplot.xy_param"; let loop out = let nsamples = nsamples - 1 in let h = (b -. a) /. float nsamples in for i = 0 to nsamples do let x = a +. float i *. h in let (y1, y2) = f x in if is_finite y1 && is_finite y2 then begin out(string_of_float y1 ^ " " ^ string_of_float y2 ^ "\n") end else out "? ?\n" done in plot_data g ~inline_if:(nsamples <= g.max_inline) loop ?tag ~axes ~label ~style:(with_style g style) (* This is similar to the second case of [plot_data] except the file is already created. *) let xy_file g ?(tag=system_tag) ?(style=Lines) ?(label="") fname = if g.closed then failwith "Gnuplot.xy_file"; let lw = if g.pen = -1 then 0.5 *. g.pen_width else g.pen_width in let cmd = sprintf "%S title %S %s %s" fname label (axes g) (with_style g style) in update_show g ~add_plot:(tag, (cmd, lw, g.pen, g.color, File fname)) (* * 3D: world coordinates, axes,... **********************************************************************) (* FIXME: 3D plots are in alpha state *) let win3 g xmin xmax ymin ymax zmin zmax = if g.closed then failwith "Gnuplot.win3"; let sp = g.subpage.(g.sub) in sp.xmin <- xmin; sp.xmax <- xmax; sp.ymin <- ymin; sp.ymax <- ymax; sp.zmin <- zmin; sp.zmax <- zmax; sp.plot3D <- true; sp.redraw <- true let default_opt3d = [border(); tics ~minor:0 (); labels()] let default_opt3d_z = [border ~which:[1] (); tics ~which:[1] ~minor:0 (); labels()] let box3 ?(x=default_opt3d) ?(y=default_opt3d) ?(z=default_opt3d_z) g = if g.closed then failwith "Gnuplot.box3"; let sp = g.subpage.(g.sub) in List.iter (fun prop -> prop g sp sp.xmin sp.xmax sp.x1 sp.x2) x; List.iter (fun prop -> prop g sp sp.ymin sp.ymax sp.y1 sp.y2) y; List.iter (fun prop -> prop g sp sp.zmin sp.zmax sp.z1 sp.z2) z; sp.plot3D <- true; sp.redraw <- true let env3 g ?(xaxis=false) ?(xgrid=false) ?(xlog=false) xmin xmax ?(yaxis=false) ?(ygrid=false) ?(ylog=false) ymin ymax ?(zaxis=false) ?(zgrid=false) ?(zlog=false) zmin zmax = if g.closed then failwith "Gnuplot.env3"; win3 g xmin xmax ymin ymax zmin zmax; let x = [border(); tics ~minor:0 ~grid:xgrid ~log:xlog (); labels()] in let x = if xaxis then axis() :: x else x in let y = [border(); tics ~minor:0 ~grid:ygrid ~log:ylog (); labels()] in let y = if yaxis then axis() :: y else y in let z = [border ~which:[1] (); tics ~which:[1] ~minor:0 ~grid:ygrid ~log:ylog (); labels()] in let z = if zaxis then axis() :: z else z in box3 g ~x ~y ~z (* * 3D Plots **********************************************************************) (* FIXME: hidden -- global? *) let fxy g ?tag ?(style=Lines) ?(label="") ?(xnsamples=30) ?(ynsamples=30) f xmin xmax ymin ymax = if g.closed then failwith "Gnuplot.fxy"; if not(is_finite xmin && is_finite xmax && is_finite ymin && is_finite ymax) || xnsamples <= 1 || ynsamples <= 1 then invalid_arg "Gnuplot.fxy"; let loop out = let xnsamples = xnsamples - 1 and ynsamples = ynsamples - 1 in let hx = (xmax -. xmin) /. float xnsamples and hy = (ymax -. ymin) /. float ynsamples in for i = 0 to xnsamples do let x = xmin +. float i *. hx in for j = 0 to ynsamples do let y = ymin +. float j *. hy in let z = f x y in if is_finite z then out (sprintf "%F %F %F\n" x y z) else out (sprintf "%F %F ?\n" x y) done; out "\n"; done in plot_data g ~inline_if:(xnsamples * ynsamples <= g.max_inline) loop ?tag ~axes:no_axes ~label ~style:(with_style g style) let fxy_param g ?tag ?(style=Lines) ?(label="") ?(xnsamples=30) ?(ynsamples=30) f xmin xmax ymin ymax = if g.closed then failwith "Gnuplot.fxy_param"; if xnsamples <= 1 || ynsamples <= 1 then invalid_arg "Gnuplot.fxy_param"; let loop out = let xnsamples = xnsamples - 1 and ynsamples = ynsamples - 1 in let hx = (xmax -. xmin) /. float xnsamples and hy = (ymax -. ymin) /. float ynsamples in for i = 0 to xnsamples do let x = xmin +. float i *. hx in for j = 0 to ynsamples do let y = ymin +. float j *. hy in let (z1, z2, z3) = f x y in if is_finite z1 && is_finite z2 && is_finite z3 then out (sprintf "%F %F %F\n" z1 z2 z3) else out "? ? ?\n" done; out "\n"; done in plot_data g ~inline_if:(xnsamples * ynsamples <= g.max_inline) loop ?tag ~axes:no_axes ~label ~style:(with_style g style) let xyz_ft g ?tag ?(style=Lines) ?(label="") ?(tnsamples=100) f tmin tmax = if g.closed then failwith "Gnuplot.xyz_ft"; if tnsamples <= 1 then invalid_arg "Gnuplot.xyz_ft"; let loop out = let tnsamples = tnsamples - 1 in let ht = (tmax -. tmin) /. float tnsamples in for i = 0 to tnsamples do let (z1, z2, z3) = f(tmin +. float i *. ht) in if is_finite z1 && is_finite z2 && is_finite z3 then out (sprintf "%F %F %F\n" z1 z2 z3) else out "? ? ?\n" done in plot_data g ~inline_if:(tnsamples <= g.max_inline) loop ?tag ~axes:no_axes ~label ~style:(with_style g style) ocaml-gnuplot-0.8.3/gnuplot_dir.mli0000644000175000017500000000232611163137466016031 0ustar trchtrch(* File: gnuplot_dir.mli Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_dir.mli,v 1.3 2004-11-28 23:49:39 chris_77 Exp $ *) (** Temporary dir creation and removal *) val mk_temp_dir : string -> string -> string -> string (** [mk_temp_dir tmpdir prefix suffix] creates a temporary directory in [tmpdir] with name consisting of [prefix] concatenated with a suitably chosen number then [suffix]. *) val remove_rec_dir : string -> unit (** [remove_rec_dir dirname] remove recursively the directory [dirname]. This function silenty fails (even if it cannot remove the directory, no exception is raised). *) ocaml-gnuplot-0.8.3/gnuplot_common.mli0000644000175000017500000003172111163243710016532 0ustar trchtrch(* Copyright (C) 2001-2004 Christophe Troestler email: Christophe.Troestler@umh.ac.be WWW: http://math.umh.ac.be/an/software/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation, with the special exception on linking described in file LICENSE. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE for more details. *) (* $Id: gnuplot_common.mli,v 1.3 2007-11-27 23:07:22 chris_77 Exp $ *) (** Functions in the Gnuplot module that do not depend on a particular datatype. @author Christophe Troestler (Christophe.Troestler(at)umh.ac.be) *) module type T = sig (** The [string] in the constructors is the name of the filename. [EPSLaTeX] creates two filenames: the given [string] is the name of the TeX file (a ".tex" extension will be added if not present); the EPS file name is constructed from it by changing the extension ".tex" to ".eps". *) type device = Gnuplot_common_.device = | X (** On screen (X11, AQUA or windows depending on your platform) *) | Wxt (** Interactive and cross-platform terminal for on-screen rendering based on Cairo. *) | PS of string (** Postscript *) | EPS of string (** Encapsulated PostScript *) | EPSLaTeX of string (** Picture environment including an EPS file. *) | FIG of string (** Xfig format *) | PNG of string (** Portable Network Graphics *) | MP of string (** Metapost *) | MF of string (** Metafont *) | SVG of string (** Scalable Vector Graphics *) type color = int (** Color, compatible with the [Graphics] module. *) (** Gnuplot handle *) type handle = Gnuplot_common_.handle (** Style of plotting lines *) type style = Gnuplot_common_.style = Lines | Linespoints | Points | Dots | Impulses (** {2 Initializing, closing and moving around (sub)pages} *) val device_of_filename : string -> device (** [device_of_filename f] guesses the device corresponding to the extension of [f]. @raise Failure if none is found. *) val init : ?offline:string -> ?max_inline:int -> ?persist:bool -> ?color:bool -> ?nxsub:int -> ?nysub:int -> ?xsize:float -> ?ysize:float -> ?aspect:float -> device -> handle (** [init ?offline ?max_inline ?persist ?color ?nsubx ?nsuby ?sizex ?sizey ?aspect dev] returns a handle to a new gnuplot session with device [dev]. @param offline name of the script file (typically with extension ".plt"). If this parameter is given, gnuplot will not be called but instead all commands and data will be written to the script file. @param max_inline the data can be communicated to gnuplot through a pipe or a file. The pipe will be used if the number of data lines to send is less or equal to [max_inline]. For example, if [max_inline] is set to [max_int], all data will be transmitted through the pipe. @param persist says whether the plot window should stay after the handle has been closed (default: [true]). @param color if [true], a color output (as opposed to a monochrome one) will be produced (default = [true]) @param nxsub number of horizontal subpages (default = 1) @param nysub number of vertical subpages (default = 1) @param xsize the horizontal size of the output; must be > 0 (default = 100. mm or 550. pixels) @param ysize the vertical size of the output; must be > 0 (default = 100. mm or 550. pixels) @param aspect the aspect ratio of the output, i.e. the ratio of the height on the width of the output; must be > 0 (default = 1.) For [Gnuplot.X], [Gnuplot.PNG] and [Gnuplot.SVG] devices, the size is expressed in pixels, for the other drivers, it is expressed in milimeters. One has to specify both [sizex] and [sizey], in which case [aspect] is ignored, or one of them and [aspect]. On Win32, [Gnuplot.X] may ignore the sizes (depending on your privileges). @raise Invalid_argument if any of the parameters does not satisfy the above constraints. *) val close : handle -> unit (** [close g] closes the gnuplot session [g]. @raise Failure if the gnupot process does exit properly. *) val adv : ?sub:int -> handle -> unit (** [adv g] advances to the next subpage or, if necessary, opens a new page. [adv ~sub:i g] goes to the subpage [i] or, if [i] is too big or [i <= 0], it starts a new page. Subpages are counted row by row, the top left one being numbered 1. Beware that some output devices (e.g., PNG) do not support multipage output. *) val clear : handle -> unit (** [clear g] clears the current subpage. *) (** {2 Pens and colors} *) val pen : handle -> int -> unit (** [pen g i] selects the [i]th pen type for the handle [g] -- [i] can at least take the values from 0 to 6 but some devices may allow a bigger range. @deprecated use [color] instead.*) val color : handle -> color -> unit (** [color g c] use the RGB color [c] active for the subsequent drawings on the handle [g]. *) val pen_width : handle -> float -> unit (** [pen_width g w] sets the pen thickness to [w] (in multiples of the default pen size) for the handle [g]. Note that some devices (e.g. PNG) do not obey such command -- this is a gnuplot limitation. *) val point : handle -> int -> unit (** [point g i] selects the [i]th point type for the handle [g]. *) val point_width : handle -> float -> unit (** [point_width g w] sets the point thickness to [w] (in multiples of the default point size) for the handle [g]. *) val font : handle -> string -> unit (** [font g s] sets the current font for the handle [g] as [s] where [s] is device and system dependent. *) val font_size : handle -> int -> unit (** [font_size g sz] sets the current font size for the handle [g] to [sz]. Negative or null values select the default size. Note that the default font on some devices is not scalable -- thus the font size may seem to have no effect. *) (** {2 Text} *) val title : handle -> string -> unit (** [title g t] sets the title for the current subpage of the gnuplot session [g] to [t]. *) val xlabel : handle -> string -> unit (** [xlabel g t] sets the label for x axis of the current subpage of the gnuplot session [g] to [t]. *) val ylabel : handle -> string -> unit (** [ylabel g t] sets the label for y axis of the current subpage of the gnuplot session [g] to [t]. *) type coord = | Graph (** The coordinates of the last labelled axis *) | Viewport (** The area delimited by the borders, (0,0) being the bottom left corner and (1,1) the top right corner. *) | Subpage (** Subpage coordinates with (0,0) being the bottom left corner and (1,1) the top right corner. *) | World (** The entire graph with (0,0) being the bottom left corner and (1,1) the top right corner. *) val text : handle -> ?tag:int -> ?frame:float -> ?rotate:float -> ?coord:coord -> float -> float -> string -> unit (** [text g x y text] write the string [text] at position ([x],[y]) in grah coordinates on the gnuplot session [g]. Graph coordinates mean that ([x], [y]) are (0., 0.) at the bottom left of the surrounding box and (1., 1.) at the top right. @param rotate in degrees *) (** {2 Tags} *) val show : ?immediately:bool -> ?tag:int -> handle -> unit (** [tag_show ?immediately ?tag g] shows the plots handled by that tag. @param immediately (Default: true). @raise Invalid_argument if [t] is the system tag [0]. *) val hide : ?immediately:bool -> ?tag:int -> handle -> unit val auto : tag:int -> handle -> unit val free : tag:int -> handle -> unit (** {2 2D world coordinates, axes,...} *) val win : handle -> float -> float -> float -> float -> unit (** [win g xmin xmax ymin ymax] sets the x and y ranges for the current subpage of the handle [g]. *) type axis_opt type border_loc = int list (** List of numbers among 1, 2, 3 and 4 corresponding to border locations. In 2D, 1 denotes the left or bottom axis and 2 the right or top axis. *) val axis : ?which:border_loc -> unit -> axis_opt (** [axis ?which ()] sets the zero axis. @param which is a list of the border numbers. *) val border : ?which:border_loc -> unit -> axis_opt (** [border ?which ()] set borders to the graph. @param which is a list of the border numbers. *) val tics : ?which:border_loc -> ?outward:bool -> ?grid:bool -> ?minor:int -> ?minor_grid:bool -> ?log:bool -> ?step:float -> unit -> axis_opt (** [tics ?which ?outward ?minor ?grid ?log ?step ()] @param which a list of the border numbers. @param outward whether the tics point outside the border (default: false). Beware this is a global setting for gnuplot, so all the tics will be affected. @param grid whether to draw a grid at each major tic (default: [false]). @param minor set the number of sub-intervals (not the number of minor tics) between two major tics (default: 1 which means no minor tics). @param minor_grid whether to draw a grid at each minor tic (default: [false]). @param log whether to enable log scaling. @param step step between two consecutive tics. *) val labels : ?which:border_loc -> ?prec:int -> ?rotate:bool -> unit -> axis_opt (** [labels ?which ?prec ?rotate ()] set the numeric labels accroding to the following parameters: @param which a list of the border numbers; @param prec precision of the numeric labels; @param rotate rotate the labels of 90 degrees w.r.t. their usual position. *) val box : ?x:axis_opt list -> ?y:axis_opt list -> handle -> unit val env : handle -> ?xaxis:bool -> ?xgrid:bool -> ?xlog:bool -> float -> float -> ?yaxis:bool -> ?ygrid:bool -> ?ylog:bool -> float -> float -> unit (** [env g ?xaxis ?xgrid ?xlog xmin xmax ?yaxis ?ygrid ?ylog ymin ymax] is a convenience function to set the x and y ranges as well as some common parameters (using [win] and [box] separately is more powerful). @param xaxis displays the x axis (default: false) @param xgrid displays a grid at each x tic (default: false) @param xlog select a logarithmic scaling for the x axis (default: false) @param yaxis displays the y axis (default: false) @param ygrid displays a grid at each y tic (default: false) @param ylog select a logarithmic scaling for the y axis (default: false) *) (** {2 2D Plots } *) val fx : handle -> ?tag:int -> ?style:style -> ?label:string -> ?nsamples:int -> (float -> float) -> float -> float -> unit (** [fx g ?style ?label ?nsamples f a b] draws the graph of [f] over the interval going from [a] to [b] (inclusive). @param style style of the graph (default: [Lines]) @param label label for this graph (default: none) @param nsamples number of points at which [f] is evaluated (default: 100) *) val xy_param : handle -> ?tag:int -> ?style:style -> ?label:string -> ?nsamples:int -> (float -> float * float) -> float -> float -> unit (** [xy_param g ?tag ?style ?label ?nsamples f a b] draws the image of the function [f] (i.e., the cuve parametrized by [f]) over the interval going from [a] to [b] (inclusive). @param style style of the graph (default: [Lines]) @param label label for this graph (default: none) @param nsamples number of points at which [f] is evaluated (default: 100) *) val xy_file : handle -> ?tag:int -> ?style:style -> ?label:string -> string -> unit (** {2 3D world coordinates, axes,...} *) val box3 : ?x : axis_opt list -> ?y : axis_opt list -> ?z : axis_opt list -> handle -> unit val env3 : handle -> ?xaxis:bool -> ?xgrid:bool -> ?xlog:bool -> float -> float -> ?yaxis:bool -> ?ygrid:bool -> ?ylog:bool -> float -> float -> ?zaxis:bool -> ?zgrid:bool -> ?zlog:bool -> float -> float -> unit (** [env g ?xgrid ?xlog xmin xmax ?ygrid ?ylog ymin ymax] sets x and y ranges. *) (** {2 3D Plots} *) val fxy : handle -> ?tag:int -> ?style:style -> ?label:string -> ?xnsamples:int -> ?ynsamples:int -> (float -> float -> float) -> float -> float -> float -> float -> unit (** [fxy g ?style ?label ?hidden ?xnsamples ?ynsamples f xmin xmax ymin ymax] *) val fxy_param : handle -> ?tag:int -> ?style:style -> ?label:string -> ?xnsamples:int -> ?ynsamples:int -> (float -> float -> float * float * float) -> float -> float -> float -> float -> unit (** [fxy_param g ?style ?label ?hidden ?xnsamples ?ynsamples f xmin xmax ymin ymax] *) val xyz_ft : handle -> ?tag:int -> ?style:style -> ?label:string -> ?tnsamples:int -> (float -> float * float * float) -> float -> float -> unit end ocaml-gnuplot-0.8.3/Makefile0000644000175000017500000001146611163720100014424 0ustar trchtrch# Ocaml-Gnuplot # Copyright (C) Christophe TROESTLER PKGNAME = $(shell grep name META.in | \ sed -e "s/.*\"\([^\"]*\)\".*/\1/") PKGVERSION = $(shell grep "@version" gnuplot.mli | \ sed -r -e "s/[^0-9.]*([0-9.]+).*/\1/") OCAMLOPT_EXISTS = $(shell which ocamlopt) include Makefile.conf OCAMLFLAGS = -dtypes OCAMLOPTFLAGS = -inline 2 OCAMLDOCFLAGS = -stars -colorize-code SED = sed # Order of the sources _must_ reflect order of dependency GENERATED_SOURCES0 = gnuplot_sys.ml GENERATED_SOURCES1 = gnuplot_ba_c.ml gnuplot_ba_f.ml gnuplot_array.ml SOURCES = gnuplot_dir.ml $(GENERATED_SOURCES0) gnuplot_common_.ml \ $(GENERATED_SOURCES1) gnuplot_bigarray.ml gnuplot_functor.ml gnuplot.ml INTERFACES = gnuplot_common.mli gnuplot.mli DISTFILES = AUTHORS INSTALL LICENSE META.in Makefile Makefile.conf \ $(filter-out $(GENERATED_SOURCES0),$(SOURCES)) $(INTERFACES) demos/ \ gnuplot_arr_ba.ml gnuplot_macos.ml gnuplot_unix.ml gnuplot_win32.ml \ make_array.ml gnuplot_dir.mli gnuplot_sys.mli INSTALL_FILES = gnuplot_common.mli gnuplot.mli gnuplot_common.cmi gnuplot.cmi \ gnuplot.cma ifeq ($(OCAMLOPT_EXISTS),) else INSTALL_FILES += gnuplot.a gnuplot.cmx gnuplot.cmxa endif PKG_TARBALL = ocaml-$(PKGNAME)-$(PKGVERSION).tar.gz ARCHIVE = $(shell grep "archive(byte)" META.in | \ sed -e "s/.*\"\([^\"]*\)\".*/\1/") XARCHIVE = $(shell grep "archive(native)" META.in | \ sed -e "s/.*\"\([^\"]*\)\".*/\1/") SRC_WEB = web SF_WEB = /home/groups/o/oc/ocaml-gnuplot/htdocs/ default: all .PHONY: all byte opt install install-byte install-opt doc dist all: byte opt byte: $(ARCHIVE) opt: $(XARCHIVE) doc: html gnuplot.cma: $(INTERFACES:.mli=.cmi) $(SOURCES:.ml=.cmo) $(OCAMLC) $(OCAMLFLAGS) -a -o $@ $(SOURCES:.ml=.cmo) gnuplot.cmxa: $(INTERFACES:.mli=.cmi) $(SOURCES:.ml=.cmx) $(OCAMLOPT) $(OCAMLOPTFLAGS) -a -o $@ $(SOURCES:.ml=.cmx) # Generated files gnuplot_array.ml: make_array.exe gnuplot_arr_ba.ml ./$< gnuplot_ba_%.ml: make_array.exe gnuplot_arr_ba.ml ./$< make_array.exe: make_array.ml $(OCAMLC) $(OCAMLFLAGS) -o $@ unix.cma str.cma $< gnuplot_sys.ml: gnuplot_$(PLATFORM).ml $(COPY) $< $@ # Installation .PHONY: install install: META all $(OCAMLFIND) install $(PKGNAME) META $(INSTALL_FILES) uninstall: $(OCAMLFIND) remove $(PKGNAME) META: META.in $(COPY) $^ $@ echo "version = \"$(PKGVERSION)\"" >> $@ # Packaging .PHONY: tar tar: $(PKG_TARBALL) TARBALL_DIR=$(subst .tar.gz,,$(PKG_TARBALL)) $(PKG_TARBALL): $(DISTFILES) mkdir $(TARBALL_DIR) cp --preserve -r $(DISTFILES) $(TARBALL_DIR)/ tar --exclude ".bzrignore" --exclude-from=.bzrignore \ -zcvf $(PKG_TARBALL) $(TARBALL_DIR) rm -rf $(TARBALL_DIR) .PHONY: sync-svn sync-svn: bzr push https://$$SF_USER@ocaml-gnuplot.svn.sourceforge.net/svnroot/ocaml-gnuplot/trunk/ocaml-gnuplot # Documentation html: $(PKGNAME).html/index.html $(PKGNAME).html/index.html: $(INTERFACES) $(INTERFACES:.mli=.cmi) [ -d $(PKGNAME).html/ ] || mkdir $(PKGNAME).html $(OCAMLDOC) -d $(PKGNAME).html -html $(OCAMLDOCFLAGS) $(INTERFACES) # cd $(PKGNAME).html; \ # for f in *; do \ # $(COPY) $$f $$f.bak; \ # $(SED) -e 's/$$VERSION/$(PKGVERSION)/' < $$f.bak > $$f; \ # rm -f $$f.bak; \ # done # Examples .PHONY: demos demos.opt webdemos demos: byte cd demos/; $(MAKE) demos.opt: opt cd demos/; $(MAKE) opt webdemos: demos mkdir images/ cd demos/; \ for f in ex*.exe; do ./$$f -dev png; done; \ mv *.png ../images/ # Upload the demos to SF scp -r images/ shell.sf.net:$(SF_WEB) rm -rf images # Release a Sourceforge tarball and publish the HTML doc .PHONY: web upload web: doc @ if [ -d $(PKGNAME).html ] ; then \ scp -r $(PKGNAME).html shell.sf.net:$(SF_WEB)/ \ && echo "*** Published documentation on SF" ; \ fi @ if [ -d $(SRC_WEB)/ ] ; then \ scp $(SRC_WEB)/*.html $(SRC_WEB)/*.jpg LICENSE \ shell.sf.net:$(SF_WEB) \ && echo "*** Published web site ($(SRC_WEB)/) on SF" ; \ fi upload: $(PKG_TARBALL) @ if [ -z "$(PKG_TARBALL)" ]; then \ echo "PKG_TARBALL not defined"; exit 1; fi scp -C $(PKG_TARBALL) $$SF_USER@frs.sourceforge.net:uploads # Caml general dependencies .SUFFIXES: .ml .mli .cmi .cmo .cma .cmx .cmxa %.cmi: %.mli $(OCAMLC) $(OCAMLFLAGS) -c $< %.cmo: %.ml $(OCAMLC) $(OCAMLFLAGS) -c $< %.cma: %.cmo $(OCAMLC) $(OCAMLFLAGS) -a -o $@ $^ %.cmx: %.ml $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $< %.cmxa: %.cmx $(OCAMLOPT) $(OCAMLOPTFLAGS) -a -o $@ $^ .PHONY: depend depend: .depend .depend: $(SOURCES) $(wildcard *.mli) $(OCAMLDEP) $^ > .depend include .depend ######################################################################## .PHONY: clean dist-clean clean: @ rm -f *~ .*~ *.{o,a} *.cm[aiox] *.cmxa *.annot @ rm -f $(GENERATED_SOURCES0) $(GENERATED_SOURCES1) @ rm -rf $(PKGNAME).html $(PKG_TARBALL) @ find . -type f -perm -u=x -exec rm -f {} \; @ if [ -d ./html ]; then rm -rf ./html; fi cd demos; $(MAKE) clean dist-clean: clean rm -f .depend META