{
"cells": [
{
"cell_type": "markdown",
"id": "70474382",
"metadata": {},
"source": [
"# hist040_TH2Poly_europe\n",
"This tutorial illustrates how to create an histogram with polygonal\n",
"bins (TH2Poly), fill it and draw it. The initial data are stored\n",
"in TMultiGraphs. They represent the european countries.\n",
"The histogram filling is done according to a Mercator projection,\n",
"therefore the bin contains should be proportional to the real surface\n",
"of the countries.\n",
"\n",
"The initial data have been downloaded from: http://www.maproom.psu.edu/dcw/\n",
"This database was developed in 1991/1992 and national boundaries reflect\n",
"political reality as of that time.\n",
"\n",
"The script is shooting npoints (script argument) randomly over the Europe area.\n",
"The number of points inside the countries should be proportional to the country surface\n",
"The estimated surface is compared to the surfaces taken from wikipedia.\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Olivier Couet \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:20 PM."
]
},
{
"cell_type": "markdown",
"id": "debe3c81",
"metadata": {},
"source": [
" Arguments are defined. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "ae8a6ad9",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:30.270543Z",
"iopub.status.busy": "2026-05-19T20:20:30.270432Z",
"iopub.status.idle": "2026-05-19T20:20:30.589538Z",
"shell.execute_reply": "2026-05-19T20:20:30.589027Z"
}
},
"outputs": [],
"source": [
"Int_t npoints = 500000;"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d645f444",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:30.591633Z",
"iopub.status.busy": "2026-05-19T20:20:30.591494Z",
"iopub.status.idle": "2026-05-19T20:20:30.797021Z",
"shell.execute_reply": "2026-05-19T20:20:30.796465Z"
}
},
"outputs": [],
"source": [
"Int_t i, j;\n",
"Double_t lon1 = -25;\n",
"Double_t lon2 = 35;\n",
"Double_t lat1 = 34;\n",
"Double_t lat2 = 72;\n",
"Double_t R = (lat2 - lat1) / (lon2 - lon1);\n",
"Int_t W = 800;\n",
"Int_t H = (Int_t)(R * 800);\n",
"gStyle->SetStatX(0.28);\n",
"gStyle->SetStatY(0.45);\n",
"gStyle->SetStatW(0.15);"
]
},
{
"cell_type": "markdown",
"id": "ffc0ebc1",
"metadata": {},
"source": [
"Canvas used to draw TH2Poly (the map)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "357e2940",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:30.799177Z",
"iopub.status.busy": "2026-05-19T20:20:30.799054Z",
"iopub.status.idle": "2026-05-19T20:20:31.004534Z",
"shell.execute_reply": "2026-05-19T20:20:31.003919Z"
}
},
"outputs": [],
"source": [
"TCanvas *ce = new TCanvas(\"ce\", \"ce\", 0, 0, W, H);\n",
"ce->ToggleEventStatus();\n",
"ce->SetGridx();\n",
"ce->SetGridy();"
]
},
{
"cell_type": "markdown",
"id": "e45a3705",
"metadata": {},
"source": [
"Real surfaces taken from Wikipedia."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "2902695f",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:31.006339Z",
"iopub.status.busy": "2026-05-19T20:20:31.006212Z",
"iopub.status.idle": "2026-05-19T20:20:31.211782Z",
"shell.execute_reply": "2026-05-19T20:20:31.211210Z"
}
},
"outputs": [],
"source": [
"const Int_t nx = 36;"
]
},
{
"cell_type": "markdown",
"id": "c932eb5f",
"metadata": {},
"source": [
"see http://en.wikipedia.org/wiki/Area_and_population_of_European_countries"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1c70d3dc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:31.213515Z",
"iopub.status.busy": "2026-05-19T20:20:31.213390Z",
"iopub.status.idle": "2026-05-19T20:20:32.187327Z",
"shell.execute_reply": "2026-05-19T20:20:32.186912Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Partitioning: Real Time = 0.54 seconds Cpu Time = 0.55 seconds\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"[TFile::Cp] Total 2.16 MB\t|>...................| 0.00 % [0.0 MB/s]\r",
"[TFile::Cp] Total 2.16 MB\t|========>...........| 44.17 % [62.5 MB/s]\r",
"[TFile::Cp] Total 2.16 MB\t|=================>..| 88.33 % [53.7 MB/s]\r",
"[TFile::Cp] Total 2.16 MB\t|====================| 100.00 % [50.9 MB/s]\r\n",
"Info in : using local cache copy of http://root.cern/files/europe.root [./files/europe.root]\n"
]
}
],
"source": [
"const char *countries[nx] = {\n",
" \"france\", \"spain\", \"sweden\", \"germany\", \"finland\", \"norway\", \"poland\", \"italy\",\n",
" \"yugoslavia\", \"united_kingdom\", \"romania\", \"belarus\", \"greece\", \"czechoslovakia\", \"bulgaria\", \"iceland\",\n",
" \"hungary\", \"portugal\", \"austria\", \"ireland\", \"lithuania\", \"latvia\", \"estonia\", \"denmark\",\n",
" \"netherlands\", \"switzerland\", \"moldova\", \"belgium\", \"albania\", \"cyprus\", \"luxembourg\", \"andorra\",\n",
" \"malta\", \"liechtenstein\", \"san_marino\", \"monaco\"};\n",
"Float_t surfaces[nx] = {547030, 505580, 449964, 357021, 338145, 324220, 312685, 301230, 255438,\n",
" 244820, 237500, 207600, 131940, 127711, 110910, 103000, 93030, 89242,\n",
" 83870, 70280, 65200, 64589, 45226, 43094, 41526, 41290, 33843,\n",
" 30528, 28748, 9250, 2586, 468, 316, 160, 61, 2};\n",
"\n",
"TH1F *h = new TH1F(\"h\", \"Countries surfaces (in km^{2})\", 3, 0, 3);\n",
"for (i = 0; i < nx; i++)\n",
" h->Fill(countries[i], surfaces[i]);\n",
"h->LabelsDeflate();\n",
"\n",
"TFile::SetCacheFileDir(\".\");\n",
"TFile *f;\n",
"f = TFile::Open(\"http://root.cern/files/europe.root\", \"cacheread\");\n",
"\n",
"if (!f) {\n",
" printf(\"Cannot access europe.root. Is internet working ?\\n\");\n",
" return;\n",
"}\n",
"\n",
"TH2Poly *p =\n",
" new TH2Poly(\"Europe\", \"Europe (bin contents are normalized to the surfaces in km^{2})\", lon1, lon2, lat1, lat2);\n",
"p->GetXaxis()->SetNdivisions(520);\n",
"p->GetXaxis()->SetTitle(\"longitude\");\n",
"p->GetYaxis()->SetTitle(\"latitude\");\n",
"\n",
"p->SetContour(100);\n",
"\n",
"TMultiGraph *mg;\n",
"TKey *key;\n",
"TIter nextkey(gDirectory->GetListOfKeys());\n",
"while ((key = (TKey *)nextkey())) {\n",
" TObject *obj = key->ReadObj();\n",
" if (obj->InheritsFrom(\"TMultiGraph\")) {\n",
" mg = (TMultiGraph *)obj;\n",
" p->AddBin(mg);\n",
" }\n",
"}\n",
"\n",
"TRandom r;\n",
"Double_t longitude, latitude;\n",
"Double_t x, y, pi4 = TMath::Pi() / 4, alpha = TMath::Pi() / 360;\n",
"\n",
"gBenchmark->Start(\"Partitioning\");\n",
"p->ChangePartition(100, 100);\n",
"gBenchmark->Show(\"Partitioning\");"
]
},
{
"cell_type": "markdown",
"id": "b843f6aa",
"metadata": {},
"source": [
"Fill TH2Poly according to a Mercator projection."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "22182ba4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:32.188995Z",
"iopub.status.busy": "2026-05-19T20:20:32.188870Z",
"iopub.status.idle": "2026-05-19T20:20:34.107959Z",
"shell.execute_reply": "2026-05-19T20:20:34.107491Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Filling : Real Time = 1.70 seconds Cpu Time = 1.71 seconds\n"
]
}
],
"source": [
"gBenchmark->Start(\"Filling\");\n",
"for (i = 0; i < npoints; i++) {\n",
" longitude = r.Uniform(lon1, lon2);\n",
" latitude = r.Uniform(lat1, lat2);\n",
" x = longitude;\n",
" y = 38 * TMath::Log(TMath::Tan(pi4 + alpha * latitude));\n",
" p->Fill(x, y);\n",
"}\n",
"gBenchmark->Show(\"Filling\");\n",
"\n",
"Int_t nbins = p->GetNumberOfBins();\n",
"Double_t maximum = p->GetMaximum();"
]
},
{
"cell_type": "markdown",
"id": "1f20830d",
"metadata": {},
"source": [
"h2 contains the surfaces computed from TH2Poly."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "29c4089a",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:34.109357Z",
"iopub.status.busy": "2026-05-19T20:20:34.109242Z",
"iopub.status.idle": "2026-05-19T20:20:34.311521Z",
"shell.execute_reply": "2026-05-19T20:20:34.310914Z"
}
},
"outputs": [],
"source": [
"TH1F *h2 = (TH1F *)h->Clone(\"h2\");\n",
"h2->Reset();\n",
"for (j = 0; j < nx; j++) {\n",
" for (i = 0; i < nbins; i++) {\n",
" if (strstr(countries[j], p->GetBinName(i + 1))) {\n",
" h2->Fill(countries[j], p->GetBinContent(i + 1));\n",
" h2->SetBinError(j, p->GetBinError(i + 1));\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "2a1eaeac",
"metadata": {},
"source": [
"Normalize the TH2Poly bin contents to the real surfaces."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "ae09dc1c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:34.313248Z",
"iopub.status.busy": "2026-05-19T20:20:34.313132Z",
"iopub.status.idle": "2026-05-19T20:20:34.763327Z",
"shell.execute_reply": "2026-05-19T20:20:34.762925Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"THPoly Europe surface estimation error wrt wikipedia = 1.260096 per cent when using 500000 points\n"
]
}
],
"source": [
"Double_t scale = surfaces[0] / maximum;\n",
"for (i = 0; i < nbins; i++)\n",
" p->SetBinContent(i + 1, scale * p->GetBinContent(i + 1));\n",
"\n",
"gStyle->SetOptStat(1111);\n",
"p->Draw(\"COLZ\");\n",
"\n",
"TCanvas *c1 = new TCanvas(\"c1\", \"c1\", W + 10, 0, W - 20, H);\n",
"c1->SetRightMargin(0.047);\n",
"\n",
"scale = h->GetMaximum() / h2->GetMaximum();\n",
"\n",
"h->SetStats(0);\n",
"h->SetLineColor(kRed - 3);\n",
"h->SetLineWidth(2);\n",
"h->SetMarkerStyle(20);\n",
"h->SetMarkerColor(kBlue);\n",
"h->SetMarkerSize(0.8);\n",
"h->Draw(\"LP\");\n",
"h->GetXaxis()->SetLabelFont(42);\n",
"h->GetXaxis()->SetLabelSize(0.03);\n",
"h->GetYaxis()->SetLabelFont(42);\n",
"\n",
"h2->Scale(scale);\n",
"Double_t scale2 = TMath::Sqrt(scale);\n",
"for (i = 0; i < nx; i++)\n",
" h2->SetBinError(i + 1, scale2 * h2->GetBinError(i + 1));\n",
"h2->Draw(\"E SAME\");\n",
"h2->SetMarkerStyle(20);\n",
"h2->SetMarkerSize(0.8);\n",
"\n",
"TLegend *leg = new TLegend(0.5, 0.67, 0.92, 0.8, nullptr, \"NDC\");\n",
"leg->SetTextFont(42);\n",
"leg->SetTextSize(0.025);\n",
"leg->AddEntry(h, \"Real countries surfaces from Wikipedia (in km^{2})\", \"lp\");\n",
"leg->AddEntry(h2, \"Countries surfaces from TH2Poly (with errors)\", \"lp\");\n",
"leg->Draw();\n",
"leg->Draw();\n",
"\n",
"Double_t wikiSum = h->Integral();\n",
"Double_t polySum = h2->Integral();\n",
"Double_t error = TMath::Abs(wikiSum - polySum) / wikiSum;\n",
"printf(\"THPoly Europe surface estimation error wrt wikipedia = %f per cent when using %d points\\n\", 100 * error,\n",
" npoints);"
]
},
{
"cell_type": "markdown",
"id": "0f681e2f",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "b3ebe13b",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:20:34.764801Z",
"iopub.status.busy": "2026-05-19T20:20:34.764678Z",
"iopub.status.idle": "2026-05-19T20:20:35.120429Z",
"shell.execute_reply": "2026-05-19T20:20:35.119889Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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
}