# 2.3.2 坐标轴属性

## 坐标轴的概念

坐标轴由轴线（axisLine）、刻度（Ticket）、刻度标签（Label）、轴标题（Title）四个部分组成。

<table><thead><tr><th width="229.38671875">root [0] TAxis::Set</th><th>作用</th></tr></thead><tbody><tr><td><code>SetAlphanumeric</code></td><td>设置轴标签为字母数字格式</td></tr><tr><td><code>SetAxisColor</code></td><td>设置轴的颜色</td></tr><tr><td><code>SetBinLabel</code></td><td>设置指定 bin 的标签</td></tr><tr><td><code>SetBit</code></td><td>设置位标志</td></tr><tr><td><code>SetCanExtend</code></td><td>设置轴是否可以扩展</td></tr><tr><td><code>SetDecimals</code></td><td>设置标签的小数位数</td></tr><tr><td><code>SetDefaults</code></td><td>设置轴的默认属性</td></tr><tr><td><code>SetDrawOption</code></td><td>设置轴的绘制选项</td></tr><tr><td><code>SetDtorOnly</code></td><td>设置仅调用析构函数</td></tr><tr><td><code>SetLabelColor</code></td><td>设置刻度标签颜色</td></tr><tr><td><code>SetLabelFont</code></td><td>设置刻度标签字体</td></tr><tr><td><code>SetLabelOffset</code></td><td>设置刻度标签偏移量</td></tr><tr><td><code>SetLabelSize</code></td><td>设置刻度标签大小<br></td></tr><tr><td><code>SetLimits</code></td><td>设置轴的范围限制</td></tr><tr><td><code>SetMaxDigits</code></td><td>设置标签的最大数字位数</td></tr><tr><td><code>SetMoreLogLabels</code></td><td>设置在对数刻度下是否显示更多的标签</td></tr><tr><td><code>SetName</code></td><td>设置轴的名称</td></tr><tr><td><code>SetNameTitle</code></td><td>设置轴的名称和标题</td></tr><tr><td><code>SetNdivisions</code></td><td>设置轴的分割数</td></tr><tr><td><code>SetNoAlphanumeric</code></td><td>设置轴标签为非字母数字格式</td></tr><tr><td><code>SetNoExponent</code></td><td>设置标签是否不使用科学计数法</td></tr><tr><td><code>SetObjectStat</code></td><td>设置对象的统计信息</td></tr><tr><td><code>SetParent</code></td><td>设置轴的父对象</td></tr><tr><td><code>SetRange</code></td><td>设置轴的范围</td></tr><tr><td><code>SetRangeUser</code></td><td>设置用户定义的范围</td></tr><tr><td><code>SetTickLength</code></td><td>设置刻度的长度</td></tr><tr><td><code>SetTickSize</code></td><td>设置刻度的大小</td></tr><tr><td><code>SetTicks</code></td><td>设置刻度的显示方式</td></tr><tr><td><code>SetTimeDisplay</code></td><td>设置是否显示时间</td></tr><tr><td><code>SetTimeFormat</code></td><td>设置时间显示的格式</td></tr><tr><td><code>SetTimeOffset</code></td><td>设置时间偏移量</td></tr><tr><td><code>SetTitle</code></td><td>设置轴的标题</td></tr><tr><td><code>SetTitleColor</code></td><td>设置标题颜色</td></tr><tr><td><code>SetTitleFont</code></td><td>设置标题字体</td></tr><tr><td><code>SetTitleOffset</code></td><td>设置标题偏移量</td></tr><tr><td><code>SetTitleSize</code></td><td>设置标题大小</td></tr><tr><td><code>SetUniqueID</code></td><td>设置唯一标识符</td></tr></tbody></table>

## 坐标轴的轴线

* **颜色** ：`SetAxisColor()` `gStyle->SetAxisColor(2, "axis")`设置 axis 轴为红色。\
  `axis`指定哪个轴 `("x","y","z")`，如果`axis="xyz"`设置所有3个轴，否则默认为`x`。 `h1->GetXaxis()->SetAxisColorAlpha(2,0.5)`设置`h1`的X轴为红色，透明度为50%。 `h1->GetXaxis()->SetAxisColor(2)`设置`h1`的X轴为红色。
* **宽度**：

## 坐标轴的边框

与坐标轴对应的位置是边框，TCanvas::？？？？

设置帧边框模式`TStyle::SetFrameBorderMode()`

设置框架边框大小无效`TStyle::SetFrameBorderSize()`

* 颜色：`TStyle::SetFrameFillColor`
* 样式：`TStyle::SetFrameFillStyle`
* 颜色：`TStyle::SetFrameLineColor`
* 线条：`TStyle::SetFrameLineStyle`

TStyle::SetFrameLineWidth

## 坐标轴的刻度

**绘制直方图或图表时，可以使用以下命令将网格设置为打开或关闭：**

* **刻度线**`TStyle::SetNdivisions()`设置绘制轴的分割数 `gStyle->SetNdivisions(550, "x")`设置X轴的一级刻度为0，二级刻度和三级刻度为5。 `n = N1 + 100\*N2 + 10000\*N3`。`N1=初级分区的数量。N2=二级划分的数量。N3=第三分区的数量`。例如：`nndi=0->无刻度线。nndi=2->2个分区`，中间有一个刻度线轴的。
* **长度**：`TStyle::SetTickLength()`设置轴的刻度线长度。
* **设置网格**：`gPad->SetGrid()`或`TCanvas::SetGrid()` \
  设置X轴上的网格：`gPad->SetGridx(1)`或`TCanvas::SetGridx()`；﻿\
  设置Y轴上的网格：`gPad->SetGridy(1)`；\
  在两个轴上设置网格：`gPad->SetGrid (1,1)`。
* **颜色**：`TStyle::SetGridColor()`
* **样式**：`TStyle::SetGridStyle()`
* **宽度**：`TStyle::SetGridWidth()`

## 坐标轴的标签

* **偏移量：**`TStyle::SetLabelOffset()`。偏移量以 pad 高度的百分比表示。 axis 指定哪个轴 ("x","y","z")，如果 axis="xyz" 设置所有 3 个轴，则默认 = "x"。
* **字体：**`SetLabelFont()`
* **颜色：**`SetLabelColor()`
* **标签大小**：`SetLabelSize()`设置轴标签的大小 尺寸以`Pad`高度的百分比表示。
* **小数对齐**：`SetStripDecimals()` 将`0,0.5,1.25`对齐为`0.00,0.50,1.25`。`TGaxis::SetMaxDigits`设置轴标签允许的最大位数。
* **偏移**：`SetLabelOffset()`&#x20;

**e.g.**

```c
hist->GetYaxis()->SetLabelOffset(0.02)
hist->GetXaxis()->SetLabelOffset(0.02)
hist->GetYaxis()->SetLabelOffset(0.02)
```

## 坐标轴的标题

ROOT 的标题支持 LaTeX 语法。

设置标题的函数是`GetX/Yaxis->SetTitle("name")`，也可以同时设置标题、x轴标题、y轴标题，方法是`SetTitle("graph tittle; x tittle; y tilttle")`

同时标题支持自定义：

* **颜色**：`SetTitleColor()`
* **大小**：`SetTitleSize()`
* **字体**：`SetTextFont()`
* **距离/偏移**：`SetTitleOffset()` 设置轴和轴标题之间的距离。偏移量=1使用标准位置，该位置根据标签偏移量和尺寸计算；偏移量=1.2将使标准偏移量增加20%。
* **标题居中**：`CenterTitle(true)`

## 坐标轴的范围

合理控制的轴范围，能够更好表达数据变化。root 可以自动选取轴的范围，如果自动的呈现效果不满意，root 也支持手动调整。

对于未分 bin 的数据，例如图表，更改轴范围使用`TAxis::SetLimits(xmin, xmax)`函数；

对于已分 bin 的数据，请清除缓存后再使用`SetLimits`函数，[参见](https://root-forum.cern.ch/t/using-setlimits-changes-the-histogram/43194/6)。

直方图轴范围使用`TAxis::SetRange(number bin1, number bin2)`函数修改，参数是分 bin 的编号的位置：

```cpp
{
   TFile f("hsimple.root");
   hpxpy->Draw("colz");
   hpxpy->GetYaxis()->SetRange(22,23);
   hpxpy->GetXaxis()->SetRange(18,19);
}
```

使用“用户坐标”而不是 bin 编号来设置范围更方便。且允许用户直接在直方图对象上`TH::SetAxisRange(min, max, "axis")`设置轴范围，而无需使用`Get[XYZ]axis()`。e.g.

```c
   hpxpy->GetYaxis()->SetRangeUser(0., 3.);
```

等价于：

```c
   hpxpy->SetAxisRange(0., 3.,"Y");
```

**支持绘制图形后更改轴范围：**

```cpp
{
   auto c = new TCanvas("c","A Zoomed Graph",200,10,700,500);

   int n = 10;
   double x[10] = {-.22,.05,.25,.35,.5,.61,.7,.85,.89,.95};
   double y[10] = {1,2.9,5.6,7.4,9,9.6,8.7,6.3,4.5,1};

   auto gr = new TGraph(n,x,y);
   gr->SetMarkerColor(4);
   gr->SetMarkerStyle(20);
   gr->Draw("ALP");
   gr->GetXaxis()->SetRangeUser(0, 0.5);
   gr->GetYaxis()->SetRangeUser(1, 8);
}
```

也可以绘制图表框架`TCanvas::DrawFrame(,,,)`。此方法允许指定比原始范围更大的轴范围。e.g.

```cpp
{
   auto c = new TCanvas("c","A Zoomed Graph",200,10,700,500);
   c->DrawFrame(0,1,0.5,8);

   int n = 10;
   double x[10] = {-.22,.05,.25,.35,.5,.61,.7,.85,.89,.95};
   double y[10] = {1,2.9,5.6,7.4,9,9.6,8.7,6.3,4.5,1};

   auto gr = new TGraph(n,x,y);
   gr->SetMarkerColor(4);
   gr->SetMarkerStyle(20);
   gr->Draw("LP");
}
```

**调整坐标极值**

**下限：**`TGraph::SetMinimum();TH::SetMinimum()`

**上限：**`TGraph::SetMaximum();TH::SetMaximum()`。

## **双轴画法**

双轴画法是一种作图技巧，通过在画面中同时运用两个或多个对称轴，以达到对称和平衡或突出、方便对比等效果。最简单的呈现效果是使用`gPad`：

```bash
gPad->SetTicks(,)    // 两个参数分别控制x、y轴的对轴
                     // 0 表示不绘制对轴
                     // 1 表示绘制对轴的刻度
                     // 2 表绘制对轴及对应坐标值
                     // 例如gPad->SetTicks(1,2)表示绘制右轴和上轴及上轴对应的坐标值
```

`gPad->SetMargin(10,10,10,10)`看不见

#### 利用透明画布

<details>

<summary>显示两个不同比例的直方图的画布示例-利用透明Pad</summary>

```c
void transpad()
{
	TCanvas *c1 = new TCanvas("c1","transparent pad",200,10,700,500);
	TPad *pad1 = new TPad("pad1","",0,0,1,1);
	TPad *pad2 = new TPad("pad2","",0,0,1,1);
	pad1->Draw();
	pad2->SetFillStyle(4000); //will be transparent
	
	pad1->cd();
	
	TH1F *h1 = new TH1F("h1","h1",100,-3,3);
	TH1F *h2 = new TH1F("h2","h2",100,-3,3);
	TRandom r;
	for (Int_t i=0;i<100000;i++) {
		Double_t x1 = r.Gaus(-1,0.5);
		Double_t x2 = r.Gaus(1,1.5);
		if (i <1000) h1->Fill(x1);
		h2->Fill(x2);
	}
	h1->Draw();
	
	pad1->Update(); //this will force the generation of the "stats" box
	TPaveStats *ps1 = (TPaveStats*)h1->GetListOfFunctions()->FindObject("stats");
	ps1->SetX1NDC(0.4); ps1->SetX2NDC(0.6);
	pad1->Modified();

	c1->cd();
	//compute the pad range with suitable margins
	Double_t ymin = 0;
	Double_t ymax = 2000;
	Double_t dy = (ymax-ymin)/0.8; //10 per cent margins top and bottom
	Double_t xmin = -3;
	Double_t xmax = 3;
	Double_t dx = (xmax-xmin)/0.8; //10 per cent margins left and right
	pad2->Range(xmin-0.1*dx,ymin-0.1*dy,xmax+0.1*dx,ymax+0.1*dy);
	pad2->Draw();

	pad2->cd();
	h2->SetLineColor(kRed);
//	h2->Draw("][sames");
	h2->Draw("sames");
	pad2->Update();
	TPaveStats *ps2 = (TPaveStats*)h2->GetListOfFunctions()->FindObject("stats");
	ps2->SetX1NDC(0.65); ps2->SetX2NDC(0.85);
	ps2->SetTextColor(kRed);

	// draw axis on the right side of the pad
	TGaxis *axis = new TGaxis(xmax,ymin,xmax,ymax,ymin,ymax,50510,"+L");
	axis->SetLabelColor(kRed);
	axis->Draw();
}

```

</details>

#### 利用缩放

参见[2.2.2直方图-积分](https://s-klnw.gitbook.io/study-manual/2-root-guide/2.2.2-zhi-fang-tu)

## **反轴画法**

参考2.3节图形的[绘图选项](https://s-klnw.gitbook.io/study-manual/2.2-shu-ju-ke-shi-hua#tu-xing-de-hui-tu-xuan-xiang)

## 多轴画法

```c
void gaxis(){
   auto c1 = new TCanvas("c1","Examples of TGaxis",10,10,700,500);
   c1->Range(-10,-1,10,1);
 
   auto axis1 = new TGaxis(-4.5,-0.2,5.5,-0.2,-6,8,510,"");
   axis1->Draw();
 
   auto axis2 = new TGaxis(-4.5,0.2,5.5,0.2,0.001,10000,510,"G");
   axis2->Draw();
 
   auto axis3 = new TGaxis(-9,-0.8,-9,0.8,-8,8,50510,"");
   axis3->SetTitle("axis3");
   axis3->SetTitleOffset(0.5);
   axis3->Draw();
 
   auto axis4 = new TGaxis(-7,-0.8,-7,0.8,1,10000,50510,"G");
   axis4->SetTitle("axis4");
   axis4->Draw();
 
   auto axis5 = new TGaxis(-4.5,-0.6,5.5,-0.6,1.2,1.32,80506,"-+");
   axis5->SetLabelSize(0.03);
   axis5->SetTextFont(72);
   axis5->Draw();
 
   auto axis6 = new TGaxis(-4.5,0.5,5.5,0.5,100,900,50510,"-");
   axis6->Draw();
 
   auto axis7 = new TGaxis(-5.5,0.85,5.5,0.85,0,4.3e-6,510,"");
   axis7->Draw();
 
   auto axis8 = new TGaxis(8,-0.8,8,0.8,0,9000,50510,"+L");
   axis8->Draw();
 
   // One can make a vertical axis going top->bottom. However the two x values should be
   // slightly different to avoid labels overlapping.
   auto axis9 = new TGaxis(6.5,0.8,6.499,-0.8,0,90,50510,"-");
   axis9->Draw();
}
```

## 断轴画法

{% file src="<https://1447085975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fpf9IsLOaNy0SNtz1zmqo%2Fuploads%2FX7LMysHTsQqJjPP81THV%2FBrokenAxis.C?alt=media&token=4fa6218d-8ff0-485e-8d75-cad3e4028a47>" %}

## 共用轴/拼接轴画法

共轴画法是一种常见的绘图技巧，在同一张 canvas 中绘制多图并共享 X 轴或 Y 轴。这种方式常用于比较不同数据集之间的趋势或关系。最简单的共轴画法是`TCanvas::Divide(numberx, numbery, 0)`。

参考[数据可视化多图画法](https://s-klnw.gitbook.io/study-manual/2.2-shu-ju-ke-shi-hua#duo-tu-hui-fa)。

## 对数轴画法

<mark style="color:green;">对数轴是Tcanvas的类，所以设置对数轴，需要先建立画布。</mark>

使用`SetLogx()`和`SetLogy()`命令来设置画布的X轴和Y轴为对数坐标轴。***E.g.***

```c
TCanvas *c1 = new TCanvas("c1", "Example", 800, 600);
    c1->SetLogx(0);
    c1->SetLogy(1);
    c1->Update();
```

`SetLogx(0)`和`SetLogy(1)`分别表示取消x对数轴和设置y轴为对数轴，不含参数默认设置对数轴。

## **时间轴画法**

<details>

<summary>e.g. 模拟地震波随时间变化的图案</summary>

```c
void seism(){

    //TStopwatch sw;sw.Start();
    //TDatime dtime;
    //gStyle->SetTimeOffset( dtime.Convert() ); // replace axis with timeaxis

    //cout << dtime.Convert() << endl;

    TCanvas *c1 = new TCanvas("seism","Time on axis",0,0,1000,500);        
    // TCanvas("canvas name","canvas title",the pixel coordinates of the top left corner of canvas,same as above,size of pixel along X,size of pixel along Y)
   
    c1->SetFillColor( 42 ); // fill background color
    c1->SetFrameFillColor( 33 ); // color in frame
    c1->SetGrid();  // add grid in the frame

    Float_t bintime =1; // set one bin = 1 second. change it to set time scale,don't chenge real time
    TH1F *ht = new TH1F("ht","The ROOT seism",10,0,10*bintime);
    // TH1 = 1D histogram;F = float;("name","title",bin,Xmin,Xmax)
    Float_t signal = 700;
    // c/c++ : int , float , double
    // POOT :int_t , float_t , double_t

    ht->SetMaximum( signal );
    ht->SetMinimum( -signal );
    ht->SetStats( 1 );  // set statistic pad,1=display,0=hide
    ht->SetLineColor( 2 );
    ht->GetXaxis()->SetTimeDisplay( 1 );    // settimedisplay,1=display,0=hide
    ht->GetYaxis()->SetNdivisions( 220 );   // n1n2n3,n1 = a bin in the bin;n2n3 = ???
    ht->Draw();

    for(int i=0;i<200;i++){
        // build a signal ; noisy damped sine
        Float_t noise = gRandom->Gaus(0,120);
        if(i>100){ noise = noise + sin((i-700)*6.28/30)*exp((700-i)/300); }
        ht->SetBinContent(i,noise); // the ith content is noise
        c1->Modified();
        c1->Update();
        gSystem->ProcessEvents();
    }
    
    //printf("real time =%8.3fs,cpu time =%8.3fsn", sw.RealTime(), sw.CpuTime());
    return 0;
}
```

</details>

![输入图片说明](https://1447085975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fpf9IsLOaNy0SNtz1zmqo%2Fuploads%2FvR7RPVxOzpdBgD4Dnl3A%2Fseism.svg?alt=media)

## 极坐标轴画法

参考2.3节图形的[极坐标图案](https://s-klnw.gitbook.io/study-manual/2.2-shu-ju-ke-shi-hua#ji-zuo-biao-tu-an-graphpolar)

## 笛卡尔坐标系

```c
{
   auto c = new TCanvas("c","c",0,0,500,500);
   c->Range(-11,-11,11,11);
 
   auto f2 = new TF1("x2","x*x",-10,10);
   f2->SetLineColor(kRed);
   f2->Draw("same");
 
   auto f3 = new TF1("x3","x*x*x",-10,10);
   f3->SetLineColor(kBlue);
   f3->Draw("same");
 
   // Draw the axis with arrows
   auto ox = new TGaxis(-10,0,10,0,-10.,10.,510,"+-S>");
   ox->SetTickSize(0.009);
   ox->SetLabelFont(42);
   ox->SetLabelSize(0.025);
   ox->Draw();
   auto oy = new TGaxis(0,-10,0,10,-10,10,510,"+-S>");
   oy->SetTickSize(0.009);
   oy->SetLabelFont(42);
   oy->SetLabelSize(0.025);
   oy->Draw();
}
```

<figure><img src="https://1447085975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fpf9IsLOaNy0SNtz1zmqo%2Fuploads%2FtFH50OESNFqNpUMJWDpW%2Fpict1_TGaxis_003.png?alt=media&#x26;token=e51c978f-0317-47df-a65f-3858e628ff4c" alt="" width="563"><figcaption></figcaption></figure>

## 画布边距

e.g.

```c
c1 = new TCanvas("c1","A Simple Graph ",300,0,750,560); 
c1->SetLeftMargin(0.12);
c1->SetBottomMargin(0.10);
```

***

## 参考

* [**classTGaxis**](https://root.cern/doc/master/classTGaxis.html)
* <https://root-forum.cern.ch/t/using-setlimits-changes-the-histogram/43194/6>
* <https://root.cern.ch/doc/master/classTStyle.html#a906e5f9060357a95f893701b3bed57a2>
* <https://root.cern/doc/v630/classTH1.html#afd36e57d93056e578d73291ae3e1bb01>
