mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
gnuPlot.hpp
Go to the documentation of this file.
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
83namespace mx
84{
85namespace math
86{
87
88// Get the gnuplot binary format string for a type
89// Specializations below.
90template <typename dataT>
91std::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
98struct 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 gpCurve()
109 {
110 }
111
112 gpCurve( const std::string &file, const std::string &title, const std::string &modifiers )
113 : m_file( file ), m_title( title ), m_modifiers( modifiers )
114 {
115 }
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 gpCurve( const gpCurve &gpc )
126 {
127 m_file = gpc.m_file;
128 m_title = gpc.m_title;
129 m_modifiers = gpc.m_modifiers;
130 m_binary = gpc.m_binary;
131 }
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 */
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
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 */
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.
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
855
856 /// Open a temporary binary file, and provide the filename.
858
859 private:
860 /// Initialize an instance, only used at construction
861 void init();
862};
863
864template <typename dataT>
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
871template <typename dataT>
872int gnuPlot::plot( const dataT *y, size_t N, const std::string &modifiers, const std::string &name )
873{
874 return plotImpl( y, N * sizeof( dataT ), gpBinaryFormat<dataT>(), modifiers, "", name );
875}
876
877template <typename dataT>
878int 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
883template <typename dataT>
884int gnuPlot::plot( const dataT *y, size_t N )
885{
886 return plotImpl( y, N * sizeof( dataT ), gpBinaryFormat<dataT>(), "", "", "" );
887}
888
889template <typename dataT>
890int 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
898template <typename dataT>
899int 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
904template <typename dataT>
905int gnuPlot::plot( const std::vector<dataT> &y, const std::string &name )
906{
907 return plot<dataT>( y.data(), y.size(), "", "", name );
908}
909
910template <typename dataT>
911int gnuPlot::plot( const std::vector<dataT> &y )
912{
913 return plot<dataT>( y.data(), y.size(), "", "", "" );
914}
915
916template <typename dataTx, typename dataTy>
917int 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 return plotImpl( x,
925 y,
926 N,
927 sizeof( dataTx ),
928 sizeof( dataTy ),
931 modifiers,
932 title,
933 name );
934}
935
936template <typename dataTx, typename dataTy>
937int 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 ),
946 modifiers,
947 "",
948 name );
949}
950
951template <typename dataTx, typename dataTy>
952int 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
958template <typename dataTx, typename dataTy>
959int 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
965template <typename dataTx, typename dataTy>
966int 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
975template <typename dataTx, typename dataTy>
976int 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 return plot( x.data(), y.data(), x.size(), modifiers, "", name );
982}
983
984template <typename dataTx, typename dataTy>
985int 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
990template <typename dataTx, typename dataTy>
991int gnuPlot::plot( const std::vector<dataTx> &x, const std::vector<dataTy> &y )
992{
993 return plot( x.data(), y.data(), x.size(), "", "", "" );
994}
995
996template <typename dataTx, typename dataTy>
997int 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
1003template <>
1004std::string gpBinaryFormat<char>();
1005
1006template <>
1007std::string gpBinaryFormat<unsigned char>();
1008
1009template <>
1010std::string gpBinaryFormat<short>();
1011
1012template <>
1013std::string gpBinaryFormat<unsigned short>();
1014
1015template <>
1016std::string gpBinaryFormat<int>();
1017
1018template <>
1019std::string gpBinaryFormat<unsigned int>();
1020
1021template <>
1022std::string gpBinaryFormat<long>();
1023
1024template <>
1025std::string gpBinaryFormat<unsigned long>();
1026
1027template <>
1028std::string gpBinaryFormat<float>();
1029
1030template <>
1031std::string gpBinaryFormat<double>();
1032
1033} // namespace math
1034} // namespace mx
1035
1036#endif // math_plot_gnuPlot_hpp
An interactive c++ interface to gnuplot.
Definition gnuPlot.hpp:194
int circle(double radius, const std::string &modifiers="", const std::string &title="", int npoints=10)
Draw a circle on the plot around the origin.
int doPlotCommand()
Issue the plot command for all the curves.
int plot(const std::string &fname)
Plot from a file without specifying the name or any modifiers.
std::string getResponse(const std::string &com, double timeout=0.5)
Get a response from gnuplot for a given command.
FILE * _pipeH
File stream for the gnuplot interface.
Definition gnuPlot.hpp:204
int plot(const std::string &fname, const std::string &modifiers, const std::string &title, const std::string &name)
Plot from a file specifying all curve components.
bool _gpError
Set to true if the response indicates a gnuplot error.
Definition gnuPlot.hpp:200
int xrange(double x0, double x1)
Set the x-axis range.
void title(const std::string &name, const std::string &title)
Modify the title for a curve.
int plot(const std::string &fname, const std::string &modifiers, const std::string &name)
Plot from a file without specifying the title.
int plotImpl(const void *x, const void *y, size_t Npts, size_t sizex, size_t sizey, const std::string &binaryx, const std::string &binaryy, const std::string &modifiers, const std::string &title, const std::string &name)
Implementation of 2-d binary plotting.
int plot(const std::string &fname, const std::string &name)
Plot from a file without modifiers.
void reset()
Clear all the curves and reset plot configuration.
int connect()
Connect to gnuplot.
int point(dataTx x, dataTy y, const std::string &modifiers="", const std::string &title="")
Plot a single point.
Definition gnuPlot.hpp:997
FILE * openTempFile(char *fname)
Open a temporary binary file, and provide the filename.
std::string _errFName
File name of the gnuplot stderr fifo.
Definition gnuPlot.hpp:212
std::vector< std::string > _tempFiles
Vector of all temporary file names opened, used for removal on destruction.
Definition gnuPlot.hpp:223
int ulogy()
Unset the y axis from log scale.
int plotImpl(const void *y, size_t Nbytes, const std::string &binary, const std::string &modifiers, const std::string &title, const std::string &name)
Implementation of 1-D binary plotting.
bool _deleteTemp
Flag to control whether temporary files are deleted on destruction. Default is true (files deleted).
Definition gnuPlot.hpp:226
int logy()
Set the y axis to log scale.
int _errFD
File descriptor for the gnuplot stderr fifo.
Definition gnuPlot.hpp:215
std::string _errLocation
Where to create gnuplot stderr fifo.
Definition gnuPlot.hpp:209
int ulogxy()
Unset the x and y axes from log scale.
int replot()
Issue the replot command.
int logxy()
Set the x and y axes to log scale.
int yrange()
Unset the y-axis range.
void listCurves()
List the curves and their specifications.
int checkResponse(std::string &response, double timeout=0)
Check for a response from gnuplot.
bool gpError()
Return the value of the gpError flag.
void modifiers(const std::string &name, const std::string &modifiers)
Modify the modifiers for a curve.
int xrange()
Unset the x-axis range.
int ulogx()
Unset the x axis from log scale.
int yrange(double y0, double y1)
Set the y-axis range.
std::string _tempLocation
Location of temporary files.
Definition gnuPlot.hpp:220
int circle(double xcen, double ycen, double radius, const std::string &modifiers="", const std::string &title="", int npoints=10)
Draw a circle on the plot.
int command(const std::string &com, bool flush=true)
Send a command to gnuplot.
int logx()
Set the x axis to log scale.
std::string gpErrorMsg()
Return the gnuplot error message.
void clear()
Clear all the curves.
@ timeout
A timeout occurred.
constexpr floatT six_fifths()
Return 6/5 in the specified precision.
MXLIB_DEFAULT_VERBOSITY d
The default verbosity.
Definition error.hpp:202
The mxlib c++ namespace.
Definition mxlib.hpp:37