GnuPlotScripting - A simple C++17 lib that helps you to quickly plot your data with GnuPlot

Overview

Easy Creation of GnuPlot Scripts from C++

https://travis-ci.org/vincent-picaud/GnuPlotScripting.svg?branch=master

Table of contents

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 {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).

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

Installation

The library currently uses the meson build system.

If you are not familiar with meson, the compilation procedure is as follows:

git clone https://github.com/vincent-picaud/GnuPlotScripting.git
cd GnuPlotScripting/
meson build
cd build
ninja test

Examples can then be found in the build/examples/ directory.

If you want to install the package:

ninja install

Note that you can define custom installation path, at the beginning of the compilation procedure, use:

meson --prefix=/install_path/ build

instead of meson build.

Examples

Plot and fit data

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>
#include <vector>

using namespace GnuPlotScripting;

// From: https://www.cs.hmc.edu/~vrable/gnuplot/using-gnuplot.html

int
main()
{
  std::vector<double> time, angle, stdvar;

  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");
}

It generates this figure:

figures/plot.png

Note: the generated plot.gp gnutplot script embeds the data and you can replay it whenever you want:

gnuplot plot.pg -

Ascii matrix data

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>

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");
}

It generates this figure:

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:

EPSLATEX().set_standalone(true).set_color(true)

(NEW) Matrix data

You can also use the Array_2 container to temporary store your data

#include "GnuPlotScripting/array_2.hpp"
#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>

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");
}

It generates this figure:

figures/array_2.png

Histogram

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>
#include <random>

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)=width*floor(x/width)+width/2.0");
  script.free_form("set boxwidth width*0.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<double> data(10000);
  for (auto& data_i : data) data_i = distribution(gen);

  Script_File script("histogram.gp");

  gnuplot_histogram(script, data, 100, 0, 3);

  script.export_as(PNG(), "histogram");
}

The generated figure is:

figures/histogram.png

Graph

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>

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");
}

It generates this figure:

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.

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <array>
#include <iostream>

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;
}

Generated figure:

figures/density_plot.png

Pipe example

Instead of creating a file, we can create a pipe with popen() to directly send data to gnuplot.

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <chrono>
#include <iostream>
#include <thread>
#include <utility>  // std::pair
#include <vector>

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));
  }
}

Supported export formats

This example silently exports a basic plot in all supported formats:

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>

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");
}

Global config demonstration

This last example shows how to use Global_Config.

#include "GnuPlotScripting/GnuPlotScripting.hpp"

#include <iostream>

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);
  }
}

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:

script.free_form("plot {} u 1:2",data);
script.free_form("replot {} u 1:3",data);
script.free_form("replot {} u 1:4",data);

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:

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");

Note: it is really easy to define your own Data class. By example Data_Ascii code is as simple as:

class Data_Ascii final : public Data
{
 public:
  Data_Ascii(const std::string& data) : Data(data) {}
};

(NEW) Data_Array_2

Data to plot is defined using an basic two-dimensional array container, Array_2.

Array_2 array_2(row_size,column_size);

// fill component: array_2(i,j)= ...

Data_Array_2 data(array_2);

// plot data

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:

std::vector<double> v1(10);
std::vector<int> v2(10);
std::valarray<double> v3(10);
// ...
Data_Vector data(v1,v2,v3);

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:

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();

Note: as AFAK it is not possible to directly plot points with symbols retrieved from the the Y column (see 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:

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 

Creating these groups allows to use the gnuplot index keyword to plot all points associated to a given category. By example:

replot "$data_uuid" index i u 1:2:3 with points; # plot points of category i

Also note that when data is embedded, the Y category column is the last one. The rational is that for:

Data_Supervised data_a(Y, X_1, X_2); 
Data_Vector data_b(X_1, X_2); 

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:

template <typename... ARGS>
Script& free_form(ARGS&&... args);

Script& export_as(const Export_As& export_as, const std::filesystem::path& output);

void flush();
  • free_form allows you to write free form using the fmt library, by example:
script.free_form("plot '{}' u {}:{}","data_file.dat",1,2);
  • flush() forces buffer to be flushed
  • export_as() generates script code to export the figure in the given format, by example:
script.export_as(EPSLATEX().set_standalone(true),"filename");

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:

Script_File(const std::filesystem::path& filename,
            Script_File_Mode_Enum script_file_mode = Script_File_Mode_Enum::Persistent);
  • 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:

gnuplot filename.gp -

(note the final ‘-‘, see GnuPlot documentation for further details).

Another possibility is to add a pause in your gnuplot script:

script.free_form("pause -1");

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:

Script_Pipe(Script_Pipe_Mode_Enum script_pipe_mode = Script_Pipe_Mode_Enum::Persistent);

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

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;
  • 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:
global_config().set_logger([](const char *const msg) {
  std::cerr << "====> My logger " << msg << std::endl;
});
  • 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:

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);
}

However at debug time, you want to force visualization to see what happens. In that case you simply have to add

global_config().set_script_file_mode(Script_File_Mode_Enum::Persistent);

before

for (size_t i = 1; i < 5; i++)
{
  ...
}

This will force all Script_File to use Script_File_Mode_Enum::Persistent

References

FAQ

-> your question here

You might also like...
This repository is a summary of the basic knowledge of recruiting job seekers and beginners in the direction of C/C++ technology, including language, program library, data structure, algorithm, system, network, link loading library, interview experience, recruitment, recommendation, etc.
This repository is a summary of the basic knowledge of recruiting job seekers and beginners in the direction of C/C++ technology, including language, program library, data structure, algorithm, system, network, link loading library, interview experience, recruitment, recommendation, etc.

📚 C/C++ 技术面试基础知识总结,包括语言、程序库、数据结构、算法、系统、网络、链接装载库等知识及面试经验、招聘、内推等信息。This repository is a summary of the basic knowledge of recruiting job seekers and beginners in the direction of C/C++ technology, including language, program library, data structure, algorithm, system, network, link loading library, interview experience, recruitment, recommendation, etc.

Data Structures and Algos - DS, DSA, Python, C

100DaysOfCode I will be following geeksforgeeks as a referrence on how to go about this challenege. I am working on DS and Algos PS : It's not consecu

The Repository Contains all about Data Structure and Algorithms with Practice problems, series, and resources to follow!

🏆 The Complete DSA Preparation 🏆 This repository contains all the DSA (Data-Structures, Algorithms, 450 DSA by Love Babbar Bhaiya,STriver Series ,FA

This repo is all about different data structures and algorithms..
This repo is all about different data structures and algorithms..

Data Structure and Algorithm : Want to learn data strutrues and algorithms ??? Then Stop thinking more and start to learn today. This repo will help y

Cs50 Week5 Data-Structure Notes

CS50-Week-5-Note Cs50 Week5 Data-Structure Notes What Is Data-Structured It is the way of arranging the data to be able to use effectively. Summa

One-Stop Destination for codes of all Data Structures & Algorithms

CodingSimplified_GK This repository is aimed at creating a One stop Destination of codes of all Data structures and Algorithms along with basic explai

For C++, help generate a default operator for classes whose components (base classes, data members) have the operator. Hideously intrusive.

C-plus-plus-library-default-operators Helps generate a default operator / member function for classes whose components (base classes, data members) ha

simple and fast scripting language

The Aument Language The Aument language is a work-in-progress dynamically-typed scripting language with performance first: this scripting language is

A simple messenger written in C for Principal of Programming course final project
A simple messenger written in C for Principal of Programming course final project

Mohsenger A simple messenger written in C for Principal of Programming course final project Implemented by socket and sqlite3 dbms and single thread c

Comments
  • Problems with fmt.h

    Problems with fmt.h

    I tried to run this code:

    #include "GnuPlotScripting/GnuPlotScripting.hpp"
    
    #include <iostream>
    
    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);
      }
    }
    

    But i when i compile-it, g++ return:

    /usr/local/include/GnuPlotScripting/script.hpp:8:10: fatal error: fmt/format.h: No such file or directory
        8 | #include "fmt/format.h"
          |          ^~~~~~~~~~~~~~
    compilation terminated.
    
    

    I checked /usr/local/include/GnuPlotScripting, but there is no fmt/format.h., and all scripts included on the README.md file don't worked.

    opened by jazzman07 1
  • Error Ninja Test

    Error Ninja Test

    HI when i run Ninja Test, I got this error ../src/GnuPlotScripting/export_as.hpp:3:10: fatal error: filesystem: No such file or directory #include <filesystem>. Can you help me to fix it. Thank U

    opened by mohammedaugie13 1
  • fmt.h?

    fmt.h?

    This: #include "GnuPlotScripting/GnuPlotScripting.h" yields that: /usr/local/include/GnuPlotScripting/script.hpp:8:10: fatal error: fmt/format.h: No such file or directory 8 | #include "fmt/format.h" | ^~~~~~~~~~~~~~

    opened by rytis-paskauskas 1
  • Add CI to project

    Add CI to project

    This PR adds:

    • the possibility to build the project with docker with a simple make command
    • CI with travis.

    Result of the CI can be seen here: https://travis-ci.org/Gjacquenot/GnuPlotScripting

    If accepted, one can add a badge showing the result of compilation and tests.

    opened by Gjacquenot 1
Owner
pixor
pixor
🧼 Cleanly pause and play your YouTube videos while cooking/crafting/doing your makeup by waving your hand over a proximity sensor!

?? Cleanly pause and play your YouTube videos while cooking/crafting/doing your makeup by waving your hand over a proximity sensor!

Tala Buwadi 10 May 1, 2022
Welcome to my dungeon. Here, I keep all my configuration files in case I have a stroke and lose all my memory. You're very welcome to explore and use anything in this repository. Have fun!

Fr1nge's Dotfiles Welcome to my dungeon. Here, I keep all my configuration files in case I have a stroke an d lose all my memory. You're very welcome

Fr1nge 32 Apr 16, 2022
Starting with OpenCV and Qt on MacOS is a bit of difficult if you haven't installed and used libraries in XCode.

OpenCV and Qt on MacOS Introduction Starting with OpenCV and Qt on MacOS is a bit of difficult if you haven't installed and used libraries in XCode. T

Martin Kersting 1 Nov 18, 2021
Introducing to the world - Maze Game! A game with an easily accessible, user-friendly interface that will provide you the serotonin a game should!

Maze-Project Maze game by Maze™ ?? About Introducing to the world - Maze game! ⛏️ Used technologies C++ ✅ Features 3 levels of difficulty User-friendl

Yoana Agafonova 6 Jun 2, 2022
A place where you can learn and practise various Problems and algorithms

Problem-Solving Problem solving is an art of solving some real time challenges. And this is a place to get started, you can find many problems to solv

Google DSC, GVP Chapter 10 Apr 22, 2022
LOSTCENTURY64 will acompany you, have a nice trip...

Works and includes lostcentury64/~backdoor Version: 1.0.0 Alias: LC64.BACKDOOR.CPP lostcentury64/~passwordgenerator Version: 1.0.1 Alias: LC64.PASSWOR

null 3 Jan 10, 2022
This is a C project, to find the weekly salary of your employees.

Weekly-Salary This is a C project, to find the weekly salary of your employees. This is a very simle project. At 1st you insert the code of the employ

Ntinos 1 Dec 3, 2021
All those who are willing to participate in the 7-day coding event Commit-Your-Code organized by GDSC, UIET have to fork this repository and contribute their solutions as per defined rules.

????‍?? Commit-Ur-Code ????‍?? GDSC UIET KUK ?? , welcomes you all to this amazing event where you will be introduced to the world of coding ?? . It i

Google Developer Student Club UIET KUK 9 Mar 24, 2022
Background Music, a macOS audio utility: automatically pause your music, set individual apps' volumes and record system audio.

Background Music macOS audio utility Overview Auto-pause music Application volume Recording system audio Download Build and Install Uninstall Troubles

Kyle Neideck 12.1k Sep 27, 2022
Add a description to your directories!

lsnotes (Part of the better coreutils initiative) Add a description to your directories! Simply add a .lsnotes file and that's it! This is the origina

Louis Aeilot 6 Apr 16, 2022