ROOT学习——在每个轮廓旁边绘制轮廓值(ContourList.C)

  绘制直方图轮廓线是在处理数据较为常用的一种手段,本文根据ROOT官方教程ContourList.C,来讲述绘制轮廓线的方法。

  首先在画板c中绘制一幅横坐标为周期函数,纵坐标为正弦函数的图像。根据所选的几个轮廓值,绘制不同颜色的图像;画板c1是根据所选的轮廓值,绘制出图像的分界线。

  下面给出具体的代码步骤:

定义pi值:

const Double_t PI = TMath::Pi();

新建画板:

TCanvas* c = new TCanvas("c","Contour List",0,0,600,600);

设置画板右边余量:

c->SetRightMargin(0.15);

设置画板顶部余量:

c->SetTopMargin(0.15);

定义变量数量:

Int_t nZsamples   = 80;
Int_t nPhiSamples = 80;

定义波长(横坐标长度):

Double_t HofZwavelength = 4.0;       // 4 meters

设置横纵坐标bin值:

Double_t dZ             =  HofZwavelength/(Double_t)(nZsamples - 1);
Double_t dPhi           = 2*PI/(Double_t)(nPhiSamples - 1);

定义变量数组:

TArrayD z(nZsamples);
TArrayD HofZ(nZsamples);
TArrayD phi(nPhiSamples);
TArrayD FofPhi(nPhiSamples);

设置离散的Z和Phi值:

for ( i = 0; i < nZsamples; i++) {
   z[i] = (i)*dZ - HofZwavelength/2.0;
   HofZ[i] = SawTooth(z[i], HofZwavelength);
}

for(Int_t i=0; i < nPhiSamples; i++){
   phi[i] = (i)*dPhi;
   FofPhi[i] = sin(phi[i]);
}

创建直方图:

TH2D *HistStreamFn = new TH2D("HstreamFn", "#splitline{Histogram with negative and positive contents. Six contours are defined.}{It is plotted with options CONT LIST to retrieve the contours points in TGraphs}", nZsamples, z[0], z[nZsamples-1], nPhiSamples, phi[0], phi[nPhiSamples-1]);

加载直方图数据:

for (Int_t i = 0; i < nZsamples; i++) {
   for(Int_t j = 0; j < nPhiSamples; j++){
      HistStreamFn->SetBinContent(i,j, HofZ[i]*FofPhi[j]);
   }
}

设置选项统计(0代表不显示统计信息):

gStyle->SetOptStat(0);

设置标题宽度:

gStyle->SetTitleW(0.99);

设置标题高度:

gStyle->SetTitleH(0.08);

设置轮廓数值:

Double_t contours[6];
contours[0] = -0.7;
contours[1] = -0.5;
contours[2] = -0.1;
contours[3] =  0.1;
contours[4] =  0.4;
contours[5] =  0.8;

将轮廓值导入直方图:

HistStreamFn->SetContour(6, contours);

将轮廓绘制为填充区域并保存点:

"CONT Z LIST"画法是指:根据Contour值进行划分轮廓,每个区域使用不同颜色绘制。

HistStreamFn->Draw("CONT Z LIST");
c->Update(); // 需要强制绘图并在TGraphs中检索轮廓

获取轮廓:

TObjArray *conts = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
TList* contLevel = NULL;
TGraph* curv     = NULL;
TGraph* gc       = NULL;

定义图型数量和总轮廓个数:

Int_t nGraphs    = 0;
Int_t TotalConts = 0;

将获取的轮廓个数提取到变量TotalConts中:

if (conts == NULL){
   printf("*** No Contours Were Extracted!\n");
   TotalConts = 0;
   return 0;
} else {
   TotalConts = conts->GetSize();
}

输出轮廓数量:

printf("TotalConts = %d\n", TotalConts);

输出每个框架有多少个图形并记录图型总量:

for(i = 0; i < TotalConts; i++){
   contLevel = (TList*)conts->At(i);
   printf("Contour %d has %d Graphs\n", i, contLevel->GetSize());
   nGraphs += contLevel->GetSize();
}

图形数量归零:

nGraphs = 0;

创建第二个画板并设置顶部余量:

TCanvas* c1 = new TCanvas("c1","Contour List",610,0,600,600);
c1->SetTopMargin(0.15);

创建第二个直方图:

TH2F *hr = new TH2F("hr", "#splitline{Negative contours are returned first (highest to lowest). Positive contours are returned from}{lowest to highest. On this plot Negative contours are drawn in red and positive contours in blue.}", 2, -2, 2, 2, 0, 6.5);

绘制直方图:

hr->Draw();

设置文本框:

Double_t xval0, yval0, zval0;
TLatex l;
l.SetTextSize(0.03);
char val[20];

绘制第二张图的轮廓:

for(i = 0; i < TotalConts; i++){
   contLevel = (TList*)conts->At(i);
   if (i<3) zval0 = contours[2-i]; //zcal0记为轮廓值
   else     zval0 = contours[i];
   printf("Z-Level Passed in as:  Z = %f\n", zval0);
      
   curv = (TGraph*)contLevel->First(); //从此级别的曲线列表中获取第一张图
   for(j = 0; j < contLevel->GetSize(); j++){
      curv->GetPoint(0, xval0, yval0);
      if (zval0<0) curv->SetLineColor(kRed); //设置画线为红色
      if (zval0>0) curv->SetLineColor(kBlue); //设置画线为蓝色
      nGraphs ++;
      printf("\tGraph: %d  -- %d Elements\n", nGraphs,curv->GetN());

      gc = (TGraph*)curv->Clone(); //克隆图形
      gc->Draw("C"); //绘制轮廓线

      sprintf(val,"%g",zval0); //将zval0转换为val文本值
      l.DrawLatex(xval0,yval0,val); //绘制文本(x位置,y位置,数值)
      curv = (TGraph*)contLevel->After(curv); //获取下一张图
   }
}

刷新画板:

c1->Update();

输出总轮廓种类和总轮廓线数量:

printf("\n\n\tExtracted %d Contours and %d Graphs \n", TotalConts, nGraphs );

设置标题宽度:

gStyle->SetTitleW(0.);

设置标题高度:

gStyle->SetTitleH(0.);

代码地址:https://github.com/root-project/root/blob/master/tutorials/hist/ContourList.C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值