//__________________________________________________________________________________________ // // This macro draws a 2-dim hist together with its projections on x and y in // one picture. For tutorial purpose a sample histogram is build if none is given. // The y-projection is drawn using class TGraph or TGraphErrors which has slightly // different drawing options than a 1-dim histogram. // The following drawing options are working: HIST, P (polymarker), E (error bars) // E1 (error bars with decoration). Log scales should work as expected. // // Nota bene: Since the y-projection is drawn as a TGraph the actions and popups // for TGraph are invoked when pressing mouse buttons on the picture. // // Author: Otto.Schaile@Physik.Uni-Muenchen.DE //___________________________________________________________________________________________ void projxy2(TH2 * h2in = NULL){ TH2 * hist = h2in; if(hist == NULL){ // generate a sample hist TH2F * hdummy = new TH2F("gvsg", "gaus vs gaus", 40,-4, 4, 40,-2, 6); Double_t px, py; for(Int_t i=0; i<10000; i++){ gRandom->Rannor(px,py); hdummy->Fill(px, 0.9*py ); gRandom->Rannor(px,py); hdummy->Fill(px, 0.6*py + 4); } hist = hdummy; } // set parameters / options, could be done outside Bool_t logZscale = kFALSE; Bool_t logXscale = kFALSE; Bool_t logYscale = kFALSE; TString option_2dim("COLz"); TString option_1dim("E"); // options for the 1-dim hists TString option_1dim_y(option_1dim.Data()); // y-projection is a TGraph // which has diff options Int_t marker_style = TAttMarker::kStar; TString fill_option(""); Int_t fill_style = 1001; Int_t fill_color = 45; Double_t x2dim = 0.5; // the space left for the 2dim hist x Double_t y2dim = 0.5; // the space left for the 2dim hist y Double_t sep = 0.005; // the space between pads gStyle->SetPalette(1,0); // violet - red Int_t ww = 900; // dimensions for the canvas Int_t wh = 900; Int_t wtopx = 800; Int_t wtopy = 20; // Need a canvas + 3 pads TCanvas * cHist = new TCanvas("forall", "forall", wtopx, wtopy, ww, wh); if(option_1dim.Length() == 0)option_1dim = "HIST"; if(x2dim > 1 || x2dim <= 0)x2dim = 0.5; if(y2dim > 1 || y2dim <= 0)y2dim = 0.5; TPad * pad2dim = new TPad("pad2dim","pad2dim",0,0, x2dim-sep, y2dim-sep); pad2dim->Draw(); pad2dim->cd(); hist->Draw(option_2dim.Data()); cHist->cd(); TPad * padprojx = new TPad("padprojx", "padprojx", 0, y2dim+sep, x2dim-sep, 1); padprojx->Draw(); cHist->cd(); TPad * padprojy = new TPad("padprojy", "padprojy", x2dim+sep, 0, 1, y2dim-sep); padprojy->Draw(); cHist->cd(); // for test only, may be used for the y-projection TPad * padprojxy = new TPad("padprojxy", "padprojxy", x2dim+sep, y2dim+sep, 1, 1); padprojxy->Draw(); if(logZscale){ pad2dim->SetLogz(); padprojx->SetLogy(); padprojy->SetLogx(); padprojxy->SetLogy(); } if(logXscale){; pad2dim->SetLogx(); padprojx->SetLogx(); } if(logYscale){ pad2dim->SetLogy(); padprojy->SetLogy(); } gStyle->SetOptStat(0); if(option_1dim.Contains("P", TString::kIgnoreCase)) gStyle->SetMarkerStyle(marker_style); else gStyle->SetMarkerStyle(0); Int_t nbins; Double_t x, y, dx2, dy2, err; TGraph * g; TGraphErrors * ge; // x-projection is simple TH1D * projHistX = hist->ProjectionX(); padprojx->cd(); projHistX->Draw(option_1dim.Data()); if(fill_option.Contains("F", TString::kIgnoreCase)){ projHistX->SetFillStyle(fill_style); projHistX->SetFillColor(fill_color); } // y-projection drawn as a TGraphErrors TH1D * projHistY = hist->ProjectionY(); // we might draw y-projection into unused space at upper right corner padprojxy->cd(); projHistY->Draw(option_1dim.Data()); if(fill_option.Contains("F", TString::kIgnoreCase)){ projHistY->SetFillStyle(fill_style); projHistY->SetFillColor(fill_color); } padprojy->cd(); if(option_1dim_y.Contains("BAR2", TString::kIgnoreCase)){ projHistY->Draw("hbar2"); } else { Int_t nbins = projHistY->GetNbinsX(); Double_t ymin = projHistY->GetXaxis()->GetXmin(); // nota bene; x <-> y Double_t ymax = projHistY->GetXaxis()->GetXmax(); Double_t xmin = projHistY->GetMinimum(); Double_t xmax = projHistY->GetMaximum(); Double_t logxmin = xmax; xmax += 0.1 * xmax; Double_t * xv = new Double_t[nbins]; Double_t * yv = new Double_t[nbins]; Double_t * xe = new Double_t[nbins]; Double_t * ye = new Double_t[nbins]; Double_t logymin = ymax; for(Int_t i=1; i <= nbins; i++){ y = projHistY->GetBinLowEdge(i); dy2 = 0.5 * projHistY->GetBinWidth(i); x = projHistY->GetBinContent(i); if(x > 0 && x < logxmin) logxmin = x; err = projHistY->GetBinError(i); xv[i-1] = x; yv[i-1] = y+dy2; xe[i-1] = err; ye[i-1] = dy2; } if(logZscale)xmin = logxmin; else if (xmin>0) xmin =0; TH2F * hy = new TH2F("hy", "", 10, xmin, xmax, 10, ymin, ymax); hy->Draw(); hy->GetXaxis()->SetNdivisions(505); if(option_1dim_y.Contains("E", TString::kIgnoreCase)){ if(!option_1dim_y.Contains("1", TString::kIgnoreCase)){ option_1dim_y += "z"; // switch off the little lines at error bars } ge = new TGraphErrors(nbins,xv,yv, xe, ye); ge->Draw(option_1dim_y.Data()); } else { if(option_1dim_y.Contains("H", TString::kIgnoreCase)){ yv[0] -= dy2; yv[1] = yv[nbins-1] + dy2; option_1dim_y += "R"; // rotate g = new TGraph(nbins, xv, yv); if(fill_option.Contains("F", TString::kIgnoreCase)){ option_1dim_y += "F"; g->SetFillStyle(fill_style); g->SetFillColor(fill_color); } } else { g = new TGraph(nbins, xv, yv); cout <Draw(option_1dim_y.Data()); } delete [] xv; delete [] yv; if(xe) {delete [] xe; xe = 0;}; if(ye) {delete [] ye; ye = 0;}; } cHist->Update(); // TCanvas * cpy = new TCanvas("cpy", "cpy"); // projHistY->Draw(); }