Mercurial > octave
view scripts/plot/util/private/__gnuplot_draw_axes__.m @ 22630:5ab3c91fc4bb
Correct hggroup plot legends for gnuplot toolkit, add legend demo 17 items (bug #49341)
* legend.m: For demo 17, use 2x1 subplots and add a stem example having both
stem series with single color and with different color for stems and markers.
Place both plot legends in the northwest corner.
* __gnuplot_draw_axes__.m: Move title and phantom data sooner in 'line' object
case and set is_image_data, parametric, have_cdata and have_3d_patch array
values all to 'false'. Distinguish between stem series data and error bar
data under 'line' case by checking for existence of 'format' property in the
hggroup. For stem series data, call another do_linestyle_command using the
parent, i.e., hggroup. For the 'patch' case, copy the parent 'displayname'
property to the object--as was done prior to the phantom data approach. The
above two changes fixes 'demo legend 17'. For 'surface' case, make a mock
key symbol using phantom data and a thick line. The above change fixes
'demo legend 18'.
(do_linestyle_command): Remove extraneous '! isempty (pt)' conditional tests.
author | Daniel J Sebald <daniel.sebald@ieee.org> |
---|---|
date | Sun, 16 Oct 2016 02:23:54 -0500 |
parents | 54332b6ddeb6 |
children | 859d48b5648d |
line wrap: on
line source
## Copyright (C) 2005-2016 John W. Eaton ## ## This file is part of Octave. ## ## Octave is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or (at ## your option) any later version. ## ## Octave 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 ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {} {} __gnuplot_draw_axes__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{bg_is_set}, @var{fg_is_set}, @var{hlgnd}) ## Undocumented internal function. ## @end deftypefn ## Author: jwe function __gnuplot_draw_axes__ (h, plot_stream, enhanced, bg_is_set, fg_is_set, hlgnd) showhiddenhandles = get (0, "showhiddenhandles"); unwind_protect set (0, "showhiddenhandles", "on"); axis_obj = __get__ (h); unwind_protect_cleanup set (0, "showhiddenhandles", showhiddenhandles); end_unwind_protect parent_figure_obj = get (axis_obj.parent); gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM"); ## Set to false for plotyy axes. ymirror = true; if (isfield (axis_obj, "__plotyy_axes__")) if (all (ishandle (axis_obj.__plotyy_axes__))) ymirror = false; else h = axis_obj.__plotyy_axes__; h = h(ishandle (h)); h = h(isprop (h, "__plotyy_axes__")); rmappdata (h, "__plotyy_axes__"); endif endif nd = __calc_dimensions__ (h); if (strcmp (axis_obj.dataaspectratiomode, "manual") && strcmp (axis_obj.xlimmode, "manual") && strcmp (axis_obj.ylimmode, "manual")) ## All can't be "manual" axis_obj.plotboxaspectratiomode = "auto"; endif if (strcmp (axis_obj.dataaspectratiomode, "manual") && strcmp (axis_obj.xlimmode, "manual") && strcmp (axis_obj.ylimmode, "manual") && (nd == 2 || all (mod (axis_obj.view, 90) == 0))) ## FIXME: adjust plotboxaspectratio to respect other fpos = get (axis_obj.parent, "position"); apos = axis_obj.position; endif pos = __actual_axis_position__ (h); if (strcmp (axis_obj.dataaspectratiomode, "manual")) dr = axis_obj.dataaspectratio; if (nd == 2 || all (mod (axis_obj.view, 90) == 0)) dr = dr(1) / dr(2); else ## FIXME: need to properly implement 3D dr = mean (dr(1:2)) / dr(3); endif else dr = 1; endif if (strcmp (axis_obj.activepositionproperty, "position")) if (nd == 2 || all (mod (axis_obj.view, 90) == 0)) x = [1, 1]; else ## 3D plots need to be sized down to fit in the window. x = 1.0 ./ sqrt ([2, 2.5]); endif fprintf (plot_stream, "set tmargin screen %.15g;\n", pos(2)+pos(4)/2+x(2)*pos(4)/2); fprintf (plot_stream, "set bmargin screen %.15g;\n", pos(2)+pos(4)/2-x(2)*pos(4)/2); fprintf (plot_stream, "set lmargin screen %.15g;\n", pos(1)+pos(3)/2-x(1)*pos(3)/2); fprintf (plot_stream, "set rmargin screen %.15g;\n", pos(1)+pos(3)/2+x(1)*pos(3)/2); sz_str = ""; else ## activepositionproperty == outerposition fprintf (plot_stream, "unset tmargin;\n"); fprintf (plot_stream, "unset bmargin;\n"); fprintf (plot_stream, "unset lmargin;\n"); fprintf (plot_stream, "unset rmargin;\n"); fprintf (plot_stream, "set origin %g, %g;\n", pos(1:2)); if (strcmp (axis_obj.dataaspectratiomode, "manual")) sz_str = sprintf ("ratio %g", -dr); else sz_str = "noratio"; endif sz_str = sprintf ("set size %s %g, %g;\n", sz_str, pos(3:4)); endif if (! isempty (sz_str)) fputs (plot_stream, sz_str); endif ## Code above uses axis size for the data aspect ratio, which isn't ## quite correct. The only fine control is to set all axes units equal. if (nd == 3 && strcmp (axis_obj.dataaspectratiomode, "manual") && axis_obj.dataaspectratio(1) == axis_obj.dataaspectratio(2)) if (axis_obj.dataaspectratio(1) == axis_obj.dataaspectratio(3)) zstr = "z"; else zstr = ""; endif fprintf (plot_stream, "set view equal xy%s;\n", zstr); endif ## Reset all labels, axis-labels, tick-labels, and title ## FIXME: We should have an function to initialize the axis. ## Presently, this is dispersed in this function. fputs (plot_stream, "unset label;\n"); fputs (plot_stream, "unset xtics;\n"); fputs (plot_stream, "unset ytics;\n"); fputs (plot_stream, "unset ztics;\n"); fputs (plot_stream, "unset x2tics;\n"); fputs (plot_stream, "unset y2tics;\n"); if (isempty (axis_obj.title) || isempty (get (axis_obj.title, "string"))) fputs (plot_stream, "unset title;\n"); else if (nd == 2) t = get(axis_obj.title); colorspec = get_text_colorspec (t.color); [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); fontspec = create_fontspec (f, s, gnuplot_term); fprintf (plot_stream, "set title \"%s\" %s %s %s;\n", undo_string_escapes (tt), fontspec, colorspec, __do_enhanced_option__ (enhanced, t)); else ## Change meaning of "normalized", but it at least gives user some control if (! strcmp (get (axis_obj.title, "units"), "normalized")) unwind_protect set (axis_obj.title, "units", "normalized"); set (axis_obj.title, "position", [0.5 1.02 0.5]); unwind_protect_cleanup end_unwind_protect endif t = get(axis_obj.title); axispos = axis_obj.position; screenpos = t.position; screenpos(1) = axispos(1)+screenpos(1)*axispos(3); screenpos(2) = axispos(2)+screenpos(2)*axispos(4); fputs (plot_stream, "unset title;\n"); do_text (plot_stream, gnuplot_term, enhanced, t, h, screenpos); endif endif if (! isempty (axis_obj.xlabel)) t = get (axis_obj.xlabel); angle = t.rotation; colorspec = get_text_colorspec (t.color); if (isempty (t.string)) fprintf (plot_stream, "unset xlabel;\n"); fprintf (plot_stream, "unset x2label;\n"); else [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); fontspec = create_fontspec (f, s, gnuplot_term); if (strcmp (axis_obj.xaxislocation, "top")) fprintf (plot_stream, "set x2label \"%s\" %s %s %s", undo_string_escapes (tt), colorspec, fontspec, __do_enhanced_option__ (enhanced, t)); else fprintf (plot_stream, "set xlabel \"%s\" %s %s %s", undo_string_escapes (tt), colorspec, fontspec, __do_enhanced_option__ (enhanced, t)); endif fprintf (plot_stream, " rotate by %f;\n", angle); if (strcmp (axis_obj.xaxislocation, "top")) fprintf (plot_stream, "unset xlabel;\n"); else fprintf (plot_stream, "unset x2label;\n"); endif endif endif if (! isempty (axis_obj.ylabel)) t = get (axis_obj.ylabel); angle = t.rotation; colorspec = get_text_colorspec (t.color); if (isempty (t.string)) fprintf (plot_stream, "unset ylabel;\n"); fprintf (plot_stream, "unset y2label;\n"); else [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); fontspec = create_fontspec (f, s, gnuplot_term); if (strcmp (axis_obj.yaxislocation, "right")) fprintf (plot_stream, "set y2label \"%s\" %s %s %s", undo_string_escapes (tt), colorspec, fontspec, __do_enhanced_option__ (enhanced, t)); else fprintf (plot_stream, "set ylabel \"%s\" %s %s %s", undo_string_escapes (tt), colorspec, fontspec, __do_enhanced_option__ (enhanced, t)); endif fprintf (plot_stream, " rotate by %f;\n", angle); if (strcmp (axis_obj.yaxislocation, "right")) fprintf (plot_stream, "unset ylabel;\n"); else fprintf (plot_stream, "unset y2label;\n"); endif endif endif if (! isempty (axis_obj.zlabel)) t = get (axis_obj.zlabel); angle = t.rotation; colorspec = get_text_colorspec (t.color); if (isempty (t.string)) fputs (plot_stream, "unset zlabel;\n"); else [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); fontspec = create_fontspec (f, s, gnuplot_term); fprintf (plot_stream, "set zlabel \"%s\" %s %s %s", undo_string_escapes (tt), colorspec, fontspec, __do_enhanced_option__ (enhanced, t)); fprintf (plot_stream, " rotate by %f;\n", angle); endif endif if (strcmp (axis_obj.xaxislocation, "top")) xaxisloc = "x2"; xaxisloc_using = "x2"; else xaxisloc = "x"; xaxisloc_using = "x1"; if (any (strcmp (axis_obj.xaxislocation, {"origin", "zero"}))) # FIXME: Remove "zero" in 4.6 fputs (plot_stream, "set xzeroaxis;\n"); endif endif if (strcmp (axis_obj.yaxislocation, "right")) yaxisloc = "y2"; yaxisloc_using = "y2"; else yaxisloc = "y"; yaxisloc_using = "y1"; if (any (strcmp (axis_obj.yaxislocation, {"origin", "zero"}))) # FIXME: Remove "zero" in 4.6 fputs (plot_stream, "set yzeroaxis;\n"); endif endif have_major_grid = false; have_minor_grid = false; visible_gls = ! strcmp (axis_obj.gridlinestyle, "none") ... && ! strcmp (axis_obj.gridcolor, "none"); visible_mgls = ! strcmp (axis_obj.minorgridlinestyle, "none") ... && ! strcmp (axis_obj.minorgridcolor, "none"); if (strcmp (axis_obj.xgrid, "on") && visible_gls) have_major_grid = true; fprintf (plot_stream, "set grid %stics;\n", xaxisloc); else fprintf (plot_stream, "set grid no%stics;\n", xaxisloc); endif if (strcmp (axis_obj.ygrid, "on") && visible_gls) have_major_grid = true; fprintf (plot_stream, "set grid %stics;\n", yaxisloc); else fprintf (plot_stream, "set grid no%stics;\n", yaxisloc); endif if (strcmp (axis_obj.zgrid, "on") && visible_gls) have_major_grid = true; fputs (plot_stream, "set grid ztics;\n"); else fputs (plot_stream, "set grid noztics;\n"); endif if (strcmp (axis_obj.xminorgrid, "on") && visible_mgls) have_minor_grid = true; if (strcmp (axis_obj.xscale, "log")) m = 10; else m = 5; endif fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m); fprintf (plot_stream, "set grid m%stics;\n", xaxisloc); else fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc); endif if (strcmp (axis_obj.yminorgrid, "on") && visible_mgls) have_minor_grid = true; if (strcmp (axis_obj.yscale, "log")) m = 10; else m = 5; endif fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m); fprintf (plot_stream, "set grid m%stics;\n", yaxisloc); else fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc); endif if (strcmp (axis_obj.zminorgrid, "on") && visible_mgls) have_minor_grid = true; if (strcmp (axis_obj.zscale, "log")) m = 10; else m = 5; endif fprintf (plot_stream, "set mztics %d;\n", m); fputs (plot_stream, "set grid mztics;\n"); else fputs (plot_stream, "set grid nomztics;\n"); endif ## The grid front/back/layerdefault option also controls the ## appearance of tics, so it is used even if the grid is absent. if (strcmp (axis_obj.layer, "top")) fputs (plot_stream, "set grid front;\n"); fputs (plot_stream, "set border front;\n"); else fputs (plot_stream, "set grid layerdefault;\n"); endif xlogscale = strcmp (axis_obj.xscale, "log"); ylogscale = strcmp (axis_obj.yscale, "log"); zlogscale = strcmp (axis_obj.zscale, "log"); ## Detect logscale and negative lims if (xlogscale && all (axis_obj.xlim < 0)) axis_obj.xsgn = -1; if (strcmp (axis_obj.xdir, "reverse")) axis_obj.xdir = "normal"; elseif (strcmp (axis_obj.xdir, "normal")) axis_obj.xdir = "reverse"; endif axis_obj.xtick = -flip (axis_obj.xtick); axis_obj.xticklabel = flip (axis_obj.xticklabel); axis_obj.xlim = -flip (axis_obj.xlim); else axis_obj.xsgn = 1; endif if (ylogscale && all (axis_obj.ylim < 0)) axis_obj.ysgn = -1; if (strcmp (axis_obj.ydir, "reverse")) axis_obj.ydir = "normal"; elseif (strcmp (axis_obj.ydir, "normal")) axis_obj.ydir = "reverse"; endif axis_obj.ytick = -flip (axis_obj.ytick); axis_obj.yticklabel = flip (axis_obj.yticklabel); axis_obj.ylim = -flip (axis_obj.ylim); else axis_obj.ysgn = 1; endif if (zlogscale && all (axis_obj.zlim < 0)) axis_obj.zsgn = -1; if (strcmp (axis_obj.zdir, "reverse")) axis_obj.zdir = "normal"; elseif (strcmp (axis_obj.zdir, "normal")) axis_obj.zdir = "reverse"; endif axis_obj.ztick = -flip (axis_obj.ztick); axis_obj.zticklabel = flip (axis_obj.zticklabel); axis_obj.zlim = -flip (axis_obj.zlim); else axis_obj.zsgn = 1; endif xlim = axis_obj.xlim; ylim = axis_obj.ylim; zlim = axis_obj.zlim; clim = axis_obj.clim; do_tics (axis_obj, plot_stream, ymirror, gnuplot_term); fputs (plot_stream, "unset logscale;\n"); if (xlogscale) fprintf (plot_stream, "set logscale %s;\n", xaxisloc); endif if (ylogscale) fprintf (plot_stream, "set logscale %s;\n", yaxisloc); endif if (zlogscale) fputs (plot_stream, "set logscale z;\n"); endif xautoscale = strcmp (axis_obj.xlimmode, "auto"); yautoscale = strcmp (axis_obj.ylimmode, "auto"); zautoscale = strcmp (axis_obj.zlimmode, "auto"); cautoscale = strcmp (axis_obj.climmode, "auto"); fputs (plot_stream, "set clip two;\n"); kids = axis_obj.children; ## Remove the axis labels and title from the children, and ## preserved the original order. [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ... axis_obj.zlabel; axis_obj.title]); kids = kids(sort (k)); if (nd == 3) fputs (plot_stream, "set parametric;\n"); fputs (plot_stream, "set style data lines;\n"); fputs (plot_stream, "set surface;\n"); fputs (plot_stream, "unset contour;\n"); endif data_idx = 0; data = cell (); is_image_data = []; hidden_removal = NaN; view_map = false; if (cautoscale) ## First pass to get cdata limits, maybe general graphics should do this kids1 = kids; clim = [Inf -Inf]; while (! isempty (kids1)) obj = get (kids1(end)); kids1 = kids1(1:(end-1)); switch (obj.type) case {"image", "patch", "surface"} if (isfield (obj, "cdatamapping") && strcmp (obj.cdatamapping, "scaled") && isfield (obj, "cdata") && ! isempty (obj.cdata)) clim(1) = min (clim(1), min (obj.cdata(:))); clim(2) = max (clim(2), max (obj.cdata(:))); endif case "hggroup" ## Push group children into the kid list. if (isempty (kids1)) kids1 = obj.children; elseif (! isempty (obj.children)) kids1 = [kids1; obj.children]; endif endswitch endwhile if (clim(1) == Inf) clim = axis_obj.clim; endif elseif (clim(1) == clim(2)) clim(2)++; endif if (rows (parent_figure_obj.colormap) != 2) ## Second pass to change color map for binary images (not sure correct) kids1 = kids; while (! isempty (kids1)) obj = get (kids1(end)); kids1 = kids1(1:(end-1)); switch (obj.type) case {"image"} if (isfield (obj, "cdata") && islogical (obj.cdata)) parent_figure_obj.colormap = [0 0 0; 1 1 1]; axis_obj.clim = [0 1]; axis_obj.climmode = "manual"; break; endif case "hggroup" ## Push group children into the kid list. if (isempty (kids1)) kids1 = obj.children; elseif (! isempty (obj.children)) kids1 = [kids1; obj.children]; endif endswitch endwhile endif cmap = parent_figure_obj.colormap; cmap_sz = rows (cmap); addedcmap = []; ximg_data = {}; ximg_data_idx = 0; while (! isempty (kids)) h_obj = kids(end); kids = kids(1:(end-1)); obj = get (h_obj); if (isfield (obj, "xdata")) obj.xdata = double (obj.xdata); endif if (isfield (obj, "ydata")) obj.ydata = double (obj.ydata); endif if (isfield (obj, "zdata")) obj.zdata = double (obj.zdata); endif if (isfield (obj, "units")) units = obj.units; unwind_protect set (h_obj, "units", "data"); obj = get (h_obj); unwind_protect_cleanup set (h_obj, "units", units); end_unwind_protect endif if (strcmp (obj.visible, "off")) continue; endif if (xlogscale && isfield (obj, "xdata")) obj.xdata = axis_obj.xsgn * obj.xdata; obj.xdata(obj.xdata<=0) = NaN; endif if (ylogscale && isfield (obj, "ydata")) obj.ydata = axis_obj.ysgn * obj.ydata; obj.ydata(obj.ydata<=0) = NaN; endif if (zlogscale && isfield (obj, "zdata")) obj.zdata = axis_obj.zsgn * obj.zdata; obj.zdata(obj.zdata<=0) = NaN; endif switch (obj.type) case "image" img_data = mapcdata (obj.cdata, obj.cdatamapping, clim, cmap_sz); img_xdata = obj.xdata; img_ydata = obj.ydata; data_idx += 1; is_image_data(data_idx) = true; parametric(data_idx) = false; have_cdata(data_idx) = false; have_3d_patch(data_idx) = false; if (img_xdata(2) < img_xdata(1)) img_xdata = img_xdata(2:-1:1); img_data = img_data(:,end:-1:1,:); elseif (img_xdata(1) == img_xdata(2)) img_xdata = img_xdata(1) + [0, columns(img_data)-1]; endif if (img_ydata(2) < img_ydata(1)) img_ydata = img_ydata(2:-1:1); img_data = img_data(end:-1:1,:,:); elseif (img_ydata(1) == img_ydata(2)) img_ydata = img_ydata(1) + [0, rows(img_data)-1]; endif x_origin = min (img_xdata); y_origin = min (img_ydata); [y_dim, x_dim] = size (img_data(:,:,1)); if (x_dim > 1) dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1); else x_dim = 2; img_data = [img_data, img_data]; dx = abs (img_xdata(2)-img_xdata(1)); if (dx < 1) ## Correct gnuplot string for 1-D images dx = 0.5; x_origin = 0.75; endif endif if (y_dim > 1) dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1); else y_dim = 2; img_data = [img_data; img_data]; dy = abs (img_ydata(2)-img_ydata(1)); if (dy < 1) ## Correct gnuplot string for 1-D images dy = 0.5; y_origin = 0.75; endif endif if (ndims (img_data) == 3) data{data_idx} = permute (img_data, [3, 1, 2])(:); format = "1:2:3"; imagetype = "rgbimage"; else data{data_idx} = img_data(:); format = "1"; imagetype = "image"; endif titlespec{data_idx} = "title \"\""; usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s", x_dim, y_dim, x_origin, y_origin, dx, dy, format); withclause{data_idx} = sprintf ("with %s;", imagetype); case "line" if (strcmp (get (obj.parent, "type"), "hggroup")) hg = get (obj.parent, "children"); if (hg(1) == h_obj && ! isempty (get (obj.parent, "displayname"))) data_idx += 1; is_image_data(data_idx) = false; parametric(data_idx) = false; have_cdata(data_idx) = false; have_3d_patch(data_idx) = false; tmpdispname = obj.displayname; obj.displayname = get (obj.parent, "displayname"); tmp = undo_string_escapes ( __maybe_munge_text__ (enhanced, obj, "displayname") ); titlespec{data_idx} = ['title "' tmp '"']; obj.displayname = tmpdispname; if (! isempty (findobj (obj.parent, "-property", "format", "-depth", 0))) # Place phantom errorbar data for legend data{data_idx} = nan (4,1); usingclause{data_idx} = sprintf ("record=1 using ($1):($2):($3):($4)"); switch (get (obj.parent, "format")) case {"box" "boxy" "boxxy"} errbars = "boxxy"; case "xyerr" errbars = "xyerrorbars"; case "yerr" errbars = "yerrorbars"; case "xerr" errbars = "xerrorbars"; otherwise errbars = "xerrorbars"; endswitch withclause{data_idx} = sprintf ("with %s linestyle %d", errbars, sidx(1)); else ## Place phantom stemseries data for legend data{data_idx} = nan (2,1); usingclause{data_idx} = sprintf ("record=1 using ($1):($2)"); hgobj = get (obj.parent); [hgstyle, hgsidx] = do_linestyle_command (hgobj, hgobj.color, data_idx, plot_stream); withclause{data_idx} = sprintf ("with %s linestyle %d", hgstyle{1}, hgsidx(1)); endif endif endif if (strcmp (obj.linestyle, "none") && (! isfield (obj, "marker") || (isfield (obj, "marker") && strcmp (obj.marker, "none")))) continue; endif data_idx += 1; is_image_data(data_idx) = false; parametric(data_idx) = true; have_cdata(data_idx) = false; have_3d_patch(data_idx) = false; if (isempty (obj.displayname)) titlespec{data_idx} = "title \"\""; else tmp = undo_string_escapes ( __maybe_munge_text__ (enhanced, obj, "displayname") ); titlespec{data_idx} = ['title "' tmp '"']; endif usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); if (nd == 3) xdat = obj.xdata(:); ydat = obj.ydata(:); if (! isempty (obj.zdata)) zdat = obj.zdata(:); else zdat = zeros (size (xdat)); endif data{data_idx} = [xdat, ydat, zdat]'; usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat)); ## fputs (plot_stream, "set parametric;\n"); else xdat = obj.xdata(:); ydat = obj.ydata(:); data{data_idx} = [xdat, ydat]'; usingclause{data_idx} = ... sprintf ("record=%d using ($1):($2) axes %s%s", rows (xdat), xaxisloc_using, yaxisloc_using); endif [style, sidx] = do_linestyle_command (obj, obj.color, data_idx, plot_stream); if isempty (style{1}) style{1} = "points"; data{data_idx} = {}; endif withclause{data_idx} = sprintf ("with %s linestyle %d", style{1}, sidx(1)); if (length (style) > 1) data_idx += 1; is_image_data(data_idx) = is_image_data(data_idx - 1); parametric(data_idx) = parametric(data_idx - 1); have_cdata(data_idx) = have_cdata(data_idx - 1); have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); titlespec{data_idx} = "title \"\""; usingclause{data_idx} = usingclause{data_idx - 1}; data{data_idx} = data{data_idx - 1}; withclause{data_idx} = sprintf ("with %s linestyle %d", style{2}, sidx(2)); endif if (length (style) > 2) data_idx += 1; is_image_data(data_idx) = is_image_data(data_idx - 1); parametric(data_idx) = parametric(data_idx - 1); have_cdata(data_idx) = have_cdata(data_idx - 1); have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); titlespec{data_idx} = "title \"\""; usingclause{data_idx} = usingclause{data_idx - 1}; data{data_idx} = data{data_idx - 1}; withclause{data_idx} = sprintf ("with %s linestyle %d", style{3}, sidx(3)); endif case "patch" if (strcmp (get (obj.parent, "type"), "hggroup")) obj.displayname = get (obj.parent, "displayname"); endif [nr, nc] = size (obj.xdata); if (! isempty (obj.cdata)) cdat = obj.cdata; else cdat = []; endif data_3d_idx = NaN; for i = 1:nc xcol = obj.xdata(:,i); ycol = obj.ydata(:,i); if (nd == 3) if (! isempty (obj.zdata)) zcol = obj.zdata(:,i); else zcol = zeros (size (xcol)); endif endif if (! isnan (xcol) && ! isnan (ycol)) ## Is the patch closed or not if (! strcmp (obj.facecolor, "none")) hidden_removal = true; if (nd == 3) if (numel (xcol) > 3) error ("__gnuplot_draw_axes__: gnuplot (as of v4.2) only supports 3-D filled triangular patches"); else if (isnan (data_3d_idx)) data_idx += 1; data_3d_idx = data_idx; is_image_data(data_idx) = false; parametric(data_idx) = false; have_cdata(data_idx) = true; have_3d_patch(data_idx) = true; withclause{data_3d_idx} = sprintf ("with pm3d"); usingclause{data_3d_idx} = "using 1:2:3:4"; data{data_3d_idx} = []; endif local_idx = data_3d_idx; ccdat = NaN; endif else data_idx += 1; local_idx = data_idx; is_image_data(data_idx) = false; parametric(data_idx) = false; have_cdata(data_idx) = false; have_3d_patch(data_idx) = false; endif if (i > 1 || isempty (obj.displayname)) titlespec{local_idx} = "title \"\""; else tmp = undo_string_escapes ( __maybe_munge_text__ (enhanced, obj, "displayname") ); titlespec{local_idx} = ['title "' tmp '"']; endif if (isfield (obj, "facecolor")) if ((strcmp (obj.facecolor, "flat") || strcmp (obj.facecolor, "interp")) && isfield (obj, "cdata")) if (ndims (obj.cdata) == 2 && (columns (obj.cdata) == nc && (rows (obj.cdata) == 1 || rows (obj.cdata) == 3))) ccol = cdat(:, i); elseif (ndims (obj.cdata) == 2 && (rows (obj.cdata) == nc && (columns (obj.cdata) == 1 || columns (obj.cdata) == 3))) ccol = cdat(i, :); elseif (ndims (obj.cdata) == 3) ccol = permute (cdat (:, i, :), [1, 3, 2]); else ccol = cdat; endif if (strcmp (obj.facecolor, "flat")) if (isequal (size (ccol), [1, 3])) ## RGB Triplet color = ccol; else ccdat = mapcdata (ccol, obj.cdatamapping, clim, cmap_sz); if (nd == 3 && numel (xcol) == 3) color = cmap(ccdat(1), :); else color = cmap(ccdat, :); endif endif elseif (strcmp (obj.facecolor, "interp")) if (nd == 3 && numel (xcol) == 3) ccdat = ccol; if (! isvector (ccdat)) tmp = cmap_sz + rows (addedcmap) + ... [1 : rows(ccdat)]; addedcmap = [addedcmap; ccdat]; ccdat = tmp(:); else ccdat = mapcdata (ccdat(:), obj.cdatamapping, clim, cmap_sz); endif else if (sum (diff (ccol))) warning ("\"interp\" not supported, using 1st entry of cdata"); endif r = mapcdata (ccol, obj.cdatamapping, clim, cmap_sz); color = cmap(r(1),:); endif endif elseif (isnumeric (obj.facecolor)) color = obj.facecolor; else color = [0, 1, 0]; endif else color = [0, 1, 0]; endif if (nd == 3 && numel (xcol) == 3) if (isnan (ccdat)) ccdat = (cmap_sz + rows (addedcmap) + 1) * ones(3, 1); addedcmap = [addedcmap; reshape(color, 1, 3)]; elseif (numel (ccdat) == 1) ccdat = ccdat * ones (size (zcol)); elseif (numel (ccdat) < 1) ccdat = zcol; endif data{data_3d_idx} = [data{data_3d_idx}, ... [[xcol; xcol(end)], [ycol; ycol(end)], ... [zcol; zcol(end)], [ccdat; ccdat(end)]]']; else if (isscalar (obj.facealpha)) colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f", round (255*color), obj.facealpha); else colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", round (255*color)); endif withclause{data_idx} = sprintf ("with filledcurve %s", colorspec); data{data_idx} = [xcol, ycol]'; usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", numel (xcol)); endif endif endif ## patch outline if (!(strcmp (obj.edgecolor, "none") && (strcmp (obj.marker, "none") || (strcmp (obj.markeredgecolor, "none") && strcmp (obj.markerfacecolor, "none"))))) data_idx += 1; is_image_data(data_idx) = false; parametric(data_idx) = false; have_cdata(data_idx) = false; have_3d_patch(data_idx) = false; titlespec{data_idx} = "title \"\""; usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); if (isfield (obj, "markersize")) mdat = obj.markersize / 3; endif if (isfield (obj, "edgecolor")) ## FIXME: This is the wrong thing to do as edgecolor, ## markeredgecolor and markerfacecolor can have different values ## and we should treat them seperately. However, the code below ## allows the scatter functions to work as expected, where only ## one of these values is set. if (strcmp (obj.edgecolor, "none")) if (strcmp (obj.markeredgecolor, "none")) ec = obj.markerfacecolor; else ec = obj.markeredgecolor; endif else ec = obj.edgecolor; endif if ((strcmp (ec, "flat") || strcmp (ec, "interp")) && isfield (obj, "cdata")) if (ndims (obj.cdata) == 2 && (columns (obj.cdata) == nc && (rows (obj.cdata) == 1 || rows (obj.cdata) == 3))) ccol = cdat(:, i); elseif (ndims (obj.cdata) == 2 && (rows (obj.cdata) == nc && (columns (obj.cdata) == 1 || columns (obj.cdata) == 3))) ccol = cdat(i, :); elseif (ndims (obj.cdata) == 3) ccol = permute (cdat (:, i, :), [1, 3, 2]); else ccol = cdat; endif if (strcmp (ec, "flat")) if (isequal (size (ccol), [1, 3])) color = ccol; else if (columns (ccol) != 3) ccol = mapcdata (ccol, obj.cdatamapping, clim, cmap_sz); endif if (isscalar (ccol)) ccol = repmat (ccol, numel (xcol), 1); endif color = "flat"; have_cdata(data_idx) = true; endif elseif (strcmp (ec, "interp")) if (numel (ccol) == 3) warning ("\"interp\" not supported, using 1st entry of cdata"); color = ccol(1,:); else if (isscalar (ccol)) ccol = repmat (ccol, numel (xcol), 1); endif color = "interp"; have_cdata(data_idx) = true; endif ccol = mapcdata (ccol, obj.cdatamapping, clim, cmap_sz); endif elseif (isnumeric (ec)) color = ec; else color = [0, 0, 0]; endif else color = [0, 0, 0]; endif lt = gnuplot_linestyletype (obj); if (isfield (obj, "linewidth")) lw = sprintf ("linewidth %f", obj.linewidth); else lw = ""; endif [pt, pt2, obj] = gnuplot_pointtype (obj); if (! isempty (pt)) pt = sprintf ("pointtype %s", pt); endif if (! isempty (pt2)) pt2 = sprintf ("pointtype %s", pt2); endif if (ischar (color)) if (columns (ccol) == 1) colorspec = "palette"; elseif (columns (ccol) == 3) colorspec = "lc rgb variable"; ccol = 255*ccol*[0x1; 0x100; 0x10000]; endif else colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", uint8 (255*color)); endif sidx = 1; if (isempty (lt)) style = ""; else style = "lines"; endif tmpwith = {}; facesame = true; if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") && ! strcmp (obj.markerfacecolor, "none")) if (strcmp (obj.markerfacecolor, "auto") || ! isnumeric (obj.markerfacecolor) || (isnumeric (obj.markerfacecolor) && isequal (color, obj.markerfacecolor))) style = [style "points"]; if (isfield (obj, "markersize")) if (length (mdat) == nc) m = mdat(i); else m = mdat; endif ps = sprintf ("pointsize %f", m / 3); else ps = ""; endif tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", style, lw, pt2, lt, ps, colorspec); else facesame = false; if (! isempty (style)) tmpwith{sidx} = sprintf ("with %s %s %s %s", style, lw, lt, colorspec); sidx += 1; endif if (isnumeric (obj.markerfacecolor)) colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", round (255*obj.markerfacecolor)); endif style = "points"; if (isfield (obj, "markersize")) if (length (mdat) == nc) m = mdat(i); else m = mdat; endif ps = sprintf ("pointsize %f", m / 3); else ps = ""; endif tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", style, lw, pt2, lt, ps, colorspec); endif endif if (isfield (obj, "markeredgecolor") && ! strcmp (obj.markeredgecolor, "none")) if (facesame && ! isempty (pt) && (strcmp (obj.markeredgecolor, "auto") || ! isnumeric (obj.markeredgecolor) || (isnumeric (obj.markeredgecolor) && isequal (color, obj.markeredgecolor)))) if (sidx == 1 && ((length (style) == 5 && strncmp (style, "lines", 5)) || isempty (style))) style = [style, "points"]; if (isfield (obj, "markersize")) if (length (mdat) == nc) m = mdat(i); else m = mdat; endif ps = sprintf ("pointsize %f", m / 3); else ps = ""; endif tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", style, lw, pt, lt, ps, colorspec); endif else if (! isempty (style)) if (length (tmpwith) < sidx || isempty (tmpwith{sidx})) tmpwith{sidx} = sprintf ("with %s %s %s %s", style, lw, lt, colorspec); endif sidx += 1; endif if (! isempty (pt)) if (strcmp (obj.markeredgecolor, "auto")) colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", round (255*color)); elseif (isnumeric (obj.markeredgecolor)) colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", round (255*obj.markeredgecolor)); endif style = "points"; if (isfield (obj, "markersize")) if (length (mdat) == nc) m = mdat(i); else m = mdat; endif ps = sprintf ("pointsize %f", m / 3); else ps = ""; endif tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", style, lw, pt, lt, ps, colorspec); endif endif endif if (! isempty (tmpwith)) withclause{data_idx} = tmpwith{1}; else if (! isempty (style)) withclause{data_idx} = sprintf ("with %s %s %s %s %s", style, lw, pt, lt, colorspec); else withclause{data_idx} = ""; endif endif if (nd == 3) if (ischar (color)) if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol)) data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... [zcol; zcol(1)], [ccol; ccol(1)]]'; else data{data_idx} = [xcol, ycol, zcol, ccol]'; endif usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", columns (data{data_idx})); else if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol)) data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... [zcol; zcol(1)]]'; else data{data_idx} = [xcol, ycol, zcol]'; endif usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx})); endif else if (ischar (color)) if (! isnan (xcol) && ! isnan (ycol)) data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... [ccol; ccol(1)]]'; else data{data_idx} = [xcol, ycol, ccol]'; endif usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx})); else if (! isnan (xcol) && ! isnan (ycol)) data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]'; else data{data_idx} = [xcol, ycol]'; endif usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx})); endif endif if (length (tmpwith) > 1) data_idx += 1; is_image_data(data_idx) = is_image_data(data_idx - 1); parametric(data_idx) = parametric(data_idx - 1); have_cdata(data_idx) = have_cdata(data_idx - 1); have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); titlespec{data_idx} = "title \"\""; usingclause{data_idx} = usingclause{data_idx - 1}; data{data_idx} = data{data_idx - 1}; withclause{data_idx} = tmpwith{2}; endif if (length (tmpwith) > 2) data_idx += 1; is_image_data(data_idx) = is_image_data(data_idx - 1); parametric(data_idx) = parametric(data_idx - 1); have_cdata(data_idx) = have_cdata(data_idx - 1); have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); titlespec{data_idx} = "title \"\""; usingclause{data_idx} = usingclause{data_idx - 1}; data{data_idx} = data{data_idx - 1}; withclause{data_idx} = tmpwith{3}; endif endif endfor case "surface" view_map = true; tspec = 'title ""'; if (! isempty (obj.displayname)) ## Place phantom line data for approximate legend symbol data_idx += 1; is_image_data(data_idx) = false; parametric(data_idx) = false; have_cdata(data_idx) = false; have_3d_patch(data_idx) = false; tmp = undo_string_escapes ( __maybe_munge_text__ (enhanced, obj, "displayname") ); titlespec{data_idx} = ['title "' tmp '"']; data{data_idx} = nan (3,1); usingclause{data_idx} = sprintf ("record=1 using ($1):($2):($3)"); withclause{data_idx} = sprintf ("with line linewidth 10 linecolor rgb \"#%02x%02x%02x\"", round (255*cmap(end/2,:))); endif xdat = obj.xdata; ydat = obj.ydata; zdat = obj.zdata; cdat = mapcdata (obj.cdata, obj.cdatamapping, clim, cmap_sz); err = false; if (! size_equal (zdat, cdat)) err = true; endif if (isvector (xdat) && isvector (ydat) && ismatrix (zdat)) if (rows (zdat) == length (ydat) && columns (zdat) == length (xdat)) [xdat, ydat] = meshgrid (xdat, ydat); else err = true; endif elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat)) if (! size_equal (xdat, ydat, zdat)) err = true; endif else err = true; endif if (err) error ("__gnuplot_draw_axes__: invalid grid data"); endif xlen = columns (zdat); ylen = rows (zdat); if (! strcmp (obj.facecolor, "none")) data_idx += 1; is_image_data(data_idx) = false; parametric(data_idx) = false; have_cdata(data_idx) = true; have_3d_patch(data_idx) = false; titlespec{data_idx} = tspec; tspec = "title \"\""; flat_interp_face = (strcmp (obj.facecolor, "flat") || strcmp (obj.facecolor, "interp")); if (xlen == columns (xdat) && xlen == columns (ydat) && ylen == rows (xdat) && ylen == rows (ydat)) len = 4 * xlen; zz = zeros (ylen, len); if (! flat_interp_face) addedcmap = [addedcmap; obj.facecolor]; endif k = 1; for kk = 1:4:len zz(:,kk) = xdat(:,k); zz(:,kk+1) = ydat(:,k); zz(:,kk+2) = zdat(:,k); if (flat_interp_face) zz(:,kk+3) = cdat(:,k); else zz(:,kk+3) = cmap_sz + rows (addedcmap); endif k += 1; endfor data{data_idx} = zz.'; endif doing_interp_color = strcmp (obj.facecolor, "interp"); if (doing_interp_color) interp_str = "interpolate 0, 0"; else ## No interpolation of facecolors. interp_str = ""; endif usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen); fputs (plot_stream, "unset pm3d\n"); fputs (plot_stream, "set style increment default;\n"); hidden_removal = true; withclause{data_idx} = sprintf ("with pm3d"); if (doing_interp_color) ## "depthorder" interferes with interpolation of colors. dord = "scansautomatic"; else dord = "depthorder"; endif if (isscalar (obj.facealpha)) fprintf (plot_stream, "set style fill transparent solid %f;\n", obj.facealpha); endif fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n", interp_str, dord); endif draw_surf_line = ! strcmp (obj.linestyle, "none") && ! strcmp (obj.edgecolor, "none"); draw_surf_marker = (! strcmp (obj.marker, "none") && ! (strcmp (obj.markeredgecolor, "none") && strcmp (obj.markerfacecolor, "none"))); if (draw_surf_line || draw_surf_marker) flat_interp_edge = (strcmp (obj.edgecolor, "flat") || strcmp (obj.edgecolor, "interp")); flat_marker = (strcmp (obj.markeredgecolor, "flat") || strcmp (obj.markerfacecolor, "flat") || strcmp (obj.markeredgecolor, "auto") || strcmp (obj.markerfacecolor, "auto")); [style, sidx] = do_linestyle_command (obj, obj.edgecolor, data_idx, plot_stream); domeshcolumn = (strcmp (obj.meshstyle, "column") || strcmp (obj.meshstyle, "both")); domeshrow = (strcmp (obj.meshstyle, "row") || strcmp (obj.meshstyle, "both")); num_pass = 0; num_cols = 0; if (domeshcolumn) num_pass += xlen; num_cols = xlen; endif if (domeshrow) num_pass += ylen; endif for np = 1:num_pass for i_stl = 1:length (style) has_ccol = ((strncmp (style{i_stl}, "lines", 5) && flat_interp_edge) || (strncmp (style{i_stl}, "points", 6) && flat_marker)); if (has_ccol) ccol = ":($4)"; N_tup = 4; else ccol = ""; N_tup = 3; endif sopt = sprintf ("ls %d", sidx (i_stl)); if (np <= num_cols) k = np; yrec = ylen; zz = zeros (ylen, N_tup); zz(:,1) = xdat(:,k); zz(:,2) = ydat(:,k); zz(:,3) = zdat(:,k); if (has_ccol) zz(:,4) = cdat(:,k); endif else j = np - num_cols; yrec = xlen; zz = zeros (xlen, N_tup); zz(:,1) = xdat(j,:)'; zz(:,2) = ydat(j,:)'; zz(:,3) = zdat(j,:)'; if (has_ccol) zz(:,4) = cdat(j,:)'; endif endif zz = zz.'; data_idx += 1; is_image_data(data_idx) = false; parametric(data_idx) = false; if (has_ccol) have_cdata(data_idx) = true; else have_cdata(data_idx) = false; endif have_3d_patch(data_idx) = false; titlespec{data_idx} = tspec; usingclause{data_idx} = sprintf ("record=%dx1 using ($1):($2):($3)%s", yrec, ccol); if isempty (style{i_stl}) style{i_stl} = "points"; data{data_idx} = {}; else data{data_idx} = zz; endif withclause{data_idx} = sprintf ("with %s %s", style{i_stl}, sopt); endfor endfor endif case "text" do_text (plot_stream, gnuplot_term, enhanced, obj, h); case "hggroup" ## Push group children into the kid list. if (isempty (kids)) kids = obj.children; elseif (! isempty (obj.children)) kids = [kids; obj.children]; endif case "light" ## ignore it otherwise error ("__gnuplot_draw_axes__: unknown object class, %s", obj.type); endswitch endwhile ## This is needed to prevent warnings for rotations in 3D plots, while ## allowing colorbars with contours. if (nd == 2 || (data_idx > 1 && ! view_map)) fputs (plot_stream, "set pm3d implicit;\n"); else fputs (plot_stream, "set pm3d explicit;\n"); endif if (! isnan (hidden_removal) && hidden_removal) fputs (plot_stream, "set hidden3d front nooffset;\n"); else fputs (plot_stream, "unset hidden3d;\n"); endif have_data = (! (isempty (data) || all (cellfun ("isempty", data)))); ## Note we don't use the [xy]2range of gnuplot as we don't use the ## dual axis plotting features of gnuplot. if (isempty (xlim)) return; endif if (strcmp (axis_obj.xdir, "reverse")) xlim = flip (xlim); endif fprintf (plot_stream, "set xrange [%.15e:%.15e];\n", xlim); if (strcmp (axis_obj.xaxislocation, "top")) fprintf (plot_stream, "set x2range [%.15e:%.15e];\n", xlim); endif if (isempty (ylim)) return; endif if (strcmp (axis_obj.ydir, "reverse")) ylim = flip (ylim); endif fprintf (plot_stream, "set yrange [%.15e:%.15e];\n", ylim); if (strcmp (axis_obj.yaxislocation, "right")) fprintf (plot_stream, "set y2range [%.15e:%.15e];\n", ylim); endif if (nd == 3) if (isempty (zlim)) return; endif if (strcmp (axis_obj.zdir, "reverse")) zlim = flip (zlim); endif fprintf (plot_stream, "set zrange [%.15e:%.15e];\n", zlim); endif if (! any (isinf (clim))) if (rows (addedcmap) > 0) fprintf (plot_stream, "set cbrange [1:%.15e];\n", cmap_sz + rows (addedcmap)); else fprintf (plot_stream, "set cbrange [1:%.15e];\n", cmap_sz); endif endif if (strcmp (axis_obj.visible, "off")) fputs (plot_stream, "unset border; unset tics\n"); else fputs (plot_stream, "unset border\n"); axis_idx = data_idx; if (strcmp (axis_obj.box, "on")) if (nd == 3) do_border_tick_3d (axis_obj, plot_stream); else axis_idx = do_border_2d (axis_obj, plot_stream, axis_idx); endif else if (nd == 3) do_border_tick_3d (axis_obj, plot_stream); elseif (! isempty (axis_obj.ytick)) if (strcmp (axis_obj.yaxislocation, "right")) fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n", axis_obj.tickdir); if (strcmp (axis_obj.xaxislocation, "top")) maybe_do_x2tick_mirror (plot_stream, axis_obj) elseif (strcmp (axis_obj.xaxislocation, "bottom")) maybe_do_xtick_mirror (plot_stream, axis_obj) else # xaxislocation == "origin" or "zero" fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n", axis_obj.tickdir); endif elseif (strcmp (axis_obj.yaxislocation, "left")) fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n", axis_obj.tickdir); if (strcmp (axis_obj.xaxislocation, "top")) maybe_do_x2tick_mirror (plot_stream, axis_obj) elseif (strcmp (axis_obj.xaxislocation, "bottom")) maybe_do_xtick_mirror (plot_stream, axis_obj) else # xaxislocation == "origin" or "zero" maybe_do_xtick_mirror (plot_stream, axis_obj) endif else # yaxislocation == "origin" or "zero" fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n", axis_obj.tickdir); if (strcmp (axis_obj.xaxislocation, "top")) maybe_do_x2tick_mirror (plot_stream, axis_obj) elseif (strcmp (axis_obj.xaxislocation, "bottom")) maybe_do_xtick_mirror (plot_stream, axis_obj) else # xaxislocation == "origin" or "zero" maybe_do_xtick_mirror (plot_stream, axis_obj) fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n", axis_obj.tickdir); fputs (plot_stream, "unset border;\n"); endif endif axis_idx = do_border_2d (axis_obj, plot_stream, axis_idx); endif endif endif if (! have_major_grid && ! have_minor_grid) fputs (plot_stream, "unset grid;\n"); else if (exist ("axis_idx", "var")) grid_idx = axis_idx; else grid_idx = data_idx; endif if (have_major_grid) grid_idx += 1; grid_obj.linestyle = axis_obj.gridlinestyle; grid_obj.linewidth = axis_obj.linewidth; grid_obj.alpha = axis_obj.gridalpha; [style, sidx_major] = do_linestyle_command (grid_obj, axis_obj.gridcolor, grid_idx, plot_stream); else sidx_major = 0; endif if (have_minor_grid) grid_idx += 1; grid_obj.linestyle = axis_obj.minorgridlinestyle; grid_obj.linewidth = axis_obj.linewidth; grid_obj.alpha = axis_obj.minorgridalpha; [style, sidx_minor] = do_linestyle_command (grid_obj, axis_obj.minorgridcolor, grid_idx, plot_stream); else sidx_minor = 0; endif fprintf (plot_stream, "set grid linestyle %d, linestyle %d;\n", sidx_major, sidx_minor); endif if (! isempty (hlgnd) && ! isempty (hlgnd.children) && any (strcmp (get (hlgnd.children, "visible"), "on"))) if (strcmp (hlgnd.box, "on")) box = "box"; else box = "nobox"; endif if (strcmp (hlgnd.orientation, "vertical")) horzvert = "vertical"; else horzvert = "horizontal"; endif if (strcmp (hlgnd.textposition, "right")) reverse = "reverse Left"; else reverse = "noreverse Right"; endif inout = "inside"; keypos = hlgnd.location; if (ischar (keypos)) keypos = lower (keypos); keyout = strfind (keypos, "outside"); if (! isempty (keyout)) inout = "outside"; keypos = keypos(1:keyout-1); endif endif switch (keypos) case "north" pos = "center top"; case "south" pos = "center bottom"; case "east" pos = "right center"; case "west" pos = "left center"; case "northeast" pos = "right top"; case "northwest" pos = "left top"; case "southeast" pos = "right bottom"; case "southwest" pos = "left bottom"; case "best" pos = ""; warning ("legend: 'Best' not yet implemented for location specifier.\n"); ## Least conflict with data in plot. ## Least unused space outside plot. otherwise pos = ""; endswitch [fontname, fontsize] = get_fontname_and_size (hlgnd); fontspacespec = [create_spacingspec(fontname, fontsize, gnuplot_term),... ' ', create_fontspec(fontname, fontsize, gnuplot_term)]; textcolors = get (findobj (hlgnd.children, "type", "text"), "color"); if (iscell (textcolors)) textcolors = cell2mat (textcolors); textcolors = unique (textcolors, "rows"); endif if (rows (textcolors) > 1) ## Gnuplot is unable to assign arbitrary colors to each text entry ## for the key/legend. But, the text color can be set to match the ## color of the plot object. colorspec = "textcolor variable"; else colorspec = get_text_colorspec (textcolors); endif fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s %s %s;\n", inout, pos, box, reverse, horzvert, fontspacespec, colorspec, __do_enhanced_option__ (enhanced, hlgnd)); else fputs (plot_stream, "unset key;\n"); endif fputs (plot_stream, "set style data lines;\n"); cmap = [cmap; addedcmap]; cmap_sz += rows (addedcmap); if (cmap_sz == 1) # bug #48083, illegal one-element colormap cmap = [cmap; cmap]; cmap_sz = 2; endif if (length (cmap) > 0) fprintf (plot_stream, "set palette positive color model RGB maxcolors %i;\n", cmap_sz); fprintf (plot_stream, "set palette file \"-\" binary record=%d using 1:2:3:4;\n", cmap_sz); fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32"); fwrite (plot_stream, "\n"); endif fputs (plot_stream, "unset colorbox;\n"); if (have_data) if (nd == 2) plot_cmd = "plot"; else plot_cmd = "splot"; ## Wrap view correctly to match Matlab if (axis_obj.view(2) <= 90) rot_x = 90 - axis_obj.view(2); else rot_x = axis_obj.view(2) - 90; endif rot_x = mod (rot_x, 360); while (rot_x < 0) rot_x += 360; endwhile if (axis_obj.view(2) <= 90) rot_z = axis_obj.view(1); else rot_z = axis_obj.view(1) + 180; endif rot_z = mod (rot_z, 360); while (rot_z < 0) rot_z += 360; endwhile fputs (plot_stream, "set ticslevel 0;\n"); if (view_map && rot_x == 0 && rot_z == 0) fputs (plot_stream, "set view map;\n"); else fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z); endif endif if (have_3d_patch (1)) fputs (plot_stream, "set pm3d depthorder\n"); fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, usingclause{1}, titlespec{1}, withclause{1}); elseif (is_image_data (1)) if (numel (is_image_data) > 1 && is_image_data(2)) ## Remove terminating semicolon n = max (strfind (withclause{1}, ";")); if (! isempty (n)) withclause{1} = withclause{1}(1:n-1); endif endif fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, usingclause{1}, titlespec{1}, withclause{1}); else fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd, usingclause{1}, titlespec{1}, withclause{1}); endif for i = 2:data_idx if (have_3d_patch (i)) fprintf (plot_stream, ", \"-\" %s %s %s \\\n", usingclause{i}, titlespec{i}, withclause{i}); elseif (is_image_data (i)) if (! is_image_data (i-1)) fputs (plot_stream, "; "); if (bg_is_set) fputs (plot_stream, "if (GPVAL_TERM eq \"qt\") unset obj 1;\n"); bg_is_set = false; endif if (fg_is_set) fputs (plot_stream, "unset obj 2; \\\n"); fg_is_set = false; endif if (numel (is_image_data) > i && is_image_data(i+1)) ## Remove terminating semicolon n = max (strfind (withclause{i}, ";")); if (! isempty (n)) withclause{i} = withclause{i}(1:n-1); endif endif fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, usingclause{i}, titlespec{i}, withclause{i}); else ## For consecutive images continue with the same plot command fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", ",", usingclause{i}, titlespec{i}, withclause{i}); endif elseif (is_image_data (i-1)) if (bg_is_set) fputs (plot_stream, "if (GPVAL_TERM eq \"qt\") unset obj 1;\n"); bg_is_set = false; endif if (fg_is_set) fputs (plot_stream, "unset obj 2; \\\n"); fg_is_set = false; endif fprintf (plot_stream,"%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd, usingclause{i}, titlespec{i}, withclause{i}); else fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n", usingclause{i}, titlespec{i}, withclause{i}); endif endfor fputs (plot_stream, ";\n"); for i = 1:data_idx if (have_3d_patch (i)) ## Can't write 3d patch data as binary as can't plot more than ## a single patch at a time and have to plot all patches together ## so that the gnuplot depth ordering is done correctly for j = 1 : 4 : columns (data{i}) if (j != 1) fputs (plot_stream, "\n\n"); endif fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).'); fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).'); fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).'); fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).'); endfor fputs (plot_stream, "e\n"); elseif (is_image_data(i)) fwrite (plot_stream, data{i}, "float32"); else __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i), have_cdata(i)); endif endfor fputs (plot_stream, "\n"); else fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n"); endif ## Needed to allow mouse rotation if gnuplot was put in map view. if (view_map && rot_x == 0 && rot_z == 0) fputs (plot_stream, "set view 0,0;\n"); endif if (bg_is_set) fputs (plot_stream, "if (GPVAL_TERM eq \"qt\") unset obj 1;\n"); bg_is_set = false; endif fflush (plot_stream); endfunction function x = flip (x) if (rows (x) == 1) x = fliplr (x); elseif (columns (x) == 1 || ischar (x)) x = flipud (x); else x = flipud (fliplr (x)); endif endfunction function spacing_spec = create_spacingspec (f, s, gp_term) ## The gnuplot default font size is 10, and default spacing is 1.25. ## gnuplot has a concept of a figure global font, and sizes everything ## appropriate to that, including the legend spacing. ## ## This means that if an alternative size is used, gnuplot will use an ## inappropriate spacing in the legend by default. ## ## FIXME: Are fractional spacing specifications allowed? Or should this ## number be rounded? spc = s / 10 * 1.25; spacing_spec = sprintf ("spacing %d", spc); endfunction function fontspec = create_fontspec (f, s, gp_term) if (isempty (f) || strcmp (f, "*") || strcmp (gp_term, "tikz")) fontspec = sprintf ("font \",%d\"", s); else fontspec = sprintf ("font \"%s,%d\"", f, s); endif endfunction function idx = do_border_2d (obj, plot_stream, idx) fprintf (plot_stream, "set border 0\n"); if (strcmp (obj.box, "on") || strcmp (obj.xaxislocation, "bottom")) arrow (1, obj.xcolor, obj.linewidth, [0,0,0], [1,0,0]); endif if (strcmp (obj.box, "on") || strcmp (obj.xaxislocation, "top")) arrow (2, obj.xcolor, obj.linewidth, [0,1,0], [1,1,0]); endif if (strcmp (obj.box, "on") || strcmp (obj.yaxislocation, "left")) arrow (3, obj.ycolor, obj.linewidth, [0,0,0], [0,1,0]); endif if (strcmp (obj.box, "on") || strcmp (obj.yaxislocation, "right")) arrow (4, obj.ycolor, obj.linewidth, [1,0,0], [1,1,0]); endif if (any (strcmp (obj.xaxislocation, {"origin", "zero"}))) # FIXME: Remove "zero" in 4.6 idx = zeroaxis (idx, obj.xcolor, "x"); endif if (any (strcmp (obj.yaxislocation, {"origin", "zero"}))) # FIXME: Remove "zero" in 4.6 idx = zeroaxis (idx, obj.ycolor, "y"); endif function idx = zeroaxis (idx, lc, ax) idx = idx + 1; do_linestyle_command (obj, lc, idx, false, plot_stream); fprintf (plot_stream, "set %szeroaxis ls %d ", ax, idx); fprintf (plot_stream, "lw %.3f\n", obj.linewidth); endfunction function arrow (idx, lc, lw, from, to) fprintf (plot_stream, "set arrow %d ", idx); fprintf (plot_stream, "nohead nofilled front "); fprintf (plot_stream, "lc rgb ""#%02x%02x%02x"" ", round (255 * lc)); fprintf (plot_stream, "linewidth %.3f ", obj.linewidth); fprintf (plot_stream, "from graph %d,%d,%d ", from); fprintf (plot_stream, "to graph %d,%d,%d\n", to); endfunction endfunction function idx = do_border_tick_3d (obj, plot_stream, idx) ## axis location has no effect if (strcmp (obj.box, "on")) fputs (plot_stream, "set border 0xFFF;\n"); mirrorstr = "mirror"; else fputs (plot_stream, "set border 0x15;\n"); mirrorstr = "nomirror"; endif tick ('x', obj.xcolor, obj.tickdir, mirrorstr); tick ('y', obj.ycolor, obj.tickdir, mirrorstr); tick ('z', obj.zcolor, obj.tickdir, mirrorstr); function tick (axischar, color, tickdir, mirrorstr); if (isnumeric (color)) if (length (color) == 3) colorspec = sprintf ("rgb \"#%02x%02x%02x\"", round (255*color)); else colorspec = sprintf ("palatte %d", round (color)); endif else colorspec = sprintf ("\"%s\"", color); endif fprintf (plot_stream, "set %ctics %s %s textcolor %s\n", axischar, tickdir, mirrorstr, colorspec); endfunction endfunction function [style, ltidx] = do_linestyle_command (obj, linecolor, idx, plot_stream) idx = idx + 8; style = {}; ltidx = []; fprintf (plot_stream, "set style line %d default;\n", idx); fprintf (plot_stream, "set style line %d", idx); found_style = false; if (isnumeric (linecolor)) color = linecolor; if (isfield (obj, "alpha") && __gnuplot_has_feature__ ("alphablend_linecolor")) alphastr = sprintf ("%02x", round (255*(1-obj.alpha))); else alphastr = ""; endif fprintf (plot_stream, " linecolor rgb \"#%s%02x%02x%02x\"", alphastr, round (255*color)); else color = [0, 0, 0]; flat_interp_edge = (strcmp (obj.edgecolor, "flat") || strcmp (obj.edgecolor, "interp")); if (flat_interp_edge) fprintf (plot_stream, " palette"); endif endif lt = gnuplot_linestyletype (obj); if (! isempty (lt)) fprintf (plot_stream, " %s", lt); endif if (isfield (obj, "linewidth")) fprintf (plot_stream, " linewidth %f", obj.linewidth); found_style = true; endif [pt, pt2, obj] = gnuplot_pointtype (obj); if (! isempty (pt)) found_style = true; endif sidx = 1; if (isempty (lt)) style{sidx} = ""; else style{sidx} = "lines"; endif ltidx(sidx) = idx; facesame = true; if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") && ! strcmp (obj.markerfacecolor, "none")) if (strcmp (obj.markerfacecolor, "auto") || (isnumeric (obj.markerfacecolor) && isequal (color, obj.markerfacecolor))) if (! isempty (pt2)) fprintf (plot_stream, " pointtype %s", pt2); style{sidx} = [style{sidx} "points"]; endif if (isfield (obj, "markersize")) fprintf (plot_stream, " pointsize %f", obj.markersize / 3); endif else facesame = false; if (! found_style) fputs (plot_stream, " default"); endif fputs (plot_stream, ";\n"); if (! isempty (style{sidx})) sidx += 1; idx += 1; else fputs (plot_stream, ";\n"); endif fprintf (plot_stream, "set style line %d default;\n", idx); fprintf (plot_stream, "set style line %d", idx); if (isnumeric (obj.markerfacecolor)) fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", round (255*obj.markerfacecolor)); else fprintf (plot_stream, " palette"); endif if (! isempty (pt2)) style{sidx} = "points"; ltidx(sidx) = idx; fprintf (plot_stream, " pointtype %s", pt2); endif if (isfield (obj, "markersize")) fprintf (plot_stream, " pointsize %f", obj.markersize / 3); endif endif endif if (! isempty(pt) && isfield (obj, "markeredgecolor") && ! strcmp (obj.markeredgecolor, "none")) if (facesame && (strcmp (obj.markeredgecolor, "auto") || (isnumeric (obj.markeredgecolor) && isequal (color, obj.markeredgecolor)))) if (sidx == 1 && ((length (style{sidx}) == 5 && strncmp (style{sidx}, "lines", 5)) || isempty (style{sidx}))) style{sidx} = [style{sidx} "points"]; fprintf (plot_stream, " pointtype %s", pt); if (isfield (obj, "markersize")) fprintf (plot_stream, " pointsize %f", obj.markersize / 3); endif endif else if (! found_style) fputs (plot_stream, " default"); endif fputs (plot_stream, ";\n"); if (! isempty (style{sidx})) sidx += 1; idx += 1; else fputs (plot_stream, ";\n"); endif fprintf (plot_stream, "set style line %d default;\n", idx); fprintf (plot_stream, "set style line %d", idx); if (isnumeric (obj.markeredgecolor) || strcmp (obj.markeredgecolor, "auto")) if (isnumeric (obj.markeredgecolor)) edgecolor = obj.markeredgecolor; else edgecolor = obj.color; end fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", round (255*edgecolor)); else fprintf (plot_stream, " palette"); endif style{sidx} = "points"; ltidx(sidx) = idx; fprintf (plot_stream, " pointtype %s", pt); if (isfield (obj, "markersize")) fprintf (plot_stream, " pointsize %f", obj.markersize / 3); endif endif endif if (! found_style && isempty (style{1})) fputs (plot_stream, " default"); endif fputs (plot_stream, ";\n"); endfunction function lt = gnuplot_linestyletype (obj) if (isfield (obj, "linestyle")) if (__gnuplot_has_feature__ ("dashtype")) opt = "dashtype"; switch (obj.linestyle) case "-" lt = "solid"; case "--" lt = "'_ '"; case ":" lt = "'. '"; case "-." lt = "'-. '"; case "none" lt = ""; otherwise lt = ""; endswitch else opt = "linetype"; switch (obj.linestyle) case "-" lt = "1"; case "--" lt = "2"; case ":" lt = "3"; case "-." lt = "6"; case "none" lt = ""; otherwise lt = ""; endswitch endif if (! isempty (lt)) lt = sprintf ("%s %s", opt, lt); endif else lt = ""; endif endfunction function [pt, pt2, obj] = gnuplot_pointtype (obj) if (isfield (obj, "marker")) switch (obj.marker) case "+" pt = pt2 = "1"; case "o" pt = "6"; pt2 = "7"; case "*" pt = pt2 = "3"; case "." pt = pt2 = "7"; if (isfield (obj, "markersize")) obj.markersize /= 3; else obj.markersize = 5; endif case "x" pt = pt2 = "2"; case {"square", "s"} pt = "4"; pt2 = "5"; case {"diamond", "d"} pt = "12"; pt2 = "13"; case "^" pt = "8"; pt2 = "9"; case "v" pt = "10"; pt2 = "11"; case ">" ## FIXME: Should be triangle pointing right, use triangle pointing up pt = "8"; pt2 = "9"; case "<" ## FIXME: Should be triangle pointing left, use triangle pointing down pt = "10"; pt2 = "11"; case {"pentagram", "p"} ## FIXME: Should be pentagram, using pentagon pt = "14"; pt2 = "15"; case {"hexagram", "h"} ## FIXME: Should be 6 pt start, using "*" instead pt = pt2 = "3"; case "none" pt = pt2 = "-1"; otherwise pt = pt2 = ""; endswitch else pt = pt2 = ""; endif endfunction function __gnuplot_write_data__ (plot_stream, data, nd, parametric, cdata) ## DATA is already transposed. ## Convert NA elements to normal NaN values because fprintf writes ## "NA" and that confuses gnuplot. data(isna (data)) = NaN; if (nd == 2) fwrite (plot_stream, data, "float64"); elseif (nd == 3) if (parametric) fwrite (plot_stream, data, "float64"); else nr = rows (data); if (cdata) for j = 1:4:nr fwrite (plot_stream, data(j:j+3,:), "float64"); endfor else for j = 1:3:nr fwrite (plot_stream, data(j:j+2,:), "float64"); endfor endif endif endif endfunction function do_tics (obj, plot_stream, ymirror, gnuplot_term) obj.xticklabel = ticklabel_to_cell (obj.xticklabel); obj.yticklabel = ticklabel_to_cell (obj.yticklabel); obj.zticklabel = ticklabel_to_cell (obj.zticklabel); if (strcmp (obj.xminorgrid, "on")) obj.xminortick = "on"; endif if (strcmp (obj.yminorgrid, "on")) obj.yminortick = "on"; endif if (strcmp (obj.zminorgrid, "on")) obj.zminortick = "on"; endif [fontname, fontsize] = get_fontname_and_size (obj); fontspec = create_fontspec (fontname, fontsize, gnuplot_term); ## A Gnuplot tic scale of 69 is equivalent to Octave's 0.5. ticklength = sprintf ("scale %4.1f", (69/0.5)*obj.ticklength(1)); if (strcmp (obj.xaxislocation, "top")) do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, obj.xticklabel, obj.xcolor, "x2", plot_stream, true, "border", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.xscale, obj.xsgn, gnuplot_term); do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, obj.xcolor, "x", plot_stream, true, "border", "", "", fontname, fontspec, obj.ticklabelinterpreter, obj.xscale, obj.xsgn, gnuplot_term); elseif (any (strcmp (obj.xaxislocation, {"origin", "zero"}))) # FIXME: Remove "zero" in 4.6 do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, obj.xticklabel, obj.xcolor, "x", plot_stream, true, "axis", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.xscale, obj.xsgn, gnuplot_term); do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, obj.xcolor, "x2", plot_stream, true, "axis", "", "", fontname, fontspec, obj.ticklabelinterpreter, obj.xscale, obj.xsgn, gnuplot_term); else do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, obj.xticklabel, obj.xcolor, "x", plot_stream, true, "border", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.xscale, obj.xsgn, gnuplot_term); do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, obj.xcolor, "x2", plot_stream, true, "border", "", "", fontname, fontspec, obj.ticklabelinterpreter, obj.xscale, obj.xsgn, gnuplot_term); endif if (strcmp (obj.yaxislocation, "right")) do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, "border", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.yscale, obj.ysgn, gnuplot_term); do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, "border", "", "", fontname, fontspec, obj.ticklabelinterpreter, obj.yscale, obj.ysgn, gnuplot_term); elseif (any (strcmp (obj.yaxislocation, {"origin", "zero"}))) # FIXME: Remove "zero" in 4.6 do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, "axis", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.yscale, obj.ysgn, gnuplot_term); do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, "axis", "", "", fontname, fontspec, obj.ticklabelinterpreter, obj.yscale, obj.ysgn, gnuplot_term); else do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, "border", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.yscale, obj.ysgn, gnuplot_term); do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, "border", "", "", fontname, fontspec, obj.ticklabelinterpreter, obj.yscale, obj.ysgn, gnuplot_term); endif do_tics_1 (obj.ztickmode, obj.ztick, obj.zminortick, obj.zticklabelmode, obj.zticklabel, obj.zcolor, "z", plot_stream, true, "border", obj.tickdir, ticklength, fontname, fontspec, obj.ticklabelinterpreter, obj.zscale, obj.zsgn, gnuplot_term); endfunction function do_tics_1 (ticmode, tics, mtics, labelmode, labels, color, ax, plot_stream, mirror, axispos, tickdir, ticklength, fontname, fontspec, interpreter, scale, sgn, gnuplot_term) persistent warned_latex = false; ## Avoid emitting anything if the tics are empty, because this undoes the ## effect of the previous unset xtics and thereby adds back in the tics. if (isempty (tics)) return; endif if (mirror) mirror = "mirror"; else mirror = "nomirror"; endif if (strcmp (interpreter, "tex")) for n = 1 : numel (labels) labels{n} = __tex2enhanced__ (labels{n}, fontname, false, false); endfor elseif (strcmp (interpreter, "latex")) if (! warned_latex) warning ("latex markup not supported for tick marks"); warned_latex = true; endif endif if (strcmp (scale, "log")) num_mtics = 10; if (any (strcmp (gnuplot_term, {"cairolatex", "eepic", "epslatex", ... "latex", "pslatex", "pstex", "pstricks", "texdraw", "tikz"}))) fmt = "$10^{%T}$"; else fmt = "10^{%T}"; endif if (sgn < 0) fmt = ["-" fmt]; endif else fmt = "%g"; num_mtics = 5; endif colorspec = get_text_colorspec (color); fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt); if (strcmp (ticmode, "manual")) if (isempty (tics)) fprintf (plot_stream, "unset %stics;\nunset m%stics;\n", ax, ax); return endif fprintf (plot_stream, "set %stics %s %s %s %s (", ax, tickdir, ticklength, axispos, mirror); fprintf (plot_stream, " %.15g,", tics(1:end-1)); fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec); else fprintf (plot_stream, "set %stics %s %s %s %s %s %s;\n", ax, tickdir, ticklength, axispos, mirror, colorspec, fontspec); endif if (strcmp (labelmode, "manual")) k = 1; ntics = numel (tics); nlabels = numel (labels); fprintf (plot_stream, "set %stics add %s %s %s %s (", ax, tickdir, ticklength, axispos, mirror); labels = strrep (labels, "%", "%%"); for i = 1:ntics fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i)); if (i < ntics) fputs (plot_stream, ", "); endif if (k > nlabels) k = 1; endif endfor fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec); endif if (strcmp (mtics, "on")) fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); else fprintf (plot_stream, "unset m%stics;\n", ax); endif endfunction function ticklabel = ticklabel_to_cell (ticklabel) if (ischar (ticklabel)) ticklabel = cellstr (ticklabel); elseif (iscellstr (ticklabel)) ticklabel = ticklabel; else error ("__gnuplot_draw_axes__: unsupported type of ticklabel"); endif endfunction function colorspec = get_text_colorspec (color) colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"", round (255*color)); endfunction function [f, s, fnt, it, bld] = get_fontname_and_size (t) if (isempty (t.fontname) || strcmp (t.fontname, "*")) if (ispc ()) ## FIXME: Should really test for "windows" terminal which is the ## only terminal to have a problem with a null font specification. ## See Bug #49135. fnt = "Arial"; else fnt = ""; endif else fnt = t.fontname; endif f = fnt; it = false; bld = false; if (! isempty (t.fontweight) && strcmp (t.fontweight, "bold")) if (! isempty (t.fontangle) && (strcmp (t.fontangle, "italic") || strcmp (t.fontangle, "oblique"))) if (__gnuplot_has_feature__ ("fontspec_5")) f = [f ":Bold:Italic"]; else f = [f "-bolditalic"]; endif it = true; bld = true; else if (__gnuplot_has_feature__ ("fontspec_5")) f = [f ":Bold"]; else f = [f "-bold"]; endif bld = true; endif elseif (! isempty (t.fontangle) && (strcmp (t.fontangle, "italic") || strcmp (t.fontangle, "oblique"))) if (__gnuplot_has_feature__ ("fontspec_5")) f = [f ":Italic"]; else f = [f "-italic"]; endif it = true; endif if (isempty (t.fontsize)) s = 10; else s = t.fontsize; endif endfunction function [str, f, s] = __maybe_munge_text__ (enhanced, obj, fld) persistent warned_latex = false; if (strcmp (fld, "string")) [f, s, fnt, it, bld] = get_fontname_and_size (obj); else f = "Helvetica"; s = 10; fnt = f; it = false; bld = false; endif ## The text object may be multiline, and may be of any class str = getfield (obj, fld); if (ischar (str) && rows (str) > 1) str = cellstr (str); elseif (isnumeric (str)) str = cellstr (num2str (str(:))); endif if (iscellstr (str)) for n = 1:numel (str) if (isnumeric (str{n})) str{n} = num2str (str{n}); endif endfor str = sprintf ("%s\n", str{:})(1:end-1); endif if (enhanced) str = regexprep (str, '(?<!\\)@', '\\@'); endif if (enhanced) if (strcmp (obj.interpreter, "tex")) if (iscellstr (str)) for n = 1:numel (str) str{n} = __tex2enhanced__ (str{n}, fnt, it, bld); endfor else str = __tex2enhanced__ (str, fnt, it, bld); endif elseif (strcmp (obj.interpreter, "latex")) if (! warned_latex) warning ("latex markup not supported for text objects"); warned_latex = true; endif endif endif endfunction function str = __tex2enhanced__ (str, fnt, it, bld) persistent sym = __setup_sym_table__ (); persistent flds = fieldnames (sym); [s, e, m] = regexp (str, "\\\\([a-zA-Z]+|0)", "start", "end", "matches"); for i = length (s) : -1 : 1 ## special case for "\0" and replace with empty set "{/Symbol \306}' if (strncmp (m{i}, '\0', 2)) str = [str(1:s(i) - 1) '{/Symbol \306}' str(s(i) + 2:end)]; else f = m{i}(2:end); if (isfield (sym, f)) g = getfield (sym, f); ## FIXME: The symbol font doesn't seem to support bold or italic ##if (bld) ## if (it) ## g = strrep (g, '/Symbol', '/Symbol-bolditalic'); ## else ## g = strrep (g, '/Symbol', '/Symbol-bold'); ## endif ##elseif (it) ## g = strrep (g, '/Symbol', '/Symbol-italic'); ##endif str = [str(1:s(i) - 1) g str(e(i) + 1:end)]; elseif (strncmp (f, "rm", 2)) bld = false; it = false; str = [str(1:s(i) - 1) '{/' fnt ' ' str(s(i) + 3:end) '}']; elseif (strncmp (f, "it", 2) || strncmp (f, "sl", 2)) it = true; if (__gnuplot_has_feature__ ("fontspec_5")) if (bld) str = [str(1:s(i)-1) '{/' fnt ':Bold:Italic ' str(s(i)+3:end) '}']; else str = [str(1:s(i)-1) '{/' fnt ':Italic ' str(s(i)+3:end) '}']; endif else if (bld) str = [str(1:s(i)-1) '{/' fnt '-bolditalic ' str(s(i)+3:end) '}']; else str = [str(1:s(i)-1) '{/' fnt '-italic ' str(s(i)+3:end) '}']; endif endif elseif (strncmp (f, "bf", 2)) bld = true; if (__gnuplot_has_feature__ ("fontspec_5")) if (it) str = [str(1:s(i)-1) '{/' fnt ':Bold:Italic ' str(s(i)+3:end) '}']; else str = [str(1:s(i)-1) '{/' fnt ':Bold ' str(s(i)+3:end) '}']; endif else if (it) str = [str(1:s(i)-1) '{/' fnt '-bolditalic ' str(s(i)+3:end) '}']; else str = [str(1:s(i)-1) '{/' fnt '-bold ' str(s(i)+3:end) '}']; endif endif elseif (strcmp (f, "color")) ## FIXME: Ignore \color but remove trailing {} block as well d = strfind (str(e(i) + 1:end),'}'); if (isempty (d)) warning ('syntax error in \color argument'); else str = [str(1:s(i) - 1) str(e(i) + d + 1:end)]; endif elseif (strcmp (f, "fontname")) b1 = strfind (str(e(i) + 1:end),'{'); b2 = strfind (str(e(i) + 1:end),'}'); if (isempty (b1) || isempty (b2)) warning ('syntax error in \fontname argument'); else str = [str(1:s(i) - 1), '/', str(e(i)+b1(1) + 1:e(i)+b2(1)-1), ... '{}', str(e(i) + b2(1) + 1:end)]; endif elseif (strcmp (f, "fontsize")) b1 = strfind (str(e(i) + 1:end),'{'); b2 = strfind (str(e(i) + 1:end),'}'); if (isempty (b1) || isempty (b2)) warning ('syntax error in \fontname argument'); else str = [str(1:s(i) - 1), '/=', str(e(i)+b1(1) + 1:e(i)+b2(1)-1), ... '{}', str(e(i) + b2(1) + 1:end)]; endif else ## Last desperate attempt to treat the symbol. Look for things ## like \pix, that should be translated to the symbol Pi and x for j = 1 : length (flds) if (strncmp (flds{j}, f, length (flds{j}))) g = getfield (sym, flds{j}); ## FIXME: The symbol font doesn't seem to support bold or italic ##if (bld) ## if (it) ## g = strrep (g, '/Symbol', '/Symbol-bolditalic'); ## else ## g = strrep (g, '/Symbol', '/Symbol-bold'); ## endif ##elseif (it) ## g = strrep (g, '/Symbol', '/Symbol-italic'); ##endif str = [str(1:s(i) - 1) g str(s(i) + length (flds{j}) + 1:end)]; break; endif endfor endif endif endfor ## Prepend @ to things like _0^x or _{-100}^{100} for alignment. ## But need to put the shorter of the two arguments first. ## Careful of nested {} and unprinted characters when defining ## shortest.. Don't have to worry about things like ^\theta as they ## are already converted to ^{/Symbol q}. ## FIXME: This is a mess. Is it worth it just for a "@" character? [s, m] = regexp (str,'[_\^]','start','matches'); i = 1; p = 0; while (i < length (s)) if (i < length (s)) if (str(s(i) + p + 1) == "{") s1 = strfind (str(s(i) + p + 2:end),'{'); si = 1; l1 = strfind (str(s(i) + p + 1:end),'}'); li = 1; while (li <= length (l1) && si <= length (s1)) if (l1(li) < s1(si)) if (li == si) break; endif li += 1; else si += 1; endif endwhile l1 = l1(min (length (l1), si)); if (s(i) + l1 + 1 == s(i+1)) if (str(s(i + 1) + p + 1) == "{") s2 = strfind (str(s(i + 1) + p + 2:end),'{'); si = 1; l2 = strfind (str(s(i + 1) + p + 1:end),'}'); li = 1; while (li <= length (l2) && si <= length (s2)) if (l2(li) < s2(si)) if (li == si) break; endif li += 1; else si += 1; endif endwhile l2 = l2(min (length (l2), si)); if (length_string (str(s(i)+p+2:s(i)+p+l1-1)) <= length_string (str(s(i+1)+p+2:s(i+1)+p+l2-1))) ## Shortest already first! str = [str(1:s(i)+p-1) "@" str(s(i)+p:end)]; else ## Have to swap sub/super-script to get shortest first. str = [str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+l2), ... str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+l2+1:end)]; endif else ## Have to swap sub/super-script to get shortest first. str = [str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+1), ... str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+2:end)]; endif i += 2; p += 1; else i += 1; endif else if (s(i+1) == s(i) + 2) ## Shortest already first! str = [str(1:s(i)+p-1) "@" str(s(i)+p:end)]; p += 1; i += 2; else i += 1; endif endif else i += 1; endif endwhile endfunction function l = length_string (s) l = length (s) - length (strfind (s,'{')) - length (strfind (s,'}')); m = regexp (s, '/([\w-]+|[\w-]+=\d+)', 'matches'); if (! isempty (m)) l -= sum (cellfun ("length", m)); endif endfunction function sym = __setup_sym_table__ () ## Setup the translation table for TeX to gnuplot enhanced mode. sym.forall = '{/Symbol \042}'; sym.exists = '{/Symbol \044}'; sym.ni = '{/Symbol \047}'; sym.cong = '{/Symbol \100}'; sym.Delta = '{/Symbol D}'; sym.Phi = '{/Symbol F}'; sym.Gamma = '{/Symbol G}'; sym.vartheta = '{/Symbol J}'; sym.Lambda = '{/Symbol L}'; sym.Pi = '{/Symbol P}'; sym.Theta = '{/Symbol Q}'; sym.Sigma = '{/Symbol S}'; sym.varsigma = '{/Symbol V}'; sym.Omega = '{/Symbol W}'; sym.Xi = '{/Symbol X}'; sym.Psi = '{/Symbol Y}'; sym.perp = '{/Symbol \136}'; sym.alpha = '{/Symbol a}'; sym.beta = '{/Symbol b}'; sym.chi = '{/Symbol c}'; sym.delta = '{/Symbol d}'; sym.epsilon = '{/Symbol e}'; sym.phi = '{/Symbol f}'; sym.gamma = '{/Symbol g}'; sym.eta = '{/Symbol h}'; sym.iota = '{/Symbol i}'; sym.varphi = '{/Symbol j}'; # Not in OpenGL sym.kappa = '{/Symbol k}'; sym.lambda = '{/Symbol l}'; sym.mu = '{/Symbol m}'; sym.nu = '{/Symbol n}'; sym.o = '{/Symbol o}'; sym.pi = '{/Symbol p}'; sym.theta = '{/Symbol q}'; sym.rho = '{/Symbol r}'; sym.sigma = '{/Symbol s}'; sym.tau = '{/Symbol t}'; sym.upsilon = '{/Symbol u}'; sym.varpi = '{/Symbol v}'; sym.omega = '{/Symbol w}'; sym.xi = '{/Symbol x}'; sym.psi = '{/Symbol y}'; sym.zeta = '{/Symbol z}'; sym.sim = '{/Symbol \176}'; sym.Upsilon = '{/Symbol \241}'; sym.prime = '{/Symbol \242}'; sym.leq = '{/Symbol \243}'; sym.infty = '{/Symbol \245}'; sym.clubsuit = '{/Symbol \247}'; sym.diamondsuit = '{/Symbol \250}'; sym.heartsuit = '{/Symbol \251}'; sym.spadesuit = '{/Symbol \252}'; sym.leftrightarrow = '{/Symbol \253}'; sym.leftarrow = '{/Symbol \254}'; sym.uparrow = '{/Symbol \255}'; sym.rightarrow = '{/Symbol \256}'; sym.downarrow = '{/Symbol \257}'; sym.circ = '{/Symbol \260}'; # degree symbol, not circ as in FLTK sym.deg = '{/Symbol \260}'; sym.ast = '{/Symbol *}'; sym.pm = '{/Symbol \261}'; sym.geq = '{/Symbol \263}'; sym.times = '{/Symbol \264}'; sym.propto = '{/Symbol \265}'; sym.partial = '{/Symbol \266}'; sym.bullet = '{/Symbol \267}'; sym.div = '{/Symbol \270}'; sym.neq = '{/Symbol \271}'; sym.equiv = '{/Symbol \272}'; sym.approx = '{/Symbol \273}'; sym.ldots = '{/Symbol \274}'; sym.mid = '{/Symbol \275}'; sym.aleph = '{/Symbol \300}'; sym.Im = '{/Symbol \301}'; sym.Re = '{/Symbol \302}'; sym.wp = '{/Symbol \303}'; sym.otimes = '{/Symbol \304}'; sym.oplus = '{/Symbol \305}'; ## empty set, not circled slash division operator as in FLTK. sym.oslash = '{/Symbol \306}'; sym.cap = '{/Symbol \307}'; sym.cup = '{/Symbol \310}'; sym.supset = '{/Symbol \311}'; sym.supseteq = '{/Symbol \312}'; sym.subset = '{/Symbol \314}'; sym.subseteq = '{/Symbol \315}'; sym.in = '{/Symbol \316}'; sym.notin = '{/Symbol \317}'; # Not in OpenGL sym.angle = '{/Symbol \320}'; sym.bigtriangledown = '{/Symbol \321}'; # Not in OpenGL sym.langle = '{/Symbol \341}'; sym.rangle = '{/Symbol \361}'; sym.nabla = '{/Symbol \321}'; sym.prod = '{/Symbol \325}'; # Not in OpenGL sym.surd = '{/Symbol \326}'; sym.cdot = '{/Symbol \327}'; sym.neg = '{/Symbol \330}'; sym.wedge = '{/Symbol \331}'; sym.vee = '{/Symbol \332}'; sym.Leftrightarrow = '{/Symbol \333}'; # Not in OpenGL sym.Leftarrow = '{/Symbol \334}'; sym.Uparrow = '{/Symbol \335}'; # Not in OpenGL sym.Rightarrow = '{/Symbol \336}'; sym.Downarrow = '{/Symbol \337}'; # Not in OpenGL sym.diamond = '{/Symbol \340}'; # Not in OpenGL sym.copyright = '{/Symbol \343}'; sym.lfloor = '{/Symbol \353}'; sym.lceil = '{/Symbol \351}'; sym.rfloor = '{/Symbol \373}'; sym.rceil = '{/Symbol \371}'; sym.int = '{/Symbol \362}'; endfunction function retval = __do_enhanced_option__ (enhanced, obj) retval = ""; if (enhanced) if (strcmp (obj.interpreter, "none")) retval = "noenhanced"; else retval = "enhanced"; endif endif endfunction function do_text (stream, gpterm, enhanced, obj, hax, screenpos) [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string"); fontspec = create_fontspec (f, s, gpterm); lpos = obj.position; halign = obj.horizontalalignment; valign = obj.verticalalignment; angle = obj.rotation; units = obj.units; color = obj.color; if (nargin > 5) units = "screen"; lpos = screenpos; elseif (strcmp (units, "normalized")) units = "graph"; elseif (strcmp (get (hax, "yaxislocation"), "right") && strcmp (units, "data")) units = "second"; else units = ""; endif if (isnumeric (color)) colorspec = get_text_colorspec (color); endif if (ischar (obj.string)) num_lines = rows (obj.string); num_lines += numel (strfind (obj.string, "\n")); else num_lines = numel (obj.string); endif switch (valign) ## Text offset in characters. Relies on gnuplot for font metrics. case "top" dy = -0.5; case "cap" dy = -0.5; case "middle" dy = 0.5 * (num_lines - 1); case "baseline" dy = 0.5 + (num_lines - 1); case "bottom" dy = 0.5 + (num_lines - 1); endswitch ## Gnuplot's Character units are different for x/y and vary with ## fontsize. The aspect ratio of 1:1.7 was determined by experiment ## to work for eps/ps/etc. For the MacOS aqua terminal a value of 2.5 ## is needed. However, the difference is barely noticeable. dx_and_dy = [(-dy * sind (angle)), (dy * cosd (angle))] .* [1.7 1]; ## FIXME: Multiline text produced the gnuplot ## "warning: ft_render: skipping glyph" if (__calc_dimensions__ (hax) == 3) zstr = sprintf (",%.15e", lpos(3)); else zstr = ""; endif fprintf (stream, "set label \"%s\" at %s %.15e,%.15e%s %s rotate by %f offset character %f,%f %s %s front %s;\n", undo_string_escapes (label), units, lpos(1), lpos(2), zstr, halign, angle, dx_and_dy, fontspec, __do_enhanced_option__ (enhanced, obj), colorspec); endfunction function maybe_do_xtick_mirror (plot_stream, axis_obj) if (! isempty(axis_obj.xtick)) fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n", axis_obj.tickdir); endif endfunction function maybe_do_x2tick_mirror (plot_stream, axis_obj) if (! isempty(axis_obj.xtick)) fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n", axis_obj.tickdir); endif endfunction function retval = mapcdata (cdata, mode, clim, cmap_sz) if (ndims (cdata) == 3) ## True Color, clamp data to 8-bit clim = double (clim); cdata = double (cdata); clim_rng = clim(2) - clim(1); if (clim_rng != 0) cdata = 255 * (cdata - clim(1)) / clim_rng; cdata(cdata < 0) = 0; cdata(cdata > 255) = 255; else cdata(:) = 255; endif ## Scale using inverse of gnuplot's cbrange mapping retval = 1 + cdata * (cmap_sz-1)/255; else if (islogical (cdata)) cdata += 1; elseif (strcmp (mode, "scaled")) clim = double (clim); cdata = double (cdata); clim_rng = clim(2) - clim(1); if (clim_rng != 0) cdata = 1 + fix (cmap_sz * (cdata - clim(1)) / clim_rng); else cdata(:) = cmap_sz; endif else if (isinteger (cdata)) cdata += 1; else cdata = fix (cdata); endif endif retval = max (1, min (cdata, cmap_sz)); endif endfunction