00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef GNUPLOT_H
00011 #define GNUPLOT_H
00012
00013 #include <cstdio>
00014 #include <map>
00015 #include <utility>
00016 #include <string>
00017 #include <sstream>
00018 #include <list>
00019
00020 #define GNUPLOT_ONLY_INCLUDES
00021
00022 #ifdef _WIN32
00023 #include "gnuplot_win32.h"
00024 #else
00025 #include "gnuplot_unix.h"
00026 #endif
00027 #undef GNUPLOT_ONLY_INCLUDES
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 template<class T> class Gnuplot {
00041
00042
00043 #ifdef _WIN32
00044 #include "gnuplot_win32.h"
00045 #else
00046 #include "gnuplot_unix.h"
00047 #endif
00048 public:
00049 typedef std::list<T> nameslist;
00050
00051 typedef T channel_name_type;
00052
00053 protected:
00054
00055 class Dataset{
00056 double *buffer;
00057 int buffersize;
00058 int current;
00059 public:
00060 std::string title;
00061 std::string style;
00062 bool show;
00063
00064 Dataset(const std::string& title="",const std::string& style="",int buffersize=256)
00065 :buffersize(buffersize),title(title),style(style){
00066 buffer=new double[buffersize];
00067 for(int i=0;i<buffersize;++i)
00068 buffer[i]=0.0;
00069 current=0;
00070 show=true;
00071 };
00072 ~Dataset(){
00073 delete []buffer;
00074 };
00075
00076 void putData(double v){
00077 buffer[current++]=v;
00078 current=current%buffersize;
00079 };
00080
00081 void plot(FILE* f, int start=0, int end=0){
00082 int _start=current+start;
00083 int _end=current+((end<=0)?buffersize:end);
00084 for(int i=_start;i<_end;++i)
00085 fprintf(f,"%f\n",buffer[i%buffersize]);
00086 };
00087
00088 double getData(int i){
00089 return buffer[(i+current)%buffersize];
00090 };
00091
00092 };
00093
00094 FILE* pipe;
00095
00096 typedef std::map<T, Dataset*> dataset_map;
00097 dataset_map datasets;
00098 nameslist namesets;
00099 int buffersize;
00100 int start;
00101 int end;
00102 public:
00103
00104 Gnuplot(int buffersize=256):buffersize(buffersize),start(0),end(buffersize){
00105 pipe=OpenGnuplot();
00106 };
00107 ~Gnuplot(){
00108 for(typename dataset_map::iterator i=datasets.begin();i!=datasets.end();++i){
00109 delete i->second;
00110 }
00111 if(pipe)CloseGnuplot(pipe);
00112 };
00113
00114
00115 void command(const std::string& cmd){
00116 fprintf(pipe,"%s\n",cmd.data());
00117 fflush(pipe);
00118 };
00119
00120
00121 void addChannel(const T& name,const std::string& title="",const std::string& style="lines"){
00122 if(title != "")
00123 datasets.insert(std::make_pair(name,new Dataset(title,style,buffersize)));
00124 else {
00125 std::ostringstream str;
00126 str << name;
00127 datasets.insert(std::make_pair(name,new Dataset(str.str(),style,buffersize)));
00128 }
00129 namesets.push_back(name);
00130 };
00131
00132
00133
00134 void putData(const T& channel, double data){
00135 typename dataset_map::iterator i = datasets.find(channel);
00136 if(i!=datasets.end())
00137 i->second->putData(data);
00138 };
00139
00140
00141 const nameslist& getNames(){
00142 return namesets;
00143 };
00144
00145
00146 std::string getTitle(const T& channel){
00147 typename dataset_map::iterator i = datasets.find(channel);
00148 if(i!=datasets.end())
00149 return i->second->title;
00150 return "";
00151 };
00152
00153
00154 void show(const T& channel, bool on=true){
00155 typename dataset_map::iterator i = datasets.find(channel);
00156 if(i!=datasets.end())
00157 i->second->show=on;
00158 };
00159
00160
00161 void hide(const T& channel){
00162 show(channel, false);
00163 };
00164
00165
00166 void show_all(bool on=true){
00167 for(typename dataset_map::iterator i=datasets.begin();i!=datasets.end();++i)
00168 i->second->show=on;
00169 };
00170
00171
00172 void hide_all(){
00173 show_all(false);
00174 };
00175
00176
00177 void setTitle(const T& channel, const std::string& title){
00178 typename dataset_map::iterator i = datasets.find(channel);
00179 if(i!=datasets.end())
00180 i->second->title=title;
00181 };
00182
00183
00184 void setStyle(const T& channel, const std::string& style){
00185 typename dataset_map::iterator i = datasets.find(channel);
00186 if(i!=datasets.end())
00187 i->second->style=style;
00188 };
00189
00190
00191 void plot(int start, int end){
00192
00193 int _start=buffersize-end;
00194 int _end=buffersize-start;
00195 fprintf(pipe,"plot ");
00196 bool first=true;
00197 for(typename dataset_map::iterator i=datasets.begin();i!=datasets.end();++i){
00198 Dataset* dataset=i->second;
00199 if(dataset->show){
00200 if(first) first=false;
00201 else fprintf(pipe,", ");
00202 fprintf(pipe,"'-'");
00203 fprintf(pipe," title '%s'",dataset->title.data());
00204 fprintf(pipe," with %s",dataset->style.data());
00205 }
00206 }
00207 fprintf(pipe,"\n");
00208 for(typename dataset_map::iterator i=datasets.begin();i!=datasets.end();++i){
00209 Dataset* dataset=i->second;
00210 if(dataset->show){
00211 dataset->plot(pipe,_start,_end);
00212 fprintf(pipe,"e\n");
00213 }
00214 }
00215 fflush(pipe);
00216 };
00217
00218 void plot(){ plot(start,end); }
00219
00220
00221
00222
00223
00224 void setStart(int n){ start=n; };
00225
00226
00227
00228
00229 void setEnd(int n){ end=n; };
00230
00231
00232 int getBuffersize() { return buffersize; };
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 void plotXY(const T *x, const T *y,int size){
00243 fprintf(pipe,"plot ");
00244 bool first=true;
00245 for(int i=0;i < size; ++i){
00246 typename dataset_map::iterator iX = datasets.find(x[i]);
00247 typename dataset_map::iterator iY = datasets.find(y[i]);
00248
00249 if(iX==datasets.end() || iY==datasets.end())
00250 continue;
00251 if(first) first=false;
00252 else fprintf(pipe,", ");
00253 Dataset* datasetX=iX->second;
00254 Dataset* datasetY=iY->second;
00255 fprintf(pipe,"'-'");
00256 fprintf(pipe," title '%s'",std::string(datasetX->title + "<->" + datasetY->title).data());
00257 fprintf(pipe," with %s",datasetY->style.data());
00258 }
00259 fprintf(pipe,"\n");
00260 for(int i=0;i < size; ++i){
00261 typename dataset_map::iterator iX = datasets.find(x[i]);
00262 typename dataset_map::iterator iY = datasets.find(y[i]);
00263
00264 if(iX==datasets.end() || iY==datasets.end())
00265 continue;
00266 for(int i2=0; i2<buffersize; ++i2)
00267 fprintf(pipe,"%f %f\n",iX->second->getData(i2),iY->second->getData(i2));
00268 fprintf(pipe,"e\n");
00269 }
00270 fflush(pipe);
00271 };
00272
00273
00274 void plotXY(const T& x, const T& y){
00275 plotXY(&x,&y,1);
00276 };
00277
00278
00279
00280 void printToFile(const std::string name="", const std::string ext=".log"){
00281 for(typename dataset_map::iterator i=datasets.begin();i!=datasets.end();++i){
00282 std::string name2 = name + i->second->title + ext;
00283 FILE* f=fopen(name2.data(),"w");
00284 i->second->plot(f);
00285 fflush(f);
00286 fclose(f);
00287 }
00288 };
00289 };
00290
00291 #endif
00292