octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Getting info back from gnuplot for auto range values


From: Daniel J Sebald
Subject: Re: Getting info back from gnuplot for auto range values
Date: Wed, 20 Jun 2007 12:16:29 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20041020

John W. Eaton wrote:
On 20-Jun-2007, Daniel J Sebald wrote:

| Attached is a patch illustrating how to get information back from
| gnuplot about auto axis ranging results if you are still interested.
| Rather than remove what would be extraneous code, I simply commented
| out the line of code that would use the octave computed settings.
| That way, this patch more clearly shows how to get the variables of
| interest.

I know this is possible, but I don't think it is the right approach to
use if we want compatibility (and I see no reason to be incompatible
when trying to implement Matlab-compatible graphics).

You give up too easily.  How about the attached patch that changes the terminal to 
"unknown" when the figure is off?  Currently an error message is issued when 
plotting for the example below.  It's a meaningless error and doesn't effect behavior; I 
could write a gnuplot patch to get rid of the message.


Here's an example of a problem with getting things like limits and
tick locations back from gnuplot.  Matlab can do this:

  figure ('visible', 'off');
  x = -pi:0.1:pi;
  plot (x, sin (x));
  get (gca (), 'xlim')  =>  [-4, 4]

If we want to emulate this by sending data to gnuplot and then asking
it for the limits, I think Octave will be slow to respond for plots
that contain many points, even when they are not displayed.

Well, yes.  There currently is something slow about plotting.  Gnuplot isn't 
the slow link.  If plotting is sped up in general, the delay would hardly be 
noticeable.


I also realize that Octave does not do this correctly now because it
skips the entire plotting process when the visible property is off.
Instead, it should be doing the computations on the data and possibly
setting some properties, but not asking the backend to render the
plot.

In a perfect world, extraneous computations would be avoided.  Other than the 
delay there isn't much harm, unless you want to duplicate exactly the way 
Matlab chooses ranges automatically.


| It would be nice if the communication link could be done through a
| pipe or stream.  However, I didn't have much luck with the pipe()
| command.  First, it would have to be a pipe that has a file system
| name so that gnuplot could use "set print '|filename'".  Second,
| reading from the pipe created with pipe() seems to get stuck for me,
| i.e., put something into the WRITE_FD and try to read from READ_FD
| just hangs.

I'm not sure that pipe is the right function for what you want to do.
Look at the popen2.m function from Octave 2.1.73 for an example of how
it is intended to be used.

I just recall Octave/gnuplot interface in older versions using popen(), but 
that was at the C level of course.

Dan

PS:  When doing these commands

figure ('visible', 'off');
figure ('visible', 'on');
figure ('visible', 'off');
figure ('visible', 'on');

should the figure number be increasing as it currently does in CVS version?
diff -Pur octave-cvs/scripts/plot/drawnow.m octave-mod/scripts/plot/drawnow.m
--- octave-cvs/scripts/plot/drawnow.m   2007-03-26 08:28:24.000000000 -0600
+++ octave-mod/scripts/plot/drawnow.m   2007-06-20 12:00:22.422288146 -0500
@@ -58,15 +58,17 @@
          if (f.__modified__)
            plot_stream = f.__plot_stream__;
            figure_is_visible = strcmp (f.visible, "on");
-           if (figure_is_visible)
-             if (isempty (plot_stream))
-               plot_stream = open_gnuplot_stream (h);
-             endif
-             __go_draw_figure__ (f, plot_stream);
-           elseif (! isempty (plot_stream))
+           if (! figure_is_visible && ! isempty (plot_stream))
+             % Close all windows that may be open.
              pclose (plot_stream);
+             plot_stream = [];
              set (h, "__plot_stream__", []);
            endif
+           % Always draw even if not visible to get variable values.
+           if (isempty (plot_stream))
+             plot_stream = open_gnuplot_stream (h);
+           endif
+           __go_draw_figure__ (f, plot_stream);
            set (h, "__modified__", false);
          endif
        endif
diff -Pur octave-cvs/scripts/plot/__go_draw_axes__.m 
octave-mod/scripts/plot/__go_draw_axes__.m
--- octave-cvs/scripts/plot/__go_draw_axes__.m  2007-06-19 01:00:08.000000000 
-0500
+++ octave-mod/scripts/plot/__go_draw_axes__.m  2007-06-20 11:36:12.458619596 
-0500
@@ -32,6 +32,11 @@
 
     parent_figure_obj = get (axis_obj.parent);
 
+    figure_is_visible = strcmp (parent_figure_obj.visible, "on");
+    if (! figure_is_visible)
+      fputs (plot_stream, "set terminal push;\nset terminal unknown;\n");
+    endif
+
     persistent have_newer_gnuplot ...
       = compare_versions (__gnuplot_version__ (), "4.0", ">");
 
@@ -511,7 +516,7 @@
 
     if (xautoscale && have_data)
       xlim = get_axis_limits (xmin, xmax, xminp, xlogscale);
-      set (h, "xlim", xlim, "xlimmode", "auto");
+%      set (h, "xlim", xlim, "xlimmode", "auto");
     else
       xlim = axis_obj.xlim;
     endif
@@ -524,7 +529,7 @@
 
     if (yautoscale && have_data)
       ylim = get_axis_limits (ymin, ymax, yminp, ylogscale);
-      set (h, "ylim", ylim, "ylimmode", "auto");
+%      set (h, "ylim", ylim, "ylimmode", "auto");
     else
       ylim = axis_obj.ylim;
     endif
@@ -538,7 +543,7 @@
     if (nd == 3)
       if (zautoscale && have_data)
        zlim = get_axis_limits (zmin, zmax, zminp, zlogscale);
-       set (h, "zlim", zlim, "zlimmode", "auto");
+%      set (h, "zlim", zlim, "zlimmode", "auto");
       else
        zlim = axis_obj.zlim;
       endif
@@ -635,8 +640,26 @@
       fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n");
     endif
 
+    if (! figure_is_visible)
+      fputs (plot_stream, "set terminal pop;\n");
+    endif
+
     fflush (plot_stream);
 
+    % Get information back from gnuplot about axis limits
+    if (xautoscale)
+      xlim = __gnuplot_read_limits__ (plot_stream, "X");
+      set (h, "xlim", xlim, "xlimmode", "auto");
+    endif
+    if (yautoscale)
+      ylim = __gnuplot_read_limits__ (plot_stream, "Y");
+      set (h, "ylim", ylim, "ylimmode", "auto");
+    endif
+    if (nd == 3 && zautoscale)
+      zlim = __gnuplot_read_limits__ (plot_stream, "Z");
+      set (h, "zlim", zlim, "zlimmode", "auto");
+    endif
+
   else
     print_usage ();
   endif    
@@ -896,6 +919,27 @@
 
 endfunction
 
+function lim = __gnuplot_read_limits__ (plot_stream, dim)
+  
+  ## Set gnuplot's print command to a file, print the values of
+  ## interest and then read them.  It would be nice if this
+  ## were a pipe so that continually opening and closing files
+  ## wasn't necessary.
+
+  persistent __gpprintfile__ = "";
+
+  if (isempty (__gpprintfile__))
+    __gpprintfile__ = tmpnam ();
+  endif
+  fprintf (plot_stream, "set print \"-\";\nset print \"%s\";\n", 
__gpprintfile__);
+  fprintf (plot_stream, "print GPVAL_%s_MIN;\nprint GPVAL_%s_MAX;\n", dim, 
dim);
+  fputs (plot_stream, "set print \"-\";\n");
+  gpfid = fopen (__gpprintfile__);
+  lim = fscanf (gpfid, "%g", 2)(:)';
+  fclose (gpfid);
+
+endfunction
+
 function do_tics (obj, plot_stream)
   do_tics_1 (obj.xtickmode, obj.xtick, obj.xticklabelmode, obj.xticklabel,
             "x", plot_stream);
diff -Pur octave-cvs/scripts/plot/__go_draw_figure__.m 
octave-mod/scripts/plot/__go_draw_figure__.m
--- octave-cvs/scripts/plot/__go_draw_figure__.m        2007-05-14 
11:32:54.000000000 -0500
+++ octave-mod/scripts/plot/__go_draw_figure__.m        2007-06-20 
11:22:41.000000000 -0500
@@ -68,8 +68,10 @@
          fputs (plot_stream, "unset multiplot;\n");
        endif
       else
-       fputs (plot_stream, "\nreset; clear;\n");
-       fflush (plot_stream);
+       if (strcmp (f.visible, "on"))
+         fputs (plot_stream, "\nreset; clear;\n");
+         fflush (plot_stream);
+       endif
       endif
     else
       error ("__go_draw_figure__: expecting figure object, found `%s'",

reply via email to

[Prev in Thread] Current Thread [Next in Thread]