Using TLegend in with RooPlot

2016.Mar.26

If you have used Root and RooFit, you will notice that the two system uses apparently different plotting interfaces. This poses some problems when you are attempting to plot RooFit objects together with Root objects. In particular, using TLegend objects alongside RooFit objects.

Storing the plotted objects of Roofit

When plotting with RooFit, we typically use something below:

Example RooFit plotting routing [cpp]
#include "RooFit.h"
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "TCanvas.h"
#include "RooPlot.h"
#include "TAxis.h"
using namespace RooFit ;

void rf101_basics()
{
  RooRealVar x("x","x",-10,10) ;
  RooRealVar mean("mean","mean of gaussian",1,-10,10) ;
  RooRealVar sigma("sigma","width of gaussian",1,0.1,10) ;
  RooGaussian gauss("gauss","gaussian PDF",x,mean,sigma) ;

  RooPlot* xframe = x.frame(Title("Gaussian p.d.f.")) ;
  gauss.plotOn(xframe) ;
  sigma.setVal(3) ;
  gauss.plotOn(xframe,LineColor(kRed)) ;
}

Now we suppose we want to generate a TLegend object to legend the objects that are being plotted. If you are familiar with TLegend, this is done through the function:

[cpp]
tlegend_instance.AddEntry( <tobject_pointer> , "<Description_in_legend>" , "<plot_settings>")

The problem now is what are the TObject pointer that we need to pass over to the TLegend method? It cannot be the gauss instance in the code above, since it is used twice in the plotting function, so what is it?

Getting the plotted objects

It turns out when you call the plotOn() method, it generates a TGraph object stored in the RooPlot instance. You could actually get a list of all these objects by the simple snippet:

[cpp]
for( int i = 0 ; i < xframe->numItems() ; ++i ){
    cout << xframe->getObject( i )->GetName();
}

But there is a much better way of getting this thing, without having to guess which name corresponds to which object you have just plotted on the RooPlot object. By directly getting storing the object after you have called the plotOn() method:

[cpp]
gauss.plotOn(xframe);
TGraph* gauss_graph = (TGraph*)xframe->getObject( xframe->numItems() - 1 );

There is another merit of using this method. You could manually define the plot style using ROOT flavored methods rather than using stuffing it all in the plotOn() methods call!

[cpp]
gauss_graph->SetFillStyle(3004);
gauss->SetLineColor( kGreen );

This gives you much more flexibility on the plots you are getting! Since not all TGraphPainter are not accessible with the RooFit plotOn methods.

So now we could use the TLegend object as expected with this method!

[cpp]
TLegend l( 0.6, 0.6, 0.9, 0.9);
l.AddEntry( gauss_graph , "My Description" , "fl" );
l.Draw();

Hopefully this quick snippet has been useful!