Multiple fitted histograms not drawing on same pad

Hi ROOTers,

So I am trying to fit multiple histos and draw them on the same pad. The fitting itself, together with the colors of the histos etc are done in an external function. I noticed if I do this in an external function, only the last histogram draws itself. Why is this?

An example code is attached: the function fit1d actually sets the cosmetics for the histos and also fits them with some TF1. The main function, FitAHisto, fills the 2 histos and calls the fit1d function. So in the TCanvas cc’s first cell, I try to draw both of these fitted histograms, but as you can see only the last histo draws. Strangely though, if I just draw the histos by themselves in seperate lines, they just draw fine, as you can see in cell 2. And ofcourse if I do this all within the same main function everything is drawn as expected also (last cell, cell 5).

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <stdio.h>

#include <TH1.h>
#include <TF1.h>
#include <TCanvas.h>


using namespace std;

void FitAHisto();

TH1F *fit1d(TH1F *hist, int i, char func[256], double lolim, double hilim)
{
  hist->SetLineColor(i+1);
  hist->SetMarkerColor(i+1);

  char fitname[256];
  strcpy (fitname,hist->GetName());
  strcat (fitname,"Fitted");
  
  TF1 *fitfunc = new TF1 (fitname,func, lolim, hilim);
  fitfunc->SetLineColor(i+1);
  hist->Fit(fitname,"EMR");
  
  return hist;

}

void FitAHisto(){
  TH1F *hh=new TH1F("hh","hh",100,-1.,1.);
  TH1F *hh2=new TH1F("hh2","hh2",100,-1.,1.);
  hh->FillRandom("gaus",100000);
  hh2->FillRandom("gaus",90000);
  
  TCanvas *cc =new TCanvas("cc","cc",500,500);
  cc->Divide(2,3);
  cc->cd(1);
  fit1d(hh, 1, "gaus", -1.,1.)->Draw("same");
  fit1d(hh2, 6, "gaus", -1.,1.)->Draw("same");
  cc->cd(2);
  hh->Draw();
  hh2->Draw("same");  
  cc->cd(3);
  fit1d(hh, 1, "gaus", -1.,1.)->Draw();
  cc->cd(4);
  fit1d(hh2, 6, "gaus", -1.,1.)->Draw("same");

  TH1F *hhh=new TH1F("hhh","hhh",100,-1.,1.);
  TH1F *hhh2=new TH1F("hhh2","hhh2",100,-1.,1.);
  hhh->SetLineColor(2);
  hhh2->SetLineColor(7);
  hhh->FillRandom("gaus",100000);
  hhh2->FillRandom("gaus",90000);


  TF1 *fff = new TF1("fff","gaus",-1.,1.);
  TF1 *fff2 = new TF1("fff2","gaus",-1.,1.);
  fff->SetLineColor(2);
  fff2->SetLineColor(7);

  hhh->Fit("fff","emr");
  hhh2->Fit("fff2","emr");
  cc->cd(5);
  hhh->Draw();
  hhh2->Draw("same");

}

And here’s the canvas produced: cctemp.ps

Thanks in advance!

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <stdio.h>

#include <TH1.h>
#include <TF1.h>
#include <TCanvas.h>


using namespace std;

void FitAHisto();

TH1F *fit1d(TH1F *hist, int i, const char *func, double lolim, double hilim)
{
  hist->SetLineColor(i+1);
  hist->SetMarkerColor(i+1);

  char fitname[256];
  strcpy (fitname,hist->GetName());
  strcat (fitname,"Fitted");
 
  TF1 *fitfunc = new TF1 (fitname,func, lolim, hilim);
  fitfunc->SetLineColor(i+1);
  hist->Fit(fitname,"0EMR"); // "0" = do NOT automatically draw "hist"
  hist->GetFunction(fitname)->ResetBit(TF1::kNotDraw); // make "fitname" visible (= 1<<9)
 
  return hist;

}

void FitAHisto(){
  TH1F *hh=new TH1F("hh","hh",100,-1.,1.);
  TH1F *hh2=new TH1F("hh2","hh2",100,-1.,1.);
  hh->FillRandom("gaus",100000);
  hh2->FillRandom("gaus",90000);
 
  TCanvas *cc =new TCanvas("cc","cc",500,500);
  cc->Divide(2,3);
  cc->cd(1);
  fit1d(hh, 1, "gaus", -1.,1.)->Draw();
  fit1d(hh2, 6, "gaus", -1.,1.)->Draw("same");
  cc->cd(2);
  hh->Draw();
  hh2->Draw("same"); 
  cc->cd(3);
  fit1d(hh, 1, "gaus", -1.,1.)->Draw();
  cc->cd(4);
  fit1d(hh2, 6, "gaus", -1.,1.)->Draw();

  TH1F *hhh=new TH1F("hhh","hhh",100,-1.,1.);
  TH1F *hhh2=new TH1F("hhh2","hhh2",100,-1.,1.);
  hhh->SetLineColor(2);
  hhh2->SetLineColor(7);
  hhh->FillRandom("gaus",100000);
  hhh2->FillRandom("gaus",90000);


  TF1 *fff = new TF1("fff","gaus",-1.,1.);
  TF1 *fff2 = new TF1("fff2","gaus",-1.,1.);
  fff->SetLineColor(2);
  fff2->SetLineColor(7);

  cc->cd(5);
  hhh->Fit("fff","emr"); // automatically draws "hhh"
  hhh2->Fit("fff2","emr","same"); // automatically draws "hhh2"
  cc->cd(6);
  hhh->Draw();
  hhh2->Draw("same");

}

You are not using the option “Same” in the Draw() method correctly.
“Same” means “draw on the same plot”, ie: use the current pad to draw.
So you should first draw an histogram without the option “same” and then you can draw as many histograms on top of it using the option “same”. They will use the coordinates defined by the first plotted histogram. Therefore they might be clipped if they are outside these coordinates.
See the details here: root.cern.ch/root/html/THistPainter.html#HP060

1 Like

Hi,

Thanks a lot! These 2 lines did it right now:
hist->Fit(fitname,“0EMR”); // “0” = do NOT automatically draw "hist"
hist->GetFunction(fitname)->ResetBit(1<<9); // make “fitname” visible

But I am trying to understand what ResetBit(1<<9) does? Can you explain what the 1<<9 means or point me to some documentation? I looked but couldn’t find this syntax for ResetBit in the ROOT site.

Thanks again!

  • Sujeewa

PS. yes the Draw(“same”) on the first histo is wrong, I did that through frustration to see if the first histo would have drawn. :confused:

Replace:
1<<9
with:
TF1::kNotDraw
(I’ve edited my post of Tue Mar 15, 2011 11:04 in this thread accordingly, too.)
http://root.cern.ch/root/html/TH1.html#TH1:Fit
http://root.cern.ch/root/html/TF1.html#TF1:kNotDraw
http://root.cern.ch/root/html/TObject.html#TObject:ResetBit

Thanks a lot! :slight_smile:

  • Sujeewa