SNAP Library , Developer Reference
2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 #include "stdafx.h" 00002 #include "gnuplot.h" 00003 00005 // GNU-Plot-Chart 00006 /*#ifdef GLib_WIN 00007 TStr TGnuPlot::GnuPlotPath = "\\Dev\\GLib\\gnuplot\\bin\\"; 00008 #else 00009 TStr TGnuPlot::GnuPlotPath = "/usr/bin/"; 00010 #endif*/ 00011 00012 // Determines the gnuplot version and the tics command syntax. 00013 // Gnuplot changed the syntax with version 4.2: 00014 // - before 4.2: set ticscale 2 1 00015 // - 4.2 and later: set tics 2 00016 int TGnuPlot::GetTics42() { 00017 #ifdef GLib_WIN 00018 return -1; 00019 #else 00020 FILE* p; 00021 char Buf[1024]; 00022 char Version[1024]; 00023 size_t n; 00024 00025 // get gnuplot version 00026 p = popen("gnuplot -V","r"); 00027 if (p == NULL) { 00028 return -1; 00029 } 00030 n = fread(Buf, 1, 100, p); 00031 if (n <= 0) { 00032 return -1; 00033 } 00034 Buf[n] = '\0'; 00035 pclose(p); 00036 00037 // printf("Buf %d .%s.\n", n, Buf); 00038 n = sscanf(Buf, "gnuplot %s", Version); 00039 if (n <= 0) { 00040 return -1; 00041 } 00042 // printf("Version %d .%s.\n", n, Version); 00043 if ((strlen(Version) < 3) || (Version[1] != '.')) { 00044 return -1; 00045 } 00046 00047 // test version < 4.2 00048 if ((Version[0] < '4') || ((Version[0] == '4') && (Version[2] < '2'))) { 00049 // printf("TGnuPlot::GetTics42 0\n"); 00050 return 0; 00051 } 00052 // printf("TGnuPlot::GetTics42 1\n"); 00053 return 1; 00054 #endif 00055 } 00056 00057 int TGnuPlot::Tics42 = TGnuPlot::GetTics42(); 00058 00059 TStr TGnuPlot::DefPlotFNm = "GnuPlot.plt"; 00060 TStr TGnuPlot::DefDataFNm = "GnuPlot.tab"; 00061 00062 TGnuPlot::TGpSeries::TGpSeries(const TGnuPlot::TGpSeries& Gps) : 00063 SeriesTy(Gps.SeriesTy), XYValV(Gps.XYValV), ZValV(Gps.ZValV), 00064 Label(Gps.Label), WithStyle(Gps.WithStyle), DataFNm(Gps.DataFNm), 00065 XCol(Gps.XCol), YCol(Gps.YCol), ZCol(Gps.ZCol) { 00066 } 00067 00068 TGnuPlot::TGpSeries& TGnuPlot::TGpSeries::operator = (const TGnuPlot::TGpSeries& Gps) { 00069 if(this != &Gps) { 00070 SeriesTy = Gps.SeriesTy; 00071 XYValV = Gps.XYValV; ZValV = Gps.ZValV; 00072 Label = Gps.Label; 00073 DataFNm = Gps.DataFNm; 00074 WithStyle = Gps.WithStyle; 00075 XCol = Gps.XCol; YCol = Gps.YCol; ZCol = Gps.ZCol; 00076 } 00077 return *this; 00078 } 00079 00080 bool TGnuPlot::TGpSeries::operator < (const TGpSeries& Gps) const { 00081 return (XYValV < Gps.XYValV) || ((XYValV == Gps.XYValV) && (Label < Gps.Label)); 00082 } 00083 00084 TGnuPlot::TGnuPlot(const TStr& FileNm, const TStr& PlotTitle, const bool& Grid) : 00085 DataFNm(FileNm+".tab"), PlotFNm(FileNm+".plt"), Title(PlotTitle), LblX(), LblY(), ScaleTy(gpsAuto), 00086 YRange(0, 0), XRange(0, 0), SetGrid(Grid), SetPause(true), 00087 SeriesV(), MoreCmds() { 00088 IAssert(! FileNm.Empty()); 00089 } 00090 00091 TGnuPlot::TGnuPlot(const TStr& DataFileNm, const TStr& PlotFileNm, const TStr& PlotTitle, const bool& Grid) : 00092 DataFNm(DataFileNm.Empty() ? DefDataFNm : DataFileNm), 00093 PlotFNm(PlotFileNm.Empty() ? DefPlotFNm : PlotFileNm), 00094 Title(PlotTitle), LblX(), LblY(), ScaleTy(gpsAuto), 00095 YRange(0, 0), XRange(0, 0), SetGrid(Grid), SetPause(true), SeriesV(), MoreCmds() { 00096 } 00097 00098 TGnuPlot::TGnuPlot(const TGnuPlot& GnuPlot) : DataFNm(GnuPlot.DataFNm), PlotFNm(GnuPlot.PlotFNm), 00099 Title(GnuPlot.Title), LblX(GnuPlot.LblX), LblY(GnuPlot.LblY), ScaleTy(GnuPlot.ScaleTy), YRange(GnuPlot.YRange), 00100 XRange(GnuPlot.XRange), SetGrid(GnuPlot.SetGrid), SetPause(GnuPlot.SetPause), SeriesV(GnuPlot.SeriesV), 00101 MoreCmds(GnuPlot.MoreCmds) { 00102 } 00103 00104 TGnuPlot& TGnuPlot::operator = (const TGnuPlot& GnuPlot) { 00105 if (this != &GnuPlot) { 00106 DataFNm = GnuPlot.DataFNm; 00107 PlotFNm = GnuPlot.PlotFNm; 00108 Title = GnuPlot.Title; 00109 LblX = GnuPlot.LblX; 00110 LblY = GnuPlot.LblY; 00111 ScaleTy = GnuPlot.ScaleTy; 00112 YRange = GnuPlot.YRange; 00113 XRange = GnuPlot.XRange; 00114 SetGrid = GnuPlot.SetGrid; 00115 SetPause = GnuPlot.SetPause; 00116 SeriesV = GnuPlot.SeriesV; 00117 MoreCmds = GnuPlot.MoreCmds; 00118 } 00119 return *this; 00120 } 00121 00122 TStr TGnuPlot::GetSeriesPlotStr(const int& SeriesId) { 00123 TChA PlotStr; 00124 TGpSeries& Series = SeriesV[SeriesId]; 00125 if (SeriesId != 0) PlotStr += ",\\\n\t"; 00126 if (Series.XCol >= 0) { 00127 PlotStr += "\"" + Series.DataFNm + "\" using " + TInt::GetStr(Series.XCol); 00128 if (Series.YCol != 0) { PlotStr += ":" + TInt::GetStr(Series.YCol); } 00129 if (Series.ZCol != 0) { PlotStr += ":" + TInt::GetStr(Series.ZCol); } 00130 else if (Series.SeriesTy==gpwFilledCurves) { PlotStr += ":(0)"; } // filled curves requres 3rd column 00131 } else { 00132 // function 00133 //IAssertR(Series.DataFNm.SearchCh('=') != -1, TStr::Fmt("Expression %s is not a function", Series.DataFNm.CStr())); 00134 PlotStr += Series.DataFNm; 00135 } 00136 PlotStr += " title \"" + Series.Label + "\""; 00137 // hard coded line style 00138 if (Series.WithStyle.Empty()) { 00139 if (Series.SeriesTy == gpwLines) Series.WithStyle = "lw 1"; 00140 //if (Series.SeriesTy == gpwPoints) Series.WithStyle = "pt 6 ps 1 lw 1"; // circles 00141 //if (Series.SeriesTy == gpwLinesPoints) Series.WithStyle = "pt 6 ps 1 lw 1"; // circles 00142 if (Series.SeriesTy == gpwBoxes) Series.WithStyle = "fill solid 0.3"; 00143 } 00144 PlotStr += " with " + GetSeriesTyStr(Series.SeriesTy) + " " + Series.WithStyle; 00145 return PlotStr; 00146 } 00147 00148 //GP.AddFunc("2*x**-2+4", gpwLines, "2*x^-2+4"); 00149 int TGnuPlot::AddFunc(const TStr& FuncStr, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00150 const int Id = SeriesV.Len(); 00151 TGpSeries Plot; 00152 Plot.SeriesTy = SeriesTy; 00153 Plot.Label = Label; 00154 if (! FuncStr.Empty()) { Plot.DataFNm = TStr::Fmt("f%d(x)=%s, f%d(x)", Id, FuncStr.CStr(), Id); } 00155 else { Plot.DataFNm = TStr::Fmt("f%d(x)", Id); } 00156 Plot.XCol = -1; 00157 Plot.WithStyle = Style; 00158 SeriesV.Add(Plot); 00159 return Id; 00160 } 00161 00162 int TGnuPlot::AddPlot(const TStr& DataFNm, const int& ColY, 00163 const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00164 return AddPlot(DataFNm, 0, ColY, SeriesTy, Label, Style); 00165 } 00166 00167 int TGnuPlot::AddPlot(const TStr& DataFNm, const int& ColX, const int& ColY, 00168 const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00169 IAssert(ColY > 0); IAssert(ColX >= 0); 00170 TGpSeries Plot; 00171 Plot.SeriesTy = SeriesTy; 00172 Plot.Label = Label; 00173 Plot.DataFNm = DataFNm; Plot.DataFNm.ChangeStrAll("\\", "\\\\"); 00174 Plot.XCol = ColX; Plot.YCol = ColY; Plot.ZCol = 0; 00175 Plot.WithStyle = Style; 00176 SeriesV.Add(Plot); 00177 return SeriesV.Len() - 1; 00178 } 00179 00180 int TGnuPlot::AddPlot(const TIntV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00181 TFltKdV XYValV(YValV.Len(), 0); 00182 for (int i = 0; i < YValV.Len(); i++) { 00183 XYValV.Add(TFltKd(TFlt(i+1), TFlt(YValV[i]))); 00184 } 00185 return AddPlot(XYValV, SeriesTy, Label, Style); 00186 } 00187 00188 int TGnuPlot::AddPlot(const TFltV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00189 TFltKdV XYValV(YValV.Len(), 0); 00190 for (int i = 0; i < YValV.Len(); i++) { 00191 XYValV.Add(TFltKd(TFlt(i+1), TFlt(YValV[i]))); 00192 } 00193 return AddPlot(XYValV, SeriesTy, Label, Style); 00194 } 00195 00196 int TGnuPlot::AddPlot(const TFltV& XValV, const TFltV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00197 IAssert(XValV.Len() == YValV.Len()); 00198 TFltKdV XYValV(XValV.Len(), 0); 00199 for (int i = 0; i < YValV.Len(); i++) { 00200 XYValV.Add(TFltKd(TFlt(XValV[i]), TFlt(YValV[i]))); 00201 } 00202 return AddPlot(XYValV, SeriesTy, Label, Style); 00203 } 00204 00205 int TGnuPlot::AddPlot(const TIntPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00206 TFltKdV XYFltValV(XYValV.Len(), 0); 00207 for (int i = 0; i < XYValV.Len(); i++) { 00208 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Val1), TFlt(XYValV[i].Val2))); 00209 } 00210 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00211 } 00212 00213 int TGnuPlot::AddPlot(const TFltPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00214 TFltKdV XYFltValV(XYValV.Len(), 0); 00215 for (int i = 0; i < XYValV.Len(); i++) { 00216 XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); 00217 } 00218 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00219 } 00220 00221 int TGnuPlot::AddPlot(const TIntKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00222 TFltKdV XYFltValV(XYValV.Len(), 0); 00223 for (int i = 0; i < XYValV.Len(); i++) { 00224 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Key), TFlt(XYValV[i].Dat))); 00225 } 00226 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00227 } 00228 00229 int TGnuPlot::AddPlot(const TIntFltKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00230 TFltKdV XYFltValV(XYValV.Len(), 0); 00231 for (int i = 0; i < XYValV.Len(); i++) { 00232 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Key), TFlt(XYValV[i].Dat))); 00233 } 00234 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00235 } 00236 00237 int TGnuPlot::AddPlot(const TIntFltPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00238 TFltKdV XYFltValV(XYValV.Len(), 0); 00239 for (int i = 0; i < XYValV.Len(); i++) { 00240 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Val1), TFlt(XYValV[i].Val2))); 00241 } 00242 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00243 } 00244 00245 int TGnuPlot::AddPlot(const TFltKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00246 if (XYValV.Empty()) { 00247 printf("***AddPlot: empty plot (%s) %s\n", DataFNm.CStr(), Title.CStr()); 00248 return -1; 00249 } 00250 TGpSeries Plot; 00251 Plot.SeriesTy = SeriesTy; 00252 Plot.Label = Label; 00253 Plot.XYValV = XYValV; 00254 Plot.WithStyle = Style; 00255 SeriesV.Add(Plot); 00256 return SeriesV.Len() - 1; 00257 } 00258 00259 int TGnuPlot::AddErrBar(const TFltTrV& XYDValV, const TStr& Label) { 00260 TFltKdV XYFltValV(XYDValV.Len(), 0); 00261 TFltV DeltaV(XYDValV.Len(), 0); 00262 for (int i = 0; i < XYDValV.Len(); i++) { 00263 XYFltValV.Add(TFltKd(XYDValV[i].Val1, XYDValV[i].Val2)); 00264 DeltaV.Add(XYDValV[i].Val3); 00265 } 00266 return AddErrBar(XYFltValV, DeltaV, Label); 00267 } 00268 00269 int TGnuPlot::AddErrBar(const TFltTrV& XYDValV, const TStr& DatLabel, const TStr& ErrLabel) { 00270 TFltKdV XYFltValV(XYDValV.Len(), 0); 00271 TFltV DeltaV(XYDValV.Len(), 0); 00272 for (int i = 0; i < XYDValV.Len(); i++) { 00273 XYFltValV.Add(TFltKd(XYDValV[i].Val1, XYDValV[i].Val2)); 00274 DeltaV.Add(XYDValV[i].Val3); 00275 } 00276 const int PlotId = AddPlot(XYFltValV, gpwLinesPoints, DatLabel); 00277 AddErrBar(XYFltValV, DeltaV, ErrLabel); 00278 return PlotId; 00279 } 00280 00281 int TGnuPlot::AddErrBar(const TFltV& YValV, const TFltV& DeltaYV, const TStr& Label) { 00282 IAssert(YValV.Len() == DeltaYV.Len()); 00283 TFltKdV XYFltValV(YValV.Len(), 0); 00284 for (int i = 0; i < YValV.Len(); i++) { 00285 XYFltValV.Add(TFltKd(TFlt(i+1), YValV[i])); 00286 } 00287 return AddErrBar(XYFltValV, DeltaYV, Label); 00288 } 00289 00290 int TGnuPlot::AddErrBar(const TFltV& XValV, const TFltV& YValV, const TFltV& DeltaYV, const TStr& Label) { 00291 IAssert(XValV.Len() == YValV.Len()); 00292 IAssert(XValV.Len() == DeltaYV.Len()); 00293 TFltKdV XYFltValV(XValV.Len(), 0); 00294 for (int i = 0; i < XValV.Len(); i++) { 00295 XYFltValV.Add(TFltKd(XValV[i], YValV[i])); 00296 } 00297 return AddErrBar(XYFltValV, DeltaYV, Label); 00298 } 00299 00300 int TGnuPlot::AddErrBar(const TFltPrV& XYValV, const TFltV& DeltaYV, const TStr& Label) { 00301 TFltKdV XYFltValV(XYValV.Len(), 0); 00302 for (int i = 0; i < XYValV.Len(); i++) { 00303 XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); 00304 } 00305 return AddErrBar(XYFltValV, DeltaYV, Label); 00306 } 00307 00308 int TGnuPlot::AddErrBar(const TFltPrV& XYValV, const TFltV& DeltaV, const TStr& DatLabel, const TStr& ErrLabel) { 00309 TFltKdV XYFltValV(XYValV.Len(), 0); 00310 for (int i = 0; i < XYValV.Len(); i++) { 00311 XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); 00312 } 00313 const int PlotId = AddPlot(XYFltValV, gpwLinesPoints, DatLabel); 00314 AddErrBar(XYFltValV, DeltaV, ErrLabel); 00315 return PlotId; 00316 } 00317 00318 int TGnuPlot::AddErrBar(const TFltKdV& XYValV, const TFltV& DeltaYV, const TStr& Label) { 00319 if (XYValV.Empty()) { 00320 printf("***AddErrBar: empty plot (%s) %s\n", DataFNm.CStr(), Title.CStr()); 00321 return -1; 00322 } 00323 IAssert(XYValV.Len() == DeltaYV.Len()); 00324 TGpSeries Plot; 00325 Plot.SeriesTy = gpwErrBars; 00326 Plot.Label = Label; 00327 Plot.XYValV = XYValV; 00328 Plot.ZValV = DeltaYV; 00329 SeriesV.Add(Plot); 00330 return SeriesV.Len() - 1; 00331 } 00332 00333 int TGnuPlot::AddLinFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00334 if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1; 00335 const TGpSeries& Plot = SeriesV[PlotId]; 00336 if(Plot.XYValV.Empty()) return -1; 00337 const TFltKdV& XY = Plot.XYValV; 00338 double A, B, R2, SigA, SigB, Chi2; 00339 // linear fit 00340 TFltPrV XYPr; 00341 int s; 00342 for (s = 0; s < XY.Len(); s++) { 00343 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00344 } 00345 TSpecFunc::LinearFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00346 TStr StyleStr=Style; 00347 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00348 const int FitId = AddFunc(TStr::Fmt("%f+%f*x", A, B), 00349 SeriesTy, TStr::Fmt("%.4g + %.4g x R^2:%.2g", A, B, R2), StyleStr); 00350 return FitId; 00351 /*SeriesV.Add(); 00352 TGpSeries& NewPlot = SeriesV.Last(); 00353 TFltKdV& EstXY = NewPlot.XYValV; 00354 for (s = 0; s < XY.Len(); s++) { 00355 EstXY.Add(TFltKd(XY[s].Key, A + B*XYPr[s].Val1)); 00356 } 00357 NewPlot.Label = TStr::Fmt("%.4g + %.4g x R^2:%.2g", A, B, R2); 00358 NewPlot.SeriesTy = SeriesTy; 00359 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00360 else { NewPlot.WithStyle = Style; } 00361 return SeriesV.Len() - 1;*/ 00362 } 00363 00364 int TGnuPlot::AddPwrFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00365 const int PlotId1 = AddPwrFit3(PlotId, SeriesTy); 00366 AddPwrFit2(PlotId, SeriesTy, 5.0); 00367 return PlotId1; 00368 } 00369 00370 // linear fit on log-log scales{% 00371 int TGnuPlot::AddPwrFit1(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00372 if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1; 00373 const TGpSeries& Plot = SeriesV[PlotId]; 00374 if(Plot.XYValV.Empty()) return -1; 00375 const TFltKdV& XY = Plot.XYValV; 00376 double A, B, R2, SigA, SigB, Chi2, MinY = TFlt::Mx, MinX = TFlt::Mx; 00377 // power fit 00378 TFltPrV XYPr; 00379 int s; 00380 for (s = 0; s < XY.Len(); s++) { 00381 if (XY[s].Key > 0) { 00382 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00383 MinX = TMath::Mn(MinX, XY[s].Key()); 00384 MinY = TMath::Mn(MinY, XY[s].Dat()); 00385 } 00386 } 00387 MinY = TMath::Mn(1.0, MinY); 00388 TSpecFunc::PowerFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00389 TStr StyleStr=Style; 00390 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00391 const int FitId = AddFunc(TStr::Fmt("%f*x**%f", A, B), 00392 SeriesTy, TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2), StyleStr); 00393 return FitId; 00394 /*SeriesV.Add(); 00395 TGpSeries& NewPlot = SeriesV.Last(); 00396 const int FitId = SeriesV.Len() - 1; 00397 NewPlot.DataFNm = ; 00398 TFltKdV& EstXY = NewPlot.XYValV; 00399 for (s = 0; s < XYPr.Len(); s++) { 00400 const double YVal = A*pow(XYPr[s].Val1(), B); 00401 if (YVal < MinY) continue; 00402 EstXY.Add(TFltKd(XYPr[s].Val1, YVal)); 00403 } 00404 NewPlot.Label = ; 00405 NewPlot.SeriesTy = SeriesTy; 00406 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00407 else { NewPlot.WithStyle = Style; } 00408 //if (MinX < 5.0) MinX = 5.0; 00409 //AddPwrFit2(PlotId, SeriesTy, MinX);*/ 00410 } 00411 00412 // MLE power-coefficient 00413 int TGnuPlot::AddPwrFit2(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style) { 00414 const TGpSeries& Plot = SeriesV[PlotId]; 00415 if(Plot.XYValV.Empty()) return -1; 00416 const TFltKdV& XY = Plot.XYValV; 00417 // power fit 00418 TFltPrV XYPr; 00419 double MinY = TFlt::Mx; 00420 for (int s = 0; s < XY.Len(); s++) { 00421 if (XY[s].Key > 0.0) { 00422 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00423 MinY = TMath::Mn(MinY, XY[s].Dat()); 00424 } 00425 } 00426 if (XYPr.Empty()) return -1; 00427 MinY = TMath::Mn(1.0, MinY); 00428 // determine the sign of power coefficient 00429 double CoefSign = 0.0; 00430 { double A, B, R2, SigA, SigB, Chi2; 00431 TSpecFunc::PowerFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00432 CoefSign = B > 0.0 ? +1.0 : -1.0; } 00433 const double PowerCf = CoefSign * TSpecFunc::GetPowerCoef(XYPr, MinX); 00434 int Mid = (int) exp(log((double)XYPr.Len())/2.0); 00435 if (Mid >= XYPr.Len()) { Mid = XYPr.Len()-1; } 00436 const double MidX = XYPr[Mid].Val1(); 00437 const double MidY = XYPr[Mid].Val2(); 00438 const double B = MidY / pow(MidX, PowerCf); 00439 TStr StyleStr=Style; 00440 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00441 const int FitId = AddFunc(TStr::Fmt("%f*x**%f", B, PowerCf), 00442 SeriesTy, TStr::Fmt("MLE = x^{%.4g}", PowerCf), StyleStr); 00443 return FitId; 00444 /*SeriesV.Add(); 00445 TGpSeries& NewPlot = SeriesV.Last(); 00446 TFltKdV& XYFit = NewPlot.XYValV; 00447 XYFit.Gen(XYPr.Len(), 0); 00448 for (int s = 0; s < XYPr.Len(); s++) { 00449 const double XVal = XYPr[s].Val1; 00450 const double YVal = B * pow(XYPr[s].Val1(), PowerCf); 00451 if (YVal < MinY || XVal < MinX) continue; 00452 XYFit.Add(TFltKd(XVal, YVal)); 00453 } 00454 NewPlot.Label = TStr::Fmt("PowerFit: %g", PowerCf); 00455 NewPlot.SeriesTy = SeriesTy; 00456 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00457 else { NewPlot.WithStyle = Style; } 00458 return SeriesV.Len() - 1;*/ 00459 } 00460 00461 int TGnuPlot::AddPwrFit3(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style) { 00462 double Intercept, Slope, R2; 00463 return AddPwrFit3(PlotId, SeriesTy, MinX, Style, Intercept, Slope, R2); 00464 } 00465 00466 // some kind of least squares power-law fitting that cutts the tail until the fit is good 00467 int TGnuPlot::AddPwrFit3(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style, double& Intercept, double& Slope, double& R2) { 00468 if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1; 00469 const TGpSeries& Plot = SeriesV[PlotId]; 00470 if(Plot.XYValV.Empty()) return -1; 00471 double A, B, SigA, SigB, Chi2, MinY=TFlt::Mx; 00472 const TFltKdV& XY = Plot.XYValV; 00473 //SeriesV.Add(); 00474 //TGpSeries& NewPlot = SeriesV.Last(); 00475 //TFltKdV& EstXY = NewPlot.XYValV; 00476 TFltPrV FitXY, NewFitXY; 00477 for (int s = 0; s < XY.Len(); s++) { 00478 if (XY[s].Key > 0 && XY[s].Key >= MinX) { 00479 FitXY.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00480 MinY = TMath::Mn(MinY, XY[s].Dat()); 00481 } 00482 } 00483 MinY = TMath::Mn(1.0, MinY); 00484 // power fit (if tail is too fat, cut everything where 00485 // extrapolation sets the value < MinY 00486 while (true) { 00487 TSpecFunc::PowerFit(FitXY, A, B, SigA, SigB, Chi2, R2); 00488 NewFitXY.Clr(false); 00489 //EstXY.Clr(false); 00490 for (int s = 0; s < FitXY.Len(); s++) { 00491 const double YVal = A*pow(FitXY[s].Val1(), B); 00492 if (YVal < MinY) continue; 00493 //EstXY.Add(TFltKd(FitXY[s].Val1, YVal)); 00494 NewFitXY.Add(TFltPr(FitXY[s].Val1, FitXY[s].Val2)); 00495 } 00496 if (NewFitXY.Len() < 10 || FitXY.Last().Val1 < 1.2 * NewFitXY.Last().Val1) { break; } 00497 else { FitXY.Swap(NewFitXY); } 00498 } 00499 TStr StyleStr=Style; 00500 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00501 const int FitId = AddFunc(TStr::Fmt("%f*x**%f", A, B), 00502 SeriesTy, TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2), StyleStr); 00503 return FitId; 00504 /*NewPlot.Label = TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2); 00505 Intercept = A; 00506 Slope = B; 00507 NewPlot.SeriesTy = SeriesTy; 00508 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00509 else { NewPlot.WithStyle = Style; } 00510 return SeriesV.Len() - 1;*/ 00511 } 00512 00513 int TGnuPlot::AddLogFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00514 const TGpSeries& Plot = SeriesV[PlotId]; 00515 if(Plot.XYValV.Empty()) return -1; 00516 const TFltKdV& XY = Plot.XYValV; 00517 double A, B, R2, SigA, SigB, Chi2; 00518 // power fit 00519 TFltPrV XYPr; 00520 int s; 00521 for (s = 0; s < XY.Len(); s++) { 00522 if (XY[s].Key > 0) { 00523 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); } 00524 } 00525 TSpecFunc::LogFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00526 TStr StyleStr=Style; 00527 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00528 const int FitId = AddFunc(TStr::Fmt("%f+%f*log(x)", A, B), 00529 SeriesTy, TStr::Fmt("%.4g + %.4g log(x) R^2:%.2g", A, B, R2), StyleStr); 00530 return FitId; 00531 /*SeriesV.Add(); 00532 TGpSeries& NewPlot = SeriesV.Last(); 00533 TFltKdV& EstXY = NewPlot.XYValV; 00534 for (s = 0; s < XYPr.Len(); s++) { 00535 EstXY.Add(TFltKd(XYPr[s].Val1, A+B*log((double)XYPr[s].Val1))); 00536 } 00537 NewPlot.Label = TStr::Fmt("%.4g + %.4g log(x) R^2:%.2g", A, B, R2); 00538 NewPlot.SeriesTy = SeriesTy; 00539 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00540 else { NewPlot.WithStyle = Style; } 00541 return SeriesV.Len() - 1;*/ 00542 } 00543 00544 int TGnuPlot::AddExpFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& FitXOffset, const TStr& Style) { 00545 const TGpSeries& Plot = SeriesV[PlotId]; 00546 if(Plot.XYValV.Empty()) return -1; 00547 const TFltKdV& XY = Plot.XYValV; 00548 double A, B, R2, SigA, SigB, Chi2; 00549 // power fit 00550 TFltPrV XYPr; 00551 int s; 00552 for (s = 0; s < XY.Len(); s++) { 00553 if (XY[s].Key-FitXOffset > 0) { 00554 XYPr.Add(TFltPr(XY[s].Key-FitXOffset, XY[s].Dat)); } 00555 } 00556 TSpecFunc::ExpFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00557 TStr Label, StyleStr=Style; 00558 if (FitXOffset == 0) { Label = TStr::Fmt("%.4g exp(%.4g x) R^2:%.2g", A, B, R2); } 00559 else { Label = TStr::Fmt("%.4g exp(%.4g x - %g) R^2:%.2g", A, B, FitXOffset, R2); } 00560 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00561 const int FitId = AddFunc(TStr::Fmt("%f*exp(%f*x-%f)", A, B, FitXOffset), 00562 SeriesTy, Label, StyleStr); 00563 return FitId; 00564 /*SeriesV.Add(); 00565 TGpSeries& NewPlot = SeriesV.Last(); 00566 TFltKdV& EstXY = NewPlot.XYValV; 00567 for (s = 0; s < XYPr.Len(); s++) { 00568 EstXY.Add(TFltKd(XYPr[s].Val1+FitXOffset, A*exp(B*XYPr[s].Val1))); 00569 } 00570 NewPlot.SeriesTy = SeriesTy; 00571 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00572 else { NewPlot.WithStyle = Style; } 00573 return SeriesV.Len() - 1;*/ 00574 } 00575 00576 void TGnuPlot::SavePng(const TStr& FNm, const int& SizeX, const int& SizeY, const TStr& Comment, const TStr& Terminal) { 00577 if (Terminal.Empty()) { 00578 //#ifdef GLib_WIN 00579 AddCmd(TStr::Fmt("set terminal png small size %d,%d", SizeX, SizeY)); 00580 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00587 } else { 00588 AddCmd(Terminal); 00589 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00590 } 00591 Pause(false); 00592 CreatePlotFile(Comment.Empty()? Title : Comment); 00593 RunGnuPlot(); 00594 MoreCmds.DelLast(); 00595 MoreCmds.DelLast(); 00596 } 00597 00598 void TGnuPlot::SaveEps(const TStr& FNm, const int& FontSz, const TStr& Comment) { 00599 AddCmd(TStr::Fmt("set terminal postscript enhanced eps %d color", FontSz)); 00600 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00601 Pause(false); 00602 CreatePlotFile(Comment.Empty()? Title : Comment); 00603 RunGnuPlot(); 00604 MoreCmds.DelLast(); 00605 MoreCmds.DelLast(); 00606 } 00607 00608 void TGnuPlot::MakeExpBins(const TFltPrV& XYValV, TFltPrV& ExpXYValV, const double& BinFactor, const double& MinYVal) { 00609 TFltKdV KdV(XYValV.Len(), 0), OutV; 00610 for (int i = 0; i < XYValV.Len(); i++) { 00611 KdV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); } 00612 KdV.Sort(); 00613 TGnuPlot::MakeExpBins(KdV, OutV, BinFactor, MinYVal); 00614 ExpXYValV.Gen(OutV.Len(), 0); 00615 for (int i = 0; i < OutV.Len(); i++) { 00616 ExpXYValV.Add(TFltPr(OutV[i].Key, OutV[i].Dat)); } 00617 } 00618 00619 void TGnuPlot::MakeExpBins(const TFltKdV& XYValV, TFltKdV& ExpXYValV, const double& BinFactor, const double& MinYVal) { 00620 if (XYValV.Empty()) { ExpXYValV.Clr(false); return; } 00621 IAssert(! XYValV.Empty()); 00622 IAssert(XYValV.IsSorted()); 00623 const TFlt MxX = XYValV.Last().Key; 00624 // find buckets 00625 TFltV BucketEndV; BucketEndV.Add(1); 00626 double PrevBPos = 1, BPos = 1; 00627 while (BPos <= MxX) { 00628 PrevBPos = (uint) floor(BPos); 00629 BPos *= BinFactor; 00630 if (floor(BPos) == PrevBPos) { 00631 BPos = PrevBPos + 1; } 00632 BucketEndV.Add(floor(BPos)); 00633 } 00634 //printf("buckets:\n"); for (int i = 0; i < BucketEndV.Len(); i++) { printf("\t%g\n", BucketEndV[i]);} 00635 ExpXYValV.Gen(BucketEndV.Len(), 0); 00636 int CurB = 0; 00637 double AvgPos=0, Cnt=0, AvgVal=0; 00638 for (int v = 0; v < XYValV.Len(); v++) { 00639 if (XYValV[v].Key() == 0.0) { continue; } 00640 AvgPos += XYValV[v].Key ;//* XYValV[v].Dat; // x 00641 AvgVal += XYValV[v].Dat; // y 00642 Cnt++; 00643 if (v+1 == XYValV.Len() || XYValV[v+1].Key > BucketEndV[CurB]) { 00644 if (Cnt != 0) { 00645 //AvgPos /= AvgVal; 00646 //AvgVal /= (BucketEndV[CurB]-BucketEndV[CurB-1]); 00647 AvgPos /= (double) Cnt; 00648 AvgVal /= (double) Cnt; 00649 if (AvgVal < MinYVal) { AvgVal = MinYVal; } 00650 ExpXYValV.Add(TFltKd(AvgPos, AvgVal)); 00651 //printf("b: %6.2f\t%6.2f\n", AvgPos, AvgVal); 00652 AvgPos = 0; AvgVal = 0; Cnt = 0; 00653 } 00654 CurB++; 00655 } 00656 } 00657 } 00658 00659 void TGnuPlot::LoadTs(const TStr& FNm, TStrV& ColNmV, TVec<TFltKdV>& ColV) { 00660 PSs Ss = TSs::LoadTxt(ssfTabSep, FNm); 00661 int row = 0; 00662 ColNmV.Clr(); 00663 while (Ss->At(0, row)[0] == '#') { row++; } 00664 for (int c = 1; c < Ss->GetXLen(row); c+=2) { 00665 ColNmV.Add(Ss->At(c, row)); 00666 } 00667 row++; 00668 ColV.Gen(ColNmV.Len(), ColNmV.Len()); 00669 for (; row < Ss->GetYLen(); row++) { 00670 for (int c = 0; c < Ss->GetXLen(row); c+=2) { 00671 if (Ss->At(c,row).Empty()) break; 00672 ColV[c/2].Add(TFltKd(Ss->At(c,row).GetFlt(), Ss->At(c+1,row).GetFlt())); 00673 } 00674 } 00675 } 00676 00677 TStr TGnuPlot::GetScaleStr(const TGpScaleTy& ScaleTy) { 00678 switch(ScaleTy){ 00679 case gpsNoAuto: return TStr("set noautoscale"); 00680 case gpsAuto: return TStr("set autoscale"); 00681 case gpsLog: return TStr("set logscale"); 00682 case gpsLog2X: return TStr("set logscale x 2"); 00683 case gpsLog2Y: return TStr("set logscale y 2"); 00684 case gpsLog2XY: return TStr("set logscale xy 2"); 00685 case gpsLog10X: return TStr("set logscale x 10"); 00686 case gpsLog10Y: return TStr("set logscale y 10"); 00687 case gpsLog10XY: return TStr("set logscale xy 10"); 00688 default: Fail; 00689 } 00690 return TStr(); 00691 } 00692 00693 TStr TGnuPlot::GetSeriesTyStr(const TGpSeriesTy& SeriesTy) { 00694 switch(SeriesTy) { 00695 case gpwLines: return TStr("lines"); 00696 case gpwPoints: return TStr("points"); 00697 case gpwLinesPoints: return TStr("linespoints"); 00698 case gpwImpulses: return TStr("impulses"); 00699 case gpwDots: return TStr("dots"); 00700 case gpwSteps: return TStr("steps"); 00701 case gpwFSteps: return TStr("fsteps"); 00702 case gpwHiSteps: return TStr("histeps"); 00703 case gpwBoxes: return TStr("boxes"); 00704 case gpwErrBars: return TStr("errorbars"); 00705 case gpwFilledCurves: return TStr("filledcurves"); 00706 default: Fail; 00707 } 00708 return TStr(); 00709 } 00710 00711 void TGnuPlot::SaveTs(const TIntKdV& KdV, const TStr& FNm, const TStr& HeadLn) { 00712 FILE *F = fopen(FNm.CStr(), "wt"); 00713 EAssert(F); 00714 if (! HeadLn.Empty()) fprintf(F, "# %s\n", HeadLn.CStr()); 00715 for (int i = 0; i < KdV.Len(); i++) { 00716 fprintf(F, "%d\t%d\n", KdV[i].Key(), KdV[i].Dat()); } 00717 fclose(F); 00718 } 00719 00720 00721 void TGnuPlot::SaveTs(const TIntFltKdV& KdV, const TStr& FNm, const TStr& HeadLn) { 00722 FILE *F = fopen(FNm.CStr(), "wt"); 00723 EAssert(F); 00724 if (! HeadLn.Empty()) fprintf(F, "# %s\n", HeadLn.CStr()); 00725 for (int i = 0; i < KdV.Len(); i++) 00726 fprintf(F, "%d\t%g\n", KdV[i].Key(), KdV[i].Dat()); 00727 fclose(F); 00728 } 00729 00730 void TGnuPlot::Test() { 00731 TFltV DeltaY; 00732 TFltPrV ValV1, ValV2, ValV3; 00733 for (int i = 1; i < 30; i++) { 00734 ValV1.Add(TFltPr(i, pow(double(i), 1.2))); 00735 DeltaY.Add(5*TInt::Rnd.GetUniDev()); 00736 ValV2.Add(TFltPr(i, 5*i-1)); 00737 } 00738 for (int i = -10; i < 20; i++) { 00739 ValV3.Add(TFltPr(i, 2*i + 2 + TInt::Rnd.GetUniDev())); 00740 } 00741 TGnuPlot GnuPlot("testDat", "TestPlot", true); 00742 GnuPlot.SetXYLabel("X", "Y"); 00743 const int id2 = GnuPlot.AddPlot(ValV2, gpwPoints, "y=5*x-1"); 00744 const int id3 = GnuPlot.AddPlot(ValV3, gpwPoints, "y=2*x+2"); 00745 GnuPlot.AddErrBar(ValV1, DeltaY, "y=x^2", "Error bar"); 00746 GnuPlot.AddLinFit(id2, gpwLines); 00747 GnuPlot.AddLinFit(id3, gpwLines); 00748 GnuPlot.Plot(); 00749 GnuPlot.SavePng("testPlot.png"); 00750 } 00751 00752 int TGnuPlot::IsSameXCol(const int& CurId, const int& PrevId) const { 00753 //if (SerId < 1) { return -1; } 00754 if (SeriesV[CurId].XYValV.Len() != SeriesV[PrevId].XYValV.Len()) { return -1; } 00755 for (int x = 0; x < SeriesV[CurId].XYValV.Len(); x++) { 00756 if (SeriesV[CurId].XYValV[x] != SeriesV[PrevId].XYValV[x]) { return -1; } 00757 } 00758 IAssert(SeriesV[PrevId].XCol > 0); 00759 return SeriesV[PrevId].XCol; 00760 } 00761 00762 void TGnuPlot::CreatePlotFile(const TStr& Comment) { 00763 time_t ltime; time(<ime); 00764 char* TimeStr = ctime(<ime); TimeStr[strlen(TimeStr) - 1] = 0; 00765 // rearrange columns so that longest are on the left 00766 //SeriesV.Sort(false); 00767 TIntV SerIdV(SeriesV.Len(), 0); 00768 for (int i = 0; i < SeriesV.Len(); i++) { SerIdV.Add(i); } 00769 SerIdV.SortCmp(TGpSeriesCmp(SeriesV)); 00770 // set columns 00771 int ColCnt = 1; 00772 bool SaveData = false; 00773 for (int s = 0; s < SeriesV.Len(); s++) { 00774 TGpSeries& Plt = SeriesV[SerIdV[s]]; 00775 if (Plt.XYValV.Empty()) { continue; } 00776 Plt.DataFNm = DataFNm; 00777 // plots use same X column 00778 const int PrevCol = s > 0 ? IsSameXCol(SerIdV[s], SerIdV[s-1]) : -1; 00779 if (PrevCol != -1) { Plt.XCol = PrevCol; } 00780 else { Plt.XCol = ColCnt; ColCnt++; } 00781 Plt.YCol = ColCnt; ColCnt++; 00782 if (! Plt.ZValV.Empty()) { Plt.ZCol = ColCnt; ColCnt++; } 00783 if (! Plt.XYValV.Empty()) { SaveData=true; } 00784 } 00785 // save data file (skip duplicate X columns) 00786 if (SaveData) { 00787 FILE *F = fopen(DataFNm.CStr(), "wt"); 00788 EAssertR(F != NULL, TStr("Can not open data file ")+DataFNm); 00789 fprintf(F, "#\n"); 00790 fprintf(F, "# %s (%s)\n", Comment.CStr(), TimeStr); 00791 fprintf(F, "#\n"); 00792 // column names 00793 for (int i = 0; i < SerIdV.Len(); i++) { 00794 const TGpSeries& Ser = SeriesV[SerIdV[i]]; 00795 if (Ser.XYValV.Empty()) { continue; } 00796 if (i == 0) { fprintf(F, "# "); } else { fprintf(F, "\t"); } 00797 if (Ser.SaveXVals()) { 00798 if (! LblX.Empty()) { fprintf(F, "%s\t", LblX.CStr()); } 00799 else { fprintf(F, "XVals\t"); } 00800 } 00801 if (Ser.Label.Empty()) { fprintf(F, "%s", LblY.CStr()); } 00802 else { fprintf(F, "%s", SeriesV[SerIdV[i]].Label.CStr()); } 00803 if (Ser.ZCol > 0) fprintf(F, "\tDeltaY"); 00804 } 00805 fprintf(F, "\n"); 00806 // data 00807 for (int row = 0; row < SeriesV[SerIdV[0]].XYValV.Len(); row++) { 00808 for (int i = 0; i < SeriesV.Len(); i++) { 00809 const TGpSeries& Ser = SeriesV[SerIdV[i]]; 00810 if (row < Ser.XYValV.Len()) { 00811 if (i > 0) { fprintf(F, "\t"); } 00812 if (Ser.SaveXVals()) { fprintf(F, "%g\t%g", Ser.XYValV[row].Key(), Ser.XYValV[row].Dat()); } 00813 else { fprintf(F, "%g", Ser.XYValV[row].Dat()); } 00814 if (! Ser.ZValV.Empty()) { fprintf(F, "\t%g", Ser.ZValV[row]()); } 00815 } 00816 } 00817 fprintf(F, "\n"); 00818 } 00819 fclose(F); 00820 } 00821 // save plot file 00822 FILE *F = fopen(PlotFNm.CStr(), "wt"); 00823 EAssertR(F != 0, TStr("Can not open plot file ")+PlotFNm); 00824 TStr CurDir = TDir::GetCurDir(); 00825 CurDir.ChangeStrAll("\\", "\\\\"); 00826 fprintf(F, "#\n"); 00827 fprintf(F, "# %s (%s)\n", Comment.CStr(), TimeStr); 00828 fprintf(F, "#\n\n"); 00829 if (! Title.Empty()) fprintf(F, "set title \"%s\"\n", Title.CStr()); 00830 fprintf(F, "set key bottom right\n"); 00831 fprintf(F, "%s\n", GetScaleStr(ScaleTy).CStr()); 00832 if (ScaleTy==gpsLog || ScaleTy==gpsLog10X || ScaleTy==gpsLog10XY) { 00833 fprintf(F, "set format x \"10^{%%L}\"\n"); 00834 fprintf(F, "set mxtics 10\n"); } 00835 if (ScaleTy==gpsLog || ScaleTy==gpsLog10Y || ScaleTy==gpsLog10XY) { 00836 fprintf(F, "set format y \"10^{%%L}\"\n"); 00837 fprintf(F, "set mytics 10\n"); } 00838 if (ScaleTy==gpsLog2X || ScaleTy==gpsLog2XY) { fprintf(F, "set format x \"2^{%%L}\"\n"); } 00839 if (ScaleTy==gpsLog2Y || ScaleTy==gpsLog2XY) { fprintf(F, "set format y \"2^{%%L}\"\n"); } 00840 if (SetGrid) fprintf(F, "set grid\n"); 00841 if (XRange.Val1 != XRange.Val2) fprintf(F, "set xrange [%g:%g]\n", XRange.Val1(), XRange.Val2()); 00842 if (YRange.Val1 != YRange.Val2) fprintf(F, "set yrange [%g:%g]\n", YRange.Val1(), YRange.Val2()); 00843 if (! LblX.Empty()) fprintf(F, "set xlabel \"%s\"\n", LblX.CStr()); 00844 if (! LblY.Empty()) fprintf(F, "set ylabel \"%s\"\n", LblY.CStr()); 00845 if (Tics42) { 00846 fprintf(F, "set tics scale 2\n"); // New in version 4.2 00847 } else { 00848 fprintf(F, "set ticscale 2 1\n"); // Old (deprecated) 00849 } 00850 // custom commands 00851 for (int i = 0; i < MoreCmds.Len(); i++) { 00852 fprintf(F, "%s\n", MoreCmds[i].CStr()); } 00853 // plot 00854 if (! SeriesV.Empty()) { 00855 fprintf(F, "plot \t"); 00856 for (int i = 0; i < SeriesV.Len(); i++) { 00857 fprintf(F, "%s", GetSeriesPlotStr(i).CStr()); } 00858 fprintf(F, "\n"); 00859 } 00860 if (SetPause) fprintf(F, "pause -1 \"Hit return to exit. %s\"\n", PlotFNm.CStr()); 00861 fclose(F); 00862 } 00863 00864 void TGnuPlot::RunGnuPlot() const { 00865 TStr GpFNm, GpPath; 00866 #if defined(GLib_WIN) 00867 GpFNm = "wgnuplot.exe"; 00868 GpPath = "C:\\gnuplot\\"; 00869 #elif defined(GLib_CYGWIN) 00870 GpFNm = "gnuplot.exe"; 00871 GpPath = "/usr/bin/"; 00872 #else 00873 GpFNm = "gnuplot"; 00874 GpPath = "/usr/bin/"; 00875 #endif 00876 if (system(TStr::Fmt("%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00877 #if defined(GLib_WIN) 00878 if (system(TStr::Fmt(".\\%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00879 #else 00880 if (system(TStr::Fmt("./%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00881 #endif 00882 if (system(TStr::Fmt("%s%s %s", GpPath.CStr(), GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00883 //FailR(TStr::Fmt("Cat not find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr()); 00884 //ErrNotify(TStr::Fmt("Cat not find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr()); 00885 fprintf(stderr, "[%s:%d] Cat not find GnuPlot (%s) for plot %s. Set the PATH.\n", __FILE__, __LINE__, GpFNm.CStr(), PlotFNm.CStr()); 00886 }