{
"cells": [
{
"cell_type": "markdown",
"id": "239c70a3",
"metadata": {},
"source": [
"# haxis\n",
"Swap X/Y axes drawing and use to draw TH1 as bar and as markers.\n",
"\n",
"Option \"haxisg;y+\" draw histogram axis as for \"hbar\" plus allow to draw grids plus draw Y labels on other side\n",
"Option \"bar,base0,same\" draws histogram as bars with 0 as reference value\n",
"Option \"P,same\" draws histogram as markers\n",
"Macro also shows how frame margins can be configured and poly-line drawing like filled arrow can be\n",
"placed relative to frame.\n",
"\n",
"Functionality available only in web-based graphics\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Sergey Linev \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:38 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "4092bc77",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:38:54.930657Z",
"iopub.status.busy": "2026-05-19T20:38:54.930530Z",
"iopub.status.idle": "2026-05-19T20:38:55.244118Z",
"shell.execute_reply": "2026-05-19T20:38:55.243475Z"
}
},
"outputs": [],
"source": [
"std::vector negative = {-5, -7, -3, -1};\n",
"std::vector positive = {2, 15, 2, 10};\n",
"std::vector labels = {\"Category 1\", \"Category 2\", \"Category 3\", \"Category 4\"};"
]
},
{
"cell_type": "markdown",
"id": "c99f8e3c",
"metadata": {},
"source": [
"position of frame"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ed1d8eea",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:38:55.246338Z",
"iopub.status.busy": "2026-05-19T20:38:55.246218Z",
"iopub.status.idle": "2026-05-19T20:38:55.458319Z",
"shell.execute_reply": "2026-05-19T20:38:55.457582Z"
}
},
"outputs": [],
"source": [
"double frame_left = 0.15, frame_right = 0.9, frame_top = 0.8, frame_bottom = 0.05;\n",
"\n",
"auto nbins = negative.size();\n",
"\n",
"auto hmain = new TH1D(\"hmain\", \"title\", nbins, 0, nbins);\n",
"hmain->SetMarkerSize(3);\n",
"hmain->SetMarkerStyle(33);\n",
"hmain->SetMarkerColor(kBlue);\n",
"\n",
"auto hpos = new TH1D(\"hpos\", \"title\", nbins, 0, nbins);\n",
"hpos->SetFillColor(kRed);\n",
"hpos->SetBarOffset(0.2);\n",
"hpos->SetBarWidth(0.6);\n",
"\n",
"auto hneg = new TH1D(\"hneg\", \"title\", nbins, 0, nbins);\n",
"hneg->SetFillColor(kGreen);\n",
"hneg->SetBarOffset(0.2);\n",
"hneg->SetBarWidth(0.6);\n",
"\n",
"double vmin = 0, vmax = 0;\n",
"\n",
"for (unsigned n = 0; n < nbins; n++) {\n",
" hmain->SetBinContent(n + 1, negative[n] + positive[n]);\n",
" hpos->SetBinContent(n + 1, positive[n]);\n",
" hneg->SetBinContent(n + 1, negative[n]);\n",
" if (negative[n] < vmin)\n",
" vmin = negative[n];\n",
" if (positive[n] > vmax)\n",
" vmax = positive[n];\n",
"}\n",
"\n",
"double scale_min = (vmin - (vmax - vmin) * 0.1), scale_max = (vmax + (vmax - vmin) * 0.1),\n",
" frame_0 = (0 - scale_min) / (scale_max - scale_min) * (frame_right - frame_left) + frame_left;\n",
"\n",
"auto haxis = new TH1D(\"haxis\", \"title\", nbins, 0, nbins);\n",
"haxis->SetMinimum(scale_min);\n",
"haxis->SetMaximum(scale_max);\n",
"haxis->SetStats(false);\n",
"for (unsigned n = 0; n < nbins; n++)\n",
" haxis->GetXaxis()->SetBinLabel(n + 1, labels[n].c_str());\n",
"haxis->GetXaxis()->SetTickSize(0);\n",
"haxis->GetXaxis()->SetLabelSize(0.07);\n",
"haxis->GetXaxis()->SetLabelOffset(0.02);\n",
"\n",
"auto c1 = new TCanvas(\"chaxis\", \"title\", 1500, 800);\n",
"\n",
"if (!gROOT->IsBatch() && !c1->IsWeb())\n",
" ::Warning(\"haxis.cxx\", \"macro may not work without enabling web-based canvas\");\n",
"\n",
"c1->SetLeftMargin(frame_left);\n",
"c1->SetRightMargin(1 - frame_right);\n",
"c1->SetTopMargin(1 - frame_top);\n",
"c1->SetBottomMargin(frame_bottom);\n",
"c1->SetGridy(1);"
]
},
{
"cell_type": "markdown",
"id": "b8c41f94",
"metadata": {},
"source": [
"c1->SetGridx(1);"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "9a2d0b73",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:38:55.459945Z",
"iopub.status.busy": "2026-05-19T20:38:55.459826Z",
"iopub.status.idle": "2026-05-19T20:38:55.671815Z",
"shell.execute_reply": "2026-05-19T20:38:55.671120Z"
}
},
"outputs": [],
"source": [
"c1->Add(haxis, \"haxisg;y+\"); // swap x/y axis, let draw grids, y on top\n",
"\n",
"c1->Add(hpos, \"bar,base0,same\"); // draw as bar, 0 as base, same\n",
"c1->Add(hneg, \"bar,base0,same\"); // draw as bar, 0 as base, same\n",
"c1->Add(hmain, \"P,same\"); // draw as marker, also text and line supported, same\n",
"\n",
"TLatex *title = new TLatex((frame_left + frame_right) * 0.5, 0.96, \"Example of haxis with overlayed histograms\");\n",
"title->SetNDC(true);\n",
"title->SetTextAlign(22);\n",
"title->SetTextSize(0.08);\n",
"title->SetTextColor(kBlue);\n",
"c1->Add(title);\n",
"\n",
"auto add_arrow = [&](bool left_side, const char *txt) {\n",
" double x1 = left_side ? frame_0 - 0.02 : frame_0 + 0.02, x2 = left_side ? frame_left + 0.05 : frame_right - 0.05,\n",
" x3 = left_side ? frame_left + 0.03 : frame_right - 0.03, y0 = frame_top + 0.08, wy = 0.02;\n",
"\n",
" std::vector xpos = {x1, x2, x2, x3, x2, x2, x1, x1};\n",
" std::vector ypos = {y0 + wy, y0 + wy, y0 + wy * 1.5, y0, y0 - wy * 1.5, y0 - wy, y0 - wy, y0 + wy};\n",
" TPolyLine *pleft = new TPolyLine(xpos.size(), xpos.data(), ypos.data());\n",
" pleft->SetFillColor(left_side ? kGreen : kRed);\n",
" pleft->SetNDC();\n",
" c1->Add(pleft, \"f\");\n",
"\n",
" TLatex *l = new TLatex(left_side ? x1 - 0.03 : x1 + 0.03, y0, txt);\n",
" l->SetNDC(true);\n",
" l->SetTextAlign(left_side ? 32 : 12);\n",
" l->SetTextSize(0.03);\n",
" l->SetTextColor(kWhite);\n",
" c1->Add(l);\n",
"};\n",
"\n",
"add_arrow(true, \"Reduction\");\n",
"\n",
"add_arrow(false, \"Increase\");\n",
"\n",
"auto box = new TBox(0.2, 6, 0.8, 14);\n",
"box->SetFillColor(kCyan);\n",
"box->SetLineColor(kRed);\n",
"box->SetLineWidth(3);"
]
},
{
"cell_type": "markdown",
"id": "d7f92951",
"metadata": {},
"source": [
"use \"frame\" option to embed box into frame, \"l\" for line drawing"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "454cbdfc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:38:55.674477Z",
"iopub.status.busy": "2026-05-19T20:38:55.674363Z",
"iopub.status.idle": "2026-05-19T20:38:55.886259Z",
"shell.execute_reply": "2026-05-19T20:38:55.885655Z"
}
},
"outputs": [],
"source": [
"c1->Add(box, \"l,frame\");\n",
"\n",
"auto l1 = new TLatex(0.5, 10, \"Text inside frame\");\n",
"l1->SetTextAlign(22);\n",
"l1->SetTextSize(0.04);\n",
"l1->SetTextColor(kMagenta);"
]
},
{
"cell_type": "markdown",
"id": "4f99a474",
"metadata": {},
"source": [
"use \"frame\" option to embed text into frame"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5a544e54",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:38:55.888369Z",
"iopub.status.busy": "2026-05-19T20:38:55.888254Z",
"iopub.status.idle": "2026-05-19T20:38:56.095740Z",
"shell.execute_reply": "2026-05-19T20:38:56.095026Z"
}
},
"outputs": [],
"source": [
"c1->Add(l1, \"frame\");"
]
},
{
"cell_type": "markdown",
"id": "b583f26d",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "214da6fa",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:38:56.097742Z",
"iopub.status.busy": "2026-05-19T20:38:56.097618Z",
"iopub.status.idle": "2026-05-19T20:38:56.333581Z",
"shell.execute_reply": "2026-05-19T20:38:56.332958Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%jsroot on\n",
"gROOT->GetListOfCanvases()->Draw()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}