SNAP Library 2.0, Developer Reference
2013-05-13 16:33:57
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 #ifndef GLib_MACOSX // The standard GNUPlot for MacOS does not support PNG 00580 AddCmd(TStr::Fmt("set terminal png small size %d,%d", SizeX, SizeY)); 00581 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00582 #else // EPS 00583 AddCmd("set terminal postscript eps 10 enhanced color"); 00584 AddCmd(TStr::Fmt("set output '%s.eps'", FNm.GetFMid().CStr())); 00585 #endif 00586 } else { 00587 AddCmd(Terminal); 00588 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00589 } 00590 Pause(false); 00591 CreatePlotFile(Comment.Empty()? Title : Comment); 00592 RunGnuPlot(); 00593 MoreCmds.DelLast(); 00594 MoreCmds.DelLast(); 00595 } 00596 00597 void TGnuPlot::SaveEps(const TStr& FNm, const int& FontSz, const TStr& Comment) { 00598 AddCmd(TStr::Fmt("set terminal postscript enhanced eps %d color", FontSz)); 00599 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00600 Pause(false); 00601 CreatePlotFile(Comment.Empty()? Title : Comment); 00602 RunGnuPlot(); 00603 MoreCmds.DelLast(); 00604 MoreCmds.DelLast(); 00605 } 00606 00607 void TGnuPlot::MakeExpBins(const TFltPrV& XYValV, TFltPrV& ExpXYValV, const double& BinFactor, const double& MinYVal) { 00608 TFltKdV KdV(XYValV.Len(), 0), OutV; 00609 for (int i = 0; i < XYValV.Len(); i++) { 00610 KdV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); } 00611 KdV.Sort(); 00612 TGnuPlot::MakeExpBins(KdV, OutV, BinFactor, MinYVal); 00613 ExpXYValV.Gen(OutV.Len(), 0); 00614 for (int i = 0; i < OutV.Len(); i++) { 00615 ExpXYValV.Add(TFltPr(OutV[i].Key, OutV[i].Dat)); } 00616 } 00617 00618 void TGnuPlot::MakeExpBins(const TFltKdV& XYValV, TFltKdV& ExpXYValV, const double& BinFactor, const double& MinYVal) { 00619 if (XYValV.Empty()) { ExpXYValV.Clr(false); return; } 00620 IAssert(! XYValV.Empty()); 00621 IAssert(XYValV.IsSorted()); 00622 const TFlt MxX = XYValV.Last().Key; 00623 // find buckets 00624 TFltV BucketEndV; BucketEndV.Add(1); 00625 double PrevBPos = 1, BPos = 1; 00626 while (BPos <= MxX) { 00627 PrevBPos = (uint) floor(BPos); 00628 BPos *= BinFactor; 00629 if (floor(BPos) == PrevBPos) { 00630 BPos = PrevBPos + 1; } 00631 BucketEndV.Add(floor(BPos)); 00632 } 00633 //printf("buckets:\n"); for (int i = 0; i < BucketEndV.Len(); i++) { printf("\t%g\n", BucketEndV[i]);} 00634 ExpXYValV.Gen(BucketEndV.Len(), 0); 00635 int CurB = 0; 00636 double AvgPos=0, Cnt=0, AvgVal=0; 00637 for (int v = 0; v < XYValV.Len(); v++) { 00638 if (XYValV[v].Key() == 0.0) { continue; } 00639 AvgPos += XYValV[v].Key ;//* XYValV[v].Dat; // x 00640 AvgVal += XYValV[v].Dat; // y 00641 Cnt++; 00642 if (v+1 == XYValV.Len() || XYValV[v+1].Key > BucketEndV[CurB]) { 00643 if (Cnt != 0) { 00644 //AvgPos /= AvgVal; 00645 //AvgVal /= (BucketEndV[CurB]-BucketEndV[CurB-1]); 00646 AvgPos /= (double) Cnt; 00647 AvgVal /= (double) Cnt; 00648 if (AvgVal < MinYVal) { AvgVal = MinYVal; } 00649 ExpXYValV.Add(TFltKd(AvgPos, AvgVal)); 00650 //printf("b: %6.2f\t%6.2f\n", AvgPos, AvgVal); 00651 AvgPos = 0; AvgVal = 0; Cnt = 0; 00652 } 00653 CurB++; 00654 } 00655 } 00656 } 00657 00658 void TGnuPlot::LoadTs(const TStr& FNm, TStrV& ColNmV, TVec<TFltKdV>& ColV) { 00659 PSs Ss = TSs::LoadTxt(ssfTabSep, FNm); 00660 int row = 0; 00661 ColNmV.Clr(); 00662 while (Ss->At(0, row)[0] == '#') { row++; } 00663 for (int c = 1; c < Ss->GetXLen(row); c+=2) { 00664 ColNmV.Add(Ss->At(c, row)); 00665 } 00666 row++; 00667 ColV.Gen(ColNmV.Len(), ColNmV.Len()); 00668 for (; row < Ss->GetYLen(); row++) { 00669 for (int c = 0; c < Ss->GetXLen(row); c+=2) { 00670 if (Ss->At(c,row).Empty()) break; 00671 ColV[c/2].Add(TFltKd(Ss->At(c,row).GetFlt(), Ss->At(c+1,row).GetFlt())); 00672 } 00673 } 00674 } 00675 00676 TStr TGnuPlot::GetScaleStr(const TGpScaleTy& ScaleTy) { 00677 switch(ScaleTy){ 00678 case gpsNoAuto: return TStr("set noautoscale"); 00679 case gpsAuto: return TStr("set autoscale"); 00680 case gpsLog: return TStr("set logscale"); 00681 case gpsLog2X: return TStr("set logscale x 2"); 00682 case gpsLog2Y: return TStr("set logscale y 2"); 00683 case gpsLog2XY: return TStr("set logscale xy 2"); 00684 case gpsLog10X: return TStr("set logscale x 10"); 00685 case gpsLog10Y: return TStr("set logscale y 10"); 00686 case gpsLog10XY: return TStr("set logscale xy 10"); 00687 default: Fail; 00688 } 00689 return TStr(); 00690 } 00691 00692 TStr TGnuPlot::GetSeriesTyStr(const TGpSeriesTy& SeriesTy) { 00693 switch(SeriesTy) { 00694 case gpwLines: return TStr("lines"); 00695 case gpwPoints: return TStr("points"); 00696 case gpwLinesPoints: return TStr("linespoints"); 00697 case gpwImpulses: return TStr("impulses"); 00698 case gpwDots: return TStr("dots"); 00699 case gpwSteps: return TStr("steps"); 00700 case gpwFSteps: return TStr("fsteps"); 00701 case gpwHiSteps: return TStr("histeps"); 00702 case gpwBoxes: return TStr("boxes"); 00703 case gpwErrBars: return TStr("errorbars"); 00704 case gpwFilledCurves: return TStr("filledcurves"); 00705 default: Fail; 00706 } 00707 return TStr(); 00708 } 00709 00710 void TGnuPlot::SaveTs(const TIntKdV& KdV, const TStr& FNm, const TStr& HeadLn) { 00711 FILE *F = fopen(FNm.CStr(), "wt"); 00712 EAssert(F); 00713 if (! HeadLn.Empty()) fprintf(F, "# %s\n", HeadLn.CStr()); 00714 for (int i = 0; i < KdV.Len(); i++) { 00715 fprintf(F, "%d\t%d\n", KdV[i].Key(), KdV[i].Dat()); } 00716 fclose(F); 00717 } 00718 00719 00720 void TGnuPlot::SaveTs(const TIntFltKdV& KdV, const TStr& FNm, const TStr& HeadLn) { 00721 FILE *F = fopen(FNm.CStr(), "wt"); 00722 EAssert(F); 00723 if (! HeadLn.Empty()) fprintf(F, "# %s\n", HeadLn.CStr()); 00724 for (int i = 0; i < KdV.Len(); i++) 00725 fprintf(F, "%d\t%g\n", KdV[i].Key(), KdV[i].Dat()); 00726 fclose(F); 00727 } 00728 00729 void TGnuPlot::Test() { 00730 TFltV DeltaY; 00731 TFltPrV ValV1, ValV2, ValV3; 00732 for (int i = 1; i < 30; i++) { 00733 ValV1.Add(TFltPr(i, pow(double(i), 1.2))); 00734 DeltaY.Add(5*TInt::Rnd.GetUniDev()); 00735 ValV2.Add(TFltPr(i, 5*i-1)); 00736 } 00737 for (int i = -10; i < 20; i++) { 00738 ValV3.Add(TFltPr(i, 2*i + 2 + TInt::Rnd.GetUniDev())); 00739 } 00740 TGnuPlot GnuPlot("testDat", "TestPlot", true); 00741 GnuPlot.SetXYLabel("X", "Y"); 00742 const int id2 = GnuPlot.AddPlot(ValV2, gpwPoints, "y=5*x-1"); 00743 const int id3 = GnuPlot.AddPlot(ValV3, gpwPoints, "y=2*x+2"); 00744 GnuPlot.AddErrBar(ValV1, DeltaY, "y=x^2", "Error bar"); 00745 GnuPlot.AddLinFit(id2, gpwLines); 00746 GnuPlot.AddLinFit(id3, gpwLines); 00747 GnuPlot.Plot(); 00748 GnuPlot.SavePng("testPlot.png"); 00749 } 00750 00751 int TGnuPlot::IsSameXCol(const int& CurId, const int& PrevId) const { 00752 //if (SerId < 1) { return -1; } 00753 if (SeriesV[CurId].XYValV.Len() != SeriesV[PrevId].XYValV.Len()) { return -1; } 00754 for (int x = 0; x < SeriesV[CurId].XYValV.Len(); x++) { 00755 if (SeriesV[CurId].XYValV[x] != SeriesV[PrevId].XYValV[x]) { return -1; } 00756 } 00757 IAssert(SeriesV[PrevId].XCol > 0); 00758 return SeriesV[PrevId].XCol; 00759 } 00760 00761 void TGnuPlot::CreatePlotFile(const TStr& Comment) { 00762 time_t ltime; time(<ime); 00763 char* TimeStr = ctime(<ime); TimeStr[strlen(TimeStr) - 1] = 0; 00764 // rearrange columns so that longest are on the left 00765 //SeriesV.Sort(false); 00766 TIntV SerIdV(SeriesV.Len(), 0); 00767 for (int i = 0; i < SeriesV.Len(); i++) { SerIdV.Add(i); } 00768 SerIdV.SortCmp(TGpSeriesCmp(SeriesV)); 00769 // set columns 00770 int ColCnt = 1; 00771 bool SaveData = false; 00772 for (int s = 0; s < SeriesV.Len(); s++) { 00773 TGpSeries& Plt = SeriesV[SerIdV[s]]; 00774 if (Plt.XYValV.Empty()) { continue; } 00775 Plt.DataFNm = DataFNm; 00776 // plots use same X column 00777 const int PrevCol = s > 0 ? IsSameXCol(SerIdV[s], SerIdV[s-1]) : -1; 00778 if (PrevCol != -1) { Plt.XCol = PrevCol; } 00779 else { Plt.XCol = ColCnt; ColCnt++; } 00780 Plt.YCol = ColCnt; ColCnt++; 00781 if (! Plt.ZValV.Empty()) { Plt.ZCol = ColCnt; ColCnt++; } 00782 if (! Plt.XYValV.Empty()) { SaveData=true; } 00783 } 00784 // save data file (skip duplicate X columns) 00785 if (SaveData) { 00786 FILE *F = fopen(DataFNm.CStr(), "wt"); 00787 EAssertR(F != NULL, TStr("Can not open data file ")+DataFNm); 00788 fprintf(F, "#\n"); 00789 fprintf(F, "# %s (%s)\n", Comment.CStr(), TimeStr); 00790 fprintf(F, "#\n"); 00791 // column names 00792 for (int i = 0; i < SerIdV.Len(); i++) { 00793 const TGpSeries& Ser = SeriesV[SerIdV[i]]; 00794 if (Ser.XYValV.Empty()) { continue; } 00795 if (i == 0) { fprintf(F, "# "); } else { fprintf(F, "\t"); } 00796 if (Ser.SaveXVals()) { 00797 if (! LblX.Empty()) { fprintf(F, "%s\t", LblX.CStr()); } 00798 else { fprintf(F, "XVals\t"); } 00799 } 00800 if (Ser.Label.Empty()) { fprintf(F, "%s", LblY.CStr()); } 00801 else { fprintf(F, "%s", SeriesV[SerIdV[i]].Label.CStr()); } 00802 if (Ser.ZCol > 0) fprintf(F, "\tDeltaY"); 00803 } 00804 fprintf(F, "\n"); 00805 // data 00806 for (int row = 0; row < SeriesV[SerIdV[0]].XYValV.Len(); row++) { 00807 for (int i = 0; i < SeriesV.Len(); i++) { 00808 const TGpSeries& Ser = SeriesV[SerIdV[i]]; 00809 if (row < Ser.XYValV.Len()) { 00810 if (i > 0) { fprintf(F, "\t"); } 00811 if (Ser.SaveXVals()) { fprintf(F, "%g\t%g", Ser.XYValV[row].Key(), Ser.XYValV[row].Dat()); } 00812 else { fprintf(F, "%g", Ser.XYValV[row].Dat()); } 00813 if (! Ser.ZValV.Empty()) { fprintf(F, "\t%g", Ser.ZValV[row]()); } 00814 } 00815 } 00816 fprintf(F, "\n"); 00817 } 00818 fclose(F); 00819 } 00820 // save plot file 00821 FILE *F = fopen(PlotFNm.CStr(), "wt"); 00822 EAssertR(F != 0, TStr("Can not open plot file ")+PlotFNm); 00823 TStr CurDir = TDir::GetCurDir(); 00824 CurDir.ChangeStrAll("\\", "\\\\"); 00825 fprintf(F, "#\n"); 00826 fprintf(F, "# %s (%s)\n", Comment.CStr(), TimeStr); 00827 fprintf(F, "#\n\n"); 00828 if (! Title.Empty()) fprintf(F, "set title \"%s\"\n", Title.CStr()); 00829 fprintf(F, "set key bottom right\n"); 00830 fprintf(F, "%s\n", GetScaleStr(ScaleTy).CStr()); 00831 if (ScaleTy==gpsLog || ScaleTy==gpsLog10X || ScaleTy==gpsLog10XY) { 00832 fprintf(F, "set format x \"10^{%%L}\"\n"); 00833 fprintf(F, "set mxtics 10\n"); } 00834 if (ScaleTy==gpsLog || ScaleTy==gpsLog10Y || ScaleTy==gpsLog10XY) { 00835 fprintf(F, "set format y \"10^{%%L}\"\n"); 00836 fprintf(F, "set mytics 10\n"); } 00837 if (ScaleTy==gpsLog2X || ScaleTy==gpsLog2XY) { fprintf(F, "set format x \"2^{%%L}\"\n"); } 00838 if (ScaleTy==gpsLog2Y || ScaleTy==gpsLog2XY) { fprintf(F, "set format y \"2^{%%L}\"\n"); } 00839 if (SetGrid) fprintf(F, "set grid\n"); 00840 if (XRange.Val1 != XRange.Val2) fprintf(F, "set xrange [%g:%g]\n", XRange.Val1(), XRange.Val2()); 00841 if (YRange.Val1 != YRange.Val2) fprintf(F, "set yrange [%g:%g]\n", YRange.Val1(), YRange.Val2()); 00842 if (! LblX.Empty()) fprintf(F, "set xlabel \"%s\"\n", LblX.CStr()); 00843 if (! LblY.Empty()) fprintf(F, "set ylabel \"%s\"\n", LblY.CStr()); 00844 if (Tics42) { 00845 fprintf(F, "set tics scale 2\n"); // New in version 4.2 00846 } else { 00847 fprintf(F, "set ticscale 2 1\n"); // Old (deprecated) 00848 } 00849 // custom commands 00850 for (int i = 0; i < MoreCmds.Len(); i++) { 00851 fprintf(F, "%s\n", MoreCmds[i].CStr()); } 00852 // plot 00853 if (! SeriesV.Empty()) { 00854 fprintf(F, "plot \t"); 00855 for (int i = 0; i < SeriesV.Len(); i++) { 00856 fprintf(F, "%s", GetSeriesPlotStr(i).CStr()); } 00857 fprintf(F, "\n"); 00858 } 00859 if (SetPause) fprintf(F, "pause -1 \"Hit return to exit. %s\"\n", PlotFNm.CStr()); 00860 fclose(F); 00861 } 00862 00863 void TGnuPlot::RunGnuPlot() const { 00864 TStr GpFNm, GpPath; 00865 #if defined(GLib_WIN) 00866 GpFNm = "wgnuplot.exe"; 00867 GpPath = "C:\\gnuplot\\"; 00868 #elif defined(GLib_CYGWIN) 00869 GpFNm = "gnuplot.exe"; 00870 GpPath = "/usr/bin/"; 00871 #else 00872 GpFNm = "gnuplot"; 00873 GpPath = "/usr/bin/"; 00874 #endif 00875 if (system(TStr::Fmt("%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00876 #if defined(GLib_WIN) 00877 if (system(TStr::Fmt(".\\%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00878 #else 00879 if (system(TStr::Fmt("./%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00880 #endif 00881 if (system(TStr::Fmt("%s%s %s", GpPath.CStr(), GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00882 //FailR(TStr::Fmt("Cat not find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr()); 00883 //ErrNotify(TStr::Fmt("Cat not find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr()); 00884 fprintf(stderr, "[%s:%d] Cat not find GnuPlot (%s) for plot %s. Set the PATH.\n", __FILE__, __LINE__, GpFNm.CStr(), PlotFNm.CStr()); 00885 }