GnuPlotScripting
GnuPlotScripting copied to clipboard
A simple C++17 lib that helps you to quickly plot your data with GnuPlot
#+OPTIONS: H:3 toc:t \n:nil ::t |:t ^:{} -:t f:t *:t tex:t d:t tags:not-in-toc #+BLOG: wordpress #+POSTID: 931 #+DATE: [2019-12-06 Fri 19:40] #+TITLE: Easy Creation of GnuPlot Scripts from C++ #+TAGS: Cpp, GnuPlot
trick from https://github.com/rexim/org-cliplink/
[[https://travis-ci.org/vincent-picaud/GnuPlotScript][file:https://travis-ci.org/vincent-picaud/GnuPlotScripting.svg?branch=master]]
- Table of contents :TOC:noexport:
- [[#what-is-it][What is it?]]
- [[#news][News]]
- [[#contributors][Contributors]]
- [[#installation][Installation]]
- [[#examples][Examples]]
- [[#plot-and-fit-data][Plot and fit data]]
- [[#ascii-matrix-data][Ascii matrix data]]
- [[#new-matrix-data][(NEW) Matrix data]]
- [[#histogram][Histogram]]
- [[#graph][Graph]]
- [[#density-plot][Density plot]]
- [[#pipe-example][Pipe example]]
- [[#supported-export-formats][Supported export formats]]
- [[#global-config-demonstration][Global config demonstration]]
- [[#documentation][Documentation]]
- [[#data-classes][Data classes]]
- [[#script-classes][Script classes]]
- [[#global_config-class][Global_Config class]]
- [[#references][References]]
- [[#faq][FAQ]]
- What is it?
A simple C++17 library that allows easy creation and execution of gnuplot scripts. These scripts will embed their data and can be replayed/modified later.
The library depends on [[https://github.com/fmtlib/fmt][{fmt} library]].
I use it when I want to plot some data with a minimal effort when I develop stuff in C++.
For the moment the library is only tested under Linux (it should also works under Windows but I have not checked yet).
Feel free to use it: [[https://github.com/vincent-picaud/GnuPlotScripting][GitHub, GnuPlotScripting]].
** News
-
[2020-10-20 Tue] \
- Version v1.1.0!
- some compilation warning fixes
- a new Data_Array_2 class
-
[2020-01-18 Sat 09:17] \
- Version v1.0.0 release!
- More documentation
- Fix a bug in export_as(...,path/output_filename): the path was ignored
-
[2020-01-09 Thu 22:46] \
- Added =Data_Supervised= class and associated example (see Density plot in Example section)
- Code cleaning (no breaking change!)
- Tagged as v0.2.0 (v1.0.0 gets closer :-) )
-
[2019-12-09 Mon 18:34] \ Added SVG, TGIF, PNGCairo and PDFCairo export formats. Tagged as v0.0.3.
-
[2019-12-08 Sun 20:21] \ Some minor fixes + doc concerning Global_Config logger methods. Tagged as v0.0.2
-
[2019-12-08 Sun 11:21] \ Initial version. Tagged as v0.0.1
** Contributors
- [[https://github.com/Gjacquenot][Guillaume Jacquenot]]: Travis CI
- Installation
The library currently uses the [[https://mesonbuild.com/][meson]] build system.
If you are not familiar with meson, the compilation procedure is as follows:
#+BEGIN_SRC sh :eval never git clone https://github.com/vincent-picaud/GnuPlotScripting.git cd GnuPlotScripting/ meson build cd build ninja test #+END_SRC
Examples can then be found in the =build/examples/= directory.
If you want to install the package: #+BEGIN_SRC sh :eval never ninja install #+END_SRC
Note that you can define custom installation path, at the beginning of the compilation procedure, use:
#+BEGIN_SRC sh :eval never meson --prefix=/install_path/ build #+END_SRC
instead of =meson build=.
- Examples
** Plot and fit data
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/plot.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
// From: https://www.cs.hmc.edu/~vrable/gnuplot/using-gnuplot.html
int
main()
{
std::vector
time = {0.0, 1.0, 2.1, 3.1, 4.2, 5.2, 6.2, 7.2, 8.2, 9.1, 10.0, 11.0, 12.0, 12.9, 13.8, 14.9, 15.9, 17.0, 17.9, 18.9, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 32.9, 33.8, 34.7, 35.7, 36.6, 37.7};
angle = {-14.7, 8.6, 28.8, 46.7, 47.4, 36.5, 37.0, 5.1, -11.2, -22.4, -35.5, -33.6, -21.1, -15.0, -1.6, 19.5, 27.5, 32.6, 27.5, 20.2, 13.8, -1.3, -24.5, -25.0, -25.0, -20.2, -9.9, 5.8, 14.7, 21.8, 29.8, 21.4, 24.6, 25.8, 0.6, -16.6, -24.0, -24.6, -19.8};
stdvar = {3.6, 3.6, 3.0, 3.4, 3.5, 3.4, 10.3, 3.4, 3.4, 3.5, 3.6, 3.9, 3.9, 4.2, 2.7, 3.2, 2.8, 3.5, 2.7, 3.3, 3.4, 4.2, 6.7, 3.3, 3.1, 3.6, 3.2, 3.2, 3.0, 3.5, 2.7, 4.1, 2.7, 12.0, 2.9, 3.2, 3.7, 3.8, 3.5};
Script_File script("plot.gp");
Data_Vector data( time, angle, stdvar); // <- you can stack as many vector/valarray etc.. as you want // only size() and operator[] are required.
script.free_form("set title 'Cavendish Data'"); script.free_form("set xlabel 'Time (s)'"); script.free_form("set ylabel 'Angle (mrad)'"); script.free_form("set grid"); script.free_form("plot {} with yerrorbars notitle", data); script.free_form("replot {} u 1:2 with lines title '{}'", data, "raw data"); script.free_form("theta(t) = theta0 + a * exp(-t / tau) * sin(2 * pi * t / T + phi)"); script.free_form("fit theta(x) {} using 1:2:3 via a, tau, phi, T, theta0", data); script.free_form("replot theta(x) lw {} lc {} title 'best-fit curve'", 2, 4); script.export_as(PNG(), "plot"); } #+END_src
It generates this figure:
[[file:figures/plot.png]]
Note: the generated =plot.gp= gnutplot script embeds the data and you can replay it whenever you want: #+BEGIN_SRC sh :eval never gnuplot plot.pg - #+END_SRC
** Ascii matrix data
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/matrix.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
// Example from: https://stackoverflow.com/a/27049991/2001017 // Also see: https://stackoverflow.com/q/32458753/2001017 // int main() { Data_Ascii data( "0.00 0.65 0.65 0.25\n" "0.25 0.00 0.75 0.25\n" "0.50 0.60 0.00 0.25\n" "0.75 0.25 0.10 0.00\n");
Script_File script("matrix.gp");
script.free_form("set autoscale fix"); script.free_form("set cbrange [-1:1]"); script.free_form("unset colorbox"); script.free_form("unset key"); script.free_form( "plot {} matrix using 1:2:3 with image, '' matrix using " "1:2:(sprintf('%.2f', $3)) with labels font ',16'", data); script.export_as(PNG(), "matrix"); script.export_as(EPSLATEX().set_standalone(true), "matrix"); } #+END_src
It generates this figure:
[[file:figures/matrix.png]]
It also generates a standalone =matrix.tex= file you can process with =pdflatex matrix.tex= to get a monochrome =matrix.pdf= file. If you want colorized pdf simply use: #+begin_src cpp :eval never EPSLATEX().set_standalone(true).set_color(true) #+end_src
** (NEW) Matrix data
You can also use the =Array_2= container to temporary store your data
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/array_2.cpp #+END_SRC
#+RESULTS: #+begin_src cpp :eval never #include "GnuPlotScripting/array_2.hpp" #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
int main() { const double X = 2, Y = 2; const std::size_t I = 100, J = 120;
const auto f = [=](const std::size_t i, const std::size_t j) { const double x = (2 * i / double(I - 1) - 1) * X; const double y = (2 * j / double(J - 1) - 1) * Y;
return exp(-x * x - y * y);
};
Array_2 array_2(I, J, f);
Data_Array_2 data(array_2);
Script_File script("array_2.gp");
script.free_form("set autoscale fix"); script.free_form("plot {} matrix using 1:2:3 with image", data); script.export_as(PNG(), "array_2"); } #+end_src
It generates this figure:
[[file:figures/array_2.png][file:figures/array_2.png]]
** Histogram
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/histogram.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
// Example from: // https://stackoverflow.com/a/7454274/2001017 // template <typename T> void gnuplot_histogram(Script& script, const std::vector<T>& data, const size_t n_bin, const typename std::vector<T>::value_type min, const typename std::vector<T>::value_type max) { assert(max > min); assert(n_bin > 0);
Data_Vector gnuplot_data(data);
const double width = (max - min) / n_bin; script.free_form("width={}", width); script.free_form("set title 'Histogram min={}, max={}, Δbin={}, #bins={}, #sample={}'", min, max, width, n_bin, data.size()); script.free_form("hist(x,width)=widthfloor(x/width)+width/2.0"); script.free_form("set boxwidth width0.9"); script.free_form("set style fill solid 0.5"); script.free_form("plot {} u (hist($1,width)):(1.0) smooth freq w boxes notitle", gnuplot_data); }
int main() { std::random_device rd; std::mt19937 gen(rd()); const double a = 2, b = 1; std::gamma_distribution<> distribution(a, b);
std::vector
Script_File script("histogram.gp");
gnuplot_histogram(script, data, 100, 0, 3);
script.export_as(PNG(), "histogram"); } #+END_src
The generated figure is:
[[file:figures/histogram.png]]
** Graph
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/graph.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never
#include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
// Example from the "Gnuplot in Action" book int main() { Data_Ascii data( "-1 -1 0 # A\n" "-1 1 0 # B\n" " 1 0 0 # C\n" " 0 0 1.75 # D\n" "\n\n" "-1 -1 0 -1 1 0 \n" "-1 -1 0 1 0 0 \n" "-1 -1 0 0 0 1.750 \n" "-1 1 0 1 0 0 \n" "-1 1 0 0 0 1.75 \n" " 1 0 0 0 0 1.75 \n");
Script_File script_a("graph_3D.gp");
script_a.free_form("unset border"); script_a.free_form("unset tics"); script_a.free_form("unset key"); script_a.free_form("set view 75,35"); script_a.free_form("splot {} index 0 with points pointtype 7 pointsize 3", data); script_a.free_form("replot {} index 1 u 1:2:3:($4-$1):($5-$2):($6-$3) with vectors nohead", data); script_a.free_form("pause -1");
Script_File script_b("graph_2D.gp");
script_b.free_form("unset border"); script_b.free_form("unset tics"); script_b.free_form("unset key"); script_b.free_form("plot {} index 0 with points pointtype 7 pointsize 3", data); script_b.free_form("replot {} index 1 u 1:2:($4-$1):($5-$2) with vectors nohead", data); script_b.export_as(PNG(), "graph"); } #+END_src
It generates this figure:
[[file:figures/graph.png]]
but also an active gnuplot 3D figure you can rotate etc... ** Density plot
This demo shows how to use the =Data_Supervised= class.
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/density_plot.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
std::array<double, 10> X_1 = {0.1, 0.3, 0.1, 0.6, 0.4, 0.6, 0.5, 0.9, 0.4, 0.7}; std::array<double, 10> X_2 = {0.1, 0.4, 0.5, 0.9, 0.2, 0.3, 0.6, 0.2, 0.4, 0.6}; std::array<int, 10> Y = {1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
int main() { Data_Supervised data(Y, X_1, X_2);
Script_File script("density_plot.gp");
script.free_form("set title 'Supervised learning'");
script.free_form("set pm3d map interpolate 2,2"); script.free_form("set palette model RGB defined ( 0 'gray80', 1 'white' )"); script.free_form("set contour base"); script.free_form("set cntrparam levels discrete 0.5"); script.free_form("unset colorbox"); // no palette
// CAVEAT: for contour use pm3d and not image script.free_form( "splot 'density_plot_data.txt' u ($1/60):($2/60):3 matrix with pm3d lw 2 notitle");
for (size_t i = 0; i < data.index_size(); i++) { // CAVEAT: to prevent // <<warning: Cannot contour non grid data. Please use "set dgrid3d">> // do not forget "nocontour" script.free_form( "replot {0} index {1} u 1:2:3 with points pt '{1}' ps 2 notitle nocontour", data, i); }
script.export_as(PNG(), "density_plot");
return EXIT_SUCCESS; } #+END_src
Generated figure:
[[file:figures/density_plot.png]]
** Pipe example
Instead of creating a file, we can create a pipe with =popen()= to directly send data to gnuplot.
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/pipe.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
int main() { // AFAIK one has to replot all data at each iteration // std::vector<std::pair<size_t, double>> data;
Script_Pipe pipe(Script_Pipe_Mode_Enum::Not_Persistent);
pipe.free_form("set xlabel 'iterations'");
for (size_t i = 0; i < 100; i++) { data.push_back({i, 1 / (i + 1.)});
pipe.free_form("plot '-' using 1:2 with lines t \"residue\" ");
for (const auto& data_i : data)
{
pipe.free_form("{} {}", data_i.first, data_i.second);
}
pipe.free_form("e");
pipe.flush();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
} } #+END_src ** Supported export formats
This example silently exports a basic plot in all supported formats:
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/available_export_formats.cpp #+END_SRC
#+RESULTS: #+begin_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
int main() { Script_File script("available_export_formats.gp", Script_File_Mode_Enum::Silent);
script.free_form("plot sin(x) t 'sin(x)'");
script.export_as(PNG(), "available_export_formats"); script.export_as(EPSLATEX().set_standalone(true), "available_export_formats"); script.export_as(SVG(), "available_export_formats"); script.export_as(TGIF(), "available_export_formats"); script.export_as(PNGCairo(), "available_export_formats_cairo"); script.export_as(PNGCairo().set_color(false), "available_export_formats_cairo_nocolor"); script.export_as(PDFCairo(), "available_export_formats_pdfcairo"); } #+end_src
** Global config demonstration
This last example shows how to use =Global_Config=.
#+BEGIN_SRC sh :wrap "src cpp :eval never" :results output :exports results cat $(pwd)/examples/global_config.cpp #+END_SRC
#+RESULTS: #+BEGIN_src cpp :eval never #include "GnuPlotScripting/GnuPlotScripting.hpp"
#include
using namespace GnuPlotScripting;
int main() { global_config().set_logger( [](const char *const msg) { std::cerr << "====> My logger " << msg << std::endl; }); // If you want to remove logger: global_config().set_logger(); // If you want to restore the default one: global_config().set_default_logger();
// If you want to globally overwrite Script_File_Mode_Enum to Persistent, do: global_config().set_script_file_mode(Script_File_Mode_Enum::Persistent);
for (size_t i = 1; i < 5; i++) { Script_File script(fmt::format("script_{}.gp", i), Script_File_Mode_Enum::Silent);
script.free_form("plot sin({0}*x) t 'sin({0}*x)'", i);
}
// To stop overwriting local choice: global_config().set_script_file_mode();
// Now this will silently run scripts for (size_t i = 1; i < 5; i++) { Script_File script(fmt::format("script_{}.gp", i), Script_File_Mode_Enum::Silent);
script.free_form("plot sin({0}*x) t 'sin({0}*x)'", i);
} } #+END_src
- Documentation The library is quite simple and there is only 3 things you must know:
- Data_XXX are classes to store your data
- Script_XXX are script classes to write your scripts
- global_config() returns a Global_Config object used to define global options.
** Data classes
=Data= classes store data that is embedded into the generated gnuplot scripts. These classes internally use an =uuid= that insures that data is embedded only once. By example, when you write:
#+BEGIN_SRC cpp :eval never script.free_form("plot {} u 1:2",data); script.free_form("replot {} u 1:3",data); script.free_form("replot {} u 1:4",data); #+END_SRC
data is copied only once into the script file.
*** =Data_Ascii=
The most basic =Data= classe is the =Data_Ascii= one. It directly uses data defined by a =std::string=. By example: #+BEGIN_SRC cpp :eval never Data_Ascii data( "0.00 0.65 0.65 0.25\n" "0.25 0.00 0.75 0.25\n" "0.50 0.60 0.00 0.25\n" "0.75 0.25 0.10 0.00\n"); #+END_SRC
Note: it is really easy to define your own =Data= class. By example =Data_Ascii= code is as simple as: #+BEGIN_SRC cpp :eval never class Data_Ascii final : public Data { public: Data_Ascii(const std::string& data) : Data(data) {} }; #+END_SRC
*** (NEW) =Data_Array_2=
Data to plot is defined using an basic two-dimensional array container, Array_2.
#+BEGIN_SRC cpp :eval never Array_2 array_2(row_size,column_size);
// fill component: array_2(i,j)= ...
Data_Array_2 data(array_2);
// plot data #+END_SRC
*** =Data_Vector=
Creates columns of data from =std::vector=, =std::valarray=... In fact only the =size()= method and the =operator[]= operator are used and you can use any object defining these two methods. By example:
#+BEGIN_SRC cpp :eval never
std::vector
*** =Data_Supervised=
The =Data_Supervised= class is similar to the =Data_Vector= except that it uses and extra category vector. It can be used to plot points associated to a supervised learning task. By example:
#+BEGIN_SRC cpp :eval never std::array<double, 10> X_1 = {0.1, 0.3, 0.1, 0.6, 0.4, 0.6, 0.5, 0.9, 0.4, 0.7}; // X_1 feature std::array<double, 10> X_2 = {0.1, 0.4, 0.5, 0.9, 0.2, 0.3, 0.6, 0.2, 0.4, 0.6}; // X_2 feature std::array<int, 10> Y = {1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; // category (=label)
Data_Supervised data(Y, X_1, X_2); // note: the category vector Y is always the first argument
std::cout << data.data(); #+END_SRC
Note: as AFAK it is not possible to directly plot points with symbols retrieved from the the Y column (see [[https://stackoverflow.com/questions/29622885/how-set-point-type-from-data-in-gnuplot][SO how-set-point-type-from-data-in-gnuplot]]), hence the =Data_Supervised= class sorts and groups the sample according to their categories. By example the previous code prints:
#+BEGIN_EXAMPLE 0.6 0.3 0 0.9 0.2 0 0.4 0.4 0
0.1 0.1 1 0.1 0.5 1 0.6 0.9 1 0.4 0.2 1
0.5 0.6 2 0.7 0.6 2
0.3 0.4 3 #+END_EXAMPLE Creating these groups allows to use the gnuplot index keyword to plot all points associated to a given category. By example: #+BEGIN_SRC gnuplot :eval never replot "$data_uuid" index i u 1:2:3 with points; # plot points of category i #+END_SRC
Also note that when data is embedded, the =Y= category column is the last one. The rational is that for: #+BEGIN_SRC cpp :eval never Data_Supervised data_a(Y, X_1, X_2); Data_Vector data_b(X_1, X_2); #+END_SRC then in both cases, =X_1= column index is 1 and =X_2= column index is 2.
** Script classes
There are two script classes:
- =Script_File= creates a file to store the script.
- =Script_Pipe= creates a pipe to push data directly to GnuPlot, in that case no file is created. They inherits from the =Script= base class that provides the following methods: #+BEGIN_SRC cpp :eval never template <typename... ARGS> Script& free_form(ARGS&&... args);
Script& export_as(const Export_As& export_as, const std::filesystem::path& output);
void flush(); #+END_SRC
-
=free_form= allows you to write free form using the =fmt= library, by example: #+BEGIN_SRC cpp :eval never script.free_form("plot '{}' u {}:{}","data_file.dat",1,2); #+END_SRC
-
=flush()= forces buffer to be flushed
-
=export_as()= generates script code to export the figure in the given format, by example:
#+BEGIN_SRC cpp :eval never script.export_as(EPSLATEX().set_standalone(true),"filename"); #+END_SRC
Note:
- the right extension for =filename= is automatically added (here this would be =.tex=).
- currently supported formats are =PNG=, =EPSLATEX=, =SVG=, =TGIF=, =PNGCairo= and =PDFCairo=.
*** =Script_File= class
The only relevant part is the constructor: #+BEGIN_SRC cpp :eval never Script_File(const std::filesystem::path& filename, Script_File_Mode_Enum script_file_mode = Script_File_Mode_Enum::Persistent); #+END_SRC
- =Filename= is the gnuplot script file name (you are free to use the file extension you want, on my side I use the =.gp= extension).
- =script_file_mode= is important as it defines what happens at destruction time
- =Script_File_Mode_Enum::None= does nothing
- =Script_File_Mode_Enum::Silent= silently runs GnuPlot (this will generate your exported figures)
- =Script_File_Mode_Enum::Persistent= runs GnuPlot in persistent mode, it will generates your figures and left a window opened that allows you to see the result. This is only an opened window and not an active gnuplot session (you cannot interact with the plot).
Note: to get an active GnuPlot session, you can replay your script with: #+BEGIN_SRC sh :eval never gnuplot filename.gp - #+END_SRC (note the final '-', see GnuPlot documentation for further details).
Another possibility is to add a pause in your gnuplot script: #+BEGIN_SRC cpp :eval never script.free_form("pause -1"); #+END_SRC
*** =Script_Pipe= class
Here instead of writing into a file, we open a pipe with =popen=. This allows you to directly command GnuPlot during your code execution. Note that this is only a unidirectional channel.
The constructor is: #+BEGIN_SRC cpp :eval never Script_Pipe(Script_Pipe_Mode_Enum script_pipe_mode = Script_Pipe_Mode_Enum::Persistent); #+END_SRC
as for =Script_File= class, =script_pipe_mode= defines what happens at destruction time:
- =Script_Pipe_Mode_Enum::Not_Persistent= does not keep an opened window
- =Script_Pipe_Mode_Enum::Persistent= keeps an opened, but inactive, window
** Global_Config class
This class allows you to define or overwrite globally some options
#+BEGIN_SRC cpp :eval never const char* gnuplot_exe() const; Global_Config& set_gnuplot_exe(const char* const gnuplot_executable);
Global_Config& set_logger(); // removes logger Global_Config& set_default_logger(); // reuses default one Global_Config& set_logger(const std::function<void(const char* const msg)>& f); // defines your own bool has_logger() const; Global_Config& set_log_message(const char* const msg);
Global_Config& set_script_file_mode( Script_File_Mode_Enum mode); // globally overwrite local 'script_file_mode' Global_Config& set_script_file_mode(); // stop overwriting local 'script_file_mode' std::optional<Script_File_Mode_Enum> script_file_mode() const; #+END_SRC
-
=set/gnuplot_exe()= functions allow you to define GnuPlot executable filename, by default this is =gnuplot= or =gnuplot.exe= for windows.
-
=set/logger()= functions allow you to stop or redirect logs, by example: #+BEGIN_SRC cpp :eval never global_config().set_logger([](const char *const msg) { std::cerr << "====> My logger " << msg << std::endl; }); #+END_SRC
-
=set_script_file_mode()= functions are more interesting as they allow you to overwrite globally what happens at =Script_File= destruction time. A typical use case is as follows:
Imagine that your code silently generates a lot of scripts:
#+BEGIN_SRC cpp :eval never for (size_t i = 1; i < 5; i++) { Script_File script(fmt::format("script_{}.gp", i), Script_File_Mode_Enum::Silent);
script.free_form("plot sin({0}*x) t 'sin({0}*x)'", i); } #+END_SRC
However at debug time, you want to force visualization to see what happens. In that case you simply have to add #+BEGIN_SRC cpp :eval never global_config().set_script_file_mode(Script_File_Mode_Enum::Persistent); #+END_SRC before #+BEGIN_SRC cpp :eval never for (size_t i = 1; i < 5; i++) { ... } #+END_SRC This will force all =Script_File= to use =Script_File_Mode_Enum::Persistent=
- References
- [[http://www.gnuplot.info/][GnuPlot]] official page
- [[https://www.manning.com/books/gnuplot-in-action-second-edition][GnuPlot in Action]] a very well written book
- [[http://www.gnuplotting.org/][www.gnuplotting.org]] a lot of great examples
- [[http://folk.uio.no/inf3330/scripting/doc/gnuplot/Kawano/index-e.html][GnuPlot not so Frequently Asked Questions]]
- [[https://en.wikipedia.org/wiki/Gnuplot][Wikipedia]] the free encyclopedia...
figures/matrix.png http://pixorblog.files.wordpress.com/2019/12/matrix.png
figures/histogram.png http://pixorblog.files.wordpress.com/2019/12/histogram.png
figures/graph.png http://pixorblog.files.wordpress.com/2019/12/graph.png
figures/plot.png http://pixorblog.files.wordpress.com/2019/12/plot.png
- FAQ -> your question here