Draw histogram on background

Hello, I have a TCanvas from a TFile with many TGraphErrors drawn inside it. Now I want to add a TH1F inside this canvas. The question is: how to do it in a way that the histogram is behind the TGraphErrors? Is there any z-index ?

May be, somebody will give an idea how it’s supposed to be done in a ROOT way.
I can suggest a hack and more legal solution.

The simple but tricky way - a hack (it’s a sketch code of a terrible quality just to show an idea):

void inject()
{
   TFile * f = new TFile("data.root", "read");
   f->cd();
   
   TCanvas * c = (TCanvas *)f->Get("test_cnv");
   c->Draw();
   
   Double_t xMin = 0., xMax = 0., yMin = 0., yMax = 0.;
   c->GetRangeAxis(xMin, yMin, xMax, yMax);

   TH1F *fakeHist = new TH1F("empty", "empty", 100, xMin, xMax);
   fakeHist->FillRandom("gaus", 100000);

   TList * lst = c->GetListOfPrimitives();
   unsigned i = 0;
   for (; i < lst->GetEntries(); ++i) {
      TObject *obj = lst->At(i);
      if (obj->InheritsFrom("TGraph")) {
         lst->AddBefore(obj, fakeHist);
         break;
      }
   }

   for (i = 0; i < lst->GetEntries(); ++i) {
      TObject *obj = lst->At(i);
      if (obj->InheritsFrom("TFrame")) {
         TFrame *frame = (TFrame *)obj;
         frame->SetFillStyle(0);
         break;
      }
   }
   
   c->Update();
}

The root file is attached. Of course, this is quite an ugly and fragile solution and you’ll have to tune it to have a good picture. Another solution (which, I think, is the right and legal way) is to:

  1. Ask your canvas for its list of primitives.
  2. Create a new canvas
  3. Create your hist (probably, you’ll have to ask the first canvas about axes ranges before)
  4. newCanvas->cd(), hist->Draw()
  5. Iterate through the list of primitives and select objects you need (graphs) and draw them in the second canvas.
    data.root (14.1 KB)

thank you. Basically you are adding the histogram in front of the TGraph inside the list of primitives. I don’t understand the second part of your code: why do you need to change the fill style of the TFrame?

It would be nice if someone can add an option like ::Draw(“bkg”)

My present solution is much worse: I am saving the file as pdf and pushing the histogram to brackground using Inkscape

[quote=“wiso”]I don’t understand the second part of your code: why do you need to change the fill style of the pad?
[/quote]

I have to change a fill style for a TFrame object, otherwise, it’s white and hides a histogram.

I tried with my code and I have a problem with the axes: the axes of the histogram and the TGraphErrors (actually I have a TMultiGraph) are different and both are drawn on the canvas

I think I have solved in this way:

objs = []
for i in range(lst.GetEntries()):
    obj = lst.At(i)
    if not obj.InheritsFrom("TFrame"):
        objs.append(obj)

for obj in objs:
    lst.Remove(obj)

histo.Draw()
for o in objs:
    o.Draw()