SNAP Library 4.0, User Reference  2017-07-27 13:18:06
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
gnuplot.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "gnuplot.h"
3 
5 // GNU-Plot-Chart
6 
7 // Set path to gnuplot
8 #if defined(GLib_WIN)
9  TStr TGnuPlot::GnuPlotPath = "C:\\gnuplot";
10  TStr TGnuPlot::GnuPlotFNm = "wgnuplot.exe";
11 #elif defined(GLib_CYGWIN)
12  TStr TGnuPlot::GnuPlotPath = "/usr/bin";
13  TStr TGnuPlot::GnuPlotFNm = "gnuplot.exe";
14 #elif defined(GLib_MACOSX)
15  TStr TGnuPlot::GnuPlotPath = "/usr/local/bin";
16  TStr TGnuPlot::GnuPlotFNm = "gnuplot";
17 #else
18  TStr TGnuPlot::GnuPlotPath = "/usr/bin";
19  TStr TGnuPlot::GnuPlotFNm = "gnuplot";
20 #endif
21 
22 // Determines the gnuplot version and the tics command syntax.
23 // Gnuplot changed the syntax with version 4.2:
24 // - before 4.2: set ticscale 2 1
25 // - 4.2 and later: set tics 2
27 #ifdef GLib_WIN
28  return -1;
29 #else
30  FILE* p;
31  char Buf[1024];
32  char Version[1024];
33  size_t n;
34 
35  // get gnuplot version
36  p = popen(TStr::Fmt("%s -V", TGnuPlot::GnuPlotFNm.CStr()).CStr(), "r");
37  if (p == NULL) { // try running using the path
38  p = popen(TStr::Fmt("%s/%s -V", TGnuPlot::GnuPlotPath.CStr(), TGnuPlot::GnuPlotFNm.CStr()).CStr(), "r");
39  if (p == NULL) { return -1; }
40  }
41  n = fread(Buf, 1, 100, p);
42  if (n <= 0) { return -1; }
43  Buf[n] = '\0';
44  pclose(p);
45  //printf("Buf %d .%s.\n", n, Buf);
46  n = sscanf(Buf, "gnuplot %s", Version);
47  if (n <= 0) { return -1; }
48  // printf("Version %d .%s.\n", n, Version);
49  if ((strlen(Version) < 3) || (Version[1] != '.')) { return -1; }
50  // test version < 4.2
51  if ((Version[0] < '4') || ((Version[0] == '4') && (Version[2] < '2'))) {
52  // printf("TGnuPlot::GetTics42 0\n");
53  return 0;
54  }
55  // printf("TGnuPlot::GetTics42 1\n");
56  return 1;
57 #endif
58 }
59 
60 int TGnuPlot::Tics42 = -2;
61 TStr TGnuPlot::DefPlotFNm = "GnuPlot.plt";
62 TStr TGnuPlot::DefDataFNm = "GnuPlot.tab";
63 
65  SeriesTy(Gps.SeriesTy), XYValV(Gps.XYValV), ZValV(Gps.ZValV),
66  Label(Gps.Label), WithStyle(Gps.WithStyle), DataFNm(Gps.DataFNm),
67  XCol(Gps.XCol), YCol(Gps.YCol), ZCol(Gps.ZCol) {
68 }
69 
71  if(this != &Gps) {
72  SeriesTy = Gps.SeriesTy;
73  XYValV = Gps.XYValV; ZValV = Gps.ZValV;
74  Label = Gps.Label;
75  DataFNm = Gps.DataFNm;
76  WithStyle = Gps.WithStyle;
77  XCol = Gps.XCol; YCol = Gps.YCol; ZCol = Gps.ZCol;
78  }
79  return *this;
80 }
81 
83  return (XYValV < Gps.XYValV) || ((XYValV == Gps.XYValV) && (Label < Gps.Label));
84 }
85 
86 TGnuPlot::TGnuPlot(const TStr& FileNm, const TStr& PlotTitle, const bool& Grid) :
87  DataFNm(FileNm+".tab"), PlotFNm(FileNm+".plt"), Title(PlotTitle), LblX(), LblY(), ScaleTy(gpsAuto),
88  YRange(0, 0), XRange(0, 0), SetGrid(Grid), SetPause(true),
89  SeriesV(), MoreCmds() {
90  IAssert(! FileNm.Empty());
91 }
92 
93 TGnuPlot::TGnuPlot(const TStr& DataFileNm, const TStr& PlotFileNm, const TStr& PlotTitle, const bool& Grid) :
94  DataFNm(DataFileNm.Empty() ? DefDataFNm : DataFileNm),
95  PlotFNm(PlotFileNm.Empty() ? DefPlotFNm : PlotFileNm),
96  Title(PlotTitle), LblX(), LblY(), ScaleTy(gpsAuto),
97  YRange(0, 0), XRange(0, 0), SetGrid(Grid), SetPause(true), SeriesV(), MoreCmds() {
98 }
99 
100 TGnuPlot::TGnuPlot(const TGnuPlot& GnuPlot) : DataFNm(GnuPlot.DataFNm), PlotFNm(GnuPlot.PlotFNm),
101  Title(GnuPlot.Title), LblX(GnuPlot.LblX), LblY(GnuPlot.LblY), ScaleTy(GnuPlot.ScaleTy), YRange(GnuPlot.YRange),
102  XRange(GnuPlot.XRange), SetGrid(GnuPlot.SetGrid), SetPause(GnuPlot.SetPause), SeriesV(GnuPlot.SeriesV),
103  MoreCmds(GnuPlot.MoreCmds) {
104 }
105 
107  if (this != &GnuPlot) {
108  DataFNm = GnuPlot.DataFNm;
109  PlotFNm = GnuPlot.PlotFNm;
110  Title = GnuPlot.Title;
111  LblX = GnuPlot.LblX;
112  LblY = GnuPlot.LblY;
113  ScaleTy = GnuPlot.ScaleTy;
114  YRange = GnuPlot.YRange;
115  XRange = GnuPlot.XRange;
116  SetGrid = GnuPlot.SetGrid;
117  SetPause = GnuPlot.SetPause;
118  SeriesV = GnuPlot.SeriesV;
119  MoreCmds = GnuPlot.MoreCmds;
120  }
121  return *this;
122 }
123 
124 TStr TGnuPlot::GetSeriesPlotStr(const int& SeriesId) {
125  TChA PlotStr;
126  TGpSeries& Series = SeriesV[SeriesId];
127  if (SeriesId != 0) PlotStr += ",\\\n\t";
128  if (Series.XCol >= 0) {
129  PlotStr += "\"" + Series.DataFNm + "\" using " + TInt::GetStr(Series.XCol);
130  if (Series.YCol != 0) { PlotStr += ":" + TInt::GetStr(Series.YCol); }
131  if (Series.ZCol != 0) { PlotStr += ":" + TInt::GetStr(Series.ZCol); }
132  else if (Series.SeriesTy==gpwFilledCurves) { PlotStr += ":(0)"; } // filled curves requres 3rd column
133  } else {
134  // function
135  //IAssertR(Series.DataFNm.SearchCh('=') != -1, TStr::Fmt("Expression %s is not a function", Series.DataFNm.CStr()));
136  PlotStr += Series.DataFNm;
137  }
138  if (Series.SeriesTy == gpwErrBars) {
139  PlotStr += " notitle";
140  } else {
141  PlotStr += " title \"" + Series.Label + "\"";
142  }
143  // hard coded line style
144  if (Series.WithStyle.Empty()) {
145  if (Series.SeriesTy == gpwLines) Series.WithStyle = "lw 1";
146  if (Series.SeriesTy == gpwPoints) Series.WithStyle = "pt 6"; // circles
147  if (Series.SeriesTy == gpwLinesPoints) Series.WithStyle = "pt 6"; // circles
148  if (Series.SeriesTy == gpwBoxes) Series.WithStyle = "fill solid 0.3";
149  }
150  PlotStr += " with " + GetSeriesTyStr(Series.SeriesTy) + " " + Series.WithStyle;
151  return PlotStr;
152 }
153 
154 //GP.AddFunc("2*x**-2+4", gpwLines, "2*x^-2+4");
155 int TGnuPlot::AddFunc(const TStr& FuncStr, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
156  const int Id = SeriesV.Len();
157  TGpSeries Plot;
158  Plot.SeriesTy = SeriesTy;
159  Plot.Label = Label;
160  if (! FuncStr.Empty()) { Plot.DataFNm = TStr::Fmt("f%d(x)=%s, f%d(x)", Id, FuncStr.CStr(), Id); }
161  else { Plot.DataFNm = TStr::Fmt("f%d(x)", Id); }
162  Plot.XCol = -1;
163  Plot.WithStyle = Style;
164  SeriesV.Add(Plot);
165  return Id;
166 }
167 
168 int TGnuPlot::AddPlot(const TStr& DataFNm, const int& ColY,
169  const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
170  return AddPlot(DataFNm, 0, ColY, SeriesTy, Label, Style);
171 }
172 
173 int TGnuPlot::AddPlot(const TStr& DataFNm, const int& ColX, const int& ColY,
174  const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
175  IAssert(ColY > 0); IAssert(ColX >= 0);
176  TGpSeries Plot;
177  Plot.SeriesTy = SeriesTy;
178  Plot.Label = Label;
179  Plot.DataFNm = DataFNm; Plot.DataFNm.ChangeStrAll("\\", "\\\\");
180  Plot.XCol = ColX; Plot.YCol = ColY; Plot.ZCol = 0;
181  Plot.WithStyle = Style;
182  SeriesV.Add(Plot);
183  return SeriesV.Len() - 1;
184 }
185 
186 int TGnuPlot::AddPlot(const TIntV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
187  TFltKdV XYValV(YValV.Len(), 0);
188  for (int i = 0; i < YValV.Len(); i++) {
189  XYValV.Add(TFltKd(TFlt(i+1), TFlt(YValV[i])));
190  }
191  return AddPlot(XYValV, SeriesTy, Label, Style);
192 }
193 
194 int TGnuPlot::AddPlot(const TFltV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
195  TFltKdV XYValV(YValV.Len(), 0);
196  for (int i = 0; i < YValV.Len(); i++) {
197  XYValV.Add(TFltKd(TFlt(i+1), TFlt(YValV[i])));
198  }
199  return AddPlot(XYValV, SeriesTy, Label, Style);
200 }
201 
202 int TGnuPlot::AddPlot(const TFltV& XValV, const TFltV& YValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
203  IAssert(XValV.Len() == YValV.Len());
204  TFltKdV XYValV(XValV.Len(), 0);
205  for (int i = 0; i < YValV.Len(); i++) {
206  XYValV.Add(TFltKd(TFlt(XValV[i]), TFlt(YValV[i])));
207  }
208  return AddPlot(XYValV, SeriesTy, Label, Style);
209 }
210 
211 int TGnuPlot::AddPlot(const TIntPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
212  TFltKdV XYFltValV(XYValV.Len(), 0);
213  for (int i = 0; i < XYValV.Len(); i++) {
214  XYFltValV.Add(TFltKd(TFlt(XYValV[i].Val1), TFlt(XYValV[i].Val2)));
215  }
216  return AddPlot(XYFltValV, SeriesTy, Label, Style);
217 }
218 
219 int TGnuPlot::AddPlot(const TFltPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
220  TFltKdV XYFltValV(XYValV.Len(), 0);
221  for (int i = 0; i < XYValV.Len(); i++) {
222  XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2));
223  }
224  return AddPlot(XYFltValV, SeriesTy, Label, Style);
225 }
226 
227 int TGnuPlot::AddPlot(const TIntKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
228  TFltKdV XYFltValV(XYValV.Len(), 0);
229  for (int i = 0; i < XYValV.Len(); i++) {
230  XYFltValV.Add(TFltKd(TFlt(XYValV[i].Key), TFlt(XYValV[i].Dat)));
231  }
232  return AddPlot(XYFltValV, SeriesTy, Label, Style);
233 }
234 
235 int TGnuPlot::AddPlot(const TIntFltKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
236  TFltKdV XYFltValV(XYValV.Len(), 0);
237  for (int i = 0; i < XYValV.Len(); i++) {
238  XYFltValV.Add(TFltKd(TFlt(XYValV[i].Key), TFlt(XYValV[i].Dat)));
239  }
240  return AddPlot(XYFltValV, SeriesTy, Label, Style);
241 }
242 
243 int TGnuPlot::AddPlot(const TIntFltPrV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
244  TFltKdV XYFltValV(XYValV.Len(), 0);
245  for (int i = 0; i < XYValV.Len(); i++) {
246  XYFltValV.Add(TFltKd(TFlt(XYValV[i].Val1), TFlt(XYValV[i].Val2)));
247  }
248  return AddPlot(XYFltValV, SeriesTy, Label, Style);
249 }
250 
251 int TGnuPlot::AddPlot(const TFltKdV& XYValV, const TGpSeriesTy& SeriesTy, const TStr& Label, const TStr& Style) {
252  if (XYValV.Empty()) {
253  printf("***AddPlot: empty plot (%s) %s\n", DataFNm.CStr(), Title.CStr());
254  return -1;
255  }
256  TGpSeries Plot;
257  Plot.SeriesTy = SeriesTy;
258  Plot.Label = Label;
259  Plot.XYValV = XYValV;
260  Plot.WithStyle = Style;
261  SeriesV.Add(Plot);
262  return SeriesV.Len() - 1;
263 }
264 
265 int TGnuPlot::AddErrBar(const TFltTrV& XYDValV, const TStr& Label) {
266  TFltKdV XYFltValV(XYDValV.Len(), 0);
267  TFltV DeltaV(XYDValV.Len(), 0);
268  for (int i = 0; i < XYDValV.Len(); i++) {
269  XYFltValV.Add(TFltKd(XYDValV[i].Val1, XYDValV[i].Val2));
270  DeltaV.Add(XYDValV[i].Val3);
271  }
272  return AddErrBar(XYFltValV, DeltaV, Label);
273 }
274 
275 int TGnuPlot::AddErrBar(const TFltTrV& XYDValV, const TStr& DatLabel, const TStr& ErrLabel) {
276  TFltKdV XYFltValV(XYDValV.Len(), 0);
277  TFltV DeltaV(XYDValV.Len(), 0);
278  for (int i = 0; i < XYDValV.Len(); i++) {
279  XYFltValV.Add(TFltKd(XYDValV[i].Val1, XYDValV[i].Val2));
280  DeltaV.Add(XYDValV[i].Val3);
281  }
282  const int PlotId = AddPlot(XYFltValV, gpwLinesPoints, DatLabel);
283  AddErrBar(XYFltValV, DeltaV, ErrLabel);
284  return PlotId;
285 }
286 
287 int TGnuPlot::AddErrBar(const TFltV& YValV, const TFltV& DeltaYV, const TStr& Label) {
288  IAssert(YValV.Len() == DeltaYV.Len());
289  TFltKdV XYFltValV(YValV.Len(), 0);
290  for (int i = 0; i < YValV.Len(); i++) {
291  XYFltValV.Add(TFltKd(TFlt(i+1), YValV[i]));
292  }
293  return AddErrBar(XYFltValV, DeltaYV, Label);
294 }
295 
296 int TGnuPlot::AddErrBar(const TFltV& XValV, const TFltV& YValV, const TFltV& DeltaYV, const TStr& Label) {
297  IAssert(XValV.Len() == YValV.Len());
298  IAssert(XValV.Len() == DeltaYV.Len());
299  TFltKdV XYFltValV(XValV.Len(), 0);
300  for (int i = 0; i < XValV.Len(); i++) {
301  XYFltValV.Add(TFltKd(XValV[i], YValV[i]));
302  }
303  return AddErrBar(XYFltValV, DeltaYV, Label);
304 }
305 
306 int TGnuPlot::AddErrBar(const TFltPrV& XYValV, const TFltV& DeltaYV, const TStr& Label) {
307  TFltKdV XYFltValV(XYValV.Len(), 0);
308  for (int i = 0; i < XYValV.Len(); i++) {
309  XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2));
310  }
311  return AddErrBar(XYFltValV, DeltaYV, Label);
312 }
313 
314 int TGnuPlot::AddErrBar(const TFltPrV& XYValV, const TFltV& DeltaV, const TStr& DatLabel, const TStr& ErrLabel) {
315  TFltKdV XYFltValV(XYValV.Len(), 0);
316  for (int i = 0; i < XYValV.Len(); i++) {
317  XYFltValV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2));
318  }
319  const int PlotId = AddPlot(XYFltValV, gpwLinesPoints, DatLabel);
320  AddErrBar(XYFltValV, DeltaV, ErrLabel);
321  return PlotId;
322 }
323 
324 int TGnuPlot::AddErrBar(const TFltKdV& XYValV, const TFltV& DeltaYV, const TStr& Label) {
325  if (XYValV.Empty()) {
326  printf("***AddErrBar: empty plot (%s) %s\n", DataFNm.CStr(), Title.CStr());
327  return -1;
328  }
329  IAssert(XYValV.Len() == DeltaYV.Len());
330  TGpSeries Plot;
331  Plot.SeriesTy = gpwErrBars;
332  Plot.Label = Label;
333  Plot.XYValV = XYValV;
334  Plot.ZValV = DeltaYV;
335  SeriesV.Add(Plot);
336  return SeriesV.Len() - 1;
337 }
338 
339 int TGnuPlot::AddLinFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) {
340  if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1;
341  const TGpSeries& Plot = SeriesV[PlotId];
342  if(Plot.XYValV.Empty()) return -1;
343  const TFltKdV& XY = Plot.XYValV;
344  double A, B, R2, SigA, SigB, Chi2;
345  // linear fit
346  TFltPrV XYPr;
347  int s;
348  for (s = 0; s < XY.Len(); s++) {
349  XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat));
350  }
351  TSpecFunc::LinearFit(XYPr, A, B, SigA, SigB, Chi2, R2);
352  TStr StyleStr=Style;
353  if (StyleStr.Empty()) { StyleStr = "linewidth 3"; }
354  const int FitId = AddFunc(TStr::Fmt("%f+%f*x", A, B),
355  SeriesTy, TStr::Fmt("%.4g + %.4g x R^2:%.2g", A, B, R2), StyleStr);
356  return FitId;
357  /*SeriesV.Add();
358  TGpSeries& NewPlot = SeriesV.Last();
359  TFltKdV& EstXY = NewPlot.XYValV;
360  for (s = 0; s < XY.Len(); s++) {
361  EstXY.Add(TFltKd(XY[s].Key, A + B*XYPr[s].Val1));
362  }
363  NewPlot.Label = TStr::Fmt("%.4g + %.4g x R^2:%.2g", A, B, R2);
364  NewPlot.SeriesTy = SeriesTy;
365  if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; }
366  else { NewPlot.WithStyle = Style; }
367  return SeriesV.Len() - 1;*/
368 }
369 
370 int TGnuPlot::AddPwrFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) {
371  const int PlotId1 = AddPwrFit3(PlotId, SeriesTy);
372  AddPwrFit2(PlotId, SeriesTy, 5.0);
373  return PlotId1;
374 }
375 
376 // linear fit on log-log scales{%
377 int TGnuPlot::AddPwrFit1(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) {
378  if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1;
379  const TGpSeries& Plot = SeriesV[PlotId];
380  if(Plot.XYValV.Empty()) return -1;
381  const TFltKdV& XY = Plot.XYValV;
382  double A, B, R2, SigA, SigB, Chi2, MinY = TFlt::Mx, MinX = TFlt::Mx;
383  // power fit
384  TFltPrV XYPr;
385  int s;
386  for (s = 0; s < XY.Len(); s++) {
387  if (XY[s].Key > 0) {
388  XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat));
389  MinX = TMath::Mn(MinX, XY[s].Key());
390  MinY = TMath::Mn(MinY, XY[s].Dat());
391  }
392  }
393  MinY = TMath::Mn(1.0, MinY);
394  TSpecFunc::PowerFit(XYPr, A, B, SigA, SigB, Chi2, R2);
395  TStr StyleStr=Style;
396  if (StyleStr.Empty()) { StyleStr = "linewidth 3"; }
397  const int FitId = AddFunc(TStr::Fmt("%f*x**%f", A, B),
398  SeriesTy, TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2), StyleStr);
399  return FitId;
400  /*SeriesV.Add();
401  TGpSeries& NewPlot = SeriesV.Last();
402  const int FitId = SeriesV.Len() - 1;
403  NewPlot.DataFNm = ;
404  TFltKdV& EstXY = NewPlot.XYValV;
405  for (s = 0; s < XYPr.Len(); s++) {
406  const double YVal = A*pow(XYPr[s].Val1(), B);
407  if (YVal < MinY) continue;
408  EstXY.Add(TFltKd(XYPr[s].Val1, YVal));
409  }
410  NewPlot.Label = ;
411  NewPlot.SeriesTy = SeriesTy;
412  if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; }
413  else { NewPlot.WithStyle = Style; }
414  //if (MinX < 5.0) MinX = 5.0;
415  //AddPwrFit2(PlotId, SeriesTy, MinX);*/
416 }
417 
418 // MLE power-coefficient
419 int TGnuPlot::AddPwrFit2(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style) {
420  const TGpSeries& Plot = SeriesV[PlotId];
421  if(Plot.XYValV.Empty()) return -1;
422  const TFltKdV& XY = Plot.XYValV;
423  // power fit
424  TFltPrV XYPr;
425  double MinY = TFlt::Mx;
426  for (int s = 0; s < XY.Len(); s++) {
427  if (XY[s].Key > 0.0) {
428  XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat));
429  MinY = TMath::Mn(MinY, XY[s].Dat());
430  }
431  }
432  if (XYPr.Empty()) return -1;
433  MinY = TMath::Mn(1.0, MinY);
434  // determine the sign of power coefficient
435  double CoefSign = 0.0;
436  { double A, B, R2, SigA, SigB, Chi2;
437  TSpecFunc::PowerFit(XYPr, A, B, SigA, SigB, Chi2, R2);
438  CoefSign = B > 0.0 ? +1.0 : -1.0; }
439  const double PowerCf = CoefSign * TSpecFunc::GetPowerCoef(XYPr, MinX);
440  int Mid = (int) exp(log((double)XYPr.Len())/2.0);
441  if (Mid >= XYPr.Len()) { Mid = XYPr.Len()-1; }
442  const double MidX = XYPr[Mid].Val1();
443  const double MidY = XYPr[Mid].Val2();
444  const double B = MidY / pow(MidX, PowerCf);
445  TStr StyleStr=Style;
446  if (StyleStr.Empty()) { StyleStr = "linewidth 3"; }
447  const int FitId = AddFunc(TStr::Fmt("%f*x**%f", B, PowerCf),
448  SeriesTy, TStr::Fmt("MLE = x^{%.4g}", PowerCf), StyleStr);
449  return FitId;
450  /*SeriesV.Add();
451  TGpSeries& NewPlot = SeriesV.Last();
452  TFltKdV& XYFit = NewPlot.XYValV;
453  XYFit.Gen(XYPr.Len(), 0);
454  for (int s = 0; s < XYPr.Len(); s++) {
455  const double XVal = XYPr[s].Val1;
456  const double YVal = B * pow(XYPr[s].Val1(), PowerCf);
457  if (YVal < MinY || XVal < MinX) continue;
458  XYFit.Add(TFltKd(XVal, YVal));
459  }
460  NewPlot.Label = TStr::Fmt("PowerFit: %g", PowerCf);
461  NewPlot.SeriesTy = SeriesTy;
462  if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; }
463  else { NewPlot.WithStyle = Style; }
464  return SeriesV.Len() - 1;*/
465 }
466 
467 int TGnuPlot::AddPwrFit3(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style) {
468  double Intercept, Slope, R2;
469  return AddPwrFit3(PlotId, SeriesTy, MinX, Style, Intercept, Slope, R2);
470 }
471 
472 // some kind of least squares power-law fitting that cutts the tail until the fit is good
473 int TGnuPlot::AddPwrFit3(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& MinX, const TStr& Style, double& Intercept, double& Slope, double& R2) {
474  if (PlotId < 0 || PlotId >= SeriesV.Len()) return -1;
475  const TGpSeries& Plot = SeriesV[PlotId];
476  if(Plot.XYValV.Empty()) return -1;
477  double A, B, SigA, SigB, Chi2, MinY=TFlt::Mx;
478  const TFltKdV& XY = Plot.XYValV;
479  //SeriesV.Add();
480  //TGpSeries& NewPlot = SeriesV.Last();
481  //TFltKdV& EstXY = NewPlot.XYValV;
482  TFltPrV FitXY, NewFitXY;
483  for (int s = 0; s < XY.Len(); s++) {
484  if (XY[s].Key > 0 && XY[s].Key >= MinX) {
485  FitXY.Add(TFltPr(XY[s].Key, XY[s].Dat));
486  MinY = TMath::Mn(MinY, XY[s].Dat());
487  }
488  }
489  MinY = TMath::Mn(1.0, MinY);
490  // power fit (if tail is too fat, cut everything where
491  // extrapolation sets the value < MinY
492  while (true) {
493  TSpecFunc::PowerFit(FitXY, A, B, SigA, SigB, Chi2, R2);
494  NewFitXY.Clr(false);
495  //EstXY.Clr(false);
496  for (int s = 0; s < FitXY.Len(); s++) {
497  const double YVal = A*pow(FitXY[s].Val1(), B);
498  if (YVal < MinY) continue;
499  //EstXY.Add(TFltKd(FitXY[s].Val1, YVal));
500  NewFitXY.Add(TFltPr(FitXY[s].Val1, FitXY[s].Val2));
501  }
502  if (NewFitXY.Len() < 10 || FitXY.Last().Val1 < 1.2 * NewFitXY.Last().Val1) { break; }
503  else { FitXY.Swap(NewFitXY); }
504  }
505  TStr StyleStr=Style;
506  if (StyleStr.Empty()) { StyleStr = "linewidth 3"; }
507  const int FitId = AddFunc(TStr::Fmt("%f*x**%f", A, B),
508  SeriesTy, TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2), StyleStr);
509  return FitId;
510  /*NewPlot.Label = TStr::Fmt("%.1g * x^{%.4g} R^2:%.2g", A, B, R2);
511  Intercept = A;
512  Slope = B;
513  NewPlot.SeriesTy = SeriesTy;
514  if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; }
515  else { NewPlot.WithStyle = Style; }
516  return SeriesV.Len() - 1;*/
517 }
518 
519 int TGnuPlot::AddLogFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const TStr& Style) {
520  const TGpSeries& Plot = SeriesV[PlotId];
521  if(Plot.XYValV.Empty()) return -1;
522  const TFltKdV& XY = Plot.XYValV;
523  double A, B, R2, SigA, SigB, Chi2;
524  // power fit
525  TFltPrV XYPr;
526  int s;
527  for (s = 0; s < XY.Len(); s++) {
528  if (XY[s].Key > 0) {
529  XYPr.Add(TFltPr(XY[s].Key, XY[s].Dat)); }
530  }
531  TSpecFunc::LogFit(XYPr, A, B, SigA, SigB, Chi2, R2);
532  TStr StyleStr=Style;
533  if (StyleStr.Empty()) { StyleStr = "linewidth 3"; }
534  const int FitId = AddFunc(TStr::Fmt("%f+%f*log(x)", A, B),
535  SeriesTy, TStr::Fmt("%.4g + %.4g log(x) R^2:%.2g", A, B, R2), StyleStr);
536  return FitId;
537  /*SeriesV.Add();
538  TGpSeries& NewPlot = SeriesV.Last();
539  TFltKdV& EstXY = NewPlot.XYValV;
540  for (s = 0; s < XYPr.Len(); s++) {
541  EstXY.Add(TFltKd(XYPr[s].Val1, A+B*log((double)XYPr[s].Val1)));
542  }
543  NewPlot.Label = TStr::Fmt("%.4g + %.4g log(x) R^2:%.2g", A, B, R2);
544  NewPlot.SeriesTy = SeriesTy;
545  if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; }
546  else { NewPlot.WithStyle = Style; }
547  return SeriesV.Len() - 1;*/
548 }
549 
550 int TGnuPlot::AddExpFit(const int& PlotId, const TGpSeriesTy& SeriesTy, const double& FitXOffset, const TStr& Style) {
551  const TGpSeries& Plot = SeriesV[PlotId];
552  if(Plot.XYValV.Empty()) return -1;
553  const TFltKdV& XY = Plot.XYValV;
554  double A, B, R2, SigA, SigB, Chi2;
555  // power fit
556  TFltPrV XYPr;
557  int s;
558  for (s = 0; s < XY.Len(); s++) {
559  if (XY[s].Key-FitXOffset > 0) {
560  XYPr.Add(TFltPr(XY[s].Key-FitXOffset, XY[s].Dat)); }
561  }
562  TSpecFunc::ExpFit(XYPr, A, B, SigA, SigB, Chi2, R2);
563  TStr Label, StyleStr=Style;
564  if (FitXOffset == 0) { Label = TStr::Fmt("%.4g exp(%.4g x) R^2:%.2g", A, B, R2); }
565  else { Label = TStr::Fmt("%.4g exp(%.4g x - %g) R^2:%.2g", A, B, FitXOffset, R2); }
566  if (StyleStr.Empty()) { StyleStr = "linewidth 3"; }
567  const int FitId = AddFunc(TStr::Fmt("%f*exp(%f*x-%f)", A, B, FitXOffset),
568  SeriesTy, Label, StyleStr);
569  return FitId;
570  /*SeriesV.Add();
571  TGpSeries& NewPlot = SeriesV.Last();
572  TFltKdV& EstXY = NewPlot.XYValV;
573  for (s = 0; s < XYPr.Len(); s++) {
574  EstXY.Add(TFltKd(XYPr[s].Val1+FitXOffset, A*exp(B*XYPr[s].Val1)));
575  }
576  NewPlot.SeriesTy = SeriesTy;
577  if (Style.Empty()) { NewPlot.WithStyle = "linewidth 3"; }
578  else { NewPlot.WithStyle = Style; }
579  return SeriesV.Len() - 1;*/
580 }
581 
582 void TGnuPlot::SavePng(const TStr& FNm, const int& SizeX, const int& SizeY, const TStr& Comment, const TStr& Terminal) {
583  if (Terminal.Empty()) {
584  //#ifdef GLib_WIN
585  //#ifndef GLib_MACOSX // The standard GNUPlot for MacOS does not support PNG (Jure: actually version 4.6 DOES!)
586  // RS 2014/06/17 standard GNUPlot is tricky to configure for PNG on MacOS
587  AddCmd(TStr::Fmt("set terminal png font arial 10 size %d,%d", SizeX, SizeY));
588  AddCmd(TStr::Fmt("set output '%s'", FNm.CStr()));
589  //#else // EPS
590  //AddCmd("set terminal postscript eps 10 enhanced color");
591  //AddCmd(TStr::Fmt("set output '%s%s.eps'", FNm.GetFPath().CStr(), FNm.GetFMid().CStr()));
592  //#endif
593  } else {
594  AddCmd(Terminal);
595  AddCmd(TStr::Fmt("set output '%s'", FNm.CStr()));
596  }
597  Pause(false);
598  CreatePlotFile(Comment.Empty()? Title : Comment);
599  RunGnuPlot();
600  MoreCmds.DelLast();
601  MoreCmds.DelLast();
602 }
603 
604 void TGnuPlot::SaveEps(const TStr& FNm, const int& FontSz, const TStr& Comment) {
605  AddCmd(TStr::Fmt("set terminal postscript enhanced eps %d color", FontSz));
606  AddCmd(TStr::Fmt("set output '%s'", FNm.CStr()));
607  Pause(false);
608  CreatePlotFile(Comment.Empty()? Title : Comment);
609  RunGnuPlot();
610  MoreCmds.DelLast();
611  MoreCmds.DelLast();
612 }
613 
614 void TGnuPlot::MakeExpBins(const TFltPrV& XYValV, TFltPrV& ExpXYValV, const double& BinFactor, const double& MinYVal) {
615  TFltKdV KdV(XYValV.Len(), 0), OutV;
616  for (int i = 0; i < XYValV.Len(); i++) {
617  KdV.Add(TFltKd(XYValV[i].Val1, XYValV[i].Val2)); }
618  KdV.Sort();
619  TGnuPlot::MakeExpBins(KdV, OutV, BinFactor, MinYVal);
620  ExpXYValV.Gen(OutV.Len(), 0);
621  for (int i = 0; i < OutV.Len(); i++) {
622  ExpXYValV.Add(TFltPr(OutV[i].Key, OutV[i].Dat)); }
623 }
624 
625 void TGnuPlot::MakeExpBins(const TFltKdV& XYValV, TFltKdV& ExpXYValV, const double& BinFactor, const double& MinYVal) {
626  if (XYValV.Empty()) { ExpXYValV.Clr(false); return; }
627  IAssert(! XYValV.Empty());
628  IAssert(XYValV.IsSorted());
629  const TFlt MxX = XYValV.Last().Key;
630  // find buckets
631  TFltV BucketEndV; BucketEndV.Add(1);
632  double PrevBPos = 1, BPos = 1;
633  while (BPos <= MxX) {
634  PrevBPos = (uint) floor(BPos);
635  BPos *= BinFactor;
636  if (floor(BPos) == PrevBPos) {
637  BPos = PrevBPos + 1; }
638  BucketEndV.Add(floor(BPos));
639  }
640  //printf("buckets:\n"); for (int i = 0; i < BucketEndV.Len(); i++) { printf("\t%g\n", BucketEndV[i]);}
641  ExpXYValV.Gen(BucketEndV.Len(), 0);
642  int CurB = 0;
643  double AvgPos=0, Cnt=0, AvgVal=0;
644  for (int v = 0; v < XYValV.Len(); v++) {
645  if (XYValV[v].Key() == 0.0) { continue; }
646  AvgPos += XYValV[v].Key ;//* XYValV[v].Dat; // x
647  AvgVal += XYValV[v].Dat; // y
648  Cnt++;
649  if (v+1 == XYValV.Len() || XYValV[v+1].Key > BucketEndV[CurB]) {
650  if (Cnt != 0) {
651  //AvgPos /= AvgVal;
652  //AvgVal /= (BucketEndV[CurB]-BucketEndV[CurB-1]);
653  AvgPos /= (double) Cnt;
654  AvgVal /= (double) Cnt;
655  if (AvgVal < MinYVal) { AvgVal = MinYVal; }
656  ExpXYValV.Add(TFltKd(AvgPos, AvgVal));
657  //printf("b: %6.2f\t%6.2f\n", AvgPos, AvgVal);
658  AvgPos = 0; AvgVal = 0; Cnt = 0;
659  }
660  CurB++;
661  }
662  }
663 }
664 
665 void TGnuPlot::LoadTs(const TStr& FNm, TStrV& ColNmV, TVec<TFltKdV>& ColV) {
666  PSs Ss = TSs::LoadTxt(ssfTabSep, FNm);
667  int row = 0;
668  ColNmV.Clr();
669  while (Ss->At(0, row)[0] == '#') { row++; }
670  for (int c = 1; c < Ss->GetXLen(row); c+=2) {
671  ColNmV.Add(Ss->At(c, row));
672  }
673  row++;
674  ColV.Gen(ColNmV.Len(), ColNmV.Len());
675  for (; row < Ss->GetYLen(); row++) {
676  for (int c = 0; c < Ss->GetXLen(row); c+=2) {
677  if (Ss->At(c,row).Empty()) break;
678  ColV[c/2].Add(TFltKd(Ss->At(c,row).GetFlt(), Ss->At(c+1,row).GetFlt()));
679  }
680  }
681 }
682 
684  switch(ScaleTy){
685  case gpsNoAuto: return TStr("set noautoscale");
686  case gpsAuto: return TStr("set autoscale");
687  case gpsLog: return TStr("set logscale");
688  case gpsLog2X: return TStr("set logscale x 2");
689  case gpsLog2Y: return TStr("set logscale y 2");
690  case gpsLog2XY: return TStr("set logscale xy 2");
691  case gpsLog10X: return TStr("set logscale x 10");
692  case gpsLog10Y: return TStr("set logscale y 10");
693  case gpsLog10XY: return TStr("set logscale xy 10");
694  default: Fail;
695  }
696  return TStr();
697 }
698 
700  switch(SeriesTy) {
701  case gpwLines: return TStr("lines");
702  case gpwPoints: return TStr("points");
703  case gpwLinesPoints: return TStr("linespoints");
704  case gpwImpulses: return TStr("impulses");
705  case gpwDots: return TStr("dots");
706  case gpwSteps: return TStr("steps");
707  case gpwFSteps: return TStr("fsteps");
708  case gpwHiSteps: return TStr("histeps");
709  case gpwBoxes: return TStr("boxes");
710  case gpwErrBars: return TStr("errorbars");
711  case gpwFilledCurves: return TStr("filledcurves");
712  default: Fail;
713  }
714  return TStr();
715 }
716 
717 void TGnuPlot::SaveTs(const TIntKdV& KdV, const TStr& FNm, const TStr& HeadLn) {
718  FILE *F = fopen(FNm.CStr(), "wt");
719  EAssert(F);
720  if (! HeadLn.Empty()) fprintf(F, "# %s\n", HeadLn.CStr());
721  for (int i = 0; i < KdV.Len(); i++) {
722  fprintf(F, "%d\t%d\n", KdV[i].Key(), KdV[i].Dat()); }
723  fclose(F);
724 }
725 
726 
727 void TGnuPlot::SaveTs(const TIntFltKdV& KdV, const TStr& FNm, const TStr& HeadLn) {
728  FILE *F = fopen(FNm.CStr(), "wt");
729  EAssert(F);
730  if (! HeadLn.Empty()) fprintf(F, "# %s\n", HeadLn.CStr());
731  for (int i = 0; i < KdV.Len(); i++)
732  fprintf(F, "%d\t%g\n", KdV[i].Key(), KdV[i].Dat());
733  fclose(F);
734 }
735 
737  TFltV DeltaY;
738  TFltPrV ValV1, ValV2, ValV3;
739  for (int i = 1; i < 30; i++) {
740  ValV1.Add(TFltPr(i, pow(double(i), 1.2)));
741  DeltaY.Add(5*TInt::Rnd.GetUniDev());
742  ValV2.Add(TFltPr(i, 5*i-1));
743  }
744  for (int i = -10; i < 20; i++) {
745  ValV3.Add(TFltPr(i, 2*i + 2 + TInt::Rnd.GetUniDev()));
746  }
747  TGnuPlot GnuPlot("testDat", "TestPlot", true);
748  GnuPlot.SetXYLabel("X", "Y");
749  const int id2 = GnuPlot.AddPlot(ValV2, gpwPoints, "y=5*x-1");
750  const int id3 = GnuPlot.AddPlot(ValV3, gpwPoints, "y=2*x+2");
751  GnuPlot.AddErrBar(ValV1, DeltaY, "y=x^2", "Error bar");
752  GnuPlot.AddLinFit(id2, gpwLines);
753  GnuPlot.AddLinFit(id3, gpwLines);
754  GnuPlot.Plot();
755  GnuPlot.SavePng("testPlot.png");
756 }
757 
758 int TGnuPlot::IsSameXCol(const int& CurId, const int& PrevId) const {
759  //if (SerId < 1) { return -1; }
760  if (SeriesV[CurId].XYValV.Len() != SeriesV[PrevId].XYValV.Len()) { return -1; }
761  for (int x = 0; x < SeriesV[CurId].XYValV.Len(); x++) {
762  if (SeriesV[CurId].XYValV[x] != SeriesV[PrevId].XYValV[x]) { return -1; }
763  }
764  IAssert(SeriesV[PrevId].XCol > 0);
765  return SeriesV[PrevId].XCol;
766 }
767 
768 void TGnuPlot::CreatePlotFile(const TStr& Comment) {
769  time_t ltime; time(&ltime);
770  char* TimeStr = ctime(&ltime); TimeStr[strlen(TimeStr) - 1] = 0;
771  // rearrange columns so that longest are on the left
772  //SeriesV.Sort(false);
773  TIntV SerIdV(SeriesV.Len(), 0);
774  for (int i = 0; i < SeriesV.Len(); i++) { SerIdV.Add(i); }
775  SerIdV.SortCmp(TGpSeriesCmp(SeriesV));
776  // set columns
777  int ColCnt = 1;
778  bool SaveData = false;
779  for (int s = 0; s < SeriesV.Len(); s++) {
780  TGpSeries& Plt = SeriesV[SerIdV[s]];
781  if (Plt.XYValV.Empty()) { continue; }
782  Plt.DataFNm = DataFNm;
783  // plots use same X column
784  const int PrevCol = s > 0 ? IsSameXCol(SerIdV[s], SerIdV[s-1]) : -1;
785  if (PrevCol != -1) { Plt.XCol = PrevCol; }
786  else { Plt.XCol = ColCnt; ColCnt++; }
787  Plt.YCol = ColCnt; ColCnt++;
788  if (! Plt.ZValV.Empty()) { Plt.ZCol = ColCnt; ColCnt++; }
789  if (! Plt.XYValV.Empty()) { SaveData=true; }
790  }
791  // save data file (skip duplicate X columns)
792  if (SaveData) {
793  FILE *F = fopen(DataFNm.CStr(), "wt");
794  EAssertR(F != NULL, TStr("Can not open data file ")+DataFNm);
795  fprintf(F, "#\n");
796  fprintf(F, "# %s (%s)\n", Comment.CStr(), TimeStr);
797  fprintf(F, "#\n");
798  // column names
799  for (int i = 0; i < SerIdV.Len(); i++) {
800  const TGpSeries& Ser = SeriesV[SerIdV[i]];
801  if (Ser.XYValV.Empty()) { continue; }
802  if (i == 0) { fprintf(F, "# "); } else { fprintf(F, "\t"); }
803  if (Ser.SaveXVals()) {
804  if (! LblX.Empty()) { fprintf(F, "%s\t", LblX.CStr()); }
805  else { fprintf(F, "XVals\t"); }
806  }
807  if (Ser.Label.Empty()) { fprintf(F, "%s", LblY.CStr()); }
808  else { fprintf(F, "%s", SeriesV[SerIdV[i]].Label.CStr()); }
809  if (Ser.ZCol > 0) fprintf(F, "\tDeltaY");
810  }
811  fprintf(F, "\n");
812  // data
813  for (int row = 0; row < SeriesV[SerIdV[0]].XYValV.Len(); row++) {
814  for (int i = 0; i < SeriesV.Len(); i++) {
815  const TGpSeries& Ser = SeriesV[SerIdV[i]];
816  if (row < Ser.XYValV.Len()) {
817  if (i > 0) { fprintf(F, "\t"); }
818  if (Ser.SaveXVals()) { fprintf(F, "%g\t%g", Ser.XYValV[row].Key(), Ser.XYValV[row].Dat()); }
819  else { fprintf(F, "%g", Ser.XYValV[row].Dat()); }
820  if (! Ser.ZValV.Empty()) { fprintf(F, "\t%g", Ser.ZValV[row]()); }
821  }
822  }
823  fprintf(F, "\n");
824  }
825  fclose(F);
826  }
827  // save plot file
828  FILE *F = fopen(PlotFNm.CStr(), "wt");
829  EAssertR(F != 0, TStr("Can not open plot file ")+PlotFNm);
830  TStr CurDir = TDir::GetCurDir();
831  CurDir.ChangeStrAll("\\", "\\\\");
832  fprintf(F, "#\n");
833  fprintf(F, "# %s (%s)\n", Comment.CStr(), TimeStr);
834  fprintf(F, "#\n\n");
835  if (! Title.Empty()) fprintf(F, "set title \"%s\"\n", Title.CStr());
836  fprintf(F, "set key bottom right\n");
837  fprintf(F, "%s\n", GetScaleStr(ScaleTy).CStr());
839  fprintf(F, "set format x \"10^{%%L}\"\n");
840  fprintf(F, "set mxtics 10\n"); }
842  fprintf(F, "set format y \"10^{%%L}\"\n");
843  fprintf(F, "set mytics 10\n"); }
844  if (ScaleTy==gpsLog2X || ScaleTy==gpsLog2XY) { fprintf(F, "set format x \"2^{%%L}\"\n"); }
845  if (ScaleTy==gpsLog2Y || ScaleTy==gpsLog2XY) { fprintf(F, "set format y \"2^{%%L}\"\n"); }
846  if (SetGrid) fprintf(F, "set grid\n");
847  if (XRange.Val1 != XRange.Val2) fprintf(F, "set xrange [%g:%g]\n", XRange.Val1(), XRange.Val2());
848  if (YRange.Val1 != YRange.Val2) fprintf(F, "set yrange [%g:%g]\n", YRange.Val1(), YRange.Val2());
849  if (! LblX.Empty()) fprintf(F, "set xlabel \"%s\"\n", LblX.CStr());
850  if (! LblY.Empty()) fprintf(F, "set ylabel \"%s\"\n", LblY.CStr());
851  if (Tics42 < -1) {
852  Tics42 = GetTics42();
853  }
854  if (Tics42) {
855  fprintf(F, "set tics scale 2\n"); // New in version 4.2
856  } else {
857  fprintf(F, "set ticscale 2 1\n"); // Old (deprecated)
858  }
859  // custom commands
860  for (int i = 0; i < MoreCmds.Len(); i++) {
861  fprintf(F, "%s\n", MoreCmds[i].CStr()); }
862  // plot
863  if (! SeriesV.Empty()) {
864  fprintf(F, "plot \t");
865  for (int i = 0; i < SeriesV.Len(); i++) {
866  fprintf(F, "%s", GetSeriesPlotStr(i).CStr()); }
867  fprintf(F, "\n");
868  }
869  if (SetPause) fprintf(F, "pause -1 \"Hit return to exit. %s\"\n", PlotFNm.CStr());
870  fclose(F);
871 }
872 
873 void TGnuPlot::RunGnuPlot() const {
874  // try running gnuplot
875  if (system(TStr::Fmt("%s %s", GnuPlotFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; }
876  if (! GnuPlotPath.Empty()) {
877  #if defined(GLib_WIN)
878  if (system(TStr::Fmt("%s\\%s %s", GnuPlotPath.CStr(), GnuPlotFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; }
879  #else
880  if (system(TStr::Fmt("%s/%s %s", GnuPlotPath.CStr(), GnuPlotFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; }
881  #endif
882  }
883  //Old
884  //#if defined(GLib_WIN)
885  //if (system(TStr::Fmt(".\\%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; }
886  //#else
887  //if (system(TStr::Fmt("./%s %s", GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; }
888  //#endif
889  //if (system(TStr::Fmt("%s%s %s", GpPath.CStr(), GpFNm.CStr(), PlotFNm.CStr()).CStr())==0) { return; }
890  //FailR(TStr::Fmt("Cannot find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr());
891  //ErrNotify(TStr::Fmt("Cannot find GnuPlot (%s) for plot %s. Set the PATH.", GpFNm.CStr(), PlotFNm.CStr()).CStr());
892  fprintf(stderr, "[%s:%d] Cannot find GnuPlot (%s) for plot %s. Set the $$PATH variable or TGnuPlot::GnuPlotPath. (%s)\n", __FILE__, __LINE__, GnuPlotFNm.CStr(), PlotFNm.CStr(), TGnuPlot::GnuPlotPath.CStr());
893 }
894 
TGnuPlot & operator=(const TGnuPlot &GnuPlot)
Definition: gnuplot.cpp:106
#define IAssert(Cond)
Definition: bd.h:262
static const T & Mn(const T &LVal, const T &RVal)
Definition: xmath.h:36
static TStr GetCurDir()
Definition: xfl.cpp:233
int AddLinFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
Definition: gnuplot.cpp:339
TFltPr XRange
Definition: gnuplot.h:53
TStr GetStr() const
Definition: dt.h:1197
int AddExpFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const double &FitXOffset=0.0, const TStr &Style=TStr())
Definition: gnuplot.cpp:550
TStr Title
Definition: gnuplot.h:51
bool operator<(const TGpSeries &Gps) const
Definition: gnuplot.cpp:82
TGpSeriesTy SeriesTy
Definition: gnuplot.h:27
static PSs LoadTxt(const TSsFmt &SsFmt, const TStr &FNm, const PNotify &Notify=NULL, const bool &IsExcelEoln=true, const int &MxY=-1, const TIntV &AllowedColNV=TIntV(), const bool &IsQStr=true)
Definition: ss.cpp:100
static void MakeExpBins(const TFltPrV &XYValV, TFltPrV &ExpXYValV, const double &BinFactor=2, const double &MinYVal=1)
Definition: gnuplot.cpp:614
void SavePng(const int &SizeX=1000, const int &SizeY=800, const TStr &Comment=TStr())
Definition: gnuplot.h:120
TStr DataFNm
Definition: gnuplot.h:50
static void PowerFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
Definition: xmath.cpp:193
unsigned int uint
Definition: bd.h:11
TGnuPlot(const TStr &FileNm="gplot", const TStr &PlotTitle=TStr(), const bool &Grid=true)
Definition: gnuplot.cpp:86
#define Fail
Definition: bd.h:238
bool Empty() const
Definition: bd.h:501
static void ExpFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
Definition: xmath.cpp:218
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
static void LogFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
Definition: xmath.cpp:208
void SetXYLabel(const TStr &XLabel, const TStr &YLabel)
Definition: gnuplot.h:73
static int GetTics42()
Definition: gnuplot.cpp:26
int AddPwrFit3(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const double &MinX=-1.0, const TStr &Style=TStr())
Definition: gnuplot.cpp:467
TKeyDat< TFlt, TFlt > TFltKd
Definition: ds.h:396
TGpSeries & operator=(const TGpSeries &Gps)
Definition: gnuplot.cpp:70
void Plot(const TStr &Comment=TStr())
Definition: gnuplot.h:126
TStr LblY
Definition: gnuplot.h:51
TVec< TGpSeries > SeriesV
Definition: gnuplot.h:55
Definition: gnuplot.h:7
static TRnd Rnd
Definition: dt.h:1143
static const double Mx
Definition: dt.h:1388
int AddPwrFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
Definition: gnuplot.cpp:370
Definition: dt.h:1383
bool Empty() const
Tests whether the vector is empty.
Definition: ds.h:570
static void LoadTs(const TStr &FNm, TStrV &ColNmV, TVec< TFltKdV > &ColV)
Definition: gnuplot.cpp:665
void Swap(TVec< TVal, TSizeTy > &Vec)
Swaps the contents of the vector with Vec.
Definition: ds.h:1101
static void SaveTs(const TIntKdV &KdV, const TStr &FNm, const TStr &HeadLn=TStr())
Definition: gnuplot.cpp:717
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
Definition: ds.h:1022
int ChangeStrAll(const TStr &SrcStr, const TStr &DstStr, const bool &FromStartP=false)
Definition: dt.cpp:1141
void AddCmd(const TStr &Cmd)
Definition: gnuplot.h:81
Definition: gnuplot.h:7
TFltKdV XYValV
Definition: gnuplot.h:28
static TStr GetSeriesTyStr(const TGpSeriesTy &SeriesTy)
Definition: gnuplot.cpp:699
bool SetPause
Definition: gnuplot.h:54
int AddLogFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
Definition: gnuplot.cpp:519
bool SetGrid
Definition: gnuplot.h:54
void Pause(const bool &DoPause)
Definition: gnuplot.h:77
const TVal & Last() const
Returns a reference to the last element of the vector.
Definition: ds.h:579
Tab separated.
Definition: ss.h:6
bool SaveXVals() const
Definition: gnuplot.h:37
TPair< TFlt, TFlt > TFltPr
Definition: ds.h:99
void SaveEps(const int &FontSz=30, const TStr &Comment=TStr())
Definition: gnuplot.h:123
TGpScaleTy ScaleTy
Definition: gnuplot.h:52
int AddPwrFit2(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const double &MinX=-1.0, const TStr &Style=TStr())
Definition: gnuplot.cpp:419
static double GetPowerCoef(const TFltV &XValV, double MinX=-1.0)
Definition: xmath.cpp:299
Definition: dt.h:201
#define EAssert(Cond)
Definition: bd.h:280
TStr LblX
Definition: gnuplot.h:51
int IsSameXCol(const int &CurId, const int &PrevId) const
Definition: gnuplot.cpp:758
TKey Key
Definition: ds.h:348
Definition: dt.h:412
bool Empty() const
Definition: dt.h:488
static TStr DefDataFNm
Definition: gnuplot.h:23
static TStr Fmt(const char *FmtStr,...)
Definition: dt.cpp:1599
bool IsSorted(const bool &Asc=true) const
Checks whether the vector is sorted in ascending (if Asc=true) or descending (if Asc=false) order...
Definition: ds.h:1323
static TStr GnuPlotPath
Path to GnuPlot executable. Set if gnuplot is not found in the PATH.
Definition: gnuplot.h:19
#define EAssertR(Cond, MsgStr)
Definition: bd.h:283
TFltPr YRange
Definition: gnuplot.h:53
TVal1 Val1
Definition: ds.h:34
int AddPlot(const TIntV &YValV, const TGpSeriesTy &SeriesTy=gpwLinesPoints, const TStr &Label=TStr(), const TStr &Style=TStr())
Definition: gnuplot.cpp:186
TVal2 Val2
Definition: ds.h:35
Definition: bd.h:196
static TStr DefPlotFNm
Definition: gnuplot.h:22
static void LinearFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
Definition: xmath.cpp:150
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
Definition: ds.h:523
static void Test()
Definition: gnuplot.cpp:736
static TStr GetScaleStr(const TGpScaleTy &ScaleTy)
Definition: gnuplot.cpp:683
int AddPwrFit1(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
Definition: gnuplot.cpp:377
int AddErrBar(const TFltTrV &XYDValV, const TStr &Label=TStr())
Definition: gnuplot.cpp:265
char * CStr()
Definition: dt.h:476
TStr GetSeriesPlotStr(const int &PlotN)
Definition: gnuplot.cpp:124
void RunGnuPlot() const
Definition: gnuplot.cpp:873
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602
static TStr GnuPlotFNm
GnuPlot executable file name. Set if different than the standard wgnuplot/gnuplot.
Definition: gnuplot.h:21
TStr PlotFNm
Definition: gnuplot.h:50
void DelLast()
Removes the last element of the vector.
Definition: ds.h:665
TGpScaleTy
Definition: gnuplot.h:6
static int Tics42
Definition: gnuplot.h:48
void CreatePlotFile(const TStr &Comment=TStr())
Definition: gnuplot.cpp:768
TGpSeriesTy
Definition: gnuplot.h:11
int AddFunc(const TStr &FuncStr, const TGpSeriesTy &SeriesTy=gpwLinesPoints, const TStr &Label=TStr(), const TStr &Style=TStr())
Definition: gnuplot.cpp:155
TStrV MoreCmds
Definition: gnuplot.h:56