TGraph synchronization

Every plotting object probably should have same title setting functions.

I think I should be able to set the titles for TGraph when constructed, i.e. ROOT.TGraph(name,“title; xtitle;y title”, n, x, y)

I should probably be able to set the titles using TGraph.SetTitle(title,xtitle,ytitle,ztitle)

TGraph.SetTitle(“title;titlex;titley”) works

And of course, by default, it would be nice if the titles were not off of the canvas when drawn.

I think the standard for plots are square plots these days, and they should plot themselves successfully by default.

It is a pain point to consult the reference guide for little quirks like this.

Furthermore the ROOT: TCanvas Class Reference TCanvas references should include x and y axis titles in the examples.

Graph.pdf (13.3 KB)

Not necessarily. ATLAS’ style guide suggest using either rectangular (800x600 pixels) or square (600x600 pixels) plots.

Of course not necessarily, which is why you can change dimensions. But like you said, square is recommended and margins should be updated thusly when a title is added.

800x600 if axis has title, then plot is still square. 600x600 with no title on y axis, square plot

Yes, we try to do it this way.

This can be understood only if you know the TGraph history: At the beginning of ROOT TGraph was a graphical object only. Like TLine and it behaved the same way. With time it was promoted as an analysis object like TH1. I agree we could have implemented a such constructor.

But, if we want to be consistent we need to duplicate all the normal constructors, not only in TGraph but also for the inherited classes. That makes a total of 14 constructors to be duplicated:

TGraph (Int_t n)
TGraph (Int_t n, const Double_t *x, const Double_t *y)
TGraph (Int_t n, const Double_t *y, Double_t start=0., Double_t step=1.)
TGraph (Int_t n, const Float_t *x, const Float_t *y)
TGraph (Int_t n, const Int_t *x, const Int_t *y)
TGraphAsymmErrors (Int_t n)
TGraphAsymmErrors (Int_t n, const Double_t *x, const Double_t *y, const Double_t *exl=nullptr, const Double_t *exh=nullptr, const Double_t *eyl=nullptr, const Double_t *eyh=nullptr)
TGraphAsymmErrors (Int_t n, const Float_t *x, const Float_t *y, const Float_t *exl=nullptr, const Float_t *exh=nullptr, const Float_t *eyl=nullptr, const Float_t *eyh=nullptr)
TGraphBentErrors (Int_t n)
TGraphBentErrors (Int_t n, const Double_t *x, const Double_t *y, const Double_t *exl=nullptr, const Double_t *exh=nullptr, const Double_t *eyl=nullptr, const Double_t *eyh=nullptr, const Double_t *exld=nullptr, const Double_t *exhd=nullptr, const Double_t *eyld=nullptr, const Double_t *eyhd=nullptr)
TGraphBentErrors (Int_t n, const Float_t *x, const Float_t *y, const Float_t *exl=nullptr, const Float_t *exh=nullptr, const Float_t *eyl=nullptr, const Float_t *eyh=nullptr, const Float_t *exld=nullptr, const Float_t *exhd=nullptr, const Float_t *eyld=nullptr, const Float_t *eyhd=nullptr)
TGraphErrors (Int_t n)
TGraphErrors (Int_t n, const Double_t *x, const Double_t *y, const Double_t *ex=nullptr, const Double_t *ey=nullptr)
TGraphErrors (Int_t n, const Float_t *x, const Float_t *y, const Float_t *ex=nullptr, const Float_t *ey=nullptr)

Do we really want this? ROOT classes are often criticized because they offer too many ways to do the same thing. That will not be a simplification of the interface …

Possibly we can add name and title at the end of the constructor parameters list with some default values. But then that will not be consistent with TH1. A such request seems to have many side effects for a little improvement and no added functionality.

Also, this can be implemented. But then, if we want to be consistent we need also to implement it for histograms. Title-setting methods for TH1 are now:

           void     SetTitle(const char *title) override;  // *MENU*
   virtual void     SetXTitle(const char *title) {fXaxis.SetTitle(title);}
   virtual void     SetYTitle(const char *title) {fYaxis.SetTitle(title);}
   virtual void     SetZTitle(const char *title) {fZaxis.SetTitle(title);}

Yes, and it also works for histograms. So we have some consistency here. :slight_smile:

And, by default they are not. See:

{
   const Int_t n = 20;
   Double_t x[n], y[n];
   for (Int_t i=0;i<n;i++) {
     x[i] = i*0.1;
     y[i] = 10*sin(x[i]+0.2);
   }

   auto gr = new TGraph(n,x,y);
   gr->SetTitle("a simple graph;X title;Y title");
   gr->Draw("ACP");
}

Yes, the standards evolve over years. When ROOT started, last century, the standard plots had 3D effects, the default palette was Rainbow, etc … That’s why we have the TStyle class allowing users, teams of users, and experiments to define their own standards.
For instance, the ATLAS Style is in the list of predefined styles.
We can decide to have square canvases by default, but that be justified by some external constraints, like some publishing instances asking for it and not only one user asking for it. Like we justified the change of the default color map.

ROOT has many tunings. We are now thinking to set them more automatically. But that’s always a difficult balance to find… For now, TStyle can help.

Or better the TGraph reference as your question was about TGraph. TCanvas is only a graphics container. We cannot document there all the graphics features. PR here.