00001
00059 #ifndef __GNUPLOT_H__
00060 #define __GNUPLOT_H__
00061
00062 #include <iostream>
00063 #include <fstream>
00064 #include <cstdio>
00065 #include <string>
00066 #include <vector>
00067
00068
00073 namespace vec {
00074
00075
00076 00077 00078 00079 00080
00082 typedef double AxisCoord;
00084 typedef std::vector<AxisCoord> AxisVector;
00086 typedef AxisVector::size_type AxisSubscript;
00087
00088
00089
00090
00091
00092
00093
00094
00096 string temporaryname(const string prefix)
00097 {
00098 char* matrixfilechars = tempnam(0,prefix.c_str());
00099 string matrixfilename(matrixfilechars);
00100 free(matrixfilechars);
00101 return matrixfilename;
00102 }
00103
00104
00105
00107 inline string call_gnuplot(const string& title,
00108 const string& matrixfilename,
00109 const string& outputfilename,
00110 const string& gpscript_command,
00111 bool parametric)
00112 {
00113 const bool interactive=(outputfilename=="");
00114 const bool view_as_ps=true;
00115 const bool create_ps=(!interactive || view_as_ps);
00116 const string ps_view_command="ghostview";
00117
00118 const string gpscript_save_to_ps =
00119 "set terminal postscript eps color solid 'Times-Roman' 14\n"
00120 "set output '";
00121
00122 const string gpscript_display = "pause -1\n";
00123
00124 const string scriptfilename = temporaryname("gnupl");
00125
00126 const string outfilename = (outputfilename!="" ? outputfilename :
00127 temporaryname("gnupl"));
00128
00129
00130 {
00131 ofstream scriptfile(scriptfilename.c_str());
00132 if (!scriptfile) return "Cannot open temporary script file";
00133
00134
00135 if (create_ps) scriptfile << gpscript_save_to_ps << outfilename << "'\n";
00136 if (parametric) scriptfile << "set parametric\n";
00137
00138 scriptfile << "set title '" << title << "'\n";
00139
00140 unsigned pos;
00141 string p = gpscript_command;
00142 const string filenamemarker="Matrix";
00143 while ((pos=p.find(filenamemarker))<p.length())
00144 p.replace(pos,filenamemarker.length(),matrixfilename);
00145
00146 scriptfile << p;
00147 if (!create_ps) scriptfile << gpscript_display;
00148
00149 if (scriptfile.bad()) return "Error writing script file";
00150 }
00151
00152
00153 string cmd = "gnuplot " + scriptfilename;
00154 system(cmd.c_str());
00155
00156
00157 if (remove(scriptfilename.c_str()) || remove(matrixfilename.c_str()))
00158 return "Cannot remove temporary files";
00159
00160 if (interactive && view_as_ps) {
00161 string viewcmd = ps_view_command + " " + outfilename + "&";
00162 system(viewcmd.c_str());
00163 }
00164
00165 return "";
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00177 template <class VectorA, class VectorX>
00178 string gnuplot(const VectorA& A,
00179 const string& title,
00180 const string& outputfilename,
00181 const string& gpscript,
00182 const VectorX& X)
00183 {
00184 typedef typename VectorA::size_type Subscript;
00185
00186 if (Subscript(X.size())!=Subscript(A.size()))
00187 return "Skipping; axis vector incompatible with vector size";
00188 if (!A.size()) return "Skipping empty vector";
00189 if (A.size()==1) return "Skipping single-element vector";
00190
00191
00192 {
00193 string matrixfilename = temporaryname("gnupl");
00194 ofstream matrixfile(matrixfilename.c_str());
00195 if (!matrixfile) return "Cannot open temporary file";
00196
00197
00198 for (Subscript i=0; i<A.size(); i++) {
00199 matrixfile << X[i] << " ";
00200 matrixfile << A[i] << " ";
00201 matrixfile << endl;
00202 }
00203
00204 if (matrixfile.bad()) return "Error writing matrix file";
00205 }
00206
00207 return call_gnuplot
00208 ( title,matrixfilename,outputfilename,
00209
00210 gpscript!="" ? gpscript :
00211 "set xlabel 'Element'\n"
00212 "set ylabel 'Value'\n"
00213 "plot 'Matrix' notitle with lines\n",
00214
00215 false);
00216 }
00217
00218
00219
00221 template <class Vector>
00222 string gnuplot(const Vector& A,
00223 const string& title="",
00224 const string& outputfilename="",
00225 const string& gpscript="",
00226 AxisCoord xo=0, AxisCoord xm=1)
00227 {
00228 AxisVector X(A.size(),0.0);
00229 for (AxisSubscript i=0; i<AxisSubscript(A.size()); i++) X[i]=xo+i*xm;
00230 return gnuplot(A,title,outputfilename,gpscript,X);
00231 }
00232
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242 namespace mat {
00243 using vec::call_gnuplot;
00244 using vec::temporaryname;
00245 using vec::AxisCoord;
00246 using vec::AxisVector;
00247 using vec::AxisSubscript;
00248
00249
00251 template <class Matrix, class Vector>
00252 string gnuplot(const Matrix& A,
00253 const string& title,
00254 const string& outputfilename,
00255 const string& gpscript,
00256 const Vector& R,
00257 const Vector& C)
00258 {
00259 typedef typename Matrix::size_type Subscript;
00260
00261 if (int(C.size())!=int(A.ncols())) return "Skipping; column axis vector incompatible with matrix size";
00262 if (int(R.size())!=int(A.nrows())) return "Skipping; row axis vector incompatible with matrix size";
00263 if (A.ncols()==0 || A.nrows()==0) return "Skipping empty matrix";
00264 if (A.ncols()==1 && A.nrows()==1) return "Skipping single-element matrix";
00265
00266 const string matrixfilename = temporaryname("gnupl");
00267
00268
00269 {
00270 ofstream matrixfile(matrixfilename.c_str());
00271 if (!matrixfile) return "Cannot open temporary file";
00272
00273
00274 for (Subscript i=0; i<A.nrows(); i++) {
00275 for (Subscript j=0; j<A.ncols(); j++) {
00276 matrixfile << R[i] << " ";
00277 matrixfile << C[j] << " ";
00278 matrixfile << A[i][j] << endl;
00279 }
00280 matrixfile << endl;
00281 }
00282
00283 if (matrixfile.bad()) return "Error writing matrix file";
00284 }
00285
00286 return call_gnuplot
00287 ( title,matrixfilename,outputfilename,
00288
00289 gpscript != "" ? gpscript :
00290 "set xlabel 'R'\n"
00291 "set ylabel 'C'\n"
00292 "set zlabel 'Value'\n"
00293 "set hidden3d\n"
00294 "splot 'Matrix' notitle with lines\n",
00295
00296 true);
00297 }
00298
00299
00300
00302 template <class Matrix>
00303 string gnuplot(const Matrix& A,
00304 const string& title="",
00305 const string& outputfilename="",
00306 const string& gpscript="",
00307 AxisCoord Ro=0, AxisCoord Rm=1,
00308 AxisCoord Co=0, AxisCoord Cm=1)
00309 {
00310 AxisVector R(A.nrows(),0.0);
00311 for (AxisSubscript i=0; i<AxisSubscript(A.nrows()); i++) R[i]=Ro+i*Rm;
00312
00313 AxisVector C(A.ncols(),0.0);
00314 for (AxisSubscript j=0; j<AxisSubscript(A.ncols()); j++) C[j]=Co+j*Cm;
00315
00316 return gnuplot(A,title,outputfilename,gpscript,R,C);
00317 }
00318
00319
00320
00321 }
00322
00323
00324 #endif