/* * Plot.hpp, part of LatAnalyze 3 * * Copyright (C) 2013 - 2020 Antonin Portelli * * LatAnalyze 3 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * LatAnalyze 3 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with LatAnalyze 3. If not, see . */ #ifndef Latan_Plot_hpp_ #define Latan_Plot_hpp_ #include #include #include #include #include #include // gnuplot default parameters #ifndef GNUPLOT_BIN #define GNUPLOT_BIN "gnuplot" #endif #ifndef GNUPLOT_ARGS #define GNUPLOT_ARGS "-p" #endif BEGIN_LATAN_NAMESPACE /****************************************************************************** * Plot objects * ******************************************************************************/ class PlotObject { public: // destructor virtual ~PlotObject(void) = default; // access std::string popTmpFile(void); const std::string & getCommand(void) const; const std::string & getHeadCommand(void) const; // test bool gotTmpFile(void) const; protected: // access void pushTmpFile(const std::string &fileName); void setCommand(const std::string &command); void setHeadCommand(const std::string &command); // dump a matrix to a temporary file std::string dumpToTmpFile(const DMat &m); private: // plot command std::string command_; std::string headCommand_; // stack of created temporary files std::stack tmpFileName_; }; class PlotCommand: public PlotObject { public: // constructor explicit PlotCommand(const std::string &command); // destructor virtual ~PlotCommand(void) = default; }; class PlotHeadCommand: public PlotObject { public: // constructor explicit PlotHeadCommand(const std::string &command); // destructor virtual ~PlotHeadCommand(void) = default; }; class PlotData: public PlotObject { public: // constructor PlotData(const DMatSample &x, const DMatSample &y, const bool abs = false); PlotData(const DVec &x, const DMatSample &y, const bool abs = false); PlotData(const DMatSample &x, const DVec &y, const bool abs = false); PlotData(const XYStatData &data, const Index i = 0, const Index j = 0, const bool abs = false); // destructor virtual ~PlotData(void) = default; }; class PlotHLine: public PlotObject { public: // constructor PlotHLine(const double y); // destructor virtual ~PlotHLine(void) = default; }; class PlotLine: public PlotObject { public: // constructor PlotLine(const DVec &x, const DVec &y); // destructor virtual ~PlotLine(void) = default; }; class PlotBand: public PlotObject { public: // constructor PlotBand(const double xMin, const double xMax, const double yMin, const double yMax, const double opacity = 0.15); // destructor virtual ~PlotBand(void) = default; }; class PlotFunction: public PlotObject { public: // constructor PlotFunction(const DoubleFunction &function, const double xMin, const double xMax, const unsigned int nPoint = 1000, const bool abs = false); // destructor virtual ~PlotFunction(void) = default; }; class PlotPredBand: public PlotObject { public: // constructor PlotPredBand(const DVec &x, const DVec &y, const DVec &yerr, const double opacity = 0.15); PlotPredBand(const DoubleFunctionSample &function, const double xMin, const double xMax, const unsigned int nPoint = 1000, const double opacity = 0.15); // destructor virtual ~PlotPredBand(void) = default; private: void makePredBand(const DMat &low, const DMat &high, const double opacity); }; class PlotHistogram: public PlotObject { public: // constructor PlotHistogram(const Histogram &h); // destructor virtual ~PlotHistogram(void) = default; }; class PlotImpulses: public PlotObject { public: // constructor PlotImpulses(const DVec &x, const DVec &y); // destructor virtual ~PlotImpulses(void) = default; }; class PlotMatrixNoRange: public PlotObject { public: // constructor PlotMatrixNoRange(const DMat &m); // destructor virtual ~PlotMatrixNoRange(void) = default; }; #define PlotMatrix(m)\ PlotRange(Axis::x, -.5, (m).cols() - .5) <<\ PlotRange(Axis::y, (m).rows() - .5, -.5) <<\ PlotMatrixNoRange(m) /****************************************************************************** * Plot modifiers * ******************************************************************************/ enum class Axis {x = 0, y = 1}; struct Range { double min, max; }; struct PlotOptions { std::string terminal; std::string output; std::string caption; std::string title; unsigned int scaleMode[2]; Range scale[2]; std::string label[2]; std::string lineColor; int lineWidth; std::string dashType; std::vector palette; }; class PlotModifier { public: // destructor virtual ~PlotModifier(void) = default; // modifier virtual void operator()(PlotOptions &option) const = 0; }; class Caption: public PlotModifier { public: // constructor explicit Caption(const std::string &title); // destructor virtual ~Caption(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::string caption_; }; class Label: public PlotModifier { public: // constructor explicit Label(const std::string &label, const Axis axis); // destructor virtual ~Label(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::string label_; const Axis axis_; }; class Color: public PlotModifier { public: // constructor explicit Color(const std::string &color); // destructor virtual ~Color(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::string color_; }; class LineWidth: public PlotModifier { public: // constructor explicit LineWidth(const unsigned int width); // destructor virtual ~LineWidth(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const unsigned width_; }; class Dash: public PlotModifier { public: // constructor explicit Dash(const std::string &dash); // destructor virtual ~Dash(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::string dash_; }; class LogScale: public PlotModifier { public: // constructor explicit LogScale(const Axis axis); // destructor virtual ~LogScale(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const Axis axis_; }; class PlotRange: public PlotModifier { public: // constructors PlotRange(const Axis axis); PlotRange(const Axis axis, const double min, const double max); // destructor virtual ~PlotRange(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const Axis axis_; const bool reset_; const double min_, max_; }; class Terminal: public PlotModifier { public: // constructor Terminal(const std::string &terminal, const std::string &options = ""); // destructor virtual ~Terminal(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::string terminalCmd_; }; class Title: public PlotModifier { public: // constructor explicit Title(const std::string &title); // destructor virtual ~Title(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::string title_; }; class Palette: public PlotModifier { public: static const std::vector category10; public: // constructor explicit Palette(const std::vector &palette); // destructor virtual ~Palette(void) = default; // modifier virtual void operator()(PlotOptions &option) const; private: const std::vector palette_; }; /****************************************************************************** * Plot class * ******************************************************************************/ class Plot { public: class Scale { public: enum { reset = 0, manual = 1 << 0, log = 1 << 1 }; }; public: // constructor/destructor Plot(void); virtual ~Plot(void) = default; // plot operations Plot & operator<<(PlotObject &&command); Plot & operator<<(PlotModifier &&modifier); // plot parsing and output void display(void); void save(std::string dirName, bool savePdf = true); friend std::ostream & operator<<(std::ostream &out, const Plot &plot); // plot reset void reset(void); // find gnuplot std::string getProgramPath(void); private: // default options void initOptions(void); private: // gnuplot execution parameters std::string gnuplotBin_ {GNUPLOT_BIN}; std::string gnuplotArgs_ {GNUPLOT_ARGS}; std::string gnuplotPath_ {""}; // string buffer for commands std::ostringstream commandBuffer_; // stack of created temporary files std::vector tmpFileName_; // plot content PlotOptions options_; std::vector headCommand_; std::vector plotCommand_; }; std::ostream & operator<<(std::ostream &out, const Plot &plot); END_LATAN_NAMESPACE #endif // Latan_Plot_hpp_