ptsouchlos /
eventbus
A simple, header only event bus library written in modern C++17.
86/100 healthLoading repository data…
vincent-picaud / repository
A simple C++17 lib that helps you to quickly plot your data with GnuPlot
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
#+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
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).
** News
[2020-10-20 Tue] \
[2020-01-18 Sat 09:17] \
[2020-01-09 Thu 22:46] \
[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
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=.
** 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 #include
using namespace GnuPlotScripting;
// From: https://www.cs.hmc.edu/~vrable/gnuplot/using-gnuplot.html
int main() { std::vector 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"); } #+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 #include
using namespace GnuPlotScripting;
// Example from: // https://stackoverflow.com/a/7454274/2001017 // template void gnuplot_histogram(Script& script, const std::vector& data, const size_t n_bin, const typename std::vector::value_type min, const typename std::vector::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 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"); } #+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 #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 s
Selected from shared topics, language and repository description—not editorial ratings.
ptsouchlos /
A simple, header only event bus library written in modern C++17.
86/100 healthrichardbiely /
A simple and powerful entity component system (ECS) written in C++17
79/100 healthSuperxwolf /
JavaScriptCore++ - A simple C++ 17 wrapper for JavaScriptCore
Timothy-Liuxf /
simple_logger - A simple, multifunctional and header-only logging library for C++17.
65/100 health9inefold /
A small, simple formatting library for C++17
72/100 healthBlueDragon28 /
A simple C++17 audio library.
58/100 health