00001
00007
#ifndef GNUPLOT_H
00008
#define GNUPLOT_H
00009
00010
#include <cstdio>
00011
#include <map>
00012
#include <utility>
00013
#include <string>
00014
#include <sstream>
00015
#include <list>
00016
00017 #define GNUPLOT_ONLY_INCLUDES
00018
00019
#ifdef _WIN32
00020
#include "gnuplot_win32.h"
00021
#else
00022
#include "gnuplot_unix.h"
00023
#endif
00024
#undef GNUPLOT_ONLY_INCLUDES
00025
00028
00029
00037 template<
class T>
class Gnuplot {
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;
00051
typedef T
channel_name_type;
00052
00053
protected:
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;
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 };
00076 void putData(
double v){
00077 buffer[current++]=v;
00078 current=current%buffersize;
00079 };
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 };
00088
double getData(
int i){
00089
return buffer[(i+current)%buffersize];
00090 };
00091
00092 };
00093
00094 FILE* pipe;
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 };
00115 void command(
const std::string& cmd){
00116 fprintf(
pipe,
"%s\n",cmd.data());
00117 fflush(
pipe);
00118 };
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 };
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
00141
const nameslist&
getNames(){
00142
return namesets;
00143 };
00144
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
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
00161
void hide(
const T& channel){
00162
show(channel,
false);
00163 };
00164
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
00172
void hide_all(){
00173
show_all(
false);
00174 };
00175
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
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
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 };
00218
void plot(){
plot(start,end); }
00219
00220
00224
void setStart(
int n){
start=n; };
00225
00229
void setEnd(
int n){
end=n; };
00230
00232 int getBuffersize() {
return buffersize; };
00233
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
00274
void plotXY(
const T& x,
const T& y){
00275
plotXY(&x,&y,1);
00276 };
00277
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