Skip to content

Commit

Permalink
fully automated legend sizing!
Browse files Browse the repository at this point in the history
  • Loading branch information
kpedro88 committed Jan 13, 2015
1 parent f80d16d commit 9ac1637
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 36 deletions.
3 changes: 2 additions & 1 deletion Plotting/KCode/KBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

//custom headers
#include "KMap.h"
#include "KLegend.h"

//ROOT headers
#include <TROOT.h>
Expand Down Expand Up @@ -142,7 +143,7 @@ class KBase {

//other virtual functions (unimplemented at this level)
virtual void Draw(TPad* pad) {}
virtual int GetLegendInfo() {}
virtual void GetLegendInfo(KLegend* kleg) {}
virtual void AddToLegend(TLegend* leg) {}
virtual void AddChild(KBase* ch) {}
virtual void Normalize(double nn, bool toYield=true) {}
Expand Down
36 changes: 23 additions & 13 deletions Plotting/KCode/KLegend.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
#include <TROOT.h>
#include <TLegend.h>
#include <TH1F.h>
#include <TLatex.h>
#include <TPad.h>

//STL headers
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <utility>
#include <iomanip>
#include <cmath>
Expand All @@ -19,19 +22,20 @@ using namespace std;
class KLegend{
public:
//constructor
KLegend(int nentries_, string chan_label_="") : nentries(nentries_), leg(0), ymin(0), ymax(0), manual_ymin(false), chan_label(chan_label_) {
KLegend(TPad* pad_, string chan_label_="") : pad(pad_), legwidth(0), legheight(0), leg(0), ymin(0), ymax(0), manual_ymin(false), chan_label(chan_label_) {
padH = pad->GetWh()*pad->GetAbsHNDC();
legentry = 26/padH; //line height for each entry
//todo: allow multiple lines of text at top of legend?
if(chan_label.size()>0) ++nentries; //will be added to top of legend
if(chan_label.size()>0) CheckSize(chan_label); //will be added to top of legend
//chan_label = "#mu#tau channel";
}
//destructor
virtual ~KLegend() {}

//functions
void Build(TPad* pad){
void Build(){
bool logy = pad->GetLogy();
bool logx = pad->GetLogx();
double padH = pad->GetWh()*pad->GetAbsHNDC();
double ytick = (hists.size()>0) ? hists[0]->GetYaxis()->GetTickLength() : 0;
double xtick = (hists.size()>0) ? hists[0]->GetXaxis()->GetTickLength() : 0;

Expand All @@ -54,8 +58,10 @@ class KLegend{
double lbound = pad->GetLeftMargin() + ytick;
double rbound = 1 - (pad->GetRightMargin() + ytick);

//how to determine width?
double legwidth = 0.33;
//symbol box takes up fMargin = 0.25 by default
legwidth /= 0.75;
//add a little padding for each line
legheight *= 1.2;

if(p > nbins/2) {
umin = lbound;
Expand All @@ -65,10 +71,6 @@ class KLegend{
umax = rbound;
umin = umax - legwidth;
}

//double legentry = 0.05; //line height for each entry
double legentry = 26/padH; //line height for each entry
double legheight = legentry*nentries; //total height of all entries

vmax = 1 - (pad->GetTopMargin() + xtick);
vmin = vmax - legheight;
Expand Down Expand Up @@ -166,10 +168,17 @@ class KLegend{

if(chan_label.size()>0) leg->AddEntry((TObject*)NULL,chan_label.c_str(),"");
}
void Draw(TPad* pad){
void Draw(){
pad->cd();
if(leg) leg->Draw("same");
}
void CheckSize(string line){
pad->cd();
TLatex size_test(0,0,line.c_str());
size_test.SetTextSize(legentry);
legheight += size_test.GetYsize();
if(size_test.GetXsize() > legwidth) legwidth = size_test.GetXsize();
}

//accessors
void AddHist(TH1F* h) { hists.push_back(h); }
Expand All @@ -179,8 +188,9 @@ class KLegend{

protected:
//member variables
int nentries;
string fbname;
TPad* pad;
double legwidth, legheight;
double padH, legentry;
vector<TH1F*> hists;
TLegend* leg;
double ymin, ymax;
Expand Down
25 changes: 12 additions & 13 deletions Plotting/KCode/KManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,9 @@ class KManager {
}
}

//build everything, check for legend height
//add some kind of check for legend width here?
double nentries = 0;
//build everything
for(unsigned s = 0; s < MySets.size(); s++){
MySets[s]->Build();
nentries += MySets[s]->GetLegendInfo();
}

//fake tau estimation is calculated during build
Expand All @@ -112,6 +109,14 @@ class KManager {
TCanvas* can = p->second->GetCanvas();
TPad* pad1 = p->second->GetPad1();

//create legend
string chan_label = "";
option->Get("chan_label",chan_label);
KLegend* kleg = new KLegend(pad1,chan_label);
double ymin = 1;
if(option->Get("ymin",ymin)) kleg->SetManualYmin(ymin);
p->second->SetLegend(kleg);

//select current histogram in sets
for(unsigned s = 0; s < MySets.size(); s++){
MySets[s]->GetHisto(p->first);
Expand Down Expand Up @@ -147,23 +152,17 @@ class KManager {
MySets[s]->BinDivide();
}
}

//create legend
string chan_label = "";
option->Get("chan_label",chan_label);
KLegend* kleg = new KLegend(nentries,chan_label);
double ymin = 1;
if(option->Get("ymin",ymin)) kleg->SetManualYmin(ymin);
p->second->SetLegend(kleg);

//pass current histogram to legend
//AFTER bindivide if requested
//and calculate legend size
for(unsigned s = 0; s < MySets.size(); s++){
kleg->AddHist(MySets[s]->GetHisto());
MySets[s]->GetLegendInfo(kleg);
}

//build legend
kleg->Build(pad1);
kleg->Build();

//add sets to legend
for(unsigned s = 0; s < MySets.size(); s++){
Expand Down
2 changes: 1 addition & 1 deletion Plotting/KCode/KPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class KPlot{
}
void DrawText(){
pad1->cd();
leg->Draw(pad1);
leg->Draw();
paveCMS->Draw("same");
paveExtra->Draw("same");
paveLumi->Draw("same");
Expand Down
18 changes: 10 additions & 8 deletions Plotting/KCode/KSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "KMap.h"
#include "KBase.h"
#include "KBuilder.h"
#include "KLegend.h"

//ROOT headers
#include <TROOT.h>
Expand Down Expand Up @@ -68,8 +69,8 @@ class KSet : public KBase {
}
else return NULL; //do not reset if the histo does not exist
}
//reports number of entries for the legend
virtual int GetLegendInfo() { return 1; }
//provides size of entries for the legend
virtual void GetLegendInfo(KLegend* kleg) { kleg->CheckSize(name); }
virtual void CloseFile(){
for(unsigned c = 0; c < children.size(); c++){
children[c]->CloseFile();
Expand Down Expand Up @@ -134,6 +135,7 @@ class KSetData: public KSet {
if(option->Get("horizerrbars",false) || htmp->GetXaxis()->IsVariableBinSize()){
leg->AddEntry(htmp,name.c_str(),"pel");
}
//note: this setting only works in ROOT 5.34.11+
else leg->AddEntry(htmp,name.c_str(),"pe");
}
//draw function
Expand Down Expand Up @@ -324,12 +326,12 @@ class KSetMCStack : public KSet {
}
else return NULL; //do not reset if the histo does not exist
}
//reports number of entries for the legend
int GetLegendInfo() {
int num = children.size();
//error band enabled by default
if(option->Get("errband",true)) num++;
return num;
//provides size of entries for the legend
void GetLegendInfo(KLegend* kleg) {
for(unsigned c = 0; c < children.size(); c++){
children[c]->GetLegendInfo(kleg);
}
if(option->Get("errband",true)) kleg->CheckSize("uncertainty");
}
//adds child histos to legend
void AddToLegend(TLegend* leg) {
Expand Down

0 comments on commit 9ac1637

Please sign in to comment.