SigPack - the C++ signal processing library
 
Loading...
Searching...
No Matches
gplot.h
Go to the documentation of this file.
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4#ifndef SP_GPLOT_H
5#define SP_GPLOT_H
6#include <vector>
7#include <typeinfo>
8
9namespace sp
10{
15
26class gplot
27{
28 private:
29 FILE* gnucmd;
30 std::string term;
31 int fig_ix;
33
35 {
36 std::string label;
37 std::string linespec;
38 };
39
40 std::vector<plot_data_s> plotlist;
41
47 template <typename T1, typename T2> void plot_str2( const T1& x, const T2& y )
48 {
49 std::ostringstream tmp_s;
50 std::string s;
51 tmp_s << "$Dxy" << plot_ix << " << EOD \n";
52 arma::uword Nelem = x.n_elem;
53 for( arma::uword n = 0; n < Nelem; n++ )
54 {
55 tmp_s << x( n ) << " " << y( n );
56 s = tmp_s.str();
57 send2gp( s.c_str() );
58 tmp_s.str( "" ); // Clear buffer
59 }
60 send2gp( "EOD" );
61 }
62
68 template <typename T> std::string get_type( T x )
69 {
70 if( typeid( x ) == typeid( int8_t ) )
71 return "int8";
72 if( typeid( x ) == typeid( uint8_t ) )
73 return "uint8";
74 if( typeid( x ) == typeid( int16_t ) )
75 return "int16";
76 if( typeid( x ) == typeid( uint16_t ) )
77 return "uint16";
78 if( typeid( x ) == typeid( int32_t ) )
79 return "int32";
80 if( typeid( x ) == typeid( uint32_t ) )
81 return "uint32";
82 if( typeid( x ) == typeid( int64_t ) )
83 return "int64";
84 if( typeid( x ) == typeid( arma::sword ) )
85 return "int64";
86 if( typeid( x ) == typeid( uint64_t ) )
87 return "uint64";
88 if( typeid( x ) == typeid( arma::uword ) )
89 return "uint64";
90 if( typeid( x ) == typeid( float ) )
91 return "float32";
92 if( typeid( x ) == typeid( double ) )
93 return "float64";
94 err_handler( "Unknown type" );
95 }
96
97 public:
105 {
106#if defined( _MSC_VER )
107 gnucmd = _popen( "gnuplot -persist 2> NUL", "wb" );
108 term = "win";
109//#elif defined(_APPLE_)
110// gnucmd = popen("gnuplot -persist &> /dev/null","w");
111//#define term "aqua"
112#else
113 gnucmd = popen( "gnuplot -persist", "w" );
114 term = "x11";
115#endif
116 if( !gnucmd )
117 {
118 err_handler( "Could not start gnuplot" );
119 }
120
121 // Set global params
122 plot_ix = 0;
123 fig_ix = 0;
124 plotlist.clear();
125 }
126
131 {
132#if defined( _MSC_VER )
133 _pclose( gnucmd );
134#else
135 pclose( gnucmd );
136#endif
137 }
138
143 void send2gp( const char* cmdstr )
144 {
145 std::string s_in( cmdstr );
146 std::string tmp = s_in + "\n";
147 std::fputs( tmp.c_str(), gnucmd );
148 // std::cout << tmp.c_str() << std::endl;
149 }
150
154 void flush_cmd_buf( void )
155 {
156 std::fflush( gnucmd );
157 }
158
162 void draw_now( void )
163 {
164 std::fflush( gnucmd );
165 }
166
171 void figure( const int fig )
172 {
173 fig_ix = fig;
174 std::ostringstream tmp_s;
175 tmp_s << "set term " << term << " " << fig;
176 std::string s = tmp_s.str();
177 send2gp( s.c_str() );
178 send2gp( "reset" );
179 }
180
190 void window( const int fig, const char* name, const int x, const int y, const int width, const int height )
191 {
192 fig_ix = fig;
193 std::ostringstream tmp_s;
194 tmp_s << "set term " << term << " " << fig << " title \"" << name << "\" position " << x << "," << y << " size " << width << "," << height;
195 std::string s = tmp_s.str();
196 send2gp( s.c_str() );
197 send2gp( "reset" );
198 }
199
209 void window( const char* name, const int x, const int y, const int width, const int height )
210 {
211 window( 0, name, x, y, width, height );
212 }
213
217 void close_window( void )
218 {
219 std::ostringstream tmp_s;
220 tmp_s << "set term " << term << " close";
221 std::string s = tmp_s.str();
222 send2gp( s.c_str() );
223 send2gp( "reset" );
224 }
225
229 void grid_on( void )
230 {
231 send2gp( "set grid" );
232 }
233
237 void grid_off( void )
238 {
239 send2gp( "unset grid" );
240 }
241
246 void xlabel( const char* label )
247 {
248 std::ostringstream tmp_s;
249 tmp_s << "set xlabel \"" << label << "\" ";
250 std::string s = tmp_s.str();
251 send2gp( s.c_str() );
252 }
253
258 void ylabel( const char* label )
259 {
260 std::ostringstream tmp_s;
261 tmp_s << "set ylabel \"" << label << "\" ";
262 std::string s = tmp_s.str();
263 send2gp( s.c_str() );
264 }
265
272 void label( const double& x, const double& y, const char* label )
273 {
274 std::ostringstream tmp_s;
275 tmp_s << "set label \"" << label << "\" at " << x << "," << y;
276 std::string s = tmp_s.str();
277 send2gp( s.c_str() );
278 }
279
284 void title( const char* name )
285 {
286 std::ostringstream tmp_s;
287 tmp_s << "set title \"" << name << " \" ";
288 std::string s = tmp_s.str();
289 send2gp( s.c_str() );
290 }
291
297 void xlim( const double xmin, const double xmax )
298 {
299 std::ostringstream tmp_s;
300 tmp_s << "set xrange [" << xmin << ":" << xmax << "]";
301 std::string s = tmp_s.str();
302 send2gp( s.c_str() );
303 }
304
310 void ylim( const double ymin, const double ymax )
311 {
312 std::ostringstream tmp_s;
313 tmp_s << "set yrange [" << ymin << ":" << ymax << "]";
314 std::string s = tmp_s.str();
315 send2gp( s.c_str() );
316 }
317
325 template <typename T1, typename T2> void plot_add( const T1& x, const T2& y, const std::string lb, const std::string ls = "lines" )
326 {
327 plot_data_s pd;
328
329 pd.linespec = ls;
330 pd.label = lb;
331
332 plotlist.push_back( pd );
333 plot_str2( x, y );
334 plot_ix++;
335 }
336
343 template <typename T1> void plot_add( const T1& y, const std::string lb, const std::string ls = "lines" )
344 {
345 arma::vec x = arma::regspace( 0, double( y.n_elem - 1 ) );
346 plot_data_s pd;
347
348 pd.linespec = ls;
349 pd.label = lb;
350
351 plotlist.push_back( pd );
352 plot_str2( x, y );
353 plot_ix++;
354 }
355
360 void plot_add_mat( const arma::mat& y )
361 {
362 arma::vec x = arma::regspace( 0, double( y.n_cols - 1 ) );
363 plot_data_s pd;
364
365 pd.linespec = "lines";
366 pd.label = "";
367 for( arma::uword r = 0; r < y.n_rows; r++ )
368 {
369 plotlist.push_back( pd );
370 plot_str2( x, y.row( r ) );
371 plot_ix++;
372 }
373 }
374
380 void plot_add_mat( const arma::mat& y, const std::string p_lb )
381 {
382 arma::vec x = arma::regspace( 0, double( y.n_cols - 1 ) );
383 plot_data_s pd;
384 pd.linespec = "lines";
385
386 for( arma::uword r = 0; r < y.n_rows; r++ )
387 {
388 std::ostringstream tmp_s;
389 tmp_s << p_lb << r;
390 std::string s = tmp_s.str();
391 pd.label = s;
392 plotlist.push_back( pd );
393 plot_str2( x, y.row( r ) );
394 plot_ix++;
395 }
396 }
397
401 void plot_show( void )
402 {
403 std::ostringstream tmp_s;
404
405 tmp_s << "plot $Dxy0 title \"" << plotlist[0].label << "\" with " << plotlist[0].linespec;
406 for( int r = 1; r < plot_ix; r++ )
407 {
408 tmp_s << " ,$Dxy" << r << " title \"" << plotlist[r].label << "\" with " << plotlist[r].linespec;
409 }
410 std::string s = tmp_s.str();
411 send2gp( s.c_str() );
412 plotlist.clear();
413 plot_ix = 0;
414 }
415
419 void plot_clear( void )
420 {
421 plotlist.clear();
422 plot_ix = 0;
423 }
424
429 template <typename T> void fast_plot( const arma::Col<T>& x, const std::string fmt_args = "with lines" )
430 {
431 std::string fmt = get_type( x.at( 0 ) );
432 std::string s;
433 send2gp( "unset key" );
434
435 s = "plot '-' binary format='%" + fmt + "' array=(" + std::to_string( x.n_elem ) + ") " + fmt_args;
436 send2gp( s.c_str() );
437 std::fwrite( x.memptr(), sizeof( x.at( 0 ) ), x.n_elem, gnucmd );
439 }
440
448 template <typename T> void fast_plot( const arma::Col<T>& x, const arma::Col<T>& y, const std::string fmt_args = "with lines" )
449 {
450 std::string fmt1 = get_type( x.at( 0 ) );
451 std::string s;
452 send2gp( "unset key" );
453 const arma::uword N = x.n_elem;
454 arma::Col<T> v( 2 * N );
455 for( arma::uword n = 0; n < N; n++ )
456 {
457 v.at( 2 * n ) = x.at( n );
458 v.at( 2 * n + 1 ) = y.at( n );
459 }
460
461 s = "plot '-' binary format='%" + fmt1 + "' record=(" + std::to_string( x.n_elem ) + ") " + fmt_args;
462 send2gp( s.c_str() );
463 std::fwrite( v.memptr(), sizeof( x.at( 0 ) ), v.n_elem, gnucmd );
465 }
466
471 template <typename T> void image( const arma::Mat<T>& x )
472 {
473 xlim( -0.5, x.n_cols - 0.5 );
474 ylim( x.n_rows - 0.5, -0.5 );
475 send2gp( "unset key" );
476 std::string fmt = get_type( x.at( 0 ) );
477 std::string s;
478
479 s = "plot '-' binary array=(" + std::to_string( x.n_cols ) + "," + std::to_string( x.n_rows ) + ") scan=yx format='%" + fmt + "' w image";
480 send2gp( s.c_str() );
481 std::fwrite( x.memptr(), sizeof( x.at( 0 ) ), x.n_elem, gnucmd );
483 }
484
489 template <typename T> void image( const arma::Cube<T>& x )
490 {
491 xlim( -0.5, x.n_cols - 0.5 );
492 ylim( x.n_rows - 0.5, -0.5 );
493 send2gp( "unset key" );
494 std::string fmt = get_type( x.at( 0 ) );
495 std::string s;
496
497 // Conv cube to gnuplot rgb array
498 arma::Cube<T> gp_im( arma::size( x ) );
499 T* ptr = gp_im.memptr();
500 for( arma::uword c = 0; c < x.n_cols; c++ )
501 {
502 for( arma::uword r = 0; r < x.n_rows; r++ )
503 {
504 *ptr++ = x.at( r, c, 0 ); // R
505 *ptr++ = x.at( r, c, 1 ); // G
506 *ptr++ = x.at( r, c, 2 ); // B
507 }
508 }
509
510 s = "plot '-' binary array=(" + std::to_string( x.n_cols ) + "," + std::to_string( x.n_rows ) + ") scan=yx format='%" + fmt + "' w rgbimage";
511 send2gp( s.c_str() );
512 std::fwrite( gp_im.memptr(), sizeof( x.at( 0 ) ), gp_im.n_elem, gnucmd );
514 }
515
520 template <typename T> void mesh( const arma::Mat<T>& x )
521 {
522 send2gp( "unset key" );
523 send2gp( "set hidden3d" );
524 std::string fmt = get_type( x.at( 0 ) );
525 std::string s = "splot '-' binary array=(" + std::to_string( x.n_cols ) + "," + std::to_string( x.n_rows ) + ") scan=yx format='%" + fmt + "' w lines";
526 send2gp( s.c_str() );
527 std::fwrite( x.memptr(), sizeof( x.at( 0 ) ), x.n_elem, gnucmd );
529 }
530
535 template <typename T> void surf( const arma::Mat<T>& x )
536 {
537 send2gp( "set pm3d" );
538 mesh( x );
539 }
540
545 void set_parula_line( void )
546 {
547 send2gp( "set linetype 1 lc rgb '#0072bd' " ); // blue
548 send2gp( "set linetype 2 lc rgb '#d95319' " ); // orange
549 send2gp( "set linetype 3 lc rgb '#edb120' " ); // yellow
550 send2gp( "set linetype 4 lc rgb '#7e2f8e' " ); // purple
551 send2gp( "set linetype 5 lc rgb '#77ac30' " ); // green
552 send2gp( "set linetype 6 lc rgb '#4dbeee' " ); // light-blue
553 send2gp( "set linetype 7 lc rgb '#a2142f' " ); // red
554 }
555
560 void set_jet_line( void )
561 {
562 send2gp( "set linetype 1 lc rgb '#0000ff' " ); // blue
563 send2gp( "set linetype 2 lc rgb '#007f00' " ); // green
564 send2gp( "set linetype 3 lc rgb '#ff0000' " ); // red
565 send2gp( "set linetype 4 lc rgb '#00bfbf' " ); // cyan
566 send2gp( "set linetype 5 lc rgb '#bf00bf' " ); // pink
567 send2gp( "set linetype 6 lc rgb '#bfbf00' " ); // yellow
568 send2gp( "set linetype 7 lc rgb '#3f3f3f' " ); // black
569 }
570
575 void set_set1_line( void )
576 {
577 send2gp( "set linetype 1 lc rgb '#E41A1C' " ); // red
578 send2gp( "set linetype 2 lc rgb '#377EB8' " ); // blue
579 send2gp( "set linetype 3 lc rgb '#4DAF4A' " ); // green
580 send2gp( "set linetype 4 lc rgb '#984EA3' " ); // purple
581 send2gp( "set linetype 5 lc rgb '#FF7F00' " ); // orange
582 send2gp( "set linetype 6 lc rgb '#FFFF33' " ); // yellow
583 send2gp( "set linetype 7 lc rgb '#A65628' " ); // brown
584 send2gp( "set linetype 8 lc rgb '#F781BF' " ); // pink
585
586 send2gp( "set palette maxcolors 8" );
587 char str[] = "set palette defined ( \
588 0 '#E41A1C',\
589 1 '#377EB8',\
590 2 '#4DAF4A',\
591 3 '#984EA3',\
592 4 '#FF7F00',\
593 5 '#FFFF33',\
594 6 '#A65628',\
595 7 '#F781BF')";
596 send2gp( str );
597 }
598
603 void set_jet_palette( void )
604 {
605 char str[] = "set palette defined ( \
606 0 '#000090',\
607 1 '#000fff',\
608 2 '#0090ff',\
609 3 '#0fffee',\
610 4 '#90ff70',\
611 5 '#ffee00',\
612 6 '#ff7000',\
613 7 '#ee0000',\
614 8 '#7f0000')";
615 send2gp( str );
616 }
617
623 {
624 char str[] = "set palette defined (\
625 0 '#352a87',\
626 1 '#0363e1',\
627 2 '#1485d4',\
628 3 '#06a7c6',\
629 4 '#38b99e',\
630 5 '#92bf73',\
631 6 '#d9ba56',\
632 7 '#fcce2e',\
633 8 '#f9fb0e')";
634 send2gp( str );
635 }
636
639 // See http://www.kennethmoreland.com/color-advice/
642 {
643 char str[] = "set palette defined (\
644 0 '#5548C1', \
645 1 '#7D87EF', \
646 2 '#A6B9FF', \
647 3 '#CDD7F0', \
648 4 '#EBD1C2', \
649 5 '#F3A889', \
650 6 '#DE6A53', \
651 7 '#B10127')";
652 send2gp( str );
653 }
654
657 // See http://www.kennethmoreland.com/color-advice/
660 {
661 char str[] = "set palette defined (\
662 0 '#000000', \
663 1 '#2B0F6B', \
664 2 '#5D00CB', \
665 3 '#C60074', \
666 4 '#EB533C', \
667 5 '#F59730', \
668 6 '#E9D839', \
669 7 '#FFFFFF')";
670 send2gp( str );
671 }
672
690 void set_output( const char* name )
691 {
692 std::string name_s( name );
693 size_t found = name_s.find_last_of( "." );
694 std::string ext;
695 ext = name_s.substr( found + 1 );
696 std::ostringstream tmp_s;
697
698 if( ext.compare( "png" ) == 0 )
699 {
700 tmp_s << "set terminal pngcairo enhanced font 'Verdana,10'";
701 }
702 else if( ext.compare( "ps" ) == 0 )
703 {
704 tmp_s << "set terminal postscript enhanced color";
705 }
706 else if( ext.compare( "eps" ) == 0 )
707 {
708 tmp_s << "set terminal postscript eps enhanced color";
709 }
710 else if( ext.compare( "tex" ) == 0 )
711 {
712 tmp_s << "set terminal cairolatex eps color";
713 }
714 else if( ext.compare( "pdf" ) == 0 )
715 {
716 tmp_s << "set terminal pdfcairo color enhanced";
717 }
718 else if( ext.compare( "svg" ) == 0 )
719 {
720 tmp_s << "set terminal svg enhanced";
721 }
722 else if( ext.compare( "emf" ) == 0 )
723 {
724 tmp_s << "set terminal emf color enhanced";
725 }
726 else if( ext.compare( "gif" ) == 0 )
727 {
728 tmp_s << "set terminal gif enhanced";
729 }
730 // else if (ext.compare("jpg") == 0)
731 //{
732 // tmp_s << "set terminal jpeg ";
733 //}
734 else
735 {
736 tmp_s << "set terminal " << term;
737 }
738 std::string s = tmp_s.str();
739 send2gp( s.c_str() );
740 tmp_s.str( "" ); // Clear buffer
741 tmp_s << "set output '" << name_s << "'";
742 s = tmp_s.str();
743 send2gp( s.c_str() );
744 }
745
749 void reset_term( void )
750 {
751 send2gp( "reset session" );
752 }
753
757 void set_term( const char* ttype )
758 {
759 std::ostringstream tmp_s;
760 tmp_s << "set terminal " << ttype;
761 std::string s = tmp_s.str();
762 term = s;
763 send2gp( s.c_str() );
764 }
765
766}; // End Gnuplot Class
767
769
770} // namespace sp
771#endif
Gnuplot class.
Definition gplot.h:27
void plot_show(void)
Show plots.
Definition gplot.h:401
void plot_str2(const T1 &x, const T2 &y)
Plot y vs. x.
Definition gplot.h:47
void plot_clear(void)
Clear plots.
Definition gplot.h:419
void grid_on(void)
Set grid.
Definition gplot.h:229
void plot_add_mat(const arma::mat &y, const std::string p_lb)
Push multiple plot, each row gives a plot with prefix label.
Definition gplot.h:380
void title(const char *name)
Set windowtitle.
Definition gplot.h:284
int plot_ix
Definition gplot.h:32
void set_jet_palette(void)
Set palette to Matlab 'jet' Data from https://github.com/Gnuplotting/gnuplot-palettes.
Definition gplot.h:603
void set_jet_line(void)
Set linetype to Matlab 'jet' NB! doesn't work with X11 -terminal Data from https://github....
Definition gplot.h:560
void set_output(const char *name)
Save plot to file.
Definition gplot.h:690
void set_blackbody_palette(void)
Set palette to 'black body'.
Definition gplot.h:659
void fast_plot(const arma::Col< T > &x, const std::string fmt_args="with lines")
Plot vector, fast version.
Definition gplot.h:429
void close_window(void)
Close window.
Definition gplot.h:217
void window(const char *name, const int x, const int y, const int width, const int height)
Configure the figure/window - used in Linux environment where no figure numbers are needed.
Definition gplot.h:209
~gplot()
Destructor.
Definition gplot.h:130
void flush_cmd_buf(void)
Flush command buffer to Gnuplot pipe.
Definition gplot.h:154
void set_coolwarm_palette(void)
Set palette to 'cool-warm'.
Definition gplot.h:641
void xlabel(const char *label)
Set label for X-axis.
Definition gplot.h:246
void ylabel(const char *label)
Set label for X-axis.
Definition gplot.h:258
void figure(const int fig)
Sets the active figure.
Definition gplot.h:171
void mesh(const arma::Mat< T > &x)
Plot mat as mesh.
Definition gplot.h:520
int fig_ix
Definition gplot.h:31
void reset_term(void)
Reset output terminal.
Definition gplot.h:749
void surf(const arma::Mat< T > &x)
Plot mat as surf.
Definition gplot.h:535
void send2gp(const char *cmdstr)
Send command to Gnuplot pipe.
Definition gplot.h:143
FILE * gnucmd
File handle to pipe.
Definition gplot.h:29
void ylim(const double ymin, const double ymax)
Set Y-axis range.
Definition gplot.h:310
void plot_add(const T1 &y, const std::string lb, const std::string ls="lines")
Push plot y vs. x with label and linespec.
Definition gplot.h:343
void set_set1_line(void)
Set linetype to Matlab 'parula' NB! doesn't work with X11 -terminal Data from https://github....
Definition gplot.h:575
void image(const arma::Mat< T > &x)
Plot mat as image.
Definition gplot.h:471
gplot()
Constructor.
Definition gplot.h:104
void set_term(const char *ttype)
Set output terminal.
Definition gplot.h:757
void image(const arma::Cube< T > &x)
Plot cube as image.
Definition gplot.h:489
void xlim(const double xmin, const double xmax)
Set X-axis range.
Definition gplot.h:297
std::string term
Definition gplot.h:30
void draw_now(void)
Updates gnuplot instantly. (Flushes the command buffer)
Definition gplot.h:162
void plot_add(const T1 &x, const T2 &y, const std::string lb, const std::string ls="lines")
Push plot y vs. x with label and linespec.
Definition gplot.h:325
void fast_plot(const arma::Col< T > &x, const arma::Col< T > &y, const std::string fmt_args="with lines")
Plot vector, fast version.
Definition gplot.h:448
void plot_add_mat(const arma::mat &y)
Push multiple plot, each row gives a plot without label.
Definition gplot.h:360
void grid_off(void)
Set grid.
Definition gplot.h:237
void label(const double &x, const double &y, const char *label)
Set label at position x,y.
Definition gplot.h:272
std::string get_type(T x)
Get type.
Definition gplot.h:68
std::vector< plot_data_s > plotlist
Definition gplot.h:40
void set_parula_palette(void)
Set palette to Matlab 'parula' Data from https://github.com/Gnuplotting/gnuplot-palettes.
Definition gplot.h:622
void set_parula_line(void)
Set linetype to Matlab 'parula' NB! doesn't work with X11 -terminal Data from https://github....
Definition gplot.h:545
void window(const int fig, const char *name, const int x, const int y, const int width, const int height)
Configure the figure used Windows environment.
Definition gplot.h:190
#define err_handler(msg)
Definition base.h:212
Definition base.h:8
std::string label
Definition gplot.h:36
std::string linespec
Definition gplot.h:37