ROOT-画双Y轴图表

2021-07-20 12:41:24 浏览数 (2)

图片要素:

Size比例:680*480

字号字体:当图片缩放占用单栏时,宽度约7.8cm,对应图片内字号与文章内字号大致相同,即10号Times New Roman。

线宽:--

绘制目标:

  1. 在同一张图上绘制两组数据,X坐标相同,但Y数据特征完全不同;
  2. 第二组数据展示右侧Y轴,颜色用红色;
  3. 添加辅助线;
  4. 添加Legend(图例)。

给出两种画法的代码示例:

A.两个透明Pad叠加,其中,第二个Pad设置与第一个Pad相同的展示Range,需要结合两组数据的Y坐标最小最大范围,此种方法难度较大。

代码语言:javascript复制
#include"lxzrootlogon.h" //此文件文末回复”roots”获得
#include<cmath>
//#include<numbers>
usingnamespace std;
voiddrawgood(){
         //void drawTestvar(char* filename){
 
         //constexpr double pi =std::numbers::pi;
         const double pi = acos(-1.0);
         myrootlogon();
         gStyle->SetOptFit();
 
         gStyle->SetPadRightMargin(.14);
         gStyle->SetPadTopMargin(0.1);
         gStyle->SetTextSize(0.06);
         Int_t eneid=100;
         //TFile *infile=TFile::Open(Form("test_%d_keV.root",eneid));
         TFile *infile=TFile::Open(Form("test2_e6_%d_keV.root",eneid));
         //TFile* infile =TFile::Open(filename); 
         using namespace std;
         ofstream fout,fmix;
         fstream fin;
         string tempdata;
         TH1D* hist_test_deg =(TH1D*)infile->Get("Testvar_Deg"); 
         //TH1D* hist_pro = (TH1D*)infile->Get("scatter_projection_1"); 
         // TH2D* hist_pro = (TH2D*)infile->GetListOfKeys()->At(1); 
         const int deg_num=180;  
         TH1F *sca_ene_hist= newTH1F("Scatter Response","Scattered Gamma Energy vsDegree",deg_num,0,180);
         //Double_t x[deg_num], y[deg_num];
         Double_t x[deg_num], counts_y[deg_num];
         Double_t ene_y[deg_num];
         for (Int_t i=0;i<deg_num;i  ) {
                  x[i] = i 0.5;
                  counts_y[i] = hist_test_deg->GetBinContent(i 1);
                  ene_y[i]=eneid/( test_var);
                  sca_ene_hist->SetBinContent(i 1,ene_y[i]);
         } 
cout<<"maxsacatter ene: "<<sca_ene_hist->GetMaximum()<<endl;
cout<<"minsacatter ene: "<<sca_ene_hist->GetMinimum()<<endl;
         double back_scatter_ene=eneid/(test_var);
         double half_ene=eneid*0.5;
         double theta_2=int(test_var);
         double theta_1=int(test_var);
         cout<<"half energy deg is"<<theta_2<<endl;
         cout<<"back scatter deg is"<<theta_1<<endl;
         cout<<"input energy is"<<eneid<<" and back scatter energy is"<<back_scatter_ene<<endl;
 
 
         double order_fraction_right=0;
         double total_right=0;
         double sum_wrong=0;
         double sum_right=0;
         for (int chai=1;chai<theta_1;chai  )
         {
                  sum_right =hist_test_deg->GetBinContent(chai);
         }
         for (intchai=theta_1;chai<theta_2;chai  )
         {
                  sum_wrong =hist_test_deg->GetBinContent(chai);
         }
         order_fraction_right=(1.-sum_wrong/(hist_test_deg->GetEntries()-sum_right))*100;
         total_right=(1.-sum_wrong/hist_test_deg->GetEntries())*100;
 
         cout<<"Right fraction of iforder events is"<<order_fraction_right<<"%"<<endl;
         cout<<"Total right fractionof events is "<<total_right<<"%"<<endl;
 
 
         TGraph *g1 = newTGraph(deg_num,x,counts_y);
         g1->SetTitle(";Degree;Counts");
         g1->SetMarkerStyle(8);
         g1->SetMarkerSize(0.75);
         g1->SetMarkerColor(1);
         g1->SetLineColor(1);
         TGraph *g2 = newTGraph(deg_num,x,ene_y);
         g2->SetTitle(";;");
         g2->SetMarkerStyle(8);
         g2->SetMarkerSize(0.75);
         g2->SetMarkerColor(2);
         g2->SetLineColor(2);
 
         //g2->GetXaxis()->SetLimits(0.,181);
         //
         //      gStyle->Reset("Modern");// "Modern", "Plain", "Classic"
         /*     
                  gStyle->SetTextFont(132);
                  gStyle->SetTextSize(0.06);
                  gStyle->SetLabelFont(132,"xyz");
                  gStyle->SetTitleFont(132,"xyz");
                  gStyle->SetLegendFont(132);
                  gStyle->SetStatFont(132);
 
                  gStyle->SetLabelSize(0.06,"xyz");//D=0.04
                  gStyle->SetTitleSize(0.06,"xyz");//D=0.02
                  gStyle->SetTitleSize(0.05,"");//maintitle
 
                  gStyle->SetLabelOffset(0.01,"xyz");//D=0.005
                  gStyle->SetTitleOffset(1.,"x");
                  gStyle->SetTitleOffset(0.8,"y");
                  gStyle->SetTitleOffset(1.2,"z");
                  */
         double canvas_x=680*3,canvas_y=480*3;
         TCanvas *myc = new TCanvas("myc","Testvar imaging", 200, 10, canvas_x, canvas_y);
         TPad *p1 = new TPad("p1","", 0, 0, 1, 1);
         p1->SetGrid();
         p1->SetFillStyle(4000); // will betransparent
         //p1->SetFillColor(kRed); // will betransparent
 
         TPad *p2 = new TPad("p2","", 0, 0, 1, 1);
         p2->SetFillStyle(4000); // will betransparent
         //
         p1->Draw();
         p1->cd();
         g1->Draw("ALP");
         //      g1->GetHistogram()->GetXaxis()->SetTitleOffset(1.25);
         //      g1->GetHistogram()->GetYaxis()->SetTitleOffset(1.2);
         g1->GetXaxis()->SetLimits(0.,180);
         gPad->Update();
         Style_t tfont =g1->GetHistogram()->GetYaxis()->GetTitleFont();
         Float_t tsize =g1->GetHistogram()->GetYaxis()->GetTitleSize();
         Style_t lfont = g1->GetHistogram()->GetYaxis()->GetLabelFont();
         Float_t lsize =g1->GetHistogram()->GetYaxis()->GetLabelSize();
 
         Double_t xmin = p1->GetUxmin();
         Double_t xmax = p1->GetUxmax();
         Double_t dx = (xmax - xmin) / 0.8; //10 percent margins left and right
         Double_t ymin =g2->GetHistogram()->GetMinimum();
         Double_t ymax =g2->GetHistogram()->GetMaximum();
         Double_t dy = (ymax - ymin) / 0.8; //10 percent margins top and bottom
         cout<<"xmin:"<<xmin<<" xmax: "<<xmax<<" ymin:"<<ymin<<" ymax: "<<ymax<<endl;
         //p2->Range(-34.2, ymin,xmax 0.3*dx,ymax);
doubleaa,bb,cc,dd;
         p1->GetRange(aa,bb,cc,dd);
cout<<"aa:"<<aa<<"bb: "<<bb<<"cc:"<<cc<<" dd:"<<dd<<endl;
         Double_t g1_ymin =g1->GetHistogram()->GetMinimum();
         Double_t g1_ymax =g1->GetHistogram()->GetMaximum();
cout<<"g1_ymin:"<<g1_ymin<<"g1_ymax:"<<g1_ymax<<endl;
doubleg1_y_len=g1_ymax-g1_ymin;
doublenewbb=(bb-g1_ymin)/g1_y_len*(ymax-ymin) ymin;
doublenewdd=(dd-g1_ymax)/g1_y_len*(ymax-ymin) ymax;
doubletestbb=ymin-0.15*dy;
cout<<"testbb: "<<testbb<<endl;
cout<<"newbb: "<<newbb<<endl;
         p2->Range(aa, newbb, cc, newdd);
         //p2->Range(xmin-0.15*dx,ymin-0.15*dy, xmax 0.13*dx, ymax 0.1*dy);
         //p2->Range(xmin-0.1*dx,ymin-0.1*dy, xmax 0.1*dx, ymax 0.1*dy);
         p2->Draw();
         p2->cd();
 
         TLine *line1=new TLine(theta_1,ymin,theta_1,ymax);
         line1->SetLineColor(kBlue);
         line1->SetLineStyle(2);
         line1->Draw();
 
         TLine *line2=newTLine(theta_2,ymin,theta_2,ymax);
         line2->SetLineColor(kBlack);
         line2->SetLineStyle(2);
         line2->Draw();
 
         TLine *line3=new TLine(0.5,half_ene,180,half_ene);
         line3->SetLineColor(kRed);
         line3->SetLineStyle(2);
         line3->Draw();
         //lines.DrawLine(0.5,331,180,331)->SetLineColor(kBlack)->SetLineWidth(1);
         g2->Draw("LP");
 
         gStyle->SetTextSize(0.06);
         gPad->Update();
 
         TGaxis *axis = new TGaxis(xmax, ymin,xmax, ymax, ymin, ymax, 510, " L");
         //https://root.cern.ch/doc/master/classTGaxis.html
         axis->SetTitle("Energy/keV");
         axis->SetTitleFont(tfont);
         axis->SetTitleSize(tsize);
         axis->SetTitleColor(kRed);
         axis->SetTitleOffset(1.0);
         axis->SetLabelFont(lfont);
         axis->SetLabelSize(lsize);
         axis->SetLabelColor(kRed);
         axis->SetLineColor(kRed);
         axis->Draw();
         gPad->Update();
 
        TLegend *leg = new TLegend(0.45, 0.8,0.82, 0.95);
leg->SetFillStyle(0);
         leg->SetFillColor(gPad->GetFillColor());
         leg->SetTextFont(lfont);
         leg->SetTextSize(lsize);
         leg->SetTextAlign(22);
 leg->SetHeader(Form(""));
        leg->AddEntry(g1, "ScatteredGamma", "L");
        leg->AddEntry(g2,"Energy", "L");
         leg->Draw();
         gPad->Update();
        
         //gStyle->SetImageScaling(3.);
         char*suffix[4]={"gif","pdf","png","eps"};
         for (int fixi=0;fixi<4;fixi  )
         {       myc->Print(Form("pic_big_new_Testvar_only_662kev_0623.%s",suffix[fixi]));}
}

B.两个透明Pad叠加,通过获取两组数据的Y坐标范围来定义Frame范围,该方法更加简单直观。

代码语言:javascript复制
#include"lxzrootlogon.h"
#include<cmath>
//#include<numbers>
usingnamespace std;
voiddrawtwoy(){
         //void drawTestvar(char* filename){
 
         //constexpr double pi =std::numbers::pi;
         const double pi = acos(-1.0);
         myrootlogon();
         gStyle->SetOptFit();
 
         gStyle->SetPadTopMargin(0.1);
         gStyle->SetTextSize(0.06);
         Int_t eneid=662;
         TFile *infile=TFile::Open(Form("Testvar_%d_keV.root",eneid));
         using namespace std;
         ofstream fout,fmix;
         fstream fin;
         string tempdata;
         TH1D* hist_test_deg =(TH1D*)infile->Get("Testvar_Deg"); 
         const int deg_num=180;  
         //Double_t x[deg_num], y[deg_num];
         Double_t x[deg_num], counts_y[deg_num];
         Double_t ene_y[deg_num];
         for (Int_t i=0;i<deg_num;i  ) {
                  x[i] = i 0.5;
                  counts_y[i] = hist_test_deg->GetBinContent(i 1);
                  ene_y[i]=eneid/((1-cos(x[i]/180.*pi))*eneid/511. 1);
         } 
         doubleback_scatter_ene=eneid/(2*eneid/511. 1);
         double half_ene=eneid*0.5;
         double theta_2=int(test_var);
         double theta_1=int(test_var);
         cout<<"half energy deg is"<<theta_2<<endl;
         cout<<"back scatter deg is"<<theta_1<<endl;
         cout<<"input energy is"<<eneid<<" and back scatter energy is"<<back_scatter_ene<<endl;
         //calculate the right fraction of orderevents
 
         double order_fraction_right=0;
         double total_right=0;
         double sum_wrong=0;
         double sum_right=0;
         for (int chai=1;chai<theta_1;chai  )
         {
                  sum_right =hist_test_deg->GetBinContent(chai);
         }
         for (intchai=theta_1;chai<theta_2;chai  )
         {
                  sum_wrong =hist_test_deg->GetBinContent(chai);
         }
         order_fraction_right=(1.-sum_wrong/(hist_test_deg->GetEntries()-sum_right))*100;
         total_right=(1.-sum_wrong/hist_test_deg->GetEntries())*100;
 
         cout<<"Right fraction of iforder events is"<<order_fraction_right<<"%"<<endl;
         cout<<"Total right fractionof events is "<<total_right<<"%"<<endl;
 
 
         TGraph *g1 = newTGraph(deg_num,x,counts_y);
         g1->SetTitle(";Degree;Counts");
         g1->SetMarkerStyle(8);
         g1->SetMarkerSize(0.75);
         g1->SetMarkerColor(1);
         g1->SetLineColor(1);
         // g1->SetLineWidth(2);
         //  g1->SetFillColor(3);
         //
         TGraph *g2 = newTGraph(deg_num,x,ene_y);
         g2->SetTitle(";;");
         g2->SetMarkerStyle(8);
         g2->SetMarkerSize(0.75);
         g2->SetMarkerColor(2);
         g2->SetLineColor(2);
 
         TCanvas *myc = newTCanvas("myc", "Testvar imaging", 200, 10, 680, 480);
         TPad *p1 = new TPad("p1","", 0, 0, 1, 1);
         p1->SetGrid();
         p1->Draw();
         p1->cd();
         TH1F *hr =myc->DrawFrame(0,0,180,3200);
         hr->SetXTitle("photon energy(MeV)");
         hr->SetYTitle("Microscopiccross-section (mb)");
         p1->GetFrame()->SetFillColor(20);
         //p1->GetFrame()->SetFillColor(21);
         p1->GetFrame()->SetBorderSize(12);
 
         g1->GetXaxis()->SetLimits(0.,180);
         g1->Draw("ALP");
 
         myc->cd();
         auto overlay = newTPad("overlay","",0,0,1,1);
         overlay->SetFillStyle(4000);
         overlay->SetFillColor(0);
         overlay->SetFrameFillStyle(4000);
         overlay->Draw();
         overlay->cd();
 
overlay->SetFrameBorderMode(0);
         TH1F *hframe =overlay->DrawFrame(0,0,180,700);
//      hframe->GetXaxis()->SetLabelOffset(0.1);
         hframe->GetXaxis()->SetLabelSize(0);
//      hframe->GetYaxis()->SetLabelOffset(99);
         hframe->GetYaxis()->SetLabelSize(0);
//overlay->GetFrame()->SetBorderSize(0);
         overlay->GetFrame()->SetFillColor(3);
         hframe->GetYaxis()->SetTickLength(0);//clean the second y axis
         hframe->GetXaxis()->SetTickLength(0);//clean the second x axis
        //g2->GetHistogram()->GetYaxis()->SetTicks("-");
 
         g2->Draw("LP");
        
 
doubleymin=0,ymax=700;     
         TLine *line1=newTLine(theta_1,ymin,theta_1,ymax);
         line1->SetLineColor(kBlue);
         line1->SetLineStyle(2);
         line1->SetLineWidth(3);
         line1->Draw();
 
         TLine *line2=newTLine(theta_2,ymin,theta_2,ymax);
         line2->SetLineColor(kBlack);
         line2->SetLineStyle(2);
         line2->SetLineWidth(3);
         line2->Draw();
 
         TLine *line3=newTLine(0.5,half_ene,180,half_ene);
         line3->SetLineColor(kRed);
         line3->SetLineStyle(2);
         line3->SetLineWidth(3);
         line3->Draw();
 
 
         gStyle->SetTextSize(0.06);
         gPad->Update();
         Double_t xmin = p1->GetUxmin();
         Double_t xmax = p1->GetUxmax();
         Double_t ymin =g2->GetHistogram()->GetMinimum();
         Double_t ymax =g2->GetHistogram()->GetMaximum();
         TGaxis *axis = newTGaxis(180,0,180,700,0,700,510," L");
         axis->SetLineColor(kRed);
         axis->SetLabelColor(kRed);
         axis->SetLabelOffset(0.01);
           axis->SetTitleColor(kRed);
       Style_t tfont =g1->GetHistogram()->GetYaxis()->GetTitleFont();
        Float_t tsize =g1->GetHistogram()->GetYaxis()->GetTitleSize();
        Style_t lfont =g1->GetHistogram()->GetYaxis()->GetLabelFont();
        Float_t lsize =g1->GetHistogram()->GetYaxis()->GetLabelSize();
           axis->SetLabelSize(lsize);
                     axis->SetLabelFont(lfont);
           axis->SetTitleFont(tfont);
   axis->SetTitleSize(tsize);
         axis->SetTitle("Energy/keV");
           axis->SetTitleOffset(1.);
         axis->Draw();
 
         gPad->Update();
 
         TLegend *leg = new TLegend(0.5, 0.8,0.82, 0.95);
leg->SetFillStyle(0);
         //leg->SetFillColor(gPad->GetFillColor());
         leg->SetTextFont(132);
         leg->SetTextSize(lsize);
         leg->SetTextAlign(22);
 
 
         leg->SetHeader(Form(""));
         leg->AddEntry(g1, "ScatteredGamma", "L");
         leg->AddEntry(g2,"Energy", "L");
 
         leg->Draw();
 
         gPad->Update();
        
         char*suffix[4]={"gif","pdf","png","eps"};
         for (int fixi=0;fixi<4;fixi  )
         {       myc->Print(Form("pic_by_frame_0627.%s",suffix[fixi]));}
        
}

后台回复“roots”获得gStyle全局格式定义头文件。

0 人点赞