From: <hez...@us...> - 2010-04-12 04:14:21
|
Revision: 10903 http://plplot.svn.sourceforge.net/plplot/?rev=10903&view=rev Author: hezekiahcarty Date: 2010-04-12 04:14:12 +0000 (Mon, 12 Apr 2010) Log Message: ----------- Simplify the way axes are drawn in the OCaml Plplot.Plot module This should both simplify axis customization and make the interface more consistent. Modified Paths: -------------- trunk/bindings/ocaml/plplot.ml trunk/bindings/ocaml/plplot.mli trunk/examples/ocaml/xplot01.ml Modified: trunk/bindings/ocaml/plplot.ml =================================================================== --- trunk/bindings/ocaml/plplot.ml 2010-04-11 23:51:49 UTC (rev 10902) +++ trunk/bindings/ocaml/plplot.ml 2010-04-12 04:14:12 UTC (rev 10903) @@ -124,7 +124,10 @@ | Unconventional_label | Label | Custom_label - | Minor_ticks | Major_ticks + | Minor_ticks + | Minor_tick_count of int + | Major_ticks + | Major_tick_spacing of float | Vertical_label type stream_t = { @@ -179,6 +182,8 @@ type plot_t = (* Standard plot elements *) | Arc of (color_t * float * float * float * float * float * float * bool) + | Axes of + (color_t * axis_options_t list * axis_options_t list * int * line_style_t) | Contours of (color_t * pltr_t * float array * float array array) | Image of image_t | Image_fr of (image_t * (float * float)) @@ -485,6 +490,13 @@ let arc ?(fill = false) color x y a b angle1 angle2 = Arc (color, x, y, a, b, angle1, angle2, fill) + (** [axes ?color ?style ?width xopt yopt] *) + let axes ?(color = Black) ?(style = Solid_line) ?(width = 1) xopt yopt = + Axes (color, xopt, yopt, width, style) + + (** Default axes *) + let default_axes = axes default_axis_options default_axis_options + (** [circle ?fill color x y r] - A special case of [arc]. *) let circle ?fill color x y r = arc ?fill color x y r r 0.0 360.0 @@ -647,6 +659,38 @@ () ) + (** An easier to deduce alternative to {Plplot.plbox} *) + let plot_axes ?stream xoptions yoptions = + let xtick = ref 0.0 in + let xsub = ref 0 in + let ytick = ref 0.0 in + let ysub = ref 0 in + let map_axis_options tick sub ol = + List.map ( + function + | Axis -> "a" + | Frame0 -> "b" + | Frame1 -> "c" + | Time -> "d" + | Fixed_point -> "f" + | Major_grid -> "g" + | Minor_grid -> "h" + | Invert_ticks -> "i" + | Log -> "l" + | Unconventional_label -> "m" + | Label -> "n" + | Custom_label -> "o" + | Minor_ticks -> "s" + | Minor_tick_count t_sub -> sub := t_sub; "s" + | Major_ticks -> "t" + | Major_tick_spacing t_space -> tick := t_space; "t" + | Vertical_label -> "v" + ) ol + in + let xopt = String.concat "" (map_axis_options xtick xsub xoptions) in + let yopt = String.concat "" (map_axis_options ytick ysub yoptions) ^ "v" in + with_stream ?stream (fun () -> plbox xopt !xtick !xsub yopt !ytick !ysub) + (** [plot stream l] plots the data in [l] to the plot [stream]. *) let rec plot ?stream plottable_list = (* TODO: Add legend support. *) @@ -681,6 +725,17 @@ fun () -> plarc x y a b angle1 angle2 fill; ) in + let plot_axes (color, xopt, yopt, width, style) = + set_color_in color ( + fun () -> + let old_width = plgwid () in + plwid width; + set_line_style style; + plot_axes xopt yopt; + set_line_style Solid_line; + plwid old_width; + ) + in let plot_contours (color, pltr, contours, data) = set_color_in color ( fun () -> @@ -801,6 +856,7 @@ let one_plot p = match p with | Arc a -> plot_arc a + | Axes ax -> plot_axes ax | Contours c -> plot_contours c | Image i -> plot_image i | Image_fr (i, scale) -> plot_imagefr i scale @@ -825,33 +881,6 @@ let label ?stream x y title = with_stream ?stream (fun () -> pllab x y title) - (** An easier to deduce alternative to {Plplot.plbox} *) - let plot_axes ?stream ?(xtick = 0.0) ?(xsub =0) - ?(ytick = 0.0) ?(ysub = 0) xoptions yoptions = - let map_axis_options ol = - List.map ( - function - | Axis -> "a" - | Frame0 -> "b" - | Frame1 -> "c" - | Time -> "d" - | Fixed_point -> "f" - | Major_grid -> "g" - | Minor_grid -> "h" - | Invert_ticks -> "i" - | Log -> "l" - | Unconventional_label -> "m" - | Label -> "n" - | Custom_label -> "o" - | Minor_ticks -> "s" - | Major_ticks -> "t" - | Vertical_label -> "v" - ) ol - in - let xopt = String.concat "" (map_axis_options xoptions) in - let yopt = String.concat "" (map_axis_options yoptions) ^ "v" in - with_stream ?stream (fun () -> plbox xopt xtick xsub yopt ytick ysub) - (** [colorbar_base ?label ?log ?pos values] draws a colorbar, using the given values for the color range. [label] gives the position and text of the colorbar label; if [log] is true then the scale is taken to be log rather @@ -1065,48 +1094,17 @@ colorbar_base ?custom_axis ?label ?log ?pos ?width (`shade values) ) - (** Default page ending steps. Just draw the plot axes. *) - let default_finish ?stream ?axis ?xtick ?ytick () = - let xopt, yopt = - match axis with - | None -> default_axis_options, default_axis_options - | Some s -> s - in - set_color_in ?stream Black ( - fun () -> - plot_axes ?stream ?xtick xopt ?ytick yopt; - ) + (** Finish the current page, start a new one (alias for {!start_page}). *) + let next_page = start_page - (** Plot axes, but don't advance the page or end the session. This is used - internally by [finish]. *) - let finish_page ?stream ?f ?post ?axis ?xtick ?ytick () = - with_stream ?stream ( - fun () -> - let actual_finish = - match f with - | Some custom_finish -> custom_finish - | None -> default_finish ?stream ?axis ?xtick ?ytick - in - actual_finish (); - Option.may (fun f -> f ()) post; - ) - - (** Finish the current page, start a new one. *) - let next_page ?stream ?f ?post ?axis ?xtick ?ytick - (x0, y0) (x1, y1) axis_scaling = - finish_page ?stream ?f ?post ?axis ?xtick ?ytick (); - start_page ?stream (x0, y0) (x1, y1) axis_scaling; - () - (** End the current plot stream *) - let end_stream ~stream = - with_stream ~stream plend1 + let end_stream ?stream () = + with_stream ?stream plend1 - (** Finish up the plot by plotting axes and ending the session. This must - be called after plotting is complete. *) - let finish ?stream ?f ?post ?axis ?xtick ?ytick () = - finish_page ?stream ?f ?post ?axis ?xtick ?ytick (); - with_stream ?stream plend1 + (** Finish up the plot by plotting axes and ending the stream. *) + let finish ?stream () = + plot ?stream [default_axes]; + end_stream ?stream () end (** The [Quick_plot] module is intended to be used for quick, "throw-away" @@ -1158,7 +1156,7 @@ let xs_list, ys_list = List.split xs_ys_list in let xmin, xmax, ymin, ymax = extents xs_list ys_list in let ys_array = Array.of_list ys_list in - let p = init ?filename (xmin, ymin) (xmax, ymax) Greedy device in + let stream = init ?filename (xmin, ymin) (xmax, ymax) Greedy device in let plottable_points = Array.to_list ( Array.mapi ( @@ -1168,9 +1166,13 @@ ) (Array.of_list xs_list) ) in - plot ~stream:p plottable_points; - Option.may (fun (x, y, t) -> label ~stream:p x y t) labels; - finish ~stream:p ~axis:(maybe_log log) (); + let x_axis, y_axis = maybe_log log in + plot ~stream [ + list plottable_points; + axes x_axis y_axis; + ]; + Option.may (fun (x, y, t) -> label ~stream x y t) labels; + end_stream ~stream (); () (** [lines [xs, ys; ...] plots the line segments described by the coordinates @@ -1179,7 +1181,7 @@ let xs_list, ys_list = List.split xs_ys_list in let xmin, xmax, ymin, ymax = extents xs_list ys_list in let ys_array = Array.of_list ys_list in - let p = init ?filename (xmin, ymin) (xmax, ymax) Greedy device in + let stream = init ?filename (xmin, ymin) (xmax, ymax) Greedy device in let colors = Array.mapi (fun i _ -> Index_color (i + 1)) ys_array in let plottable_lines = Array.to_list ( @@ -1188,10 +1190,14 @@ ) (Array.of_list xs_list) ) in - plot ~stream:p plottable_lines; - Option.may (fun (x, y, t) -> label ~stream:p x y t) labels; - Option.may (fun n -> draw_legend ~stream:p n (Array.to_list colors)) names; - finish ~stream:p ~axis:(maybe_log log) (); + let x_axis, y_axis = maybe_log log in + plot ~stream [ + list plottable_lines; + axes x_axis y_axis; + ]; + Option.may (fun (x, y, t) -> label ~stream x y t) labels; + Option.may (fun n -> draw_legend ~stream n (Array.to_list colors)) names; + end_stream ~stream (); () (** [image ?log m] plots the image [m] with a matching colorbar. If [log] is @@ -1201,12 +1207,15 @@ let xmin, ymin = 0.0, 0.0 in let xmax, ymax = Array_ext.matrix_dims m in let xmax, ymax = float_of_int xmax, float_of_int ymax in - let p = init ?filename (xmin, ymin) (xmax, ymax) Equal_square device in - Option.may (load_palette ~stream:p) palette; - plot ~stream:p [image (xmin, ymin) (xmax, ymax) m]; - Option.may (fun (x, y, t) -> label ~stream:p x y t) labels; - colorbar ~stream:p ?log ~pos:(Right 0.12) (m_min, m_max); - finish ~stream:p (); + let stream = init ?filename (xmin, ymin) (xmax, ymax) Equal_square device in + Option.may (load_palette ~stream) palette; + plot ~stream [ + image (xmin, ymin) (xmax, ymax) m; + default_axes; + ]; + Option.may (fun (x, y, t) -> label ~stream x y t) labels; + colorbar ~stream ?log ~pos:(Right 0.12) (m_min, m_max); + end_stream ~stream (); () (** [func ?point ?step fs (min, max)] plots the functions [fs] from [x = min] @@ -1237,10 +1246,13 @@ in let ymax, ymin = plMinMax2dGrid ys in let stream = init ?filename (xmin, ymin) (xmax, ymax) Greedy device in - plot ~stream plot_content; + plot ~stream [ + list plot_content; + default_axes; + ]; Option.may (fun n -> draw_legend ~stream n (Array.to_list colors)) names; Option.may (fun (x, y, t) -> label ~stream x y t) labels; - finish ~stream (); + end_stream ~stream (); () let shades ?filename ?(device = Window Cairo) ?labels ?log ?palette ?contours @@ -1248,18 +1260,21 @@ let xmin, ymin = 0.0, 0.0 in let xmax, ymax = Array_ext.matrix_dims m in let xmax, ymax = float_of_int xmax, float_of_int ymax in - let p = init ?filename (xmin, ymin) (xmax, ymax) Equal_square device in - Option.may (load_palette ~stream:p) palette; + let stream = init ?filename (xmin, ymin) (xmax, ymax) Equal_square device in + Option.may (load_palette ~stream) palette; let contours = contours |? ( let m_max, m_min = plMinMax2dGrid m in Array_ext.range ~n:11 m_min m_max ) in - plot ~stream:p [shades (xmin, ymin) (xmax, ymax) contours m]; - Option.may (fun (x, y, t) -> label ~stream:p x y t) labels; - shadebar ~stream:p ?log ~pos:(Right 0.12) contours; - finish ~stream:p (); + plot ~stream [ + shades (xmin, ymin) (xmax, ymax) contours m; + default_axes; + ]; + Option.may (fun (x, y, t) -> label ~stream x y t) labels; + shadebar ~stream ?log ~pos:(Right 0.12) contours; + end_stream ~stream (); () end Modified: trunk/bindings/ocaml/plplot.mli =================================================================== --- trunk/bindings/ocaml/plplot.mli 2010-04-11 23:51:49 UTC (rev 10902) +++ trunk/bindings/ocaml/plplot.mli 2010-04-12 04:14:12 UTC (rev 10903) @@ -55,7 +55,9 @@ | Label | Custom_label | Minor_ticks + | Minor_tick_count of int | Major_ticks + | Major_tick_spacing of float | Vertical_label (** A plot stream. *) @@ -172,6 +174,11 @@ ?stream:stream_t -> float * float -> float * float -> plot_scaling_t -> unit + (** An alias for {!start_page}. *) + val next_page : + ?stream:stream_t -> + float * float -> float * float -> plot_scaling_t -> unit + (** Create a new plot instance. See {!init} for a description of the parameters. *) val make : @@ -246,6 +253,17 @@ ?fill:bool -> color_t -> float -> float -> float -> float -> float -> float -> plot_t + (** [axes ?color ?style ?width xopt yopt] *) + val axes : + ?color:color_t -> + ?style:line_style_t -> + ?width:int -> + axis_options_t list -> axis_options_t list -> plot_t + + (** [default_axes] is equivalent to + [axes default_axis_options default_axis_options] *) + val default_axes : plot_t + (** [circle ?fill color x y r] *) val circle : ?fill:bool -> color_t -> float -> float -> float -> plot_t @@ -404,43 +422,16 @@ (** Draw the plot axes on the current plot page *) val plot_axes : ?stream:stream_t -> - ?xtick:float -> - ?xsub:int -> - ?ytick:float -> - ?ysub:int -> axis_options_t list -> axis_options_t list -> unit (** {4 Finishing up a plot page} *) - (** Plot axes, but don't advance the page or end the session. This is used - internally by [finish]. *) - val finish_page : - ?stream:stream_t -> - ?f:(unit -> unit) -> - ?post:(unit -> unit) -> - ?axis:axis_options_t list * axis_options_t list -> - ?xtick:float -> ?ytick:float -> - unit -> unit + (** [end_stream ?stream ()] ends [stream]. This or {!finish} should be + called once all plotting is complete. *) + val end_stream : ?stream:stream_t -> unit -> unit - (** Finish the current page, start a new one. *) - val next_page : - ?stream:stream_t -> - ?f:(unit -> unit) -> - ?post:(unit -> unit) -> - ?axis:axis_options_t list * axis_options_t list -> - ?xtick:float -> - ?ytick:float -> - float * float -> float * float -> plot_scaling_t -> unit - - (** [finish ?stream xstep ystep] finishes up the plot [stream], using - [xstep] and [ystep] for the axis tick. *) - val finish : - ?stream:stream_t -> - ?f:(unit -> unit) -> - ?post:(unit -> unit) -> - ?axis:axis_options_t list * axis_options_t list -> - ?xtick:float -> ?ytick:float -> - unit -> unit + (** [finish ?stream ()] draws default x and y axes, then closes [stream]. *) + val finish : ?stream:stream_t -> unit -> unit end (** {3 A module for quick, "throw-away" plots} *) Modified: trunk/examples/ocaml/xplot01.ml =================================================================== --- trunk/examples/ocaml/xplot01.ml 2010-04-11 23:51:49 UTC (rev 10902) +++ trunk/examples/ocaml/xplot01.ml 2010-04-12 04:14:12 UTC (rev 10903) @@ -98,11 +98,10 @@ P.points ~symbol:P.Solar_symbol P.Green xs ys; (* Draw the line through the data *) P.lines P.Red x y; + (* Show the axes *) + P.default_axes; ]; - (* Show the axes *) - P.finish_page ~stream (); - (* All done. *) stream @@ -128,16 +127,18 @@ ) in - (* Draw the line *) - P.plot ~stream [P.lines ~width:2 P.Red x y]; - (* Show the axes *) - let axis = + let x_axis, y_axis = P.Axis :: P.default_axis_options, P.Axis :: P.default_axis_options in - P.finish_page ~stream ~axis (); + (* Draw the line *) + P.plot ~stream [ + P.lines ~width:2 P.Red x y; + P.axes x_axis y_axis; + ]; + (* All done. *) () @@ -149,15 +150,6 @@ from -1.2 to 1.2.*) P.start_page ~stream (0.0, -1.2) (360.0, 1.2) P.Greedy; - (* Superimpose a dashed line grid, with 1.5 mm marks and spaces. *) - P.with_stream ~stream ( - fun () -> - plstyl [|mark1|] [|space1|]; - P.set_color P.Yellow; - P.plot_axes ~xtick:30.0 ~ytick:0.2 [P.Major_grid] [P.Major_grid]; - plstyl [||] [||]; - ); - P.set_color ~stream P.Red; P.label ~stream "Angle (degrees)" "sine" "#frPLplot Example 1 - Sine function"; @@ -165,22 +157,28 @@ let x = Array.init 101 (fun i -> 3.6 *. float_of_int i) in let y = Array.init 101 (fun i -> sin (x.(i) *. pi /. 180.0)) in - P.plot ~stream [P.lines P.Brown x y]; - (* For the final graph we wish to override the default axis attributes, including tick intervals. Draw a box with ticks spaced 60 degrees apart in X, and 0.2 in Y. *) - let axis = + let x_axis, y_axis = (* x-axis *) - [P.Frame0; P.Frame1; P.Label; P.Minor_ticks; P.Major_ticks], + [P.Frame0; P.Frame1; P.Label; P.Minor_ticks; P.Major_tick_spacing 60.0], (* y-axis *) [ - P.Frame0; P.Frame1; P.Label; P.Minor_ticks; P.Major_ticks; + P.Frame0; P.Frame1; P.Label; P.Minor_ticks; P.Major_tick_spacing 0.2; P.Vertical_label ] in - P.finish_page ~stream ~axis ~xtick:60.0 ~ytick:0.2 (); + P.plot ~stream [ + (* Superimpose a dashed line grid, with 1.5 mm marks and spaces. *) + P.axes ~color:P.Yellow ~style:(P.Custom_line [mark1, space1]) + [P.Major_grid; P.Major_tick_spacing 30.0] + [P.Major_grid; P.Major_tick_spacing 0.2]; + P.lines P.Brown x y; + (* The normal plot axes *) + P.axes x_axis y_axis; + ]; (* All done. *) () @@ -232,9 +230,9 @@ plot3 stream; - (* Don't forget to finish off! Each function does the needed end-of-page - steps, so all we need to do here is wrap up the plotting session. *) - P.finish ~stream ~f:(fun () -> ()) (); + (* Don't forget to finish off! All we need to do here is close up the + plot stream. *) + P.end_stream ~stream (); () let () = main true This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |