changeset 29451:75ba68c686ab stable

doc: Document single precision issues with OpenGL graphics toolkits (bug #59418). * doc/interpreter/plot.txi: Add section about single precision issues with OpenGL graphics toolkits and possible work-arounds. * doc/interpreter/plotimages.m, doc/interpreter/images: Add build rule for example figure.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 20 Mar 2021 11:00:25 +0100
parents 6448a10a642a
children a0eb1ae33192 766db6d094fe
files doc/interpreter/images doc/interpreter/plot.txi doc/interpreter/plotimages.m
diffstat 3 files changed, 79 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/images	Sat Mar 20 11:17:09 2021 +0100
+++ b/doc/interpreter/images	Sat Mar 20 11:00:25 2021 +0100
@@ -1,5 +1,5 @@
 geometryimages.m voronoi triplot griddata convhull delaunay inpolygon
 interpimages.m interpft interpn interpderiv1 interpderiv2
-plotimages.m plot hist errorbar polar mesh plot3 extended
+plotimages.m plot hist errorbar polar mesh plot3 extended precisiondate
 sparseimages.m gplot grid spmatrix spchol spcholperm
 splineimages.m splinefit1 splinefit2 splinefit3 splinefit4 splinefit6
--- a/doc/interpreter/plot.txi	Sat Mar 20 11:17:09 2021 +0100
+++ b/doc/interpreter/plot.txi	Sat Mar 20 11:00:25 2021 +0100
@@ -2664,6 +2664,7 @@
 @menu
 * Customizing Toolkit Behavior::
 * Hardware vs. Software Rendering::
+* Precision issues::
 @end menu
 
 @node Customizing Toolkit Behavior
@@ -2707,3 +2708,60 @@
 @file{@var{octave-home}\bin\opengl32.dll}
 @*where @var{octave-home} is the directory in which Octave is installed (the
 default is @file{C:\Octave\Octave-@var{version}}).
+
+@node Precision issues
+@subsubsection Precision issues
+@cindex opengl single precision date time
+
+The OpenGL graphics toolkits (@qcode{"qt"} and @qcode{"fltk"}) use single
+precision for rendering.  This limitation in particular applies to plots of
+timeseries against serial dates as used by the @code{datenum}, @code{datestr},
+@code{datestruct}, and @code{datetick} functions.
+
+Serial dates encode timestamps as days elapsed since the year zero with hours,
+minutes, seconds as the fractional part. On December 31st 1999, the serial date
+representation was 730485.  A double precision variable with this integer part
+allows for a resolution in its fractional part of 1.2e-10, representing about 5
+microseconds.  But with single precision, the resolution is reduced to about
+0.06, representing 45 minutes.  Any attempt to plot timestamped data with finer
+granularity will result in a distorted graph.
+
+As a workaround, it is possible to use the @qcode{"gnuplot"} graphics toolkit
+or subtract 2000 years---i.e. datenum(2000,0,0) or 730485---from the time
+values.  Due to the fact that the calendar structure repeats every 2000 years,
+the relation between year, month, day of month and day of week will stay
+unchanged and the ticks and ticklabels produced by the @code{datetick} function
+will still be correct.  Only years will lack the millennium digit.  Thus,
+"2020" will be printed as "20".  For example:
+
+@example
+@group
+# timestamps of 24 hours in one minute steps
+t = datenum (2020, 1, 1):(1/1440):datenum (2020, 1, 2);
+
+# some example timeseries data
+x = -cos (2*pi*t) + rand (size (t)) / 10;
+
+subplot (1, 2, 1);
+plot (t, x);
+datetick ("x");
+xlabel ("serial date");
+title ("problem");
+
+subplot (1, 2, 2);
+plot (t - 730485, x);
+datetick ("x");
+xlabel ("2000 years off");
+title ("workaround");
+@end group
+@end example
+
+@ifnotinfo
+@noindent
+The result of which can be seen in @ref{fig:precisiondate}.
+
+@float Figure,fig:precisiondate
+@center @image{precisiondate,4in}
+@caption{Single precision issues with OpenGL graphics toolkits}
+@end float
+@end ifnotinfo
--- a/doc/interpreter/plotimages.m	Sat Mar 20 11:17:09 2021 +0100
+++ b/doc/interpreter/plotimages.m	Sat Mar 20 11:00:25 2021 +0100
@@ -121,6 +121,26 @@
             '\int_{\fontsize{8}0}^{\fontsize{8}x}} e^{-t^2} dt} = 0.6175']);
       print (outfile, d_typ);
     endif
+  elseif (strcmp (nm, "precisiondate"))
+    rand ("state", 1);
+    t = datenum (2020, 1, 1):(1/1440):datenum (2020, 1, 2);
+    x = -cos (2*pi*t) + rand (size (t)) / 10;
+    subplot (1, 2, 1);
+    plot (t, x);
+    datetick ("x");
+    xlabel ("serial date");
+    title ("problem");
+    subplot (1, 2, 2);
+    plot (t - 730485, x);
+    datetick ("x");
+    xlabel ("2000 years off");
+    title ("workaround");
+    # set wider aspect ratio
+    image_size = [8.25, 3.5]; # in inches, 5:2 format
+    border = 0;              # For postscript use 50/72
+    set (gcf, "papersize", image_size + 2*border);
+    set (gcf, "paperposition", [border, border, image_size]);
+    print (outfile, d_typ);
   else
     error ("unrecognized plot requested");
   endif