SNAP Library 6.0, Developer Reference  2020-12-09 16:24:20
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
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:1200
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:1146
static const double Mx
Definition: dt.h:1391
int AddPwrFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
Definition: gnuplot.cpp:370
Definition: dt.h:1386
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:491
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:479
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