ROOT 提供了许多图形类,如TGraph图表,TGraphErrors具有对称误差线的图表,TGraph2D由三个数组 X、Y 和 Z 组成的图表等。
图表的使用
TGraph支持批量创建和运算,TGraph的创建方法是:
// 创建了一个名字是name,标题是title,有n个坐标为x,y的点:TGraph *gr = new TGraph("name","title", number, x, y)TGraph* gr = new TGraph("name","title", number, x, y)TGraph *gr = new TGraph(number, x, y)auto gr = new TGraph(number, x, y)auto gr = new TGraph() // 使用AddPoint()函数添加坐标点auto dt = new TGraph2D() // 二维图表,其他形式同理
绘制图表前需要先定义坐标数组,然后使用TGraph构造图形。E.g.
int n =20;double x[n], y[n];for (int i=0; i<n; i++) { x[i] = i*0.1; y[i] =10*sin(x[i]+0.2); } auto gr = new TGraph (n, x, y);
也支持使用AddPoint()函数添加点:
auto gr = new TGraph();for (int i=0; i<20; i++) gr->AddPoint(i*0.1,10*sin(i*0.1+0.2));
使用以下选项绘制图表,在Draw()命令中它们不区分大小写,可不间隔的使用多个参数如Draw("APL")和Draw("A p l"),均表示绘制包涵坐标轴和坐标点的图,并用直线相连:
E.g. X轴在上Y轴反转和自动取色
voidgraphpalettecolor () {gStyle->SetOptTitle(kFALSE);gStyle->SetPalette(kSolar);double x[5] = {1,2,3,4,5};double y1[5] = {1.0,2.0,1.0,2.5,3.0};double y2[5] = {1.1,2.1,1.1,2.6,3.1};double y3[5] = {1.2,2.2,1.2,2.7,3.2};double y4[5] = {1.3,2.3,1.3,2.8,3.3};double y5[5] = {1.4,2.4,1.4,2.9,3.4}; TGraph *g1 = new TGraph(5,x,y1); g1->SetTitle("Graph with a red star"); TGraph *g2 = new TGraph(5,x,y2); g2->SetTitle("Graph with a circular marker"); TGraph *g3 = new TGraph(5,x,y3); g3->SetTitle("Graph with an open square marker"); TGraph *g4 = new TGraph(5,x,y4); g4->SetTitle("Graph with a blue star"); TGraph *g5 = new TGraph(5,x,y5); g5->SetTitle("Graph with a full square marker");g1->SetLineWidth(3); g1->SetMarkerColor(kRed);g2->SetLineWidth(3); g2->SetMarkerStyle(kCircle);g3->SetLineWidth(3); g3->SetMarkerStyle(kOpenSquare);g4->SetLineWidth(3); g4->SetMarkerColor(kBlue);g5->SetLineWidth(3); g5->SetMarkerStyle(kFullSquare);g1->Draw("CA*x+ry PLC PFC");g2->Draw("PCx+ry PLC PFC");g3->Draw("PC PLC PFC");g4->Draw("*C PLC PFC");g5->Draw("PC PLC PFC");gPad->BuildLegend();}
{ TCanvas* canvas = new TCanvas("canvas"); TH1F* histo = new TH1F("histo","test 1",10,0.,10.);histo->SetFillColor(2);histo->Fill(2.);histo->Draw();canvas->Print("plots.pdf(","Title:One bin filled");histo->Fill(4.);histo->Draw();canvas->Print("plots.pdf","Title:Two bins filled");histo->Fill(6.);histo->Draw();canvas->Print("plots.pdf","Title:Three bins filled");histo->Fill(8.);histo->Draw();canvas->Print("plots.pdf","Title:Four bins filled");histo->Fill(8.);histo->Draw();canvas->Print("plots.pdf)","Title:The fourth bin content is 2");}
误差与拟合
二维图表
使用符合标准的数据可以绘制二维图表。E.g.
{ auto c = new TCanvas("c","Graph2D example",0,0,700,600); // 画布距离左上角的距离(0,0)double x, y, z, P =6.;int np =200; auto dt = new TGraph2D(); auto r = new TRandom();for (int N=0; N<np; N++) { x =2*P*(r->Rndm(N))-P; y =2*P*(r->Rndm(N))-P; z = (sin(x)/x)*(sin(y)/y)+0.2;dt->SetPoint(N,x,y,z); }dt->Draw("tri1 p0");}
绘图选项
极坐标 TGraphPolar
极坐标TGraphPolar()的绘图选项有:
E.g. 极坐标例子
{ auto c46 = new TCanvas("c46","c46",500,500); auto grP1 = new TGraphPolar();grP1->SetTitle("TGraphPolar example");grP1->SetPoint(0, (1*TMath::Pi())/4.,0.05);grP1->SetPoint(1, (2*TMath::Pi())/4.,0.10);grP1->SetPoint(2, (3*TMath::Pi())/4.,0.15);grP1->SetPoint(3, (4*TMath::Pi())/4.,0.20);grP1->SetPoint(4, (5*TMath::Pi())/4.,0.25);grP1->SetPoint(5, (6*TMath::Pi())/4.,0.30);grP1->SetPoint(6, (7*TMath::Pi())/4.,0.35);grP1->SetPoint(7, (8*TMath::Pi())/4.,0.40);grP1->SetMarkerStyle(20);grP1->SetMarkerSize(1.);grP1->SetMarkerColor(4);grP1->SetLineColor(4);grP1->Draw("ALP");// Update, otherwise GetPolargram returns 0c46->Update();grP1->GetPolargram()->SetToRadian();}
voidCanvasPartition(TCanvas *C,constInt_t Nx =2,constInt_t Ny =2,Float_t lMargin =0.15,Float_t rMargin =0.05,Float_t bMargin =0.15,Float_t tMargin =0.05);doubleXtoPad(double x);doubleYtoPad(double x);voidcanvas2(){gStyle->SetOptStat(0); auto C = (TCanvas*) gROOT->FindObject("C");if (C) delete C; C = new TCanvas("C","canvas",1024,640);C->SetFillStyle(4000);// Number of PADSconstInt_t Nx =5;constInt_t Ny =5;// MarginsFloat_t lMargin =0.12;Float_t rMargin =0.05;Float_t bMargin =0.15;Float_t tMargin =0.05;// Canvas setupCanvasPartition(C,Nx,Ny,lMargin,rMargin,bMargin,tMargin);// Dummy histogram. auto h = (TH1F*) gROOT->FindObject("histo");if (h) delete h; h = new TH1F("histo","",100,-5.0,5.0);h->FillRandom("gaus",10000);h->GetXaxis()->SetTitle("x axis");h->GetYaxis()->SetTitle("y axis"); TPad *pad[Nx][Ny];for (Int_t i =0; i < Nx; i++) {for (Int_t j =0; j < Ny; j++) {C->cd(0);// Get the pads previously created. pad[i][j] = (TPad*) C->FindObject(TString::Format("pad_%d_%d",i,j).Data()); pad[i][j]->Draw(); pad[i][j]->SetFillStyle(4000); pad[i][j]->SetFrameFillStyle(4000); pad[i][j]->cd();// Size factorsFloat_t xFactor = pad[0][0]->GetAbsWNDC()/pad[i][j]->GetAbsWNDC();Float_t yFactor = pad[0][0]->GetAbsHNDC()/pad[i][j]->GetAbsHNDC(); TH1F *hFrame = (TH1F*) h->Clone(TString::Format("h_%d_%d",i,j).Data());// y axis rangehFrame->SetMinimum(0.0001); // do not show 0hFrame->SetMaximum(1.2*h->GetMaximum());// Format for y axishFrame->GetYaxis()->SetLabelFont(43);hFrame->GetYaxis()->SetLabelSize(16);hFrame->GetYaxis()->SetLabelOffset(0.02);hFrame->GetYaxis()->SetTitleFont(43);hFrame->GetYaxis()->SetTitleSize(16);hFrame->GetYaxis()->SetTitleOffset(2);hFrame->GetYaxis()->CenterTitle();hFrame->GetYaxis()->SetNdivisions(505);// TICKS Y AxishFrame->GetYaxis()->SetTickLength(xFactor*0.04/yFactor);// Format for x axishFrame->GetXaxis()->SetLabelFont(43);hFrame->GetXaxis()->SetLabelSize(16);hFrame->GetXaxis()->SetLabelOffset(0.02);hFrame->GetXaxis()->SetTitleFont(43);hFrame->GetXaxis()->SetTitleSize(16);hFrame->GetXaxis()->SetTitleOffset(1);hFrame->GetXaxis()->CenterTitle();hFrame->GetXaxis()->SetNdivisions(505);// TICKS X AxishFrame->GetXaxis()->SetTickLength(yFactor*0.06/xFactor);// Draw cloned histogram with individual settingshFrame->Draw(); TText text;text.SetTextAlign(31);text.SetTextFont(43);text.SetTextSize(10);text.DrawTextNDC(XtoPad(0.9), YtoPad(0.8),gPad->GetName()); } }C->cd();}voidCanvasPartition(TCanvas *C,constInt_t Nx,constInt_t Ny,Float_t lMargin,Float_t rMargin,Float_t bMargin,Float_t tMargin){if (!C) return;// Setup Pad layout:Float_t vSpacing =0.0;Float_t vStep = (1.- bMargin - tMargin - (Ny-1) * vSpacing) / Ny;Float_t hSpacing =0.0;Float_t hStep = (1.- lMargin - rMargin - (Nx-1) * hSpacing) / Nx;Float_t vposd,vposu,vmard,vmaru,vfactor;Float_t hposl,hposr,hmarl,hmarr,hfactor;for (Int_t i=0;i<Nx;i++) {if (i==0) { hposl =0.0; hposr = lMargin + hStep; hfactor = hposr-hposl; hmarl = lMargin / hfactor; hmarr =0.0; } elseif (i == Nx-1) { hposl = hposr + hSpacing; hposr = hposl + hStep + rMargin; hfactor = hposr-hposl; hmarl =0.0; hmarr = rMargin / (hposr-hposl); } else { hposl = hposr + hSpacing; hposr = hposl + hStep; hfactor = hposr-hposl; hmarl =0.0; hmarr =0.0; }for (Int_t j=0;j<Ny;j++) {if (j==0) { vposd =0.0; vposu = bMargin + vStep; vfactor = vposu-vposd; vmard = bMargin / vfactor; vmaru =0.0; } elseif (j == Ny-1) { vposd = vposu + vSpacing; vposu = vposd + vStep + tMargin; vfactor = vposu-vposd; vmard =0.0; vmaru = tMargin / (vposu-vposd); } else { vposd = vposu + vSpacing; vposu = vposd + vStep; vfactor = vposu-vposd; vmard =0.0; vmaru =0.0; }C->cd(0); auto name =TString::Format("pad_%d_%d",i,j); auto pad = (TPad*) C->FindObject(name.Data());if (pad) delete pad; pad = new TPad(name.Data(),"",hposl,vposd,hposr,vposu);pad->SetLeftMargin(hmarl);pad->SetRightMargin(hmarr);pad->SetBottomMargin(vmard);pad->SetTopMargin(vmaru);pad->SetFrameBorderMode(0);pad->SetBorderMode(0);pad->SetBorderSize(0);pad->Draw(); } }}doubleXtoPad(double x){double xl,yl,xu,yu;gPad->GetPadPar(xl,yl,xu,yu);double pw = xu-xl;double lm =gPad->GetLeftMargin();double rm =gPad->GetRightMargin();double fw = pw-pw*lm-pw*rm;return (x*fw+pw*lm)/pw;}doubleYtoPad(double y){double xl,yl,xu,yu;gPad->GetPadPar(xl,yl,xu,yu);double ph = yu-yl;double tm =gPad->GetTopMargin();double bm =gPad->GetBottomMargin();double fh = ph-ph*bm-ph*tm;return (y*fh+bm*ph)/ph;}
重叠绘制
将多个 graph 绘制在一张 pad 上,只需要在TGraph::Draw()函数中使用same参数即可。
合并绘制
TMultiGraph::TMultiGraph(),函数支持将一组图作为单个实体进行操作。且绘制时 X 轴和 Y 轴范围会自动计算,因此所有图形都将可见。TMultiGraph::Add()用于将新图表添加到列表中。E.g.
TGraph *gr1 = new TGraph(...TGraphErrors *gr2 = new TGraphErrors(...TMultiGraph *mg = new TMultiGraph();mg->Add(gr1,"lp");mg->Add(gr2,"cp");mg->Draw("a");
The Delaunay triangles are drawn using filled area. An hidden surface drawing technique is used. The surface is painted with the current fill area color. The edges of each triangles are painted with the current line color.
"TRIW"
The Delaunay triangles are drawn as wire frame.
"TRI1"
The Delaunay triangles are painted with color levels. The edges of each triangles are painted with the current line color.
"TRI2"
The Delaunay triangles are painted with color levels.
"P"
Draw a marker at each vertex.
"P0"
Draw a circle at each vertex. Each circle background is white.
"PCOL"
Draw a marker at each vertex. The color of each marker is defined according to its Z position.