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