LCOV - code coverage report
Current view: top level - include/math/plot - gnuPlot.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 0.0 % 22 0
Test Date: 2026-08-30 22:23:37 Functions: 0.0 % 6 0

            Line data    Source code
       1              : /** \file gnuPlot.hpp
       2              :  * \author Jared R. Males (jaredmales@gmail.com)
       3              :  * \brief Declaration and definition of an interface to the gnuplot program
       4              :  * \ingroup plotting_files
       5              :  *
       6              :  */
       7              : 
       8              : //***********************************************************************//
       9              : // Copyright 2015-2023 Jared R. Males (jaredmales@gmail.com)
      10              : //
      11              : // This file is part of mxlib.
      12              : //
      13              : // mxlib is free software: you can redistribute it and/or modify
      14              : // it under the terms of the GNU General Public License as published by
      15              : // the Free Software Foundation, either version 3 of the License, or
      16              : // (at your option) any later version.
      17              : //
      18              : // mxlib is distributed in the hope that it will be useful,
      19              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      20              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21              : // GNU General Public License for more details.
      22              : //
      23              : // You should have received a copy of the GNU General Public License
      24              : // along with mxlib.  If not, see <http://www.gnu.org/licenses/>.
      25              : //***********************************************************************//
      26              : 
      27              : #ifndef math_plot_gnuPlot_hpp
      28              : #define math_plot_gnuPlot_hpp
      29              : 
      30              : #include <sys/types.h>
      31              : #include <sys/stat.h>
      32              : #include <unistd.h>
      33              : #include <stdio.h>
      34              : #include <fcntl.h>
      35              : #include <poll.h>
      36              : 
      37              : #include <stdlib.h>
      38              : 
      39              : #include <string>
      40              : #include <iostream>
      41              : #include <fstream>
      42              : #include <vector>
      43              : 
      44              : #include <cmath>
      45              : 
      46              : #include <map>
      47              : 
      48              : #include "../constants.hpp"
      49              : #include "../../mxlib.hpp"
      50              : #include "../../sys/timeUtils.hpp"
      51              : 
      52              : #ifndef MX_GP_FNAME_SZ
      53              : /// The size of the string for managing the stderr fifo
      54              : /** \ingroup plotting
      55              :  */
      56              : #define MX_GP_FNAME_SZ ( 128 )
      57              : #endif
      58              : 
      59              : #ifndef MX_GP_TEMP_SZ
      60              : /// The size of the string for managing temporary file names
      61              : /** \ingroup plotting
      62              :  */
      63              : #define MX_GP_TEMP_SZ ( 128 )
      64              : #endif
      65              : 
      66              : #ifndef MX_GP_FC_TIME
      67              : /** \def MX_GP_FC_TIME
      68              :  * Time, in microseconds, to wait for gnuplot startup and file creation to complete.
      69              :  * Opening is retried after each timeout of this length for MX_GP_FC_RETRIES attempts.
      70              :  * \ingroup plotting
      71              :  */
      72              : #define MX_GP_FC_TIME ( 10000 )
      73              : #endif
      74              : 
      75              : #ifndef MX_GP_FC_RETRIES
      76              : /** \def MX_GP_FC_RETRIES
      77              :  * Number of times to retry opening the gnuplot stderr file.
      78              :  * \ingroup plotting
      79              :  */
      80              : #define MX_GP_FC_RETRIES ( 10 )
      81              : #endif
      82              : 
      83              : namespace mx
      84              : {
      85              : namespace math
      86              : {
      87              : 
      88              : // Get the gnuplot binary format string for a type
      89              : // Specializations below.
      90              : template <typename dataT>
      91              : std::string gpBinaryFormat()
      92              : {
      93              :     static_assert( std::is_fundamental<dataT>::value || !std::is_fundamental<dataT>::value,
      94              :                    "No gnuplot format specifier available for this type." );
      95              :     return "";
      96              : }
      97              : 
      98              : struct gpCurve
      99              : {
     100              :     std::string m_file;
     101              : 
     102              :     std::string m_title;
     103              : 
     104              :     std::string m_modifiers;
     105              : 
     106              :     std::string m_binary;
     107              : 
     108            0 :     gpCurve()
     109            0 :     {
     110            0 :     }
     111              : 
     112            0 :     gpCurve( const std::string &file, const std::string &title, const std::string &modifiers )
     113            0 :         : m_file( file ), m_title( title ), m_modifiers( modifiers )
     114              :     {
     115            0 :     }
     116              : 
     117              :     gpCurve( const std::string &file,
     118              :              const std::string &title,
     119              :              const std::string &modifiers,
     120              :              const std::string &binary )
     121              :         : m_file( file ), m_title( title ), m_modifiers( modifiers ), m_binary( binary )
     122              :     {
     123              :     }
     124              : 
     125            0 :     gpCurve( const gpCurve &gpc )
     126            0 :     {
     127            0 :         m_file = gpc.m_file;
     128            0 :         m_title = gpc.m_title;
     129            0 :         m_modifiers = gpc.m_modifiers;
     130            0 :         m_binary = gpc.m_binary;
     131            0 :     }
     132              : };
     133              : 
     134              : /// An interactive c++ interface to gnuplot
     135              : /** Spawns a gnuplot sesssion and communicates with it.
     136              :  * \ingroup plotting
     137              :  *
     138              :  * \todo Use mxError for error reporting.
     139              :  *
     140              :  * An example of using gnuPlot to plot data from a file:
     141              :  * \code
     142              :  * gnuPlot gp; //This automatically connects, and is now ready to plot.
     143              :  *
     144              :  * gp.plot("my_data_file.dat", "u 1:2 w l"); //Plots the data in the file
     145              :  * \endcode
     146              :  *
     147              :  * Arrays can be plotted directly:
     148              :  * \code
     149              :  * std::vector<float> x;
     150              :  * std::vector<double> y;
     151              :  *
     152              :  * //...code to populate x and y
     153              :  *
     154              :  * gp.plot(x, y); //Plots y vs x.
     155              :  * \endcode
     156              :  * Note that the vector data types are different -- this is handled automatically.
     157              :  *
     158              :  * To get a response from the gnuplot session:
     159              :  * \code
     160              :  * std::cout << gp.getResponse("show terminal") << "\n"; //Sends the command to gnuplot, gets the response.
     161              :  * \endcode
     162              :  * Error checking and reporting is not straightforward since gnuplot does not return a result if there is no error.  If
     163              :  * there is an error, it can take several hundred milliseconds for a response to be available.  So for a typical plot
     164              :  * command, say, one does not want to try to read the stderr ouput just in case as this will just time out with a delay.
     165              :  *
     166              :  * For cases where a response is expected, the following example shows how to check for errors.
     167              :  * \code
     168              :  * errno = 0;
     169              :  * std::string response = gp.getResponse("show terminal"); //Waits up to 0.5 seconds, or a user specified timeout.
     170              :  *
     171              :  * if(response == "") //This indicates some error occurred, or a timeout.
     172              :  * {
     173              :  *   if(gp.gpError())
     174              :  *   {
     175              :  *      std::cerr << "gnuplot returned error:\n" << gp.gpErrorMsg() << "\n";
     176              :  *   }
     177              :  *   else if(errno)
     178              :  *   {
     179              :  *      perror("error getting response: ");
     180              :  *   }
     181              :  *   else
     182              :  *   {
     183              :  *      std::cerr << "timed out\n";
     184              :  *   }
     185              :  * }
     186              :  * else
     187              :  * {
     188              :  *   std::cout << response << "\n";
     189              :  * }
     190              :  *
     191              :  * \endcode
     192              :  */
     193              : class gnuPlot
     194              : {
     195              :     typedef verbose::d verboseT;
     196              :   protected:
     197              :     int _connected{ 0 };
     198              : 
     199              :     /// Set to true if the response indicates a gnuplot error
     200              :     bool _gpError{ false };
     201              :     std::string _gpErrorMsg;
     202              : 
     203              :     /// File stream for the gnuplot interface
     204              :     FILE *_pipeH{ 0 };
     205              : 
     206              :     /// Where to create gnuplot stderr fifo
     207              :     /** Default is /dev/shm/
     208              :      */
     209              :     std::string _errLocation;
     210              : 
     211              :     /// File name of the gnuplot stderr fifo
     212              :     std::string _errFName;
     213              : 
     214              :     /// File descriptor for the gnuplot stderr fifo
     215              :     int _errFD{ 0 };
     216              : 
     217              :     /// Location of temporary files
     218              :     /** Default is /dev/shm/
     219              :      */
     220              :     std::string _tempLocation;
     221              : 
     222              :     /// Vector of all temporary file names opened, used for removal on destruction.
     223              :     std::vector<std::string> _tempFiles;
     224              : 
     225              :     /// Flag to control whether temporary files are deleted on destruction.  Default is true (files deleted).
     226              :     bool _deleteTemp{ true };
     227              : 
     228              :     std::map<std::string, gpCurve> m_curveMap;
     229              : 
     230              :   public:
     231              :     gnuPlot();
     232              : 
     233              :     ~gnuPlot();
     234              : 
     235              :     /// Connect to gnuplot
     236              :     /** Spawns a gnuplot session using popen with stderr redirected to a temporary file.  The temporary file
     237              :      * is opened for reading.
     238              :      *
     239              :      * \retval 0 on success
     240              :      * \retval -1 on error
     241              :      */
     242              :     int connect();
     243              : 
     244              :     /// Return the value of the gpError flag.
     245              :     /** This flag is set if gnuplot returns an error message (see checkResponse()).  The error message
     246              :      * can be accessed with gpErrorMsg().
     247              :      *
     248              :      * \retval 0 if no error
     249              :      * \retval -1 if an error has occurred.
     250              :      */
     251              :     bool gpError();
     252              : 
     253              :     /// Return the gnuplot error message
     254              :     /** The error message is extracted by checkResponse() when the response from gnuplot begins with "gnuplot>".
     255              :      */
     256              :     std::string gpErrorMsg();
     257              : 
     258              :     /// Send a command to gnuplot
     259              :     /** The newline is appended to the command, and then it is sent to gnuplot.
     260              :      *
     261              :      *
     262              :      * \retval 0 on success
     263              :      * \retval -1 on error
     264              :      */
     265              :     int command( const std::string &com, ///< [in] the command string
     266              :                  bool flush = true ///< [in] [optional] if true (default), then the output stream is flushed once the
     267              :                                    ///< command is written
     268              :     );
     269              : 
     270              :     /// Check for a response from gnuplot.
     271              :     /** It typically takes some time for a response from gnuplot to become readable,
     272              :      * whether an error occurs or not. It is often 0.3 seconds or more.  If there is no error, there will be no response
     273              :      * so waiting for a response to check for errors after every command can be very time consuming.  Thus it is a
     274              :      * choice whether to check for errors from gnuplot after every command, and what timeout to use.
     275              :      *
     276              :      * \todo investigate having a second thread monitor for responses.
     277              :      *
     278              :      * gnuplot terminates all outputs with \c \\n\\n, so this reads up to these two characters.  It then strips any
     279              :      * leading and trailing whitespace. If the response begins with \c gnuplot>, then the response is an error.  In this
     280              :      * case, checkResponse returns -1 and the gpError flag is set.  If gpError is not set but the return value is -1,
     281              :      * then some other error occurred (check \c errno).
     282              :      *
     283              :      * \retval 0 on timeout or successful read
     284              :      * \retval -1 on error, or if the gnuplot response indicates an error.
     285              :      */
     286              :     int checkResponse(
     287              :         std::string &response, ///< [out] contains the response from gnuplot, but is empty on timeout or error.
     288              :         double timeout = 0 ///< [in] [optional] the length of time, in seconds, to wait for a response. Default is 0,
     289              :                            ///< but a minimum of 0.5 if a response is expected.
     290              :     );
     291              : 
     292              :     /// Get a response from gnuplot for a given command.
     293              :     /** This should only be used if a response is expected.
     294              :      *
     295              :      * \returns "" (empty string) on timeout or error (\c errno and gpError() should be checked), and the response from
     296              :      * gnuplot otherwise.
     297              :      */
     298              :     std::string getResponse( const std::string &com, ///< [in] the command string
     299              :                              double timeout = 0.5    ///< [in] the length of time, in seconds, to wait for a response.
     300              :                                                      ///< Default is 0.5, which is the minimum that should be used.
     301              :     );
     302              : 
     303              :     /// Issue the \b replot command
     304              :     /**
     305              :      * \retval 0 on success
     306              :      * \retval -1 on error
     307              :      */
     308              :     int replot();
     309              : 
     310              :     /// Set the x-axis range
     311              :     /** Sends the command:
     312              :      * \verbatim
     313              :      * set xrange [x0:x1]
     314              :      * \endverbatim
     315              :      *
     316              :      * \returns 0 on success
     317              :      * \returns -1 on error
     318              :      */
     319              :     int xrange( double x0, double x1 );
     320              : 
     321              :     /// Unset the x-axis range
     322              :     /** Sends the command:
     323              :      * \verbatim
     324              :      * unset xrange
     325              :      * \endverbatim
     326              :      *
     327              :      * \returns 0 on success
     328              :      * \returns -1 on error
     329              :      */
     330              :     int xrange();
     331              : 
     332              :     /// Set the y-axis range
     333              :     /** Sends the command:
     334              :      * \verbatim
     335              :      * set yrange [y0:y1]
     336              :      * \endverbatim
     337              :      *
     338              :      * \returns 0 on success
     339              :      * \returns -1 on error
     340              :      */
     341              :     int yrange( double y0, double y1 );
     342              : 
     343              :     /// Unset the y-axis range
     344              :     /** Sends the command:
     345              :      * \verbatim
     346              :      * unset yrange
     347              :      * \endverbatim
     348              :      *
     349              :      * \returns 0 on success
     350              :      * \returns -1 on error
     351              :      */
     352              :     int yrange();
     353              : 
     354              :     /// Set the y axis to log scale
     355              :     /** Sends the command:
     356              :       * \verbatim
     357              :         set log y
     358              :        \endverbatim
     359              :       *
     360              :       * \retval 0 on success
     361              :       * \retval -1 on error
     362              :       */
     363              :     int logy();
     364              : 
     365              :     /// Set the x axis to log scale
     366              :     /** Sends the command:
     367              :       * \verbatim
     368              :         set log x
     369              :        \endverbatim
     370              :       *
     371              :       * \retval 0 on success
     372              :       * \retval -1 on error
     373              :       */
     374              :     int logx();
     375              : 
     376              :     /// Set the x and y axes to log scale
     377              :     /** Sends the commands:
     378              :       * \verbatim
     379              :         set log x
     380              :         set log y
     381              :        \endverbatim
     382              :       *
     383              :       * \retval 0 on success
     384              :       * \retval -1 on error
     385              :       */
     386              :     int logxy();
     387              : 
     388              :     /// Unset the y axis from log scale
     389              :     /** Sends the command:
     390              :       * \verbatim
     391              :         unset log y
     392              :        \endverbatim
     393              :       *
     394              :       * \retval 0 on success
     395              :       * \retval -1 on error
     396              :       */
     397              :     int ulogy();
     398              : 
     399              :     /// Unset the x axis from log scale
     400              :     /** Sends the command:
     401              :       * \verbatim
     402              :         unset log x
     403              :        \endverbatim
     404              :       *
     405              :       * \retval 0 on success
     406              :       * \retval -1 on error
     407              :       */
     408              :     int ulogx();
     409              : 
     410              :     /// Unset the x and y axes from log scale
     411              :     /** Sends the command:
     412              :       * \verbatim
     413              :         unset log x
     414              :         unset log y
     415              :        \endverbatim
     416              :       *
     417              :       * \retval 0 on success
     418              :       * \retval -1 on error
     419              :       */
     420              :     int ulogxy();
     421              : 
     422              :     /// Plot from a file specifying all curve components.
     423              :     /** Forms the gnuplot plot command as follows:
     424              :      * \verbatim
     425              :      * plot '<fname>' <modifiers> t '<title>'
     426              :      * \endverbatim
     427              :      * The modifiers string can contain any modifiers such as \a using, etc.  Should generally not include \a title.
     428              :      *
     429              :      * \retval 0 on success
     430              :      * \retval -1 on error
     431              :      */
     432              :     int plot( const std::string &fname,     ///< [in] the name (with full path) of the file containing data to plot
     433              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command.
     434              :               const std::string &title,     ///< [in] the title for this curve
     435              :               const std::string &name       ///< [in] the name for this curve.  If "" then curve# is used.
     436              :     );
     437              : 
     438              :     /// Plot from a file without specifying the title
     439              :     /** Forms the gnuplot plot command as follows:
     440              :      * \verbatim
     441              :      * plot '<fname>' <modifiers> t ''
     442              :      * \endverbatim
     443              :      * The modifiers string can contain any modifiers such as \a using, etc.  Should generally not include \a title.
     444              :      *
     445              :      * \retval 0 on success
     446              :      * \retval -1 on error
     447              :      *
     448              :      * \overload
     449              :      */
     450              :     int plot( const std::string &fname,     ///< [in] the name (with full path) of the file containing data to plot
     451              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command.
     452              :               const std::string &name       ///< [in] the name for this curve.  If "" then the curve# is used.
     453              :     );
     454              : 
     455              :     /// Plot from a file without modifiers
     456              :     /** The file name is used for the identifying name
     457              :      *
     458              :      * Forms the gnuplot plot command as follows:
     459              :      * \verbatim
     460              :      * plot '<fname>' <modifiers> t ''
     461              :      * \endverbatim
     462              :      * The modifiers string can contain any modifiers such as \a using, etc.  Should generally not include \a title.
     463              :      *
     464              :      * \retval 0 on success
     465              :      * \retval -1 on error
     466              :      *
     467              :      * \overload
     468              :      */
     469              :     int plot( const std::string &fname, ///< [in] the name (with full path) of the file containing data to plot
     470              :               const std::string &name   ///< [in] the name for this curve.  If "" then the curve# is used
     471              :     );
     472              : 
     473              :     /// Plot from a file without specifying the name or any modifiers
     474              :     /** The file name is used for the identifying name
     475              :      *
     476              :      * Forms the gnuplot plot command as follows:
     477              :      * \verbatim
     478              :      * plot '<fname>' t ''
     479              :      * \endverbatim
     480              :      * The modifiers string can contain any modifiers such as \a using, etc.  Should generally not include \a title.
     481              :      *
     482              :      * \retval 0 on success
     483              :      * \retval -1 on error
     484              :      *
     485              :      * \overload
     486              :      */
     487              :     int plot( const std::string &fname /**< [in] the name (with full path) of the file containing data to plot */ );
     488              : 
     489              :     /// Plot data from an array
     490              :     /** Copies the data in the array to a temporary binary file, and then forms the gnuplot plot command as follows:
     491              :      * \verbatim
     492              :      *  plot "temp-file-name" binary format="%dataT" u 1 t "title" <modifiers>
     493              :      * \endverbatim
     494              :      * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     495              :      * can contain any other modifiers.  Title is specified so that the name of the temporary file name is not printed
     496              :      * on the plot.
     497              :      *
     498              :      * \retval 0 on success
     499              :      * \retval -1 on error
     500              :      */
     501              :     template <typename dataT>
     502              :     int plot( const dataT *y,               ///< [in] a pointer to an array of data
     503              :               size_t N,                     ///< [in] the length of the array
     504              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     505              :                                             ///< \b format, \b using, and \b title.
     506              :               const std::string &
     507              :                   title, ///< [in] contains the title of the data set, default is an empty string and no key on the plot
     508              :               const std::string &name ///< [in] the identifying name of this curve
     509              :     );
     510              : 
     511              :     /// Plot data from an array
     512              :     /** Copies the data in the array to a temporary binary file, and then forms the gnuplot plot command as follows:
     513              :      * \verbatim
     514              :      *  plot "temp-file-name" binary format="%dataT" u 1 t '' <modifiers>
     515              :      * \endverbatim
     516              :      * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     517              :      * can contain any other modifiers.  Title is specified so that the name of the temporary file name is not printed
     518              :      * on the plot.
     519              :      *
     520              :      * \retval 0 on success
     521              :      * \retval -1 on error
     522              :      */
     523              :     template <typename dataT>
     524              :     int plot( const dataT *y,               ///< [in] a pointer to an array of data
     525              :               size_t N,                     ///< [in] the length of the array
     526              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     527              :                                             ///< \b format, \b using, and \b title.
     528              :               const std::string &name       ///< [in] the identifying name of this curve
     529              :     );
     530              : 
     531              :     /// Plot data from an array
     532              :     /** Copies the data in the array to a temporary binary file, and then forms the gnuplot plot command as follows:
     533              :      * \verbatim
     534              :      *  plot "temp-file-name" binary format="%dataT" u 1 t '' <modifiers>
     535              :      * \endverbatim
     536              :      *
     537              :      *
     538              :      * \retval 0 on success
     539              :      * \retval -1 on error
     540              :      */
     541              :     template <typename dataT>
     542              :     int plot( const dataT *y,         ///< [in] a pointer to an array of data
     543              :               size_t N,               ///< [in] the length of the array
     544              :               const std::string &name ///< [in] the identifying name of this curve
     545              :     );
     546              : 
     547              :     /// Plot data from an array
     548              :     /** Copies the data in the array to a temporary binary file, and then forms the gnuplot plot command as follows:
     549              :      * \verbatim
     550              :      *  plot "temp-file-name" binary format="%dataT" u 1 t ''
     551              :      * \endverbatim
     552              :      *
     553              :      * \retval 0 on success
     554              :      * \retval -1 on error
     555              :      */
     556              :     template <typename dataT>
     557              :     int plot( const dataT *y, ///< [in] a pointer to an array of data
     558              :               size_t N        ///< [in] the length of the array
     559              :     );
     560              : 
     561              :     /// Plot data from a vector
     562              :     /** Copies the data in the vector to a temporary binary file, and then forms the gnuplot plot command as follows:
     563              :      * \verbatim
     564              :      *  plot "temp-file-name" binary format="%dataT" u 1 t "title" <modifiers>
     565              :      * \endverbatim
     566              :      * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     567              :      * can contain any other modifiers.  Title is specified so that the name of the temporary file name is not printed
     568              :      * on the plot.
     569              :      *
     570              :      * \retval 0 on success
     571              :      * \retval -1 on error
     572              :      */
     573              :     template <typename dataT>
     574              :     int plot( const std::vector<dataT> &y,  ///< [in] the vector containing the data
     575              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     576              :                                             ///< \b format, \b using, and \b title.
     577              :               const std::string &
     578              :                   title, ///< [in] contains the title of the data set, default is an empty string and no key on the plot
     579              :               const std::string &name ///< [in] the identifying name of this curve
     580              :     );
     581              : 
     582              :     /// Plot data from a vector
     583              :     /** Copies the data in the vector to a temporary binary file, and then forms the gnuplot plot command as follows:
     584              :      * \verbatim
     585              :      *  plot "temp-file-name" binary format="%dataT" u 1 t '' <modifiers>
     586              :      * \endverbatim
     587              :      * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     588              :      * can contain any other modifiers.  Title is specified so that the name of the temporary file name is not printed
     589              :      * on the plot.
     590              :      *
     591              :      * \retval 0 on success
     592              :      * \retval -1 on error
     593              :      */
     594              :     template <typename dataT>
     595              :     int plot( const std::vector<dataT> &y,  ///< [in] the vector containing the data
     596              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     597              :                                             ///< \b format, \b using, and \b title.
     598              :               const std::string &name       ///< [in] the identifying name of this curve
     599              :     );
     600              : 
     601              :     /// Plot data from a vector
     602              :     /** Copies the data in the vector to a temporary binary file, and then forms the gnuplot plot command as follows:
     603              :      * \verbatim
     604              :      *  plot "temp-file-name" binary format="%dataT" u 1 t ''
     605              :      * \endverbatim
     606              :      *
     607              :      * \retval 0 on success
     608              :      * \retval -1 on error
     609              :      */
     610              :     template <typename dataT>
     611              :     int plot( const std::vector<dataT> &y, ///< [in] the vector containing the data
     612              :               const std::string &name      ///< [in] the identifying name of this curve
     613              :     );
     614              : 
     615              :     /// Plot data from a vector
     616              :     /** Copies the data in the vector to a temporary binary file, and then forms the gnuplot plot command as follows:
     617              :      * \verbatim
     618              :      *  plot "temp-file-name" binary format="%dataT" u 1 t ''
     619              :      * \endverbatim
     620              :      *
     621              :      * \retval 0 on success
     622              :      * \retval -1 on error
     623              :      */
     624              :     template <typename dataT>
     625              :     int plot( const std::vector<dataT> &y /**< [in] the vector containing the data*/ );
     626              : 
     627              :     /// Plot y vs. x data from arrays
     628              :     /** Copies the data in the arrays to a temporary binary file, and then forms the gnuplot plot command as follows:
     629              :       * \verbatim
     630              :         plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t "title" <modifiers>
     631              :        \endverbatim
     632              :       * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     633              :       can contain any other modifiers.  Title is
     634              :       * specified so that the name of the temporary file name is not printed on the plot.
     635              :       *
     636              :       * \retval 0 on success
     637              :       * \retval -1 on error
     638              :       */
     639              :     template <typename dataTx, typename dataTy>
     640              :     int plot( const dataTx *x,              ///< [in] a pointer to an array of data for the independent variable
     641              :               const dataTy *y,              ///< [in] a pointer to an array of data for the dependent variable
     642              :               size_t N,                     ///< [in] the length of the arrays
     643              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     644              :                                             ///< \b format, \b using, and \b title.
     645              :               const std::string &title,     ///< [in] contains the title of the data set
     646              :               const std::string &name       ///< [in] the identifying name of the curve
     647              :     );
     648              : 
     649              :     /// Plot y vs. x data from arrays
     650              :     /** Copies the data in the arrays to a temporary binary file, and then forms the gnuplot plot command as follows:
     651              :      * \verbatim
     652              :      *  plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t '' <modifiers>
     653              :      * \endverbatim
     654              :      * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     655              :      * can contain any other modifiers.  Title is specified so that the name of the temporary file name is not printed
     656              :      * on the plot.
     657              :      *
     658              :      * \retval 0 on success
     659              :      * \retval -1 on error
     660              :      */
     661              :     template <typename dataTx, typename dataTy>
     662              :     int plot( const dataTx *x,              ///< [in] a pointer to an array of data for the independent variable
     663              :               const dataTy *y,              ///< [in] a pointer to an array of data for the dependent variable
     664              :               size_t N,                     ///< [in] the length of the arrays
     665              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     666              :                                             ///< \b format, \b using, and \b title.
     667              :               const std::string &name       ///< [in] the identifying name of the curve
     668              :     );
     669              : 
     670              :     /// Plot y vs. x data from arrays
     671              :     /** Copies the data in the arrays to a temporary binary file, and then forms the gnuplot plot command as follows:
     672              :      * \verbatim
     673              :      *  plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t ''
     674              :      * \endverbatim
     675              :      *
     676              :      * \retval 0 on success
     677              :      * \retval -1 on error
     678              :      */
     679              :     template <typename dataTx, typename dataTy>
     680              :     int plot( const dataTx *x,        ///< [in] a pointer to an array of data for the independent variable
     681              :               const dataTy *y,        ///< [in] a pointer to an array of data for the dependent variable
     682              :               size_t N,               ///< [in] the length of the arrays
     683              :               const std::string &name ///< [in] the identifying name of the curve
     684              :     );
     685              : 
     686              :     /// Plot y vs. x data from arrays
     687              :     /** Copies the data in the arrays to a temporary binary file, and then forms the gnuplot plot command as follows:
     688              :      * \verbatim
     689              :      *  plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t ''
     690              :      * \endverbatim
     691              :      *
     692              :      * \retval 0 on success
     693              :      * \retval -1 on error
     694              :      */
     695              :     template <typename dataTx, typename dataTy>
     696              :     int plot( const dataTx *x, ///< [in] a pointer to an array of data for the independent variable
     697              :               const dataTy *y, ///< [in] a pointer to an array of data for the dependent variable
     698              :               size_t N         ///< [in] the length of the arrays
     699              :     );
     700              : 
     701              :     /// Plot y vs. x data from vectors
     702              :     /** Copies the data in the vectors to a temporary binary file, and then forms the gnuplot plot command as follows:
     703              :       * \verbatim
     704              :         plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t "title" <modifiers>
     705              :        \endverbatim
     706              :       * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     707              :       can contain any other modifiers.  Title is
     708              :       * specified so that the name of the temporary file name is not printed on the plot.
     709              :       *
     710              :       * \retval 0 on success
     711              :       * \retval -1 on error
     712              :       */
     713              :     template <typename dataTx, typename dataTy>
     714              :     int plot( const std::vector<dataTx> &x, ///< [in] a vector of data for the independent variable
     715              :               const std::vector<dataTy> &y, ///< [in] a vector of data for the dependent variable
     716              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     717              :                                             ///< \b format, \b using, and \b title.
     718              :               const std::string &title,     ///< [in] contains the title of the data set
     719              :               const std::string &name       ///< [in] the identifying name of the curve
     720              :     );
     721              : 
     722              :     /// Plot y vs. x data from vectors
     723              :     /** Copies the data in the vectors to a temporary binary file, and then forms the gnuplot plot command as follows:
     724              :       * \verbatim
     725              :         plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t '' <modifiers>
     726              :        \endverbatim
     727              :       * The modifiers string \b must \b NOT contain the \b binary, \b format, \b using, or the \b title  modifiers, but
     728              :       can contain any other modifiers.  Title is
     729              :       * specified so that the name of the temporary file name is not printed on the plot.
     730              :       *
     731              :       * \retval 0 on success
     732              :       * \retval -1 on error
     733              :       */
     734              :     template <typename dataTx, typename dataTy>
     735              :     int plot( const std::vector<dataTx> &x, ///< [in] a vector of data for the independent variable
     736              :               const std::vector<dataTy> &y, ///< [in] a vector of data for the dependent variable
     737              :               const std::string &modifiers, ///< [in] contains any modifiers to the plot command other than \b binary,
     738              :                                             ///< \b format, \b using, and \b title.
     739              :               const std::string &name       ///< [in] the identifying name of the curve
     740              :     );
     741              : 
     742              :     /// Plot y vs. x data from vectors
     743              :     /** Copies the data in the vectors to a temporary binary file, and then forms the gnuplot plot command as follows:
     744              :      * \verbatim
     745              :      *  plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t ''
     746              :      * \endverbatim
     747              :      *
     748              :      * \retval 0 on success
     749              :      * \retval -1 on error
     750              :      */
     751              :     template <typename dataTx, typename dataTy>
     752              :     int plot( const std::vector<dataTx> &x, ///< [in] a vector of data for the independent variable
     753              :               const std::vector<dataTy> &y, ///< [in] a vector of data for the dependent variable
     754              :               const std::string &name       ///< [in] the identifying name of the curve
     755              :     );
     756              : 
     757              :     /// Plot y vs. x data from vectors
     758              :     /** Copies the data in the vectors to a temporary binary file, and then forms the gnuplot plot command as follows:
     759              :      * \verbatim
     760              :      *  plot "temp-file-name" binary format="%dataTx%dataTy" u 1:2 t ''
     761              :      * \endverbatim
     762              :      *
     763              :      * \retval 0 on success
     764              :      * \retval -1 on error
     765              :      */
     766              :     template <typename dataTx, typename dataTy>
     767              :     int plot( const std::vector<dataTx> &x, ///< [in] a vector of data for the independent variable
     768              :               const std::vector<dataTy> &y  ///< [in] a vector of data for the dependent variable
     769              :     );
     770              : 
     771              :     /// Plot a single point
     772              :     /** Copies the position as a length-1 vector to a temporary binary file, and then plots it.
     773              :      *
     774              :      *
     775              :      * \retval 0 on success
     776              :      * \retval -1 on error
     777              :      */
     778              :     template <typename dataTx, typename dataTy>
     779              :     int point( dataTx x,                          ///< [in] the independent axis (x) coordinate of the point
     780              :                dataTy y,                          ///< [in] the dependent axis (y) coordinate of the point
     781              :                const std::string &modifiers = "", ///< [in] [optional] contains any modifiers to the plot command other
     782              :                                                   ///< than \b binary, \b format, \b using, and \b title.
     783              :                const std::string &title = ""      ///< [in] [optional] contains the title of the data set, default is an
     784              :                                                   ///< empty string and no key on the plot
     785              :     );
     786              : 
     787              :     /// Draw a circle on the plot
     788              :     /** Creates a circle with specified center and radius, and plots it.
     789              :      */
     790              :     int circle( double xcen,                       ///< [in] the x-coordinate of the circle center
     791              :                 double ycen,                       ///< [in] the y-coordinate of the circle center
     792              :                 double radius,                     ///< [in] the circle radius
     793              :                 const std::string &modifiers = "", ///< [in] [optional] contains any modifiers to the plot command other
     794              :                                                    ///< than \b binary, \b format, \b using, and \b title.
     795              :                 const std::string &title = "", ///< [in] [optional] contains the title of the data set, default is an
     796              :                                                ///< empty string and no key on the plot
     797              :                 int npoints = 10 ///< [in] [optional] specifies the number of points in each half circle.  Default 10 is
     798              :                                  ///< usually sufficient.
     799              :     );
     800              : 
     801              :     /// Draw a circle on the plot around the origin
     802              :     /** Creates a circle with radius and center (0,0), and plots it.
     803              :      */
     804              :     int circle( double radius,                     ///< [in] the circle radius
     805              :                 const std::string &modifiers = "", ///< [in] [optional] contains any modifiers to the plot command other
     806              :                                                    ///< than \b binary, \b format, \b using, and \b title.
     807              :                 const std::string &title = "", ///< [in] [optional] contains the title of the data set, default is an
     808              :                                                ///< empty string and no key on the plot
     809              :                 int npoints = 10 ///< [in] [optional] specifies the number of points in each half circle.  Default 10 is
     810              :                                  ///< usually sufficient.
     811              :     );
     812              : 
     813              :     /// Clear all the curves
     814              :     void clear();
     815              : 
     816              :     /// Clear all the curves and reset plot configuration
     817              :     void reset();
     818              : 
     819              :     /// List the curves and their specifications.
     820              :     void listCurves();
     821              : 
     822              :     /// Modify the modifiers for a curve
     823              :     void modifiers( const std::string &name,     ///< [in] the name of the curve
     824              :                     const std::string &modifiers ///< [in] the new modifiers
     825              :     );
     826              : 
     827              :     /// Modify the title for a curve
     828              :     void title( const std::string &name, ///< [in] the name of the curve
     829              :                 const std::string &title ///< [in] the new title
     830              :     );
     831              : 
     832              :   protected:
     833              :     /// Implementation of 1-D binary plotting.
     834              :     int plotImpl( const void *y,
     835              :                   size_t Nbytes,
     836              :                   const std::string &binary,
     837              :                   const std::string &modifiers,
     838              :                   const std::string &title,
     839              :                   const std::string &name );
     840              : 
     841              :     /// Implementation of 2-d binary plotting.
     842              :     int plotImpl( const void *x,
     843              :                   const void *y,
     844              :                   size_t Npts,
     845              :                   size_t sizex,
     846              :                   size_t sizey,
     847              :                   const std::string &binaryx,
     848              :                   const std::string &binaryy,
     849              :                   const std::string &modifiers,
     850              :                   const std::string &title,
     851              :                   const std::string &name );
     852              : 
     853              :     /// Issue the plot command for all the curves
     854              :     int doPlotCommand();
     855              : 
     856              :     /// Open a temporary binary file, and provide the filename.
     857              :     FILE *openTempFile( char *fname );
     858              : 
     859              :   private:
     860              :     /// Initialize an instance, only used at construction
     861              :     void init();
     862              : };
     863              : 
     864              : template <typename dataT>
     865              : int gnuPlot::plot(
     866              :     const dataT *y, size_t N, const std::string &modifiers, const std::string &title, const std::string &name )
     867              : {
     868              :     return plotImpl( y, N * sizeof( dataT ), gpBinaryFormat<dataT>(), modifiers, title, name );
     869              : }
     870              : 
     871              : template <typename dataT>
     872            0 : int gnuPlot::plot( const dataT *y, size_t N, const std::string &modifiers, const std::string &name )
     873              : {
     874            0 :     return plotImpl( y, N * sizeof( dataT ), gpBinaryFormat<dataT>(), modifiers, "", name );
     875              : }
     876              : 
     877              : template <typename dataT>
     878              : int gnuPlot::plot( const dataT *y, size_t N, const std::string &name )
     879              : {
     880              :     return plotImpl( y, N * sizeof( dataT ), gpBinaryFormat<dataT>(), "", "", name );
     881              : }
     882              : 
     883              : template <typename dataT>
     884              : int gnuPlot::plot( const dataT *y, size_t N )
     885              : {
     886              :     return plotImpl( y, N * sizeof( dataT ), gpBinaryFormat<dataT>(), "", "", "" );
     887              : }
     888              : 
     889              : template <typename dataT>
     890              : int gnuPlot::plot( const std::vector<dataT> &y,
     891              :                    const std::string &modifiers,
     892              :                    const std::string &title,
     893              :                    const std::string &name )
     894              : {
     895              :     return plot<dataT>( y.data(), y.size(), modifiers, title, name );
     896              : }
     897              : 
     898              : template <typename dataT>
     899              : int gnuPlot::plot( const std::vector<dataT> &y, const std::string &modifiers, const std::string &name )
     900              : {
     901              :     return plot<dataT>( y.data(), y.size(), modifiers, "", name );
     902              : }
     903              : 
     904              : template <typename dataT>
     905              : int gnuPlot::plot( const std::vector<dataT> &y, const std::string &name )
     906              : {
     907              :     return plot<dataT>( y.data(), y.size(), "", "", name );
     908              : }
     909              : 
     910              : template <typename dataT>
     911              : int gnuPlot::plot( const std::vector<dataT> &y )
     912              : {
     913              :     return plot<dataT>( y.data(), y.size(), "", "", "" );
     914              : }
     915              : 
     916              : template <typename dataTx, typename dataTy>
     917            0 : int gnuPlot::plot( const dataTx *x,
     918              :                    const dataTy *y,
     919              :                    size_t N,
     920              :                    const std::string &modifiers,
     921              :                    const std::string &title,
     922              :                    const std::string &name )
     923              : {
     924            0 :     return plotImpl( x,
     925              :                      y,
     926              :                      N,
     927              :                      sizeof( dataTx ),
     928              :                      sizeof( dataTy ),
     929            0 :                      gpBinaryFormat<dataTx>(),
     930            0 :                      gpBinaryFormat<dataTy>(),
     931              :                      modifiers,
     932              :                      title,
     933            0 :                      name );
     934              : }
     935              : 
     936              : template <typename dataTx, typename dataTy>
     937              : int gnuPlot::plot( const dataTx *x, const dataTy *y, size_t N, const std::string &modifiers, const std::string &name )
     938              : {
     939              :     return plotImpl( x,
     940              :                      y,
     941              :                      N,
     942              :                      sizeof( dataTx ),
     943              :                      sizeof( dataTy ),
     944              :                      gpBinaryFormat<dataTx>(),
     945              :                      gpBinaryFormat<dataTy>(),
     946              :                      modifiers,
     947              :                      "",
     948              :                      name );
     949              : }
     950              : 
     951              : template <typename dataTx, typename dataTy>
     952              : int gnuPlot::plot( const dataTx *x, const dataTy *y, size_t N, const std::string &name )
     953              : {
     954              :     return plotImpl(
     955              :         x, y, N, sizeof( dataTx ), sizeof( dataTy ), gpBinaryFormat<dataTx>(), gpBinaryFormat<dataTy>(), "", "", name );
     956              : }
     957              : 
     958              : template <typename dataTx, typename dataTy>
     959              : int gnuPlot::plot( const dataTx *x, const dataTy *y, size_t N )
     960              : {
     961              :     return plotImpl(
     962              :         x, y, N, sizeof( dataTx ), sizeof( dataTy ), gpBinaryFormat<dataTx>(), gpBinaryFormat<dataTy>(), "", "", "" );
     963              : }
     964              : 
     965              : template <typename dataTx, typename dataTy>
     966              : int gnuPlot::plot( const std::vector<dataTx> &x,
     967              :                    const std::vector<dataTy> &y,
     968              :                    const std::string &modifiers,
     969              :                    const std::string &title,
     970              :                    const std::string &name )
     971              : {
     972              :     return plot( x.data(), y.data(), x.size(), modifiers, title, name );
     973              : }
     974              : 
     975              : template <typename dataTx, typename dataTy>
     976            0 : int gnuPlot::plot( const std::vector<dataTx> &x,
     977              :                    const std::vector<dataTy> &y,
     978              :                    const std::string &modifiers,
     979              :                    const std::string &name )
     980              : {
     981            0 :     return plot( x.data(), y.data(), x.size(), modifiers, "", name );
     982              : }
     983              : 
     984              : template <typename dataTx, typename dataTy>
     985              : int gnuPlot::plot( const std::vector<dataTx> &x, const std::vector<dataTy> &y, const std::string &name )
     986              : {
     987              :     return plot( x.data(), y.data(), x.size(), "", "", name );
     988              : }
     989              : 
     990              : template <typename dataTx, typename dataTy>
     991              : int gnuPlot::plot( const std::vector<dataTx> &x, const std::vector<dataTy> &y )
     992              : {
     993              :     return plot( x.data(), y.data(), x.size(), "", "", "" );
     994              : }
     995              : 
     996              : template <typename dataTx, typename dataTy>
     997              : int gnuPlot::point( dataTx x, dataTy y, const std::string &modifiers, const std::string &title )
     998              : {
     999              : 
    1000              :     return plot( &x, &y, 1, modifiers, title );
    1001              : }
    1002              : 
    1003              : template <>
    1004              : std::string gpBinaryFormat<char>();
    1005              : 
    1006              : template <>
    1007              : std::string gpBinaryFormat<unsigned char>();
    1008              : 
    1009              : template <>
    1010              : std::string gpBinaryFormat<short>();
    1011              : 
    1012              : template <>
    1013              : std::string gpBinaryFormat<unsigned short>();
    1014              : 
    1015              : template <>
    1016              : std::string gpBinaryFormat<int>();
    1017              : 
    1018              : template <>
    1019              : std::string gpBinaryFormat<unsigned int>();
    1020              : 
    1021              : template <>
    1022              : std::string gpBinaryFormat<long>();
    1023              : 
    1024              : template <>
    1025              : std::string gpBinaryFormat<unsigned long>();
    1026              : 
    1027              : template <>
    1028              : std::string gpBinaryFormat<float>();
    1029              : 
    1030              : template <>
    1031              : std::string gpBinaryFormat<double>();
    1032              : 
    1033              : } // namespace math
    1034              : } // namespace mx
    1035              : 
    1036              : #endif // math_plot_gnuPlot_hpp
        

Generated by: LCOV version 2.0-1