diff --git a/example/gnuplot_ex.cpp b/example/gnuplot_ex.cpp index 2c429db..99d77e8 100644 --- a/example/gnuplot_ex.cpp +++ b/example/gnuplot_ex.cpp @@ -25,6 +25,7 @@ * Also add information on how to contact you by electronic and paper mail. ******************************************************/ +#include "../lib/core/macro.h" #include "../lib/graphic/gnuplot.h" int main(int argc, char *argv[]) @@ -32,8 +33,8 @@ int main(int argc, char *argv[]) gctl::gnuplot gt; //one line test - gt.send("set terminal dumb"); - gt.send("plot [-pi/2:pi] cos(x),-(sin(x) > sin(x+1) ? sin(x) : sin(x+1))"); + //gt.send("set terminal dumb"); + //gt.send("plot [-pi/2:pi] cos(x),-(sin(x) > sin(x+1) ? sin(x) : sin(x+1))"); //buffer test (bessel animation) /* @@ -72,16 +73,25 @@ int main(int argc, char *argv[]) */ //data test - /* + std::vector x(101); + std::vector y1(101); + std::vector y2(101); + for (size_t i = 0; i < 101; i++) + { + x[i] = -1.0*GCTL_Pi + 2.0*GCTL_Pi*i/100.0; + y1[i] = sin(x[i]); + y2[i] = cos(x[i]); + } + + std::vector > data; + data.push_back(x); + data.push_back(y1); + data.push_back(y2); + gt.to_buffer(); - gt.send("$Data << EOD"); - gt.send("0 0 0"); - gt.send("1 1 0.5"); - gt.send("2 4 2"); - gt.send("3 9 3"); - gt.send("EOD"); + gt.send_data("$Data", data); gt.send("plot $Data using 1:2 with lines title 'y1', '' using 1:3 with lines title 'y2'"); + gt.save_buffer("sin_cos"); gt.send_buffer(); - */ return 0; } diff --git a/lib/graphic/gnuplot.cpp b/lib/graphic/gnuplot.cpp index 0c73243..0e3e750 100644 --- a/lib/graphic/gnuplot.cpp +++ b/lib/graphic/gnuplot.cpp @@ -72,6 +72,52 @@ void gctl::gnuplot::send_buffer(size_t repeat) return; } +void gctl::gnuplot::send_data(std::string name, const std::vector > &data, bool next_block) +{ + if (!pipe) return; + + if (!_2buffer) + { + fputs((name + " << EOD\n").c_str(), pipe); + + int cnum = data.size(); + int dnum = data[0].size(); + std::string line; + for (size_t i = 0; i < dnum; i++) + { + line = std::to_string(data[0][i]); + for (size_t j = 1; j < cnum; j++) + { + line += " " + std::to_string(data[j][i]); + } + fputs((line + "\n").c_str(), pipe); + } + + fputs("EOD\n", pipe); + } + else + { + buffer.push_back(name + " << EOD\n"); + + int cnum = data.size(); + int dnum = data[0].size(); + std::string line; + for (size_t i = 0; i < dnum; i++) + { + line = std::to_string(data[0][i]); + for (size_t j = 1; j < cnum; j++) + { + line += " " + std::to_string(data[j][i]); + } + buffer.push_back(line + "\n"); + } + + buffer.push_back("EOD\n"); + if (next_block) buffer.push_back("\n"); + } + return; +} + void gctl::gnuplot::save_buffer(const std::string& filename) { time_t now = time(0); diff --git a/lib/graphic/gnuplot.h b/lib/graphic/gnuplot.h index 1093df9..73b9f32 100644 --- a/lib/graphic/gnuplot.h +++ b/lib/graphic/gnuplot.h @@ -49,6 +49,7 @@ namespace gctl * @param persist Gnuplot will hold the window after plot if true. */ gnuplot(bool persist = true); + // destructor virtual ~gnuplot(); @@ -65,6 +66,15 @@ namespace gctl */ void send(const std::string& cmd, bool next_block = false); + /** + * @brief Send a data block + * + * @param name Name of the data block which could be used later for ploting. + * @param data data block. Note that each vector object represents a data column. + * @param next_block If true, an empty line will be added to the buffer after the cmd. + */ + void send_data(std::string name, const std::vector > &data, bool next_block = false); + /** * @brief Send the buffer to gnuplot and execute it at once. Then clear the buffer. * @@ -85,6 +95,7 @@ namespace gctl FILE* pipe; std::vector buffer; + std::vector data_lines; bool _2buffer; }; };