SNAP Library 2.1, Developer Reference
2013-09-25 10:47:25
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 00007 // Set path to gnuplot 00008 #if defined(GLib_WIN) 00009 TStr TGnuPlot::GnuPlotPath = "C:\\gnuplot"; 00010 TStr TGnuPlot::GnuPlotFNm = "wgnuplot.exe"; 00011 #elif defined(GLib_CYGWIN) 00012 TStr TGnuPlot::GnuPlotPath = "/usr/bin"; 00013 TStr TGnuPlot::GnuPlotFNm = "gnuplot.exe"; 00014 #elif defined(GLib_MACOSX) 00015 TStr TGnuPlot::GnuPlotPath = "/opt/local/bin"; 00016 TStr TGnuPlot::GnuPlotFNm = "gnuplot"; 00017 #else 00018 TStr TGnuPlot::GnuPlotPath = "/usr/bin"; 00019 TStr TGnuPlot::GnuPlotFNm = "gnuplot"; 00020 #endif 00021 00022 // Determines the gnuplot version and the tics command syntax. 00023 // Gnuplot changed the syntax with version 4.2: 00024 // - before 4.2: set ticscale 2 1 00025 // - 4.2 and later: set tics 2 00026 int TGnuPlot::GetTics42() { 00027 #ifdef GLib_WIN 00028 return -1; 00029 #else 00030 FILE* p; 00031 char Buf[1024]; 00032 char Version[1024]; 00033 size_t n; 00034 // get gnuplot version 00035 p = popen(TStr::Fmt("%s -V", TGnuPlot::GnuPlotFNm.CStr()).CStr(), "r"); 00036 if (p == NULL) { // try running using the path 00037 p = popen(TStr::Fmt("%s/%s -V", TGnuPlot::GnuPlotPath.CStr(), TGnuPlot::GnuPlotFNm.CStr()).CStr(), "r"); 00038 if (p == NULL) { return -1; } 00039 } 00040 n = fread(Buf, 1, 100, p); 00041 if (n <= 0) { return -1; } 00042 Buf[n] = '\0'; 00043 pclose(p); 00044 //printf("Buf %d .%s.\n", n, Buf); 00045 n = sscanf(Buf, "gnuplot %s", Version); 00046 if (n <= 0) { return -1; } 00047 // printf("Version %d .%s.\n", n, Version); 00048 if ((strlen(Version) < 3) || (Version[1] != '.')) { return -1; } 00049 // test version < 4.2 00050 if ((Version[0] < '4') || ((Version[0] == '4') && (Version[2] < '2'))) { 00051 // printf("TGnuPlot::GetTics42 0\n"); 00052 return 0; 00053 } 00054 // printf("TGnuPlot::GetTics42 1\n"); 00055 return 1; 00056 #endif 00057 } 00058 00059 int TGnuPlot::Tics42 = TGnuPlot::GetTics42(); 00060 TStr TGnuPlot::DefPlotFNm = "GnuPlot.plt"; 00061 TStr TGnuPlot::DefDataFNm = "GnuPlot.tab"; 00062 00063 TGnuPlot::TGpSeries::TGpSeries(const TGnuPlot::TGpSeries& Gps) : 00064 SeriesTy(Gps.SeriesTy), XYValV(Gps.XYValV), ZValV(Gps.ZValV), 00065 Label(Gps.Label), WithStyle(Gps.WithStyle), DataFNm(Gps.DataFNm), 00066 XCol(Gps.XCol), YCol(Gps.YCol), ZCol(Gps.ZCol) { 00067 } 00068 00069 TGnuPlot::TGpSeries& TGnuPlot::TGpSeries::operator = (const TGnuPlot::TGpSeries& Gps) { 00070 if(this != &Gps) { 00071 SeriesTy = Gps.SeriesTy; 00072 XYValV = Gps.XYValV; ZValV = Gps.ZValV; 00073 Label = Gps.Label; 00074 DataFNm = Gps.DataFNm; 00075 WithStyle = Gps.WithStyle; 00076 XCol = Gps.XCol; YCol = Gps.YCol; ZCol = Gps.ZCol; 00077 } 00078 return *this; 00079 } 00080 00081 bool TGnuPlot::TGpSeries::operator < (const TGpSeries& Gps) const { 00082 return (XYValV < Gps.XYValV) || ((XYValV == Gps.XYValV) && (Label < Gps.Label)); 00083 } 00084 00085 TGnuPlot::TGnuPlot(const TStr& FileNm, const TStr& PlotTitle, const bool& Grid) : 00086 DataFNm(FileNm+".tab"), PlotFNm(FileNm+".plt"), Title(PlotTitle), LblX(), LblY(), ScaleTy(gpsAuto), 00087 YRange(0, 0), XRange(0, 0), SetGrid(Grid), SetPause(true), 00088 SeriesV(), MoreCmds() { 00089 IAssert(! FileNm.Empty()); 00090 } 00091 00092 TGnuPlot::TGnuPlot(const TStr& DataFileNm, const TStr& PlotFileNm, const TStr& PlotTitle, const bool& Grid) : 00093 DataFNm(DataFileNm.Empty() ? DefDataFNm : DataFileNm), 00094 PlotFNm(PlotFileNm.Empty() ? DefPlotFNm : PlotFileNm), 00095 Title(PlotTitle), LblX(), LblY(), ScaleTy(gpsAuto), 00096 YRange(0, 0), XRange(0, 0), SetGrid(Grid), SetPause(true), SeriesV(), MoreCmds() { 00097 } 00098 00099 TGnuPlot::TGnuPlot(const TGnuPlot& GnuPlot) : DataFNm(GnuPlot.DataFNm), PlotFNm(GnuPlot.PlotFNm), 00100 Title(GnuPlot.Title), LblX(GnuPlot.LblX), LblY(GnuPlot.LblY), ScaleTy(GnuPlot.ScaleTy), YRange(GnuPlot.YRange), 00101 XRange(GnuPlot.XRange), SetGrid(GnuPlot.SetGrid), SetPause(GnuPlot.SetPause), SeriesV(GnuPlot.SeriesV), 00102 MoreCmds(GnuPlot.MoreCmds) { 00103 } 00104 00105 TGnuPlot& TGnuPlot::operator = (const TGnuPlot& GnuPlot) { 00106 if (this != &GnuPlot) { 00107 DataFNm = GnuPlot.DataFNm; 00108 PlotFNm = GnuPlot.PlotFNm; 00109 Title = GnuPlot.Title; 00110 LblX = GnuPlot.LblX; 00111 LblY = GnuPlot.LblY; 00112 ScaleTy = GnuPlot.ScaleTy; 00113 YRange = GnuPlot.YRange; 00114 XRange = GnuPlot.XRange; 00115 SetGrid = GnuPlot.SetGrid; 00116 SetPause = GnuPlot.SetPause; 00117 SeriesV = GnuPlot.SeriesV; 00118 MoreCmds = GnuPlot.MoreCmds; 00119 } 00120 return *this; 00121 } 00122 00123 TStr TGnuPlot::GetSeriesPlotStr(const int& SeriesId) { 00124 TChA PlotStr; 00125 TGpSeries& Series = SeriesV[SeriesId]; 00126 if (SeriesId != 0) PlotStr += ",\\\n\t"; 00127 if (Series.XCol >= 0) { 00128 PlotStr += "\"" + Series.DataFNm + "\" using " + TInt::GetStr(Series.XCol); 00129 if (Series.YCol != 0) { PlotStr += ":" + TInt::GetStr(Series.YCol); } 00130 if (Series.ZCol != 0) { PlotStr += ":" + TInt::GetStr(Series.ZCol); } 00131 else if (Series.SeriesTy==gpwFilledCurves) { PlotStr += ":(0)"; } // filled curves requres 3rd column 00132 } else { 00133 // function 00134 //IAssertR(Series.DataFNm.SearchCh('=') != -1, TStr::Fmt("Expression %s is not a function", Series.DataFNm.CStr())); 00135 PlotStr += Series.DataFNm; 00136 } 00137 PlotStr += " title \"" + Series.Label + "\""; 00138 // hard coded line style 00139 if (Series.WithStyle.Empty()) { 00140 if (Series.SeriesTy == gpwLines) Series.WithStyle = "lw 1"; 00141 if (Series.SeriesTy == gpwPoints) Series.WithStyle = "pt 6"; // circles 00142 if (Series.SeriesTy == gpwLinesPoints) Series.WithStyle = "pt 6"; // circles 00143 if (Series.SeriesTy == gpwBoxes) Series.WithStyle = "fill solid 0.3"; 00144 } 00145 PlotStr += " with " + GetSeriesTyStr(Series.SeriesTy) + " " + Series.WithStyle; 00146 return PlotStr; 00147 } 00148 00149 //GP.AddFunc("2*x**-2+4", gpwLines, "2*x^-2+4"); 00150 int TGnuPlot::AddFunc(const TStr& FuncStr, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00151 const int Id = SeriesV.Len(); 00152 TGpSeries Plot; 00153 Plot.SeriesTy = SeriesTy; 00154 Plot.Label = Label; 00155 if (! FuncStr.Empty()) { Plot.DataFNm = TStr::Fmt("f%d(x)=%s, f%d(x)", Id, FuncStr.CStr(), Id); } 00156 else { Plot.DataFNm = TStr::Fmt("f%d(x)", Id); } 00157 Plot.XCol = -1; 00158 Plot.WithStyle = Style; 00159 SeriesV.Add(Plot); 00160 return Id; 00161 } 00162 00163 int TGnuPlot::AddPlot(const TStr& DataFNm, const int& ColY, 00164 const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00165 return AddPlot(DataFNm, 0, ColY, SeriesTy, Label, Style); 00166 } 00167 00168 int TGnuPlot::AddPlot(const TStr& DataFNm, const int& ColX, const int& ColY, 00169 const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00170 IAssert(ColY > 0); IAssert(ColX >= 0); 00171 TGpSeries Plot; 00172 Plot.SeriesTy = SeriesTy; 00173 Plot.Label = Label; 00174 Plot.DataFNm = DataFNm; Plot.DataFNm.ChangeStrAll("\\", "\\\\"); 00175 Plot.XCol = ColX; Plot.YCol = ColY; Plot.ZCol = 0; 00176 Plot.WithStyle = Style; 00177 SeriesV.Add(Plot); 00178 return SeriesV.Len() - 1; 00179 } 00180 00181 int TGnuPlot::AddPlot(const TIntV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00182 TFltKdV XYValV(YValV.Len(), 0); 00183 for (int i = 0; i < YValV.Len(); i++) { 00184 XYValV.Add(TFltKd(TFlt(i+1), TFlt(YValV[i]))); 00185 } 00186 return AddPlot(XYValV, SeriesTy, Label, Style); 00187 } 00188 00189 int TGnuPlot::AddPlot(const TFltV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00190 TFltKdV XYValV(YValV.Len(), 0); 00191 for (int i = 0; i < YValV.Len(); i++) { 00192 XYValV.Add(TFltKd(TFlt(i+1), TFlt(YValV[i]))); 00193 } 00194 return AddPlot(XYValV, SeriesTy, Label, Style); 00195 } 00196 00197 int TGnuPlot::AddPlot(const TFltV& XValV, const TFltV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00198 IAssert(XValV.Len() == YValV.Len()); 00199 TFltKdV XYValV(XValV.Len(), 0); 00200 for (int i = 0; i < YValV.Len(); i++) { 00201 XYValV.Add(TFltKd(TFlt(XValV[i]), TFlt(YValV[i]))); 00202 } 00203 return AddPlot(XYValV, SeriesTy, Label, Style); 00204 } 00205 00206 int TGnuPlot::AddPlot(const TIntPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00207 TFltKdV XYFltValV(XYValV.Len(), 0); 00208 for (int i = 0; i < XYValV.Len(); i++) { 00209 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Val1), TFlt(XYValV[i].Val2))); 00210 } 00211 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00212 } 00213 00214 int TGnuPlot::AddPlot(const TFltPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00215 TFltKdV XYFltValV(XYValV.Len(), 0); 00216 for (int i = 0; i < XYValV.Len(); i++) { 00217 XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); 00218 } 00219 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00220 } 00221 00222 int TGnuPlot::AddPlot(const TIntKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00223 TFltKdV XYFltValV(XYValV.Len(), 0); 00224 for (int i = 0; i < XYValV.Len(); i++) { 00225 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Key), TFlt(XYValV[i].Dat))); 00226 } 00227 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00228 } 00229 00230 int TGnuPlot::AddPlot(const TIntFltKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00231 TFltKdV XYFltValV(XYValV.Len(), 0); 00232 for (int i = 0; i < XYValV.Len(); i++) { 00233 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Key), TFlt(XYValV[i].Dat))); 00234 } 00235 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00236 } 00237 00238 int TGnuPlot::AddPlot(const TIntFltPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00239 TFltKdV XYFltValV(XYValV.Len(), 0); 00240 for (int i = 0; i < XYValV.Len(); i++) { 00241 XYFltValV.Add(TFltKd(TFlt(XYValV[i].Val1), TFlt(XYValV[i].Val2))); 00242 } 00243 return AddPlot(XYFltValV, SeriesTy, Label, Style); 00244 } 00245 00246 int TGnuPlot::AddPlot(const TFltKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) { 00247 if (XYValV.Empty()) { 00248 printf("***AddPlot: empty plot (%s) %s\n", DataFNm.CStr(), Title.CStr()); 00249 return -1; 00250 } 00251 TGpSeries Plot; 00252 Plot.SeriesTy = SeriesTy; 00253 Plot.Label = Label; 00254 Plot.XYValV = XYValV; 00255 Plot.WithStyle = Style; 00256 SeriesV.Add(Plot); 00257 return SeriesV.Len() - 1; 00258 } 00259 00260 int TGnuPlot::AddErrBar(const TFltTrV& XYDValV, const TStr& Label) { 00261 TFltKdV XYFltValV(XYDValV.Len(), 0); 00262 TFltV DeltaV(XYDValV.Len(), 0); 00263 for (int i = 0; i < XYDValV.Len(); i++) { 00264 XYFltValV.Add(TFltKd(XYDValV[i].Val1, XYDValV[i].Val2)); 00265 DeltaV.Add(XYDValV[i].Val3); 00266 } 00267 return AddErrBar(XYFltValV, DeltaV, Label); 00268 } 00269 00270 int TGnuPlot::AddErrBar(const TFltTrV& XYDValV, const TStr& DatLabel, const TStr& ErrLabel) { 00271 TFltKdV XYFltValV(XYDValV.Len(), 0); 00272 TFltV DeltaV(XYDValV.Len(), 0); 00273 for (int i = 0; i < XYDValV.Len(); i++) { 00274 XYFltValV.Add(TFltKd(XYDValV[i].Val1, XYDValV[i].Val2)); 00275 DeltaV.Add(XYDValV[i].Val3); 00276 } 00277 const int PlotId = AddPlot(XYFltValV, gpwLinesPoints, DatLabel); 00278 AddErrBar(XYFltValV, DeltaV, ErrLabel); 00279 return PlotId; 00280 } 00281 00282 int TGnuPlot::AddErrBar(const TFltV& YValV, const TFltV& DeltaYV, const TStr& Label) { 00283 IAssert(YValV.Len() == DeltaYV.Len()); 00284 TFltKdV XYFltValV(YValV.Len(), 0); 00285 for (int i = 0; i < YValV.Len(); i++) { 00286 XYFltValV.Add(TFltKd(TFlt(i+1), YValV[i])); 00287 } 00288 return AddErrBar(XYFltValV, DeltaYV, Label); 00289 } 00290 00291 int TGnuPlot::AddErrBar(const TFltV& XValV, const TFltV& YValV, const TFltV& DeltaYV, const TStr& Label) { 00292 IAssert(XValV.Len() == YValV.Len()); 00293 IAssert(XValV.Len() == DeltaYV.Len()); 00294 TFltKdV XYFltValV(XValV.Len(), 0); 00295 for (int i = 0; i < XValV.Len(); i++) { 00296 XYFltValV.Add(TFltKd(XValV[i], YValV[i])); 00297 } 00298 return AddErrBar(XYFltValV, DeltaYV, Label); 00299 } 00300 00301 int TGnuPlot::AddErrBar(const TFltPrV& XYValV, const TFltV& DeltaYV, const TStr& Label) { 00302 TFltKdV XYFltValV(XYValV.Len(), 0); 00303 for (int i = 0; i < XYValV.Len(); i++) { 00304 XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); 00305 } 00306 return AddErrBar(XYFltValV, DeltaYV, Label); 00307 } 00308 00309 int TGnuPlot::AddErrBar(const TFltPrV& XYValV, const TFltV& DeltaV, const TStr& DatLabel, const TStr& ErrLabel) { 00310 TFltKdV XYFltValV(XYValV.Len(), 0); 00311 for (int i = 0; i < XYValV.Len(); i++) { 00312 XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); 00313 } 00314 const int PlotId = AddPlot(XYFltValV, gpwLinesPoints, DatLabel); 00315 AddErrBar(XYFltValV, DeltaV, ErrLabel); 00316 return PlotId; 00317 } 00318 00319 int TGnuPlot::AddErrBar(const TFltKdV& XYValV, const TFltV& DeltaYV, const TStr& Label) { 00320 if (XYValV.Empty()) { 00321 printf("***AddErrBar: empty plot (%s) %s\n", DataFNm.CStr(), Title.CStr()); 00322 return -1; 00323 } 00324 IAssert(XYValV.Len() == DeltaYV.Len()); 00325 TGpSeries Plot; 00326 Plot.SeriesTy = gpwErrBars; 00327 Plot.Label = Label; 00328 Plot.XYValV = XYValV; 00329 Plot.ZValV = DeltaYV; 00330 SeriesV.Add(Plot); 00331 return SeriesV.Len() - 1; 00332 } 00333 00334 int TGnuPlot::AddLinFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00335 if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1; 00336 const TGpSeries& Plot = SeriesV[PlotId]; 00337 if(Plot.XYValV.Empty()) return -1; 00338 const TFltKdV& XY = Plot.XYValV; 00339 double A, B, R2, SigA, SigB, Chi2; 00340 // linear fit 00341 TFltPrV XYPr; 00342 int s; 00343 for (s = 0; s < XY.Len(); s++) { 00344 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00345 } 00346 TSpecFunc::LinearFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00347 TStr StyleStr=Style; 00348 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00349 const int FitId = AddFunc(TStr::Fmt("%f+%f*x", A, B), 00350 SeriesTy, TStr::Fmt("%.4g + %.4g x R^2:%.2g", A, B, R2), StyleStr); 00351 return FitId; 00352 /*SeriesV.Add(); 00353 TGpSeries& NewPlot = SeriesV.Last(); 00354 TFltKdV& EstXY = NewPlot.XYValV; 00355 for (s = 0; s < XY.Len(); s++) { 00356 EstXY.Add(TFltKd(XY[s].Key, A + B*XYPr[s].Val1)); 00357 } 00358 NewPlot.Label = TStr::Fmt("%.4g + %.4g x R^2:%.2g", A, B, R2); 00359 NewPlot.SeriesTy = SeriesTy; 00360 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00361 else { NewPlot.WithStyle = Style; } 00362 return SeriesV.Len() - 1;*/ 00363 } 00364 00365 int TGnuPlot::AddPwrFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00366 const int PlotId1 = AddPwrFit3(PlotId, SeriesTy); 00367 AddPwrFit2(PlotId, SeriesTy, 5.0); 00368 return PlotId1; 00369 } 00370 00371 // linear fit on log-log scales{% 00372 int TGnuPlot::AddPwrFit1(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00373 if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1; 00374 const TGpSeries& Plot = SeriesV[PlotId]; 00375 if(Plot.XYValV.Empty()) return -1; 00376 const TFltKdV& XY = Plot.XYValV; 00377 double A, B, R2, SigA, SigB, Chi2, MinY = TFlt::Mx, MinX = TFlt::Mx; 00378 // power fit 00379 TFltPrV XYPr; 00380 int s; 00381 for (s = 0; s < XY.Len(); s++) { 00382 if (XY[s].Key > 0) { 00383 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00384 MinX = TMath::Mn(MinX, XY[s].Key()); 00385 MinY = TMath::Mn(MinY, XY[s].Dat()); 00386 } 00387 } 00388 MinY = TMath::Mn(1.0, MinY); 00389 TSpecFunc::PowerFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00390 TStr StyleStr=Style; 00391 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00392 const int FitId = AddFunc(TStr::Fmt("%f*x**%f", A, B), 00393 SeriesTy, TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2), StyleStr); 00394 return FitId; 00395 /*SeriesV.Add(); 00396 TGpSeries& NewPlot = SeriesV.Last(); 00397 const int FitId = SeriesV.Len() - 1; 00398 NewPlot.DataFNm = ; 00399 TFltKdV& EstXY = NewPlot.XYValV; 00400 for (s = 0; s < XYPr.Len(); s++) { 00401 const double YVal = A*pow(XYPr[s].Val1(), B); 00402 if (YVal < MinY) continue; 00403 EstXY.Add(TFltKd(XYPr[s].Val1, YVal)); 00404 } 00405 NewPlot.Label = ; 00406 NewPlot.SeriesTy = SeriesTy; 00407 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00408 else { NewPlot.WithStyle = Style; } 00409 //if (MinX < 5.0) MinX = 5.0; 00410 //AddPwrFit2(PlotId, SeriesTy, MinX);*/ 00411 } 00412 00413 // MLE power-coefficient 00414 int TGnuPlot::AddPwrFit2(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style) { 00415 const TGpSeries& Plot = SeriesV[PlotId]; 00416 if(Plot.XYValV.Empty()) return -1; 00417 const TFltKdV& XY = Plot.XYValV; 00418 // power fit 00419 TFltPrV XYPr; 00420 double MinY = TFlt::Mx; 00421 for (int s = 0; s < XY.Len(); s++) { 00422 if (XY[s].Key > 0.0) { 00423 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00424 MinY = TMath::Mn(MinY, XY[s].Dat()); 00425 } 00426 } 00427 if (XYPr.Empty()) return -1; 00428 MinY = TMath::Mn(1.0, MinY); 00429 // determine the sign of power coefficient 00430 double CoefSign = 0.0; 00431 { double A, B, R2, SigA, SigB, Chi2; 00432 TSpecFunc::PowerFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00433 CoefSign = B > 0.0 ? +1.0 : -1.0; } 00434 const double PowerCf = CoefSign * TSpecFunc::GetPowerCoef(XYPr, MinX); 00435 int Mid = (int) exp(log((double)XYPr.Len())/2.0); 00436 if (Mid >= XYPr.Len()) { Mid = XYPr.Len()-1; } 00437 const double MidX = XYPr[Mid].Val1(); 00438 const double MidY = XYPr[Mid].Val2(); 00439 const double B = MidY / pow(MidX, PowerCf); 00440 TStr StyleStr=Style; 00441 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00442 const int FitId = AddFunc(TStr::Fmt("%f*x**%f", B, PowerCf), 00443 SeriesTy, TStr::Fmt("MLE = x^{%.4g}", PowerCf), StyleStr); 00444 return FitId; 00445 /*SeriesV.Add(); 00446 TGpSeries& NewPlot = SeriesV.Last(); 00447 TFltKdV& XYFit = NewPlot.XYValV; 00448 XYFit.Gen(XYPr.Len(), 0); 00449 for (int s = 0; s < XYPr.Len(); s++) { 00450 const double XVal = XYPr[s].Val1; 00451 const double YVal = B * pow(XYPr[s].Val1(), PowerCf); 00452 if (YVal < MinY || XVal < MinX) continue; 00453 XYFit.Add(TFltKd(XVal, YVal)); 00454 } 00455 NewPlot.Label = TStr::Fmt("PowerFit: %g", PowerCf); 00456 NewPlot.SeriesTy = SeriesTy; 00457 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00458 else { NewPlot.WithStyle = Style; } 00459 return SeriesV.Len() - 1;*/ 00460 } 00461 00462 int TGnuPlot::AddPwrFit3(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style) { 00463 double Intercept, Slope, R2; 00464 return AddPwrFit3(PlotId, SeriesTy, MinX, Style, Intercept, Slope, R2); 00465 } 00466 00467 // some kind of least squares power-law fitting that cutts the tail until the fit is good 00468 int TGnuPlot::AddPwrFit3(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style, double& Intercept, double& Slope, double& R2) { 00469 if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1; 00470 const TGpSeries& Plot = SeriesV[PlotId]; 00471 if(Plot.XYValV.Empty()) return -1; 00472 double A, B, SigA, SigB, Chi2, MinY=TFlt::Mx; 00473 const TFltKdV& XY = Plot.XYValV; 00474 //SeriesV.Add(); 00475 //TGpSeries& NewPlot = SeriesV.Last(); 00476 //TFltKdV& EstXY = NewPlot.XYValV; 00477 TFltPrV FitXY, NewFitXY; 00478 for (int s = 0; s < XY.Len(); s++) { 00479 if (XY[s].Key > 0 && XY[s].Key >= MinX) { 00480 FitXY.Add(TFltPr(XY[s].Key, XY[s].Dat)); 00481 MinY = TMath::Mn(MinY, XY[s].Dat()); 00482 } 00483 } 00484 MinY = TMath::Mn(1.0, MinY); 00485 // power fit (if tail is too fat, cut everything where 00486 // extrapolation sets the value < MinY 00487 while (true) { 00488 TSpecFunc::PowerFit(FitXY, A, B, SigA, SigB, Chi2, R2); 00489 NewFitXY.Clr(false); 00490 //EstXY.Clr(false); 00491 for (int s = 0; s < FitXY.Len(); s++) { 00492 const double YVal = A*pow(FitXY[s].Val1(), B); 00493 if (YVal < MinY) continue; 00494 //EstXY.Add(TFltKd(FitXY[s].Val1, YVal)); 00495 NewFitXY.Add(TFltPr(FitXY[s].Val1, FitXY[s].Val2)); 00496 } 00497 if (NewFitXY.Len() < 10 || FitXY.Last().Val1 < 1.2 * NewFitXY.Last().Val1) { break; } 00498 else { FitXY.Swap(NewFitXY); } 00499 } 00500 TStr StyleStr=Style; 00501 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00502 const int FitId = AddFunc(TStr::Fmt("%f*x**%f", A, B), 00503 SeriesTy, TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2), StyleStr); 00504 return FitId; 00505 /*NewPlot.Label = TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2); 00506 Intercept = A; 00507 Slope = B; 00508 NewPlot.SeriesTy = SeriesTy; 00509 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00510 else { NewPlot.WithStyle = Style; } 00511 return SeriesV.Len() - 1;*/ 00512 } 00513 00514 int TGnuPlot::AddLogFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) { 00515 const TGpSeries& Plot = SeriesV[PlotId]; 00516 if(Plot.XYValV.Empty()) return -1; 00517 const TFltKdV& XY = Plot.XYValV; 00518 double A, B, R2, SigA, SigB, Chi2; 00519 // power fit 00520 TFltPrV XYPr; 00521 int s; 00522 for (s = 0; s < XY.Len(); s++) { 00523 if (XY[s].Key > 0) { 00524 XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); } 00525 } 00526 TSpecFunc::LogFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00527 TStr StyleStr=Style; 00528 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00529 const int FitId = AddFunc(TStr::Fmt("%f+%f*log(x)", A, B), 00530 SeriesTy, TStr::Fmt("%.4g + %.4g log(x) R^2:%.2g", A, B, R2), StyleStr); 00531 return FitId; 00532 /*SeriesV.Add(); 00533 TGpSeries& NewPlot = SeriesV.Last(); 00534 TFltKdV& EstXY = NewPlot.XYValV; 00535 for (s = 0; s < XYPr.Len(); s++) { 00536 EstXY.Add(TFltKd(XYPr[s].Val1, A+B*log((double)XYPr[s].Val1))); 00537 } 00538 NewPlot.Label = TStr::Fmt("%.4g + %.4g log(x) R^2:%.2g", A, B, R2); 00539 NewPlot.SeriesTy = SeriesTy; 00540 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00541 else { NewPlot.WithStyle = Style; } 00542 return SeriesV.Len() - 1;*/ 00543 } 00544 00545 int TGnuPlot::AddExpFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& FitXOffset, const TStr& Style) { 00546 const TGpSeries& Plot = SeriesV[PlotId]; 00547 if(Plot.XYValV.Empty()) return -1; 00548 const TFltKdV& XY = Plot.XYValV; 00549 double A, B, R2, SigA, SigB, Chi2; 00550 // power fit 00551 TFltPrV XYPr; 00552 int s; 00553 for (s = 0; s < XY.Len(); s++) { 00554 if (XY[s].Key-FitXOffset > 0) { 00555 XYPr.Add(TFltPr(XY[s].Key-FitXOffset, XY[s].Dat)); } 00556 } 00557 TSpecFunc::ExpFit(XYPr, A, B, SigA, SigB, Chi2, R2); 00558 TStr Label, StyleStr=Style; 00559 if (FitXOffset == 0) { Label = TStr::Fmt("%.4g exp(%.4g x) R^2:%.2g", A, B, R2); } 00560 else { Label = TStr::Fmt("%.4g exp(%.4g x - %g) R^2:%.2g", A, B, FitXOffset, R2); } 00561 if (StyleStr.Empty()) { StyleStr = "linewidth 3"; } 00562 const int FitId = AddFunc(TStr::Fmt("%f*exp(%f*x-%f)", A, B, FitXOffset), 00563 SeriesTy, Label, StyleStr); 00564 return FitId; 00565 /*SeriesV.Add(); 00566 TGpSeries& NewPlot = SeriesV.Last(); 00567 TFltKdV& EstXY = NewPlot.XYValV; 00568 for (s = 0; s < XYPr.Len(); s++) { 00569 EstXY.Add(TFltKd(XYPr[s].Val1+FitXOffset, A*exp(B*XYPr[s].Val1))); 00570 } 00571 NewPlot.SeriesTy = SeriesTy; 00572 if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; } 00573 else { NewPlot.WithStyle = Style; } 00574 return SeriesV.Len() - 1;*/ 00575 } 00576 00577 void TGnuPlot::SavePng(const TStr& FNm, const int& SizeX, const int& SizeY, const TStr& Comment, const TStr& Terminal) { 00578 if (Terminal.Empty()) { 00579 //#ifdef GLib_WIN 00580 #ifndef GLib_MACOSX // The standard GNUPlot for MacOS does not support PNG 00581 AddCmd(TStr::Fmt("set terminal png small size %d,%d", SizeX, SizeY)); 00582 AddCmd(TStr::Fmt("set output '%s'", FNm.CStr())); 00583 #else // EPS 00584 AddCmd("set terminal postscript eps 10 enhanced color"); 00585 AddCmd(TStr::Fmt("set output '%s%s.eps'", FNm.GetFPath().CStr(), FNm.GetFMid().CStr())); 00586 #endif 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 // try running gnuplot 00866 if (system(TStr::Fmt("%s %s", GnuPlotFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00867 if (! GnuPlotPath.Empty()) { 00868 #if defined(GLib_WIN) 00869 if (system(TStr::Fmt("%s\\%s %s", GnuPlotPath.CStr(), GnuPlotFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00870 #else 00871 if (system(TStr::Fmt("%s/%s %s", GnuPlotPath.CStr(), GnuPlotFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00872 #endif 00873 } 00874 //Old 00875 //#if defined(GLib_WIN) 00876 //if (system(TStr::Fmt(".\\%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00877 //#else 00878 //if (system(TStr::Fmt("./%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00879 //#endif 00880 //if (system(TStr::Fmt("%s%s %s", GpPath.CStr(), GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; } 00881 //FailR(TStr::Fmt("Cat not find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr()); 00882 //ErrNotify(TStr::Fmt("Cat not find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr()); 00883 fprintf(stderr, "[%s:%d] Cat not find GnuPlot (%s) for plot %s. Set the $$PATH variable or TGnuPlot::GnuPlotPath. (%s)\n", __FILE__, __LINE__, GnuPlotFNm.CStr(), PlotFNm.CStr(), TGnuPlot::GnuPlotPath.CStr()); 00884 }