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";
 
   18   TStr TGnuPlot::GnuPlotPath = 
"/usr/bin";
 
   19   TStr TGnuPlot::GnuPlotFNm = 
"gnuplot";
 
   36   p = popen(
TStr::Fmt(
"%s -V", TGnuPlot::GnuPlotFNm.CStr()).CStr(), 
"r");
 
   38     p = popen(
TStr::Fmt(
"%s/%s -V", TGnuPlot::GnuPlotPath.CStr(), TGnuPlot::GnuPlotFNm.CStr()).CStr(), 
"r");
 
   39     if (p == NULL) { 
return -1; }
 
   41   n = fread(Buf, 1, 100, p);
 
   42   if (n <= 0) { 
return -1; }
 
   46   n = sscanf(Buf, 
"gnuplot %s", Version);
 
   47   if (n <= 0) { 
return -1; }
 
   49   if ((strlen(Version) < 3) || (Version[1] != 
'.')) { 
return -1; }
 
   51   if ((Version[0] < 
'4') || ((Version[0] == 
'4') && (Version[2] < 
'2'))) {
 
   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) {
 
   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() {
 
  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) {
 
  107   if (
this != &GnuPlot) {
 
  127   if (SeriesId != 0) PlotStr += 
",\\\n\t";
 
  128   if (Series.
XCol >= 0) {
 
  139     PlotStr += 
" notitle";
 
  141     PlotStr += 
" title \"" + Series.
Label + 
"\"";
 
  170   return AddPlot(DataFNm, 0, ColY, SeriesTy, Label, Style);
 
  188   for (
int i = 0; i < YValV.
Len(); i++) {
 
  191   return AddPlot(XYValV, SeriesTy, Label, Style);
 
  196   for (
int i = 0; i < YValV.
Len(); i++) {
 
  199   return AddPlot(XYValV, SeriesTy, Label, Style);
 
  205   for (
int i = 0; i < YValV.
Len(); i++) {
 
  208   return AddPlot(XYValV, SeriesTy, Label, Style);
 
  213   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  216   return AddPlot(XYFltValV, SeriesTy, Label, Style);
 
  221   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  222     XYFltValV.
Add(
TFltKd(XYValV[i].Val1, XYValV[i].Val2));
 
  224   return AddPlot(XYFltValV, SeriesTy, Label, Style);
 
  229   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  232   return AddPlot(XYFltValV, SeriesTy, Label, Style);
 
  237   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  240   return AddPlot(XYFltValV, SeriesTy, Label, Style);
 
  245   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  248   return AddPlot(XYFltValV, SeriesTy, Label, Style);
 
  252   if (XYValV.
Empty()) {
 
  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);
 
  272   return AddErrBar(XYFltValV, DeltaV, Label);
 
  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);
 
  290   for (
int i = 0; i < YValV.
Len(); i++) {
 
  293   return AddErrBar(XYFltValV, DeltaYV, Label);
 
  300   for (
int i = 0; i < XValV.
Len(); i++) {
 
  301     XYFltValV.
Add(
TFltKd(XValV[i], YValV[i]));
 
  303   return AddErrBar(XYFltValV, DeltaYV, Label);
 
  308   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  309     XYFltValV.
Add(
TFltKd(XYValV[i].Val1, XYValV[i].Val2));
 
  311   return AddErrBar(XYFltValV, DeltaYV, Label);
 
  316   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  317     XYFltValV.
Add(
TFltKd(XYValV[i].Val1, XYValV[i].Val2));
 
  325   if (XYValV.
Empty()) {
 
  333   Plot.XYValV = XYValV;
 
  334   Plot.ZValV = DeltaYV;
 
  340   if (PlotId < 0 || PlotId >= 
SeriesV.Len()) 
return -1;
 
  344   double A, B, R2, SigA, SigB, Chi2;
 
  348   for (s = 0; s < XY.
Len(); s++) {
 
  353   if (StyleStr.
Empty()) { StyleStr = 
"linewidth 3"; }
 
  355     SeriesTy, 
TStr::Fmt(
"%.4g + %.4g x  R^2:%.2g", A, B, R2), StyleStr);
 
  371   const int PlotId1 = 
AddPwrFit3(PlotId, SeriesTy);
 
  378   if (PlotId < 0 || PlotId >= 
SeriesV.Len()) 
return -1;
 
  386   for (s = 0; s < XY.
Len(); s++) {
 
  396   if (StyleStr.
Empty()) { StyleStr = 
"linewidth 3"; }
 
  398     SeriesTy, 
TStr::Fmt(
"%.1g * x^{%.4g}  R^2:%.2g", A, B, R2), StyleStr);
 
  426   for (
int s = 0; s < XY.
Len(); s++) {
 
  427     if (XY[s].Key > 0.0) {
 
  432   if (XYPr.
Empty()) 
return -1;
 
  435   double CoefSign = 0.0;
 
  436   { 
double A, B, R2, SigA, SigB, Chi2;
 
  438   CoefSign = B > 0.0 ? +1.0 : -1.0; }
 
  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);
 
  446   if (StyleStr.
Empty()) { StyleStr = 
"linewidth 3"; }
 
  448     SeriesTy, 
TStr::Fmt(
"MLE = x^{%.4g}", PowerCf), StyleStr);
 
  468   double Intercept, Slope, R2;
 
  469   return AddPwrFit3(PlotId, SeriesTy, MinX, Style, Intercept, Slope, R2);
 
  474   if (PlotId < 0 || PlotId >= 
SeriesV.Len()) 
return -1;
 
  477   double A, B, SigA, SigB, Chi2, MinY=
TFlt::Mx;
 
  483   for (
int s = 0; s < XY.
Len(); s++) {
 
  484     if (XY[s].Key > 0 && XY[s].Key >= MinX) {
 
  496     for (
int s = 0; s < FitXY.
Len(); s++) {
 
  497       const double YVal = A*pow(FitXY[s].Val1(), B);
 
  498       if (YVal < MinY) 
continue;
 
  500       NewFitXY.
Add(
TFltPr(FitXY[s].Val1, FitXY[s].Val2));
 
  503     else { FitXY.
Swap(NewFitXY); }
 
  506   if (StyleStr.
Empty()) { StyleStr = 
"linewidth 3"; }
 
  508     SeriesTy, 
TStr::Fmt(
"%.1g * x^{%.4g}  R^2:%.2g", A, B, R2), StyleStr);
 
  523   double A, B, R2, SigA, SigB, Chi2;
 
  527   for (s = 0; s < XY.
Len(); s++) {
 
  529       XYPr.
Add(
TFltPr(XY[s].Key, XY[s].Dat)); } 
 
  533   if (StyleStr.
Empty()) { StyleStr = 
"linewidth 3"; }
 
  535     SeriesTy, 
TStr::Fmt(
"%.4g + %.4g log(x)  R^2:%.2g", A, B, R2), StyleStr);
 
  554   double A, B, R2, SigA, SigB, Chi2;
 
  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)); } 
 
  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"; }
 
  568     SeriesTy, Label, StyleStr);
 
  583   if (Terminal.
Empty()) {
 
  587     AddCmd(
TStr::Fmt(
"set terminal png font arial 10 size %d,%d", SizeX, SizeY));
 
  605   AddCmd(
TStr::Fmt(
"set terminal postscript enhanced eps %d color", FontSz));
 
  616   for (
int i = 0; i < XYValV.
Len(); i++) {
 
  617     KdV.
Add(
TFltKd(XYValV[i].Val1, XYValV[i].Val2)); }
 
  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)); }
 
  626   if (XYValV.
Empty()) { ExpXYValV.
Clr(
false); 
return; }
 
  631   TFltV BucketEndV; BucketEndV.
Add(1);
 
  632   double PrevBPos = 1, BPos = 1;
 
  633   while (BPos <= MxX) {
 
  634     PrevBPos = (
uint) floor(BPos);
 
  636     if (floor(BPos) == PrevBPos) {
 
  637       BPos = PrevBPos + 1; }
 
  638     BucketEndV.
Add(floor(BPos));
 
  641   ExpXYValV.
Gen(BucketEndV.
Len(), 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 ;
 
  647     AvgVal += XYValV[v].Dat;  
 
  649     if (v+1 == XYValV.
Len() || XYValV[v+1].Key > BucketEndV[CurB]) {
 
  653         AvgPos /= (double) Cnt;
 
  654         AvgVal /= (double) Cnt;
 
  655         if (AvgVal < MinYVal) { AvgVal = MinYVal; }
 
  658         AvgPos = 0;  AvgVal = 0;  Cnt = 0;
 
  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));
 
  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()));
 
  718   FILE *F = fopen(FNm.
CStr(), 
"wt");
 
  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()); }
 
  728   FILE *F = fopen(FNm.
CStr(), 
"wt");
 
  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());
 
  739   for (
int i = 1; i < 30; i++) {
 
  740     ValV1.
Add(
TFltPr(i, pow(
double(i), 1.2)));
 
  744   for (
int i = -10; i < 20; i++) {
 
  747   TGnuPlot GnuPlot(
"testDat", 
"TestPlot", 
true);
 
  751   GnuPlot.
AddErrBar(ValV1, DeltaY, 
"y=x^2", 
"Error bar");
 
  755   GnuPlot.
SavePng(
"testPlot.png");
 
  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; }
 
  769   time_t ltime;  time(<ime);
 
  770   char* TimeStr = ctime(<ime);  TimeStr[strlen(TimeStr) - 1] = 0;
 
  774   for (
int i = 0; i < 
SeriesV.Len(); i++) { SerIdV.
Add(i); }
 
  778   bool SaveData = 
false;
 
  779   for (
int s = 0; s < 
SeriesV.Len(); s++) {
 
  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++;
 
  796     fprintf(F, 
"# %s (%s)\n", Comment.
CStr(), TimeStr);
 
  799     for (
int i = 0; i < SerIdV.Len(); i++) {
 
  802       if (i == 0) { fprintf(F, 
"# "); } 
else { fprintf(F, 
"\t"); }
 
  805         else { fprintf(F, 
"XVals\t"); }
 
  808       else { fprintf(F, 
"%s", 
SeriesV[SerIdV[i]].Label.CStr()); }
 
  809       if (Ser.
ZCol > 0) fprintf(F, 
"\tDeltaY");
 
  813     for (
int row = 0; row < 
SeriesV[SerIdV[0]].XYValV.Len(); row++) {
 
  814       for (
int i = 0; i < 
SeriesV.Len(); i++) {
 
  817           if (i > 0) { fprintf(F, 
"\t"); }
 
  819           else { fprintf(F, 
"%g", Ser.
XYValV[row].Dat()); }
 
  833   fprintf(F, 
"# %s (%s)\n", Comment.
CStr(), TimeStr);
 
  836   fprintf(F, 
"set key bottom right\n");
 
  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"); }
 
  846   if (
SetGrid) fprintf(F, 
"set grid\n");
 
  855     fprintf(F, 
"set tics scale 2\n"); 
 
  857     fprintf(F, 
"set ticscale 2 1\n"); 
 
  861     fprintf(F, 
"%s\n", 
MoreCmds[i].CStr()); }
 
  864     fprintf(F, 
"plot \t");
 
  865     for (
int i = 0; i < 
SeriesV.Len(); i++) {
 
  877     #if defined(GLib_WIN) 
  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());
 
TGnuPlot & operator=(const TGnuPlot &GnuPlot)
 
static const T & Mn(const T &LVal, const T &RVal)
 
int AddLinFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
 
int AddExpFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const double &FitXOffset=0.0, const TStr &Style=TStr())
 
bool operator<(const TGpSeries &Gps) const 
 
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)
 
static void MakeExpBins(const TFltPrV &XYValV, TFltPrV &ExpXYValV, const double &BinFactor=2, const double &MinYVal=1)
 
void SavePng(const int &SizeX=1000, const int &SizeY=800, const TStr &Comment=TStr())
 
static void PowerFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
 
TGnuPlot(const TStr &FileNm="gplot", const TStr &PlotTitle=TStr(), const bool &Grid=true)
 
static void ExpFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
 
TSizeTy Len() const 
Returns the number of elements in the vector. 
 
static void LogFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
 
void SetXYLabel(const TStr &XLabel, const TStr &YLabel)
 
int AddPwrFit3(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const double &MinX=-1.0, const TStr &Style=TStr())
 
TKeyDat< TFlt, TFlt > TFltKd
 
TGpSeries & operator=(const TGpSeries &Gps)
 
void Plot(const TStr &Comment=TStr())
 
TVec< TGpSeries > SeriesV
 
int AddPwrFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
 
bool Empty() const 
Tests whether the vector is empty. 
 
static void LoadTs(const TStr &FNm, TStrV &ColNmV, TVec< TFltKdV > &ColV)
 
void Swap(TVec< TVal, TSizeTy > &Vec)
Swaps the contents of the vector with Vec. 
 
static void SaveTs(const TIntKdV &KdV, const TStr &FNm, const TStr &HeadLn=TStr())
 
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector. 
 
int ChangeStrAll(const TStr &SrcStr, const TStr &DstStr, const bool &FromStartP=false)
 
void AddCmd(const TStr &Cmd)
 
static TStr GetSeriesTyStr(const TGpSeriesTy &SeriesTy)
 
int AddLogFit(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
 
void Pause(const bool &DoPause)
 
const TVal & Last() const 
Returns a reference to the last element of the vector. 
 
TPair< TFlt, TFlt > TFltPr
 
void SaveEps(const int &FontSz=30, const TStr &Comment=TStr())
 
int AddPwrFit2(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const double &MinX=-1.0, const TStr &Style=TStr())
 
static double GetPowerCoef(const TFltV &XValV, double MinX=-1.0)
 
int IsSameXCol(const int &CurId, const int &PrevId) const 
 
static TStr Fmt(const char *FmtStr,...)
 
bool IsSorted(const bool &Asc=true) const 
Checks whether the vector is sorted in ascending (if Asc=true) or descending (if Asc=false) order...
 
static TStr GnuPlotPath
Path to GnuPlot executable. Set if gnuplot is not found in the PATH. 
 
#define EAssertR(Cond, MsgStr)
 
int AddPlot(const TIntV &YValV, const TGpSeriesTy &SeriesTy=gpwLinesPoints, const TStr &Label=TStr(), const TStr &Style=TStr())
 
static void LinearFit(const TVec< TFltPr > &XY, double &A, double &B, double &SigA, double &SigB, double &Chi2, double &R2)
 
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements. 
 
static TStr GetScaleStr(const TGpScaleTy &ScaleTy)
 
int AddPwrFit1(const int &PlotId, const TGpSeriesTy &SeriesTy=gpwLines, const TStr &Style=TStr())
 
int AddErrBar(const TFltTrV &XYDValV, const TStr &Label=TStr())
 
TStr GetSeriesPlotStr(const int &PlotN)
 
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element. 
 
static TStr GnuPlotFNm
GnuPlot executable file name. Set if different than the standard wgnuplot/gnuplot. 
 
void DelLast()
Removes the last element of the vector. 
 
void CreatePlotFile(const TStr &Comment=TStr())
 
int AddFunc(const TStr &FuncStr, const TGpSeriesTy &SeriesTy=gpwLinesPoints, const TStr &Label=TStr(), const TStr &Style=TStr())