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())