Roofit: TLegend

Hello,

I’m not sure how to plot the colors of my lines in a TLegend by using the GUI or any member functions. Does anyone have any code snippits? I can do this in root with something like:

leg = new TLegend(0.4,0.6,0.89,0.89);
leg->AddEntry(hgamma1PCms_signalhist,“Signal”,“l”);
leg->AddEntry(hgamma1PCms_udshist,“uds”,“f”);
leg->Draw()

however when I make even if I explicitly make an object and plot he lines corresponding to different components of the fit:

RooChebychev *polyBg = new RooChebychev(“polyBg”, “polyBg”, d0Mass, coefLs)

totalD0MassPdf.plotOn(pAll_D0Mass);
totalD0MassPdf.plotOn(pAll_D0Mass,Components(RooArgList(*polyBg,cbPP_D0Mass)) , LineStyle(kDashed), LineColor(kMagenta));
totalD0MassPdf.plotOn(pAll_D0Mass,Components(RooArgList(*polyBg)) , LineStyle(kDashed), LineColor(kRed));

however I cant add theses lines/color to the TLegend. What’s going on?

james

Each legend item takes its attributes form the object the legend item is attached too. See the example here: root.cern.ch/root/html/TLegend.h … nd:TLegend

I understand that, but my problem is that it doesn’t appear to work this way in roofit. If I define an object:

RooChebychev *polyBg = new RooChebychev(“polyBg”, “polyBg”, d0Mass, coefLs)

and then try and make a legend for this

leg = new TLegend(0.4,0.6,0.89,0.89);
leg->AddEntry(polyBg,“Signal”,“l”);
leg->Draw()

It does not seem to get the color/style information if the object is a RooAbsPdf. It works fine under root if it’s a TH1F, but not under roofit if its a RooAbsPdf.

james

Is it possible to have an update on this issue ?

Thanks.

Hi to all,

Solution described in attachment.

Cheers,
Yuri
legend_in_roofit.txt (1.62 KB)

Sorry to revive a very old thread but I felt I could provide a better solution to the one given and thought it could be useful for people later searching.

The way to do it is when plotting assign a name to the plot and then use the RooPlot::findObject() method to add to the legend. The critical lines being:

MyHist->plotOn(MyFrame,RooFit::Name("some name");
leg->AddEntry(MyFrame->findObject("some name"),"description","options");

I hope this helps anyone trying to do this.

8 Likes

Yes! Your comment helped a lot! Kind regards, Arno

It does not work for me. This is part of code.

    c->cd(1);
    RooPlot* xFrame2 = integral.frame();
    xFrame2->SetAxisRange( 400., 1000 );
    xFrame2->SetTitle( "CsI(Tl) with #gamma-sourse (pedestal)" );
    data.plotOn( xFrame2, DrawOption( "PX" ) );
    model.plotOn( xFrame2 );
    model.plotOn( xFrame2, Components( pGaus ), LineStyle( kDashed), LineColor(kRed), Name("pGaus") );
    model.plotOn( xFrame2, Components( eGaus ), LineStyle( kDashed), Name("eGaus") );
    model.paramOn( xFrame2, Layout( 0.4, 0.9, 0.9) );


    xFrame2->Draw();

    TLegend* leg2 = new TLegend(0.1, 0.7, 0.48, 0.9);
    leg2->AddEntry( xFrame->FindObject("pGaus"), "Pedestal", "lp" );

    leg2->Draw("same");

This is what I get

It seems ok … the Object “pGaus” is in the TLegend… I do not see what’s wrong.

Yes, but the question is “How do you know this from the picture only”. I mean despite providing “lp” draw option I do not see red dashed line on the legend pad.

Because, very likely, you do not give the right object to TLegend.

OK. There was a typo. It should be

xFrame2->FindObject("pGaus");

But nothing has changed.

Some more info.

pGaus object

    RooRealVar pMean( "pMean", "Pedestal Mean", 550, 0, 1000 );
    RooRealVar pSigma( "pSigma", "Pedestal Sigma", 50, 1, 100 );
    RooGaussian pGaus( "pGaus", "Pedestal Gaus", integral, pMean, pSigma );

model jbject

    RooAddPdf model( "model", "Model", RooArgList( pGaus, eGaus ), fPed );
    model.fitTo( data, Range( 400, 700) );

DRAWING

    TCanvas* c = new TCanvas( "c", "c", 800, 600 );
    c->Divide( 2, 1 );

    c->cd(1);
    RooPlot* xFrame2 = integral.frame();
    xFrame2->SetAxisRange( 400., 1000 );
    xFrame2->SetTitle( "CsI(Tl) with #gamma-sourse (pedestal)" );
    data.plotOn( xFrame2, DrawOption( "PX" ) );
    model.plotOn( xFrame2 );
    model.plotOn( xFrame2, Components( pGaus ), LineStyle( kDashed), LineColor(kRed), Name("pGaus") );
    model.plotOn( xFrame2, Components( eGaus ), LineStyle( kDashed), Name("eGaus") );
    model.paramOn( xFrame2, Layout( 0.4, 0.9, 0.9) );


    xFrame2->Draw();

    TLegend* leg2 = new TLegend(0.1, 0.7, 0.48, 0.9);
    leg2->AddEntry( xFrame2->FindObject("pGaus"), "Pedestal", "lp" );

    leg2->Draw("same");

What’s wrong? Can it be because objects are in the stack not in the heap?

If you know the object name try to add it by name:

leg2->AddEntry( "name_of_the_object_to_be_put_in_the_legend", "Pedestal", "lp" );
1 Like

It worked. Thank you.

Hello, please let me resuscitate the topic. I’ve had the same problem as @p73. I found that the correct function used in AddEntry should be “findObject” instead of “FindObject”. Worst of all, both “findObject” and “FindObject” are defined in RooPlot. Therefore, if you use “FindObject”, the compiler still pass but it does not show the correct result, and it would be very hard to debug.

I’ve checked the documentation. The “FindObject” is an empty function inherited from TObject class, and it should be re-implemented in the derived classes, but there is no re-defined “FindObject” in RooPlot. So I guess maybe the “findObject” function was a typo of the re-defined “FindObject” in the source code?

1 Like

Hello!

The issue occurs to me as well, but none of the suggestions aboove worked for me.

Here is the code:
RooDataSet *data1 = new RooDataSet(“data1”,"", RooArgSet(*mass),“GeV”);
RooDataSet *data2 = new RooDataSet(“data2”,"", RooArgSet(*mass),“GeV”);
RooDataSet *data3 = new RooDataSet(“data3”,"", RooArgSet(*mass),“GeV”);
RooDataSet *data4 = new RooDataSet(“data4”,"", RooArgSet(*mass),“GeV”);
RooDataSet *data5 = new RooDataSet(“data5”,"", RooArgSet(*mass),“GeV”);
//filling datasets
TCanvas *cv=new TCanvas(“cv”,“Just Canvas”,5,5,800,800);

RooPlot *frame = mass->frame();
data1->plotOn(frame, MarkerSize(0.7));
data2->plotOn(frame, MarkerColor(kGreen+3), MarkerSize(0.7), LineColor(kGreen+3));
data3->plotOn(frame, MarkerColor(kRed+1), MarkerSize(0.7), LineColor(kRed+1));
data4->plotOn(frame, MarkerColor(kMagenta+2), MarkerSize(0.7), LineColor(kMagenta+2));
data5->plotOn(frame, MarkerColor(kBlue+2), MarkerSize(0.7), LineColor(kBlue+2));

frame->Draw();

TLegend *leg = new TLegend(0.65,0.73,0.86,0.87);
leg->SetFillColor(kWhite);
leg->SetLineColor(kWhite);
leg->AddEntry(data1, “Dsprt exclusive signal MC”, “P”);
leg->AddEntry(data2, “Dsprt inclusive signal MC”, “P”);
leg->AddEntry(“data3”, “Direct signal MC”, “ep”);
leg->AddEntry(data4, “Generic MC”, “p”);
leg->AddEntry(frame->FindObject(“data5”), “Data”, “P”);
leg->Draw();

And here is the output:

As you ccan see, all the contributiobs, independently on the way I introduce them in Legend appear to be black.

1 Like

RooPlot does not inherits from any graphical attributes that’s why adding it to TLegend does not produce any change to the markers in the TLegend. As said in the previous answers the plotted objects should be retrieved and added to the TLegend. You said you tried what was suggested before but that does not show in the code you posted. Can you post what you tried ?

Thank You So much!

Thank you for following-up!

As I show I show in the posted code, I tried both direct referring to a dataset with `

leg->AddEntry(“some_dataset”, “Some description”, “some_option”);

Alongside with search for it with:

leg->AddEntry(frame->FindObject(“some_dataset”), “Some description”, “some_option”);

In both cases color was not caught. I would be grateful if you let me know if I am doing something in a wrong way.

Can you post a small script reproducing the problem ? (something we can run)