{ "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 }