/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* ExprTk GNUPlot Example *
* Author: Arash Partow (1999-2025) *
* URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
* https://www.opensource.org/licenses/MIT *
* SPDX-License-Identifier: MIT *
* *
**************************************************************
*/
#include
#include
#include
#include
#include
#include "exprtk.hpp"
class exprtk_gnuplot_fx
{
public:
exprtk_gnuplot_fx()
: min_x_(0.0)
, max_x_(0.0)
, min_y_(0.0)
, max_y_(0.0)
{}
exprtk_gnuplot_fx& set_title(const std::string& title)
{
title_ = title;
return *this;
}
exprtk_gnuplot_fx& set_domain(const double min_x, const double max_x)
{
min_x_ = min_x;
max_x_ = max_x;
return *this;
}
exprtk_gnuplot_fx& set_expression(const std::string& expression)
{
expression_ = expression;
return *this;
}
bool plot()
{
if (!generate_data())
return false;
else
return generate_gp_script();
}
private:
bool generate_gp_script()
{
std::ofstream stream("plot.gp");
if (!stream)
{
return false;
}
stream << "set term png\n";
stream << "set output 'plot.png'\n";
stream << "set xrange[" << min_x_ << ":" << max_x_ <<"]\n";
stream << "set yrange[" << min_y_ << ":" << max_y_ <<"]\n";
stream << "set xzeroaxis\n";
stream << "set yzeroaxis\n";
stream << "plot 'data.dat' using 1:2:(1.0) smooth unique title '" << title_ <<"'\n";
return true;
}
bool generate_data()
{
typedef exprtk::symbol_table symbol_table_t;
typedef exprtk::expression expression_t;
typedef exprtk::parser parser_t;
double x = 0.0;
symbol_table_t symbol_table;
symbol_table.add_constants();
symbol_table.add_variable("x",x);
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
if (!parser.compile(expression_,expression))
{
return false;
}
std::ofstream stream("data.dat");
if (!stream)
{
return false;
}
min_y_ = +std::numeric_limits::max();
max_y_ = -std::numeric_limits::max();
stream << std::setprecision(10);
const double increment = std::min(0.00005,std::abs(max_x_ - min_x_) / 1000.0);
for (x = min_x_; x <= max_x_; x += increment)
{
const double y = expression.value();
if (y < min_y_) min_y_ = y;
else if (y > max_y_) max_y_ = y;
stream << x << "\t" << y << "\n";
}
const double diff_y = std::abs(max_y_ - min_y_);
const double perc7_5 = diff_y * 0.075; //7.5%
min_y_ -= perc7_5;
max_y_ += perc7_5;
return true;
}
std::string title_;
std::string expression_;
double min_x_;
double max_x_;
double min_y_;
double max_y_;
};
int main()
{
exprtk_gnuplot_fx plotter;
plotter
.set_expression("clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)")
.set_domain(-5,+5)
.set_title("ExprTk GNUPlot Example");
plotter.plot();
return 0;
}
/*
Build and Run:
1. c++ -ansi -pedantic-errors -Wall -Wextra -Werror -Wno-long-long -O3 -DNDEBUG -o exprtk_gnuplot exprtk_gnuplot.cpp -lstdc++
2. ./exprtk_gnuplot
3. gnuplot plot.gp
*/