Logo ROOT  
Reference Guide
THistPainter.cxx
Go to the documentation of this file.
1// @(#)root/histpainter:$Id$
2// Author: Rene Brun, Olivier Couet
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <cstdlib>
13#include <cstring>
14#include <cstdio>
15#include <cctype>
16#include <iostream>
17
18#include "TROOT.h"
19#include "TSystem.h"
20#include "THistPainter.h"
21#include "TH2.h"
22#include "TH2Poly.h"
23#include "TH3.h"
24#include "TProfile.h"
25#include "TProfile2D.h"
26#include "THStack.h"
27#include "TF2.h"
28#include "TF3.h"
29#include "TCutG.h"
30#include "TMatrixDBase.h"
31#include "TMatrixFBase.h"
32#include "TVectorD.h"
33#include "TVectorF.h"
34#include "TCanvas.h"
35#include "TPad.h"
36#include "TPaveStats.h"
37#include "TFrame.h"
38#include "TLatex.h"
39#include "TPolyLine.h"
40#include "TPoints.h"
41#include "TStyle.h"
42#include "TGraph.h"
43#include "TMultiGraph.h"
44#include "TPie.h"
45#include "TGaxis.h"
46#include "TColor.h"
48#include "TGraph2DPainter.h"
49#include "TGraphDelaunay2D.h"
50#include "TView.h"
51#include "TMath.h"
52#include "TRandom2.h"
53#include "TObjArray.h"
54#include "Hoption.h"
55#include "Hparam.h"
56#include "TPluginManager.h"
57#include "TPaletteAxis.h"
58#include "TCrown.h"
59#include "TArrow.h"
60#include "TVirtualPadEditor.h"
61#include "TVirtualX.h"
62#include "TEnv.h"
63#include "TPoint.h"
64#include "TImage.h"
65#include "TCandle.h"
66#include "strlcpy.h"
67
68/*! \class THistPainter
69 \ingroup Histpainter
70 \brief The histogram painter class. Implements all histograms' drawing's options.
71
72- [Introduction](\ref HP00)
73- [Histograms' plotting options](\ref HP01)
74 - [Options supported for 1D and 2D histograms](\ref HP01a)
75 - [Options supported for 1D histograms](\ref HP01b)
76 - [Options supported for 2D histograms](\ref HP01c)
77 - [Options supported for 3D histograms](\ref HP01d)
78 - [Options supported for histograms' stacks (THStack)](\ref HP01e)
79- [Setting the Style](\ref HP02)
80- [Setting line, fill, marker, and text attributes](\ref HP03)
81- [Setting Tick marks on the histogram axis](\ref HP04)
82- [Giving titles to the X, Y and Z axis](\ref HP05)
83- [The option \"SAME\"](\ref HP060)
84 - [Limitations](\ref HP060a)
85- [Colors automatically picked in palette](\ref HP061)
86- [Superimposing two histograms with different scales in the same pad](\ref HP06)
87- [Statistics Display](\ref HP07)
88- [Fit Statistics](\ref HP08)
89- [The error bars options](\ref HP09)
90- [The bar chart option](\ref HP100)
91- [The \"BAR\" and \"HBAR\" options](\ref HP10)
92- [The SCATter plot option (default for 2D histograms)](\ref HP11)
93- [The ARRow option](\ref HP12)
94- [The BOX option](\ref HP13)
95- [The COLor option](\ref HP14)
96- [The CANDLE and VIOLIN options](\ref HP140)
97 - [The CANDLE option](\ref HP140a)
98 - [The VIOLIN option](\ref HP140b)
99- [The TEXT and TEXTnn Option](\ref HP15)
100- [The CONTour options](\ref HP16)
101 - [The LIST option](\ref HP16a)
102 - [The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options](\ref HP16b)
103- [The LEGO options](\ref HP17)
104- [The \"SURFace\" options](\ref HP18)
105- [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](\ref HP19)
106- [Base line for bar-charts and lego plots](\ref HP20)
107- [TH2Poly Drawing](\ref HP20a)
108- [The SPEC option](\ref HP21)
109- [Option \"Z\" : Adding the color palette on the right side of the pad](\ref HP22)
110- [Setting the color palette](\ref HP23)
111- [Drawing a sub-range of a 2-D histogram; the [cutg] option](\ref HP24)
112- [Drawing options for 3D histograms](\ref HP25)
113- [Drawing option for histograms' stacks](\ref HP26)
114- [Drawing of 3D implicit functions](\ref HP27)
115- [Associated functions drawing](\ref HP28)
116- [Drawing using OpenGL](\ref HP29)
117 - [General information: plot types and supported options](\ref HP29a)
118 - [TH3 as color boxes](\ref HP290)
119 - [TH3 as boxes (spheres)](\ref HP29b)
120 - [TH3 as iso-surface(s)](\ref HP29c)
121 - [TF3 (implicit function)](\ref HP29d)
122 - [Parametric surfaces](\ref HP29e)
123 - [Interaction with the plots](\ref HP29f)
124 - [Selectable parts](\ref HP29g)
125 - [Rotation and zooming](\ref HP29h)
126 - [Panning](\ref HP29i)
127 - [Box cut](\ref HP29j)
128 - [Plot specific interactions (dynamic slicing etc.)](\ref HP29k)
129 - [Surface with option \"GLSURF\"](\ref HP29l)
130 - [TF3](\ref HP29m)
131 - [Box](\ref HP29n)
132 - [Iso](\ref HP29o)
133 - [Parametric plot](\ref HP29p)
134- [Highlight mode for histogram](\ref HP30)
135 - [Highlight mode and user function](\ref HP30a)
136
137
138\anchor HP00
139## Introduction
140
141
142Histograms are drawn via the `THistPainter` class. Each histogram has a
143pointer to its own painter (to be usable in a multithreaded program). When the
144canvas has to be redrawn, the `Paint` function of each objects in the
145pad is called. In case of histograms, `TH1::Paint` invokes directly
146`THistPainter::Paint`.
147
148To draw a histogram `h` it is enough to do:
149
150 h->Draw();
151
152`h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
153be drawn, the `Draw()` method can be invoked with an option. For instance
154to draw a 2D histogram as a lego plot it is enough to do:
155
156 h->Draw("lego");
157
158`THistPainter` offers many options to paint 1D, 2D and 3D histograms.
159
160When the `Draw()` method of a histogram is called for the first time
161(`TH1::Draw`), it creates a `THistPainter` object and saves a
162pointer to this "painter" as a data member of the histogram. The
163`THistPainter` class specializes in the drawing of histograms. It is
164separated from the histogram so that one can have histograms without the
165graphics overhead, for example in a batch program. Each histogram having its own
166painter (rather than a central singleton painter painting all histograms), allows
167two histograms to be drawn in two threads without overwriting the painter's
168values.
169
170When a displayed histogram is filled again, there is no need to call the
171`Draw()` method again; the image will be refreshed the next time the
172pad will be updated.
173
174A pad is updated after one of these three actions:
175
1761. a carriage control on the ROOT command line,
1772. a click inside the pad,
1783. a call to `TPad::Update`.
179
180
181By default a call to `TH1::Draw()` clears the pad of all objects
182before drawing the new image of the histogram. One can use the `SAME`
183option to leave the previous display intact and superimpose the new histogram.
184The same histogram can be drawn with different graphics options in different
185pads.
186
187When a displayed histogram is deleted, its image is automatically removed
188from the pad.
189
190To create a copy of the histogram when drawing it, one can use
191`TH1::DrawClone()`. This will clone the histogram and allow to change
192and delete the original one without affecting the clone.
193
194
195\anchor HP01
196### Histograms' plotting options
197
198
199Most options can be concatenated with or without spaces or commas, for example:
200
201 h->Draw("E1 SAME");
202
203The options are not case sensitive:
204
205 h->Draw("e1 same");
206
207
208The default drawing option can be set with `TH1::SetOption` and retrieve
209using `TH1::GetOption`:
210
211 root [0] h->Draw(); // Draw "h" using the standard histogram representation.
212 root [1] h->Draw("E"); // Draw "h" using error bars
213 root [3] h->SetOption("E"); // Change the default drawing option for "h"
214 root [4] h->Draw(); // Draw "h" using error bars
215 root [5] h->GetOption(); // Retrieve the default drawing option for "h"
216 (const Option_t* 0xa3ff948)"E"
217
218
219\anchor HP01a
220#### Options supported for 1D and 2D histograms
221
222| Option | Description |
223|----------|-------------------------------------------------------------------|
224| "E" | Draw error bars. |
225| "AXIS" | Draw only axis. |
226| "AXIG" | Draw only grid (if the grid is requested). |
227| \anchor OPTHIST "HIST" | When an histogram has errors it is visualized by default with error bars. To visualize it without errors use the option "HIST" together with the required option (eg "hist same c"). The "HIST" option can also be used to plot only the histogram and not the associated function(s). |
228| "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
229| "SAME" | Superimpose on previous picture in the same pad. |
230| "SAMES" | Same as "SAME" and draw the statistics box|
231| "PFC" | Palette Fill Color: histogram's fill color is taken in the current palette. |
232| "PLC" | Palette Line Color: histogram's line color is taken in the current palette. |
233| "PMC" | Palette Marker Color: histogram's marker color is taken in the current palette. |
234| "LEGO" | Draw a lego plot with hidden line removal. |
235| "LEGO1" | Draw a lego plot with hidden surface removal. |
236| "LEGO2" | Draw a lego plot using colors to show the cell contents When the option "0" is used with any LEGO option, the empty bins are not drawn.|
237| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
238| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
239| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
240| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
241| "X+" | The X-axis is drawn on the top side of the plot. |
242| "Y+" | The Y-axis is drawn on the right side of the plot. |
243| "MIN0" | Set minimum value for the Y axis to 0, equivalent to gStyle->SetHistMinimumZero(). |
244
245\anchor HP01b
246#### Options supported for 1D histograms
247
248| Option | Description |
249|----------|-------------------------------------------------------------------|
250| " " | Default. |
251| "AH" | Draw histogram without axis. "A" can be combined with any drawing option. For instance, "AC" draws the histogram as a smooth Curve without axis.|
252| "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
253| "B" | Bar chart option.|
254| "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
255| "HBAR" | Like option "BAR", but bars are drawn horizontally.|
256| "C" | Draw a smooth Curve through the histogram bins.|
257| "E0" | Draw error bars. Markers are drawn for bins with 0 contents. Combined with E1 or E2 it avoids error bars clipping|
258| "E1" | Draw error bars with perpendicular lines at the edges.|
259| "E2" | Draw error bars with rectangles.|
260| "E3" | Draw a fill area through the end points of the vertical error bars.|
261| "E4" | Draw a smoothed filled area through the end points of the error bars.|
262| "E5" | Like E3 but ignore the bins with 0 contents.|
263| "E6" | Like E4 but ignore the bins with 0 contents.|
264| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
265| "L" | Draw a line through the bin contents.|
266| "P" | Draw current marker at each bin except empty bins.|
267| "P*" | Draw a star marker at each bin except empty bins.|
268| "P0" | Draw current marker at each bin including empty bins.|
269| "PIE" | Draw histogram as a Pie Chart.|
270| "*H" | Draw histogram with a * at each bin.|
271| "LF2" | Draw histogram like with option "L" but with a fill area. Note that "L" draws also a fill area if the hist fill color is set but the fill area corresponds to the histogram contour.|
272
273
274\anchor HP01c
275#### Options supported for 2D histograms
276
277| Option | Description |
278|--------------|------------------------------------------------------------------|
279| " " | Default (scatter plot).|
280| "ARR" | Arrow mode. Shows gradient between adjacent cells.|
281| "BOX" | A box is drawn for each cell with surface proportional to the content's absolute value. A negative content is marked with a X.|
282| "BOX1" | A button is drawn for each cell with surface proportional to content's absolute value. A sunken button is drawn for negative values a raised one for positive.|
283| "COL" | A box is drawn for each cell with a color scale varying with contents. All the none empty bins are painted. Empty bins are not painted unless some bins have a negative content because in that case the null bins might be not empty. `TProfile2D` histograms are handled differently because, for this type of 2D histograms, it is possible to know if an empty bin has been filled or not. So even if all the bins' contents are positive some empty bins might be painted. And vice versa, if some bins have a negative content some empty bins might be not painted.|
284| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
285| "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
286| "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
287| "Z CJUST" | In combination with colored options "COL","CONT0" etc: Justify labels in the color palette at color boudaries. For more details see `TPaletteAxis`|
288| "CANDLE" | Draw a candle plot along X axis.|
289| "CANDLEX" | Same as "CANDLE".|
290| "CANDLEY" | Draw a candle plot along Y axis.|
291| "CANDLEXn" | Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
292| "CANDLEYn" | Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
293| "VIOLIN" | Draw a violin plot along X axis.|
294| "VIOLINX" | Same as "VIOLIN".|
295| "VIOLINY" | Draw a violin plot along Y axis.|
296| "VIOLINXn" | Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
297| "VIOLINYn" | Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
298| "CONT" | Draw a contour plot (same as CONT0).|
299| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
300| "CONT1" | Draw a contour plot using line styles to distinguish contours.|
301| "CONT2" | Draw a contour plot using the same line style for all contours.|
302| "CONT3" | Draw a contour plot using fill area colors.|
303| "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
304| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
305| "LIST" | Generate a list of TGraph objects for each contour.|
306| "SAME0" | Same as "SAME" but do not use the z-axis range of the first plot. |
307| "SAMES0" | Same as "SAMES" but do not use the z-axis range of the first plot. |
308| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
309| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
310| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
311| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
312| "SURF" | Draw a surface plot with hidden line removal.|
313| "SURF1" | Draw a surface plot with hidden surface removal.|
314| "SURF2" | Draw a surface plot using colors to show the cell contents.|
315| "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
316| "SURF4" | Draw a surface using Gouraud shading.|
317| "SURF5" | Same as SURF3 but only the colored contour is drawn. Used with option CYL, SPH or PSR it allows to draw colored contours on a sphere, a cylinder or a in pseudo rapidity space. In cartesian or polar coordinates, option SURF3 is used.|
318| "AITOFF" | Draw a contour via an AITOFF projection.|
319| "MERCATOR" | Draw a contour via an Mercator projection.|
320| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
321| "PARABOLIC" | Draw a contour via an Parabolic projection.|
322| "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
323| "FB" | With LEGO or SURFACE, suppress the Front-Box.|
324| "BB" | With LEGO or SURFACE, suppress the Back-Box.|
325| "A" | With LEGO or SURFACE, suppress the axis.|
326| "SCAT" | Draw a scatter-plot (default).|
327| "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
328
329
330\anchor HP01d
331#### Options supported for 3D histograms
332
333| Option | Description |
334|----------|-------------------------------------------------------------------|
335| " " | Default (scatter plot).|
336| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`.|
337| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
338| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
339| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
340| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
341| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
342| "LEGO" | Same as `BOX`.|
343
344
345\anchor HP01e
346#### Options supported for histograms' stacks (`THStack`)
347
348| Option | Description |
349|------------|-----------------------------------------------------------------|
350| " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
351| "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
352| "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
353| "PADS" | The current pad/canvas is subdivided into a number of pads equal to the number of histograms in the stack and each histogram is paint into a separate pad.|
354| "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
355| "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
356| "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
357
358
359
360\anchor HP02
361### Setting the Style
362
363
364Histograms use the current style (`gStyle`). When one changes the current
365style and would like to propagate the changes to the histogram,
366`TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
367each histogram is needed.
368
369To force all the histogram to use the current style use:
370
371 gROOT->ForceStyle();
372
373All the histograms read after this call will use the current style.
374
375
376\anchor HP03
377### Setting line, fill, marker, and text attributes
378
379
380The histogram classes inherit from the attribute classes:
381`TAttLine`, `TAttFill` and `TAttMarker`.
382See the description of these classes for the list of options.
383
384
385\anchor HP04
386### Setting Tick marks on the histogram axis
387
388
389The `TPad::SetTicks` method specifies the type of tick marks on the axis.
390If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
391
392 tx = 1; tick marks on top side are drawn (inside)
393 tx = 2; tick marks and labels on top side are drawn
394 ty = 1; tick marks on right side are drawn (inside)
395 ty = 2; tick marks and labels on right side are drawn
396
397By default only the left Y axis and X bottom axis are drawn
398(`tx = ty = 0`)
399
400`TPad::SetTicks(tx,ty)` allows to set these options.
401See also The `TAxis` functions to set specific axis attributes.
402
403In case multiple color filled histograms are drawn on the same pad, the fill
404area may hide the axis tick marks. One can force a redraw of the axis over all
405the histograms by calling:
406
407 gPad->RedrawAxis();
408
409
410\anchor HP05
411### Giving titles to the X, Y and Z axis
412
413
414 h->GetXaxis()->SetTitle("X axis title");
415 h->GetYaxis()->SetTitle("Y axis title");
416
417The histogram title and the axis titles can be any `TLatex` string.
418The titles are part of the persistent histogram.
419
420
421\anchor HP060
422### The option "SAME"
423
424
425By default, when an histogram is drawn, the current pad is cleared before
426drawing. In order to keep the previous drawing and draw on top of it the
427option `SAME` should be use. The histogram drawn with the option
428`SAME` uses the coordinates system available in the current pad.
429
430This option can be used alone or combined with any valid drawing option but
431some combinations must be use with care.
432
433\anchor HP060a
434#### Limitations
435
436- It does not work when combined with the `LEGO` and `SURF` options unless the
437 histogram plotted with the option `SAME` has exactly the same
438 ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
439 lego plots [histograms' stacks](\ref HP26) should be used.
440
441
442\anchor HP061
443### Colors automatically picked in palette
444
445\since **ROOT version 6.09/01**
446
447When several histograms are painted in the same canvas thanks to the option "SAME"
448or via a `THStack` it might be useful to have an easy and automatic way to choose
449their color. The simplest way is to pick colors in the current active color
450palette. Palette coloring for histogram is activated thanks to the options `PFC`
451(Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
452When one of these options is given to `TH1::Draw` the histogram get its color
453from the current color palette defined by `gStyle->SetPalette(…)`. The color
454is determined according to the number of objects having palette coloring in
455the current pad.
456
457Begin_Macro(source)
458../../../tutorials/hist/histpalettecolor.C
459End_Macro
460
461Begin_Macro(source)
462../../../tutorials/hist/thstackpalettecolor.C
463End_Macro
464
465Begin_Macro(source)
466../../../tutorials/hist/thstack2palettecolor.C
467End_Macro
468
469\anchor HP06
470### Superimposing two histograms with different scales in the same pad
471
472
473The following example creates two histograms, the second histogram is the bins
474integral of the first one. It shows a procedure to draw the two histograms in
475the same pad and it draws the scale of the second histogram using a new vertical
476axis on the right side. See also the tutorial `transpad.C` for a variant
477of this example.
478
479Begin_Macro(source)
480{
481 auto c1 = new TCanvas("c1","c1",600,400);
482 // create/fill draw h1
483 gStyle->SetOptStat(kFALSE);
484 auto h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
485 Int_t i;
486 for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
487 h1->Draw();
488 c1->Update();
489
490 // create hint1 filled with the bins integral of h1
491 auto hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
492 float sum = 0.f;
493 for (i=1;i<=100;i++) {
494 sum += h1->GetBinContent(i);
495 hint1->SetBinContent(i,sum);
496 }
497
498 // scale hint1 to the pad coordinates
499 float rightmax = 1.1*hint1->GetMaximum();
500 float scale = gPad->GetUymax()/rightmax;
501 hint1->SetLineColor(kRed);
502 hint1->Scale(scale);
503 hint1->Draw("same");
504
505 // draw an axis on the right side
506 auto axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
507 gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
508 axis->SetLineColor(kRed);
509 axis->SetTextColor(kRed);
510 axis->Draw();
511}
512End_Macro
513
514
515\anchor HP07
516### Statistics Display
517
518
519The type of information shown in the histogram statistics box can be selected
520with:
521
522 gStyle->SetOptStat(mode);
523
524The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
525
526 mode = ksiourmen (default = 000001111)
527 k = 1; kurtosis printed
528 k = 2; kurtosis and kurtosis error printed
529 s = 1; skewness printed
530 s = 2; skewness and skewness error printed
531 i = 1; integral of bins printed
532 i = 2; integral of bins with option "width" printed
533 o = 1; number of overflows printed
534 u = 1; number of underflows printed
535 r = 1; standard deviation printed
536 r = 2; standard deviation and standard deviation error printed
537 m = 1; mean value printed
538 m = 2; mean and mean error values printed
539 e = 1; number of entries printed
540 n = 1; name of histogram is printed
541
542For example:
543
544 gStyle->SetOptStat(11);
545
546displays only the name of histogram and the number of entries, whereas:
547
548 gStyle->SetOptStat(1101);
549
550displays the name of histogram, mean value and standard deviation.
551
552<b>WARNING 1:</b> never do:
553
554 gStyle->SetOptStat(0001111);
555
556but instead do:
557
558 gStyle->SetOptStat(1111);
559
560because `0001111` will be taken as an octal number!
561
562<b>WARNING 2:</b> for backward compatibility with older versions
563
564 gStyle->SetOptStat(1);
565
566is taken as:
567
568 gStyle->SetOptStat(1111)
569
570To print only the name of the histogram do:
571
572 gStyle->SetOptStat(1000000001);
573
574<b>NOTE</b> that in case of 2D histograms, when selecting only underflow
575(10000) or overflow (100000), the statistics box will show all combinations
576of underflow/overflows and not just one single number.
577
578The parameter mode can be any combination of the letters `kKsSiIourRmMen`
579
580 k : kurtosis printed
581 K : kurtosis and kurtosis error printed
582 s : skewness printed
583 S : skewness and skewness error printed
584 i : integral of bins printed
585 I : integral of bins with option "width" printed
586 o : number of overflows printed
587 u : number of underflows printed
588 r : standard deviation printed
589 R : standard deviation and standard deviation error printed
590 m : mean value printed
591 M : mean value mean error values printed
592 e : number of entries printed
593 n : name of histogram is printed
594
595For example, to print only name of histogram and number of entries do:
596
597 gStyle->SetOptStat("ne");
598
599To print only the name of the histogram do:
600
601 gStyle->SetOptStat("n");
602
603The default value is:
604
605 gStyle->SetOptStat("nemr");
606
607When a histogram is painted, a `TPaveStats` object is created and added
608to the list of functions of the histogram. If a `TPaveStats` object
609already exists in the histogram list of functions, the existing object is just
610updated with the current histogram parameters.
611
612Once a histogram is painted, the statistics box can be accessed using
613`h->FindObject("stats")`. In the command line it is enough to do:
614
615 Root > h->Draw()
616 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
617
618because after `h->Draw()` the histogram is automatically painted. But
619in a script file the painting should be forced using `gPad->Update()`
620in order to make sure the statistics box is created:
621
622 h->Draw();
623 gPad->Update();
624 TPaveStats *st = (TPaveStats*)h->FindObject("stats");
625
626Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
627
628When a histogram is drawn with the option `SAME`, the statistics box
629is not drawn. To force the statistics box drawing with the option
630`SAME`, the option `SAMES` must be used.
631If the new statistics box hides the previous statistics box, one can change
632its position with these lines (`h` being the pointer to the histogram):
633
634 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
635 Root > st->SetX1NDC(newx1); //new x start position
636 Root > st->SetX2NDC(newx2); //new x end position
637
638To change the type of information for an histogram with an existing
639`TPaveStats` one should do:
640
641 st->SetOptStat(mode);
642
643Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
644(see above).
645
646One can delete the statistics box for a histogram `TH1* h` with:
647
648 h->SetStats(0)
649
650and activate it again with:
651
652 h->SetStats(1).
653
654Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
655`$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
656
657
658\anchor HP08
659### Fit Statistics
660
661
662The type of information about fit parameters printed in the histogram statistics
663box can be selected via the parameter mode. The parameter mode can be
664`= pcev` (default `= 0111`)
665
666 p = 1; print Probability
667 c = 1; print Chisquare/Number of degrees of freedom
668 e = 1; print errors (if e=1, v must be 1)
669 v = 1; print name/values of parameters
670
671Example:
672
673 gStyle->SetOptFit(1011);
674
675print fit probability, parameter names/values and errors.
676
6771. When `v = 1` is specified, only the non-fixed parameters are shown.
6782. When `v = 2` all parameters are shown.
679
680Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
681to `gStyle->SetOptFit(111)`
682
683
684\anchor HP09
685### The error bars options
686
687
688| Option | Description |
689|----------|-------------------------------------------------------------------|
690| "E" | Default. Shows only the error bars, not a marker.|
691| "E1" | Small lines are drawn at the end of the error bars.|
692| "E2" | Error rectangles are drawn.|
693| "E3" | A filled area is drawn through the end points of the vertical error bars.|
694| "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
695| "E0" | Draw error bars. Markers are drawn for bins with 0 contents. Combined with E1 or E2 it avoids error bars clipping|
696| "E5" | Like E3 but ignore the bins with 0 contents.|
697| "E6" | Like E4 but ignore the bins with 0 contents.|
698| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
699
700Begin_Macro(source)
701{
702 auto c1 = new TCanvas("c1","c1",600,400);
703 auto he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
704 for (int i=0; i<10000; i++) he->Fill(gRandom->Gaus(0,1));
705 gStyle->SetEndErrorSize(3);
706 gStyle->SetErrorX(1.);
707 he->SetMarkerStyle(20);
708 he->Draw("E1");
709}
710End_Macro
711
712The options "E3" and "E4" draw an error band through the end points of the
713vertical error bars. With "E4" the error band is smoothed. Because of the
714smoothing algorithm used some artefacts may appear at the end of the band
715like in the following example. In such cases "E3" should be used instead
716of "E4".
717
718Begin_Macro(source)
719{
720 auto ce4 = new TCanvas("ce4","ce4",600,400);
721 ce4->Divide(2,1);
722 auto he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
723 Int_t i;
724 for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
725 he4->SetFillColor(kRed);
726 he4->GetXaxis()->SetRange(40,48);
727 ce4->cd(1);
728 he4->Draw("E4");
729 ce4->cd(2);
730 auto he3 = (TH1F*)he4->DrawClone("E3");
731 he3->SetTitle("Distribution drawn option E3");
732}
733End_Macro
734
7352D histograms can be drawn with error bars as shown is the following example:
736
737Begin_Macro(source)
738{
739 auto c2e = new TCanvas("c2e","c2e",600,400);
740 auto h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
741 float px, py;
742 for (Int_t i = 0; i < 25000; i++) {
743 gRandom->Rannor(px,py);
744 h2e->Fill(px,5*py);
745 }
746 h2e->Draw("E");
747}
748End_Macro
749
750
751\anchor HP100
752### The bar chart option
753
754
755The option "B" allows to draw simple vertical bar charts.
756The bar width is controlled with `TH1::SetBarWidth()`,
757and the bar offset within the bin, with `TH1::SetBarOffset()`.
758These two settings are useful to draw several histograms on the
759same plot as shown in the following example:
760
761Begin_Macro(source)
762{
763 int i;
764 const Int_t nx = 8;
765 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
766 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
767 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
768
769 auto cb = new TCanvas("cb","cb",600,400);
770 cb->SetGrid();
771
772 gStyle->SetHistMinimumZero();
773
774 auto h1b = new TH1F("h1b","Option B example",nx,0,nx);
775 h1b->SetFillColor(4);
776 h1b->SetBarWidth(0.4);
777 h1b->SetBarOffset(0.1);
778 h1b->SetStats(0);
779 h1b->SetMinimum(-5);
780 h1b->SetMaximum(5);
781
782 for (i=1; i<=nx; i++) {
783 h1b->SetBinContent(i, d_35_0[i-1]);
784 h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
785 }
786
787 h1b->Draw("b");
788
789 auto h2b = new TH1F("h2b","h2b",nx,0,nx);
790 h2b->SetFillColor(38);
791 h2b->SetBarWidth(0.4);
792 h2b->SetBarOffset(0.5);
793 h2b->SetStats(0);
794 for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
795
796 h2b->Draw("b same");
797}
798End_Macro
799
800
801\anchor HP10
802### The "BAR" and "HBAR" options
803
804
805When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
806bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
807An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
808`hbar2`, `hbar3`, `hbar4` (hbars.C).
809
810- The bar is filled with the histogram fill color.
811- The left side of the bar is drawn with a light fill color.
812- The right side of the bar is drawn with a dark fill color.
813- The percentage of the bar drawn with either the light or dark color is:
814 - 0% for option "(h)bar" or "(h)bar0"
815 - 10% for option "(h)bar1"
816 - 20% for option "(h)bar2"
817 - 30% for option "(h)bar3"
818 - 40% for option "(h)bar4"
819
820When an histogram has errors the option [\"HIST\"](\ref OPTHIST) together with the `(h)bar` option.
821
822Begin_Macro(source)
823../../../tutorials/hist/hbars.C
824End_Macro
825
826To control the bar width (default is the bin width) `TH1::SetBarWidth()`
827should be used.
828
829To control the bar offset (default is 0) `TH1::SetBarOffset()` should
830be used.
831
832These two parameters are useful when several histograms are plotted using
833the option `SAME`. They allow to plot the histograms next to each other.
834
835
836\anchor HP11
837### The SCATter plot option (default for 2D histograms)
838
839
840For each cell (i,j) a number of points proportional to the cell content is
841drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
842`kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
843If option is of the form `scat=ff`, (eg `scat=1.8`,
844`scat=1e-3`), then `ff` is used as a scale factor to compute the
845number of dots. `scat=1` is the default.
846
847By default the scatter plot is painted with a "dot marker" which not scalable
848(see the `TAttMarker` documentation). To change the marker size, a scalable marker
849type should be used. For instance a circle (marker style 20).
850
851Begin_Macro(source)
852{
853 auto c1 = new TCanvas("c1","c1",600,400);
854 auto hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
855 float px, py;
856 for (Int_t i = 0; i < 25000; i++) {
857 gRandom->Rannor(px,py);
858 hscat->Fill(px,5*py);
859 hscat->Fill(3+0.5*px,2*py-10.);
860 }
861 hscat->Draw("scat=0.5");
862}
863End_Macro
864
865
866\anchor HP12
867### The ARRow option
868
869
870Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
871The orientation of the arrow follows the cell gradient.
872
873Begin_Macro(source)
874{
875 auto c1 = new TCanvas("c1","c1",600,400);
876 auto harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
877 harr->SetLineColor(kRed);
878 float px, py;
879 for (Int_t i = 0; i < 25000; i++) {
880 gRandom->Rannor(px,py);
881 harr->Fill(px,5*py);
882 harr->Fill(3+0.5*px,2*py-10.,0.1);
883 }
884 harr->Draw("ARR");
885}
886End_Macro
887
888\since **ROOT version 6.17/01**
889
890The option `ARR` can be combined with the option `COL` or `COLZ`.
891
892Begin_Macro(source)
893{
894 auto c1 = new TCanvas("c1","c1",600,400);
895 auto harr = new TH2F("harr","Option ARR + COLZ example",20,-4,4,20,-20,20);
896 harr->SetStats(0);
897 float px, py;
898 for (Int_t i = 0; i < 25000; i++) {
899 gRandom->Rannor(px,py);
900 harr->Fill(px,5*py);
901 harr->Fill(3+0.5*px,2*py-10.,0.1);
902 }
903 harr->Draw("ARR COLZ");
904}
905End_Macro
906
907
908\anchor HP13
909### The BOX option
910
911
912For each cell (i,j) a box is drawn. The size (surface) of the box is
913proportional to the absolute value of the cell content.
914The cells with a negative content are drawn with a `X` on top of the box.
915
916Begin_Macro(source)
917{
918 auto c1 = new TCanvas("c1","c1",600,400);
919 auto hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
920 hbox->SetFillColor(42);
921 hbox->Fill(0.5, 0.5, 1.);
922 hbox->Fill(0.5, 1.5, 4.);
923 hbox->Fill(0.5, 2.5, 3.);
924 hbox->Fill(1.5, 0.5, 2.);
925 hbox->Fill(1.5, 1.5, 12.);
926 hbox->Fill(1.5, 2.5, -6.);
927 hbox->Fill(2.5, 0.5, -4.);
928 hbox->Fill(2.5, 1.5, 6.);
929 hbox->Fill(2.5, 2.5, 0.5);
930 hbox->Draw("BOX");
931}
932End_Macro
933
934With option `BOX1` a button is drawn for each cell with surface
935proportional to content's absolute value. A sunken button is drawn for
936negative values a raised one for positive.
937
938Begin_Macro(source)
939{
940 auto c1 = new TCanvas("c1","c1",600,400);
941 auto hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
942 hbox1->SetFillColor(42);
943 hbox1->Fill(0.5, 0.5, 1.);
944 hbox1->Fill(0.5, 1.5, 4.);
945 hbox1->Fill(0.5, 2.5, 3.);
946 hbox1->Fill(1.5, 0.5, 2.);
947 hbox1->Fill(1.5, 1.5, 12.);
948 hbox1->Fill(1.5, 2.5, -6.);
949 hbox1->Fill(2.5, 0.5, -4.);
950 hbox1->Fill(2.5, 1.5, 6.);
951 hbox1->Fill(2.5, 2.5, 0.5);
952 hbox1->Draw("BOX1");
953}
954End_Macro
955
956When the option `SAME` (or "SAMES") is used with the option `BOX`,
957the boxes' sizes are computing taking the previous plots into account. The range
958along the Z axis is imposed by the first plot (the one without option
959`SAME`); therefore the order in which the plots are done is relevant.
960
961Begin_Macro(source)
962{
963 auto c1 = new TCanvas("c1","c1",600,400);
964 auto hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
965 auto hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
966 auto hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
967 auto hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
968 for (Int_t i=0;i<1000;i++) {
969 double x,y;
970 gRandom->Rannor(x,y);
971 if (x>0 && y>0) hb1->Fill(x,y,4);
972 if (x<0 && y<0) hb2->Fill(x,y,3);
973 if (x>0 && y<0) hb3->Fill(x,y,2);
974 if (x<0 && y>0) hb4->Fill(x,y,1);
975 }
976 hb1->SetFillColor(1);
977 hb2->SetFillColor(2);
978 hb3->SetFillColor(3);
979 hb4->SetFillColor(4);
980 hb1->Draw("box");
981 hb2->Draw("box same");
982 hb3->Draw("box same");
983 hb4->Draw("box same");
984}
985End_Macro
986
987\since **ROOT version 6.17/01:**
988
989Sometimes the change of the range of the Z axis is unwanted, in which case, one
990can use `SAME0` (or `SAMES0`) option to opt out of this change.
991
992Begin_Macro(source)
993{
994 auto h2 = new TH2F("h2"," ",10,0,10,10,20,30);
995 auto hf = (TH2F*)h2->Clone("hf");
996 h2->SetBit(TH1::kNoStats);
997 hf->SetBit(TH1::kNoStats);
998 h2->Fill(5,22);
999 h2->Fill(5,23);
1000 h2->Fill(6,22);
1001 h2->Fill(6,23);
1002 hf->Fill(6,23);
1003 hf->Fill(6,23);
1004 hf->Fill(6,23);
1005 hf->Fill(6,23);
1006 hf->Fill(5,23);
1007
1008 auto hf_copy1 = hf->Clone("hf_copy1");
1009 auto lt = new TLatex();
1010
1011 auto cx = new TCanvas(); cx->Divide(2,1);
1012
1013 cx->cd(1);
1014 h2->Draw("box");
1015 hf->Draw("text colz same");
1016 lt->DrawLatexNDC(0.3,0.5,"SAME");
1017
1018 cx->cd(2);
1019 h2->Draw("box");
1020 hf_copy1->Draw("text colz same0");
1021 lt->DrawLatexNDC(0.3,0.5,"SAME0");
1022}
1023End_Macro
1024
1025
1026\anchor HP14
1027### The COLor option
1028
1029
1030For each cell (i,j) a box is drawn with a color proportional to the cell
1031content.
1032
1033The color table used is defined in the current style.
1034
1035If the histogram's minimum and maximum are the same (flat histogram), the
1036mapping on colors is not possible, therefore nothing is painted. To paint a
1037flat histogram it is enough to set the histogram minimum
1038(`TH1::SetMinimum()`) different from the bins' content.
1039
1040The default number of color levels used to paint the cells is 20.
1041It can be changed with `TH1::SetContour()` or
1042`TStyle::SetNumberContours()`. The higher this number is, the smoother
1043is the color change between cells.
1044
1045The color palette in TStyle can be modified via `gStyle->SetPalette()`.
1046
1047All the non-empty bins are painted. Empty bins are not painted unless
1048some bins have a negative content because in that case the null bins
1049might be not empty.
1050
1051`TProfile2D` histograms are handled differently because, for this type of 2D
1052histograms, it is possible to know if an empty bin has been filled or not. So even
1053if all the bins' contents are positive some empty bins might be painted. And vice versa,
1054if some bins have a negative content some empty bins might be not painted.
1055
1056Combined with the option `COL`, the option `Z` allows to
1057display the color palette defined by `gStyle->SetPalette()`.
1058
1059In the following example, the histogram has only positive bins; the empty
1060bins (containing 0) are not drawn.
1061
1062Begin_Macro(source)
1063{
1064 auto c1 = new TCanvas("c1","c1",600,400);
1065 auto hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
1066 float px, py;
1067 for (Int_t i = 0; i < 25000; i++) {
1068 gRandom->Rannor(px,py);
1069 hcol1->Fill(px,5*py);
1070 }
1071 hcol1->Draw("COLZ");
1072}
1073End_Macro
1074
1075In the first plot of following example, the histogram has some negative bins;
1076the empty bins (containing 0) are drawn. In some cases one wants to not draw
1077empty bins (containing 0) of histograms having a negative minimum. The option
1078`1`, used to produce the second plot in the following picture, allows to do that.
1079
1080Begin_Macro(source)
1081{
1082 auto c1 = new TCanvas("c1","c1",600,600);
1083 c1->Divide(1,2);
1084 auto hcol23 = new TH2F("hcol23","Option COLZ example ",40,-4,4,40,-20,20);
1085 auto hcol24 = new TH2F("hcol24","Option COLZ1 example ",40,-4,4,40,-20,20);
1086 float px, py;
1087 for (Int_t i = 0; i < 25000; i++) {
1088 gRandom->Rannor(px,py);
1089 hcol23->Fill(px,5*py);
1090 hcol24->Fill(px,5*py);
1091 }
1092 hcol23->Fill(0.,0.,-200.);
1093 hcol24->Fill(0.,0.,-200.);
1094 c1->cd(1); hcol23->Draw("COLZ");
1095 c1->cd(2); hcol24->Draw("COLZ1");
1096}
1097End_Macro
1098
1099When the maximum of the histogram is set to a smaller value than the real maximum,
1100 the bins having a content between the new maximum and the real maximum are
1101painted with the color corresponding to the new maximum.
1102
1103When the minimum of the histogram is set to a greater value than the real minimum,
1104 the bins having a value between the real minimum and the new minimum are not drawn
1105 unless the option `0` is set.
1106
1107The following example illustrates the option `0` combined with the option `COL`.
1108
1109Begin_Macro(source)
1110{
1111 auto c1 = new TCanvas("c1","c1",600,600);
1112 c1->Divide(1,2);
1113 auto hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1114 auto hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1115 float px, py;
1116 for (Int_t i = 0; i < 25000; i++) {
1117 gRandom->Rannor(px,py);
1118 hcol21->Fill(px,5*py);
1119 hcol22->Fill(px,5*py);
1120 }
1121 hcol21->SetBit(TH1::kNoStats);
1122 hcol22->SetBit(TH1::kNoStats);
1123 c1->cd(1); hcol21->Draw("COLZ");
1124 c1->cd(2); hcol22->Draw("COLZ0");
1125 hcol22->SetMaximum(100);
1126 hcol22->SetMinimum(40);
1127}
1128End_Macro
1129
1130\since **ROOT version 6.09/01:**
1131
1132When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1133are computing taking the previous plots into account. The range along the Z axis
1134is imposed by the first plot (the one without option SAME); therefore the order
1135in which the plots are done is relevant. Same as [in the `BOX` option](\ref HP13), one can use
1136`SAME0` (or `SAMES0`) to opt out of this imposition.
1137
1138Begin_Macro(source)
1139{
1140 auto c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1141 auto h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1142 auto h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1143 auto h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1144 auto h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1145 h1->SetBit(TH1::kNoStats);
1146 for (Int_t i=0;i<5000;i++) {
1147 double x,y;
1148 gRandom->Rannor(x,y);
1149 if(x>0 && y>0) h1->Fill(x,y,4);
1150 if(x<0 && y<0) h2->Fill(x,y,3);
1151 if(x>0 && y<0) h3->Fill(x,y,2);
1152 if(x<0 && y>0) h4->Fill(x,y,1);
1153 }
1154 h1->Draw("colz");
1155 h2->Draw("col same");
1156 h3->Draw("col same");
1157 h4->Draw("col same");
1158}
1159End_Macro
1160
1161The option `COL` can be combined with the option `POL`:
1162
1163Begin_Macro(source)
1164{
1165 auto c1 = new TCanvas("c1","c1",600,400);
1166 auto hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1167 float px, py;
1168 for (Int_t i = 0; i < 25000; i++) {
1169 gRandom->Rannor(px,py);
1170 hcol1->Fill(px,py);
1171 }
1172 hcol1->Draw("COLZPOL");
1173}
1174End_Macro
1175
1176\since **ROOT version 6.07/03:**
1177
1178A second rendering technique is also available with the COL2 and COLZ2 options.
1179
1180These options provide potential performance improvements compared to the standard
1181COL option. The performance comparison of the COL2 to the COL option depends on
1182the histogram and the size of the rendering region in the current pad. In general,
1183a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1184faster with the COL option.
1185
1186However, for larger histograms (approx. more than 100 bins per axis)
1187that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1188For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1189faster with the COL2 option.
1190
1191The COL2 option will also scale its performance based on the size of the
1192pixmap the histogram image is being rendered into. It also is much better optimized for
1193sessions where the user is forwarding X11 windows through an `ssh` connection.
1194
1195For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1196and COLZ options. There is one major difference and that concerns the treatment of
1197bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1198
1199COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1200graphics file format like PostScript or PDF (an empty image will be generated). It can
1201be saved only in bitmap files like PNG format for instance.
1202
1203
1204\anchor HP140
1205### The CANDLE and VIOLIN options
1206
1207The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1208implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1209the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1210vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1211(1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1212
1213Instead of using the predefined representations, the candle and violin parameters can be
1214changed individually. In that case the option have the following form:
1215
1216 CANDLEX(<option-string>)
1217 CANDLEY(<option-string>)
1218 VIOLINX(<option-string>)
1219 VIOLINY(<option-string>).
1220
1221All zeros at the beginning of `option-string` can be omitted.
1222
1223`option-string` consists eight values, defined as follow:
1224
1225 "CANDLEX(zhpawMmb)"
1226
1227Where:
1228
1229 - `b = 0`; no box drawn
1230 - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1231 makes sense in the very most cases to always draw the box
1232 - `b = 2`; draw a filled box with border
1233
1234 - `m = 0`; no median drawn
1235 - `m = 1`; median is drawn as a line
1236 - `m = 2`; median is drawn with errors (notches)
1237 - `m = 3`; median is drawn as a circle
1238
1239 - `M = 0`; no mean drawn
1240 - `M = 1`; mean is drawn as a dashed line
1241 - `M = 3`; mean is drawn as a circle
1242
1243 - `w = 0`; no whisker drawn
1244 - `w = 1`; whisker is drawn to end of distribution.
1245 - `w = 2`; whisker is drawn to max 1.5*iqr
1246
1247 - `a = 0`; no anchor drawn
1248 - `a = 1`; the anchors are drawn
1249
1250 - `p = 0`; no points drawn
1251 - `p = 1`; only outliers are drawn
1252 - `p = 2`; all datapoints are drawn
1253 - `p = 3`: all datapoints are drawn scattered
1254
1255 - `h = 0`; no histogram is drawn
1256 - `h = 1`; histogram at the left or bottom side is drawn
1257 - `h = 2`; histogram at the right or top side is drawn
1258 - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1259
1260 - `z = 0`; no zero indicator line is drawn
1261 - `z = 1`; zero indicator line is drawn.
1262
1263As one can see all individual options for both candle and violin plots can be accessed by this
1264mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1265meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1266vice versa, if you wish.
1267
1268Using a logarithmic x- or y-axis is possible for candle and violin charts.
1269
1270\since **ROOT version 6.11/01**
1271
1272a logarithmic z-axis is possible, too but will only affect violin charts of course.
1273
1274\anchor HP140a
1275#### The CANDLE option
1276
1277<a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1278a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1279way to describe graphically a data distribution (D) with only five numbers:
1280
1281 1. The minimum value of the distribution D (bottom or left whisker).
1282 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1283 3. The median (M): 50% of the data points in D are less than M.
1284 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1285 5. The maximum value of the distribution D (top or right whisker).
1286
1287In this implementation a TH2 is considered as a collection of TH1 along
1288X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1289Each TH1 is represented as one candle.
1290
1291Begin_Macro(source)
1292../../../tutorials/hist/candleplotwhiskers.C
1293End_Macro
1294
1295The candle reduces the information coming from a whole distribution into few values.
1296Independently from the number of entries or the significance of the underlying distribution
1297a candle will always look like a candle. So candle plots should be used carefully in
1298particular with unknown distributions. The definition of a candle is based on
1299__unbinned data__. Here, candles are created from binned data. Because of this, the
1300deviation is connected to the bin width used. The calculation of the quantiles
1301normally done on unbinned data also. Because data are binned, this will
1302only work the best possible way within the resolution of one bin
1303
1304Because of all these facts one should take care that:
1305
1306 - there are enough points per candle
1307 - the bin width is small enough (more bins will increase the maximum
1308 available resolution of the quantiles although there will be some
1309 bins with no entries)
1310 - never make a candle-plot if the underlying distribution is double-distributed
1311 - only create candles of distributions that are more-or-less gaussian (the
1312 MPV should be not too far away from the mean).
1313
1314#### What a candle is made of
1315
1316\since **ROOT version 6.07/05**
1317
1318##### The box
1319The box displays the position of the inter-quantile-range of the underlying
1320distribution. The box contains 25% of the distribution below the median
1321and 25% of the distribution above the median. If the underlying distribution is large
1322enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1323(Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1324the position of the box can be modified by SetBarWidth() and SetBarOffset().
1325The +-25% quantiles are calculated by the GetQuantiles() methods.
1326
1327\since **ROOT version 6.11/01**
1328
1329Using the static function TCandle::SetBoxRange(double) the box definition will be
1330overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1331to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1332The static function will affect all candle-charts in the running program.
1333Default is 0.5.
1334
1335Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1336whole candle) can be influenced. Deactivated, the width is constant (to be set by
1337SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1338amount of data in the corresponding candle, the maximum width can be influenced by
1339SetBarWidth(). The static function will affect all candle-charts in the running program.
1340Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1341supported, yet
1342
1343##### The Median
1344For a sorted list of numbers, the median is the value in the middle of the list.
1345E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1346because it is in the middle of the list. If the number of entries is even the
1347average of the two values in the middle will be used. As histograms are binned
1348data, the situation is a bit more complex. The following example shows this:
1349
1350~~~ {.cpp}
1351void quantiles() {
1352 auto h = new TH1I("h","h",10,0,10);
1353 //h->Fill(3);
1354 //h->Fill(3);
1355 h->Fill(4);
1356 h->Draw();
1357 double p = 0.;
1358 double q = 0.;
1359 h->GetQuantiles(1,&q,&p);
1360
1361 cout << "Median is: " << q << std::endl;
1362}
1363~~~
1364
1365Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1366the example will return a calculated median of 4.5, because that's the bin center
1367of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1368commented out, it will return 3.75, because the algorithm tries to evenly distribute
1369the individual values of a bin with bin content > 0. It means the sorted list
1370would be "3.25, 3.75, 4.5".
1371
1372The consequence is a median of 3.75. This shows how important it is to use a
1373small enough bin-width when using candle-plots on binned data.
1374If the distribution is large enough and gaussian shaped the median will be exactly
1375equal to the mean.
1376The median can be shown as a line or as a circle or not shown at all.
1377
1378In order to show the significance of the median notched candle plots apply a "notch" or
1379narrowing of the box around the median. The significance is defined by
1380\f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1381(where iqr is the size of the box and N is the number of entries of the whole
1382distribution). Candle plots like these are usually called "notched candle plots".
1383
1384In case the significance of the median is greater that the size of the box, the
1385box will have an unnatural shape. Usually it means the chart has not enough data,
1386or that representing this uncertainty is not useful
1387
1388##### The Mean
1389The mean can be drawn as a dashed line or as a circle or not drawn at all.
1390The mean is the arithmetic average of the values in the distribution.
1391It is calculated using GetMean(). Because histograms are
1392binned data, the mean value can differ from a calculation on the raw-data.
1393If the distribution is large enough and gaussian shaped the mean will be
1394exactly the median.
1395
1396##### The Whiskers
1397The whiskers represent the part of the distribution not covered by the box.
1398The upper 25% and the lower 25% of the distribution are located within the whiskers.
1399Two representations are available.
1400
1401 - A simple one (using w=1) defining the lower whisker from the lowest data value
1402 to the bottom of the box, and the upper whisker from the top of the box to the
1403 highest data value. In this representation the whisker-lines are dashed.
1404 - A more complex one having a further restriction. The whiskers are still connected
1405 to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1406 be that the outermost part of the underlying distribution will not be covered
1407 by the whiskers. Usually these missing parts will be represented by the outliers
1408 (see points). Of course the upper and the lower whisker may differ in length.
1409 In this representation the whiskers are drawn as solid lines.
1410
1411\since **ROOT version 6.11/01**
1412
1413Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1414will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1415the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1416that candle. The static function will affect all candle-charts in the running program.
1417Default is 1.
1418
1419If the distribution is large enough and gaussian shaped, the maximum length of
1420the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
14211.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1422(see picture above). In that case 99.3% of the total distribution will be covered
1423by the box and the whiskers, whereas 0.7% are represented by the outliers.
1424
1425##### The Anchors
1426The anchors have no special meaning in terms of statistical calculation. They mark
1427the end of the whiskers and they have the width of the box. Both representation
1428with and without anchors are common.
1429
1430##### The Points
1431Depending on the configuration the points can have different meanings:
1432 - If p=1 the points represent the outliers. If they are shown, it means
1433 some parts of the underlying distribution are not covered by the whiskers.
1434 This can only occur when the whiskers are set to option w=2. Here the whiskers
1435 can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1436 whiskers will be drawn as outliers. The outliers will be represented by crosses.
1437 - If p=2 all points in the distribution will be painted as crosses. This is
1438 useful for small datasets only (up to 10 or 20 points per candle).
1439 The outliers are shown along the candle. Because the underlying distribution
1440 is binned, is frequently occurs that a bin contains more than one value.
1441 Because of this the points will be randomly scattered within their bin along
1442 the candle axis. If the bin content for a bin is exactly 1 (usually
1443 this happens for the outliers) if will be drawn in the middle of the bin along
1444 the candle axis. As the maximum number of points per candle is limited by kNMax/2
1445 on very large datasets scaling will be performed automatically. In that case one
1446 would loose all outliers because they have usually a bin content of 1 (and a
1447 bin content between 0 and 1 after the scaling). Because of this all bin contents
1448 between 0 and 1 - after the scaling - will be forced to be 1.
1449 - As the drawing of all values on large datasets can lead to big amounts of crosses,
1450 one can show all values as a scatter plot instead by choosing p=3. The points will be
1451 drawn as dots and will be scattered within the width of the candle. The color
1452 of the points will be the color of the candle-chart.
1453
1454##### Other Options
1455Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1456with a histogram.
1457
1458#### How to use the candle-plots drawing option
1459
1460There are six predefined candle-plot representations:
1461
1462 - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1463 - "CANDLEX2": Standard candle with better whisker definition + outliers.
1464 It is a good compromise
1465 - "CANDLEX3": Like candle2 but with a mean as a circle.
1466 It is easier to distinguish mean and median
1467 - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1468 (notched candle plots).
1469 For bigger datasets per candle
1470 - "CANDLEX5": Like candle2 but showing all data points.
1471 For very small datasets
1472 - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1473 For huge datasets
1474
1475
1476The following picture shows how the six predefined representations look.
1477
1478Begin_Macro
1479{
1480 auto c1 = new TCanvas("c1","c1",700,800);
1481 c1->Divide(2,3);
1482 gStyle->SetOptStat(kFALSE);
1483
1484 auto hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1485 float px, py;
1486 for (Int_t i = 0; i < 15000; i++) {
1487 gRandom->Rannor(px,py);
1488 hcandle->Fill(px,5*py);
1489 }
1490 hcandle->SetMarkerSize(0.5);
1491
1492 TH2F *h2;
1493 for (Int_t i=1; i<7; i++) {
1494 c1->cd(i);
1495 h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1496 h2->SetTitle(Form("CANDLE%d",i));
1497 }
1498}
1499End_Macro
1500
1501
1502#### Example 1
1503Box and improved whisker, no mean, no median, no anchor no outliers
1504
1505 h1->Draw("CANDLEX(2001)");
1506
1507#### Example 2
1508A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1509
1510 h1->Draw("CANDLEX(112111)");
1511
1512#### Example 3
1513The following example shows how several candle plots can be super-imposed using
1514the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1515Also the color, the line width, the size of the points and so on can be changed by the
1516standard attribute setting methods such as SetLineColor() SetLineWidth().
1517
1518Begin_Macro(source)
1519../../../tutorials/hist/candleplot.C
1520End_Macro
1521
1522\anchor HP140b
1523#### The VIOLIN option
1524
1525<a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1526that also encodes the pdf information at each point.
1527
1528
1529Quartiles and mean are also represented at each point, with a marker
1530and two lines.
1531
1532In this implementation a TH2 is considered as a collection of TH1 along
1533X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1534
1535#### What a violin is made of
1536
1537\since **ROOT version 6.09/02**
1538
1539##### The histogram
1540The histogram is typically drawn to both directions with respect to the middle-line of the
1541corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1542one side (h=1, or h=2).
1543The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1544histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1545be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1546A solid fill style is recommended.
1547
1548\since **ROOT version 6.11/01**
1549
1550Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1551violin can be influenced. Activated, the height of the bins of the individual violins will be
1552scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1553Deactivated, the height of the bin with the maximum content of each individual violin is
1554set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1555in the running program. Default is true. Scaling between multiple violin-charts
1556(using "same" or THStack) is not supported, yet.
1557
1558##### The zero indicator line
1559Typical for violin charts is a line in the background over the whole histogram indicating
1560the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1561will always be the same as the fill-color of the histogram.
1562
1563##### The Mean
1564The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1565
1566##### Whiskers
1567The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1568difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1569the whiskers will be forced to be solid (usually hashed)
1570
1571##### Points
1572The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1573better whisker definition (w=2) and outliers (p=1).
1574
1575##### Other options
1576It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1577including a box-plot.
1578
1579#### How to use the violin-plots drawing option
1580
1581There are two predefined violin-plot representations:
1582 - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1583 zero indicator line)
1584 - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1585
1586A solid fill style is recommended for this plot (as opposed to a hollow or
1587hashed style).
1588
1589Begin_Macro(source)
1590{
1591 auto c1 = new TCanvas("c1","c1",600,400);
1592 Int_t nx(6), ny(40);
1593 double xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1594 auto hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1595 TF1 f1("f1", "gaus", +0,0 +4.0);
1596 double x,y;
1597 for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1598 double xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1599 f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1600 for(Int_t i=0; i<10000; ++i){
1601 x = xc;
1602 y = f1.GetRandom();
1603 hviolin->Fill(x, y);
1604 }
1605 }
1606 hviolin->SetFillColor(kGray);
1607 hviolin->SetMarkerStyle(20);
1608 hviolin->SetMarkerSize(0.5);
1609 hviolin->Draw("VIOLIN");
1610 c1->Update();
1611}
1612End_Macro
1613
1614The next example illustrates a time development of a certain value:
1615
1616Begin_Macro(source)
1617../../../tutorials/hist/candledecay.C
1618End_Macro
1619
1620
1621\anchor HP15
1622### The TEXT and TEXTnn Option
1623
1624
1625For each bin the content is printed. The text attributes are:
1626
1627- text font = current TStyle font (`gStyle->SetTextFont()`).
1628- text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1629 with the option `TEXT` the marker size can be changed with
1630 `h->SetMarkerSize(markersize)`).
1631- text color = marker color.
1632
1633By default the format `g` is used. This format can be redefined
1634by calling `gStyle->SetPaintTextFormat()`.
1635
1636It is also possible to use `TEXTnn` in order to draw the text with
1637the angle `nn` (`0 < nn < 90`).
1638
1639For 2D histograms the text is plotted in the center of each non empty cells.
1640It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`
1641or providing MIN0 draw option. For 1D histogram the text is plotted at a y
1642position equal to the bin content.
1643
1644For 2D histograms when the option "E" (errors) is combined with the option
1645text ("TEXTE"), the error for each bin is also printed.
1646
1647Begin_Macro(source)
1648{
1649 auto c01 = new TCanvas("c01","c01",700,400);
1650 c01->Divide(2,1);
1651 auto htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1652 auto htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1653 float px, py;
1654 for (Int_t i = 0; i < 25000; i++) {
1655 gRandom->Rannor(px,py);
1656 htext1->Fill(px,0.1);
1657 htext2->Fill(px,5*py,0.1);
1658 }
1659 gStyle->SetPaintTextFormat("4.1f m");
1660 htext2->SetMarkerSize(1.8);
1661 c01->cd(1);
1662 htext2->Draw("TEXT45");
1663 c01->cd(2);
1664 htext1->Draw();
1665 htext1->Draw("HIST TEXT0 SAME");
1666}
1667End_Macro
1668
1669\since **ROOT version 6.07/07:**
1670
1671In case several histograms are drawn on top ot each other (using option `SAME`),
1672the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1673text position in each cell, in percentage of the bin width.
1674
1675Begin_Macro(source)
1676{
1677 auto c03 = new TCanvas("c03","c03",700,400);
1678 gStyle->SetOptStat(0);
1679 auto htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1680 auto htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1681 auto htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1682 float px, py;
1683 for (Int_t i = 0; i < 25000; i++) {
1684 gRandom->Rannor(px,py);
1685 htext3->Fill(4*px,20*py,0.1);
1686 htext4->Fill(4*px,20*py,0.5);
1687 htext5->Fill(4*px,20*py,1.0);
1688 }
1689 htext4->SetMarkerSize(1.8);
1690 htext5->SetMarkerSize(1.8);
1691 htext5->SetMarkerColor(kRed);
1692 htext3->Draw("COL");
1693 htext4->SetBarOffset(0.2);
1694 htext4->Draw("TEXT SAME");
1695 htext5->SetBarOffset(-0.2);
1696 htext5->Draw("TEXT SAME");
1697}
1698End_Macro
1699
1700In the case of profile histograms it is possible to print the number
1701of entries instead of the bin content. It is enough to combine the
1702option "E" (for entries) with the option "TEXT".
1703
1704Begin_Macro(source)
1705{
1706 auto c02 = new TCanvas("c02","c02",700,400);
1707 c02->Divide(2,1);
1708 gStyle->SetPaintTextFormat("g");
1709
1710 auto profile = new TProfile("profile","profile",10,0,10);
1711 profile->SetMarkerSize(2.2);
1712 profile->Fill(0.5,1);
1713 profile->Fill(1.5,2);
1714 profile->Fill(2.5,3);
1715 profile->Fill(3.5,4);
1716 profile->Fill(4.5,5);
1717 profile->Fill(5.5,5);
1718 profile->Fill(6.5,4);
1719 profile->Fill(7.5,3);
1720 profile->Fill(8.5,2);
1721 profile->Fill(9.5,1);
1722 c02->cd(1); profile->Draw("HIST TEXT0");
1723 c02->cd(2); profile->Draw("HIST TEXT0E");
1724}
1725End_Macro
1726
1727\anchor HP16
1728### The CONTour options
1729
1730
1731The following contour options are supported:
1732
1733| Option | Description |
1734|----------|-----------------------------------------------------------------------------|
1735| "CONT" | Draw a contour plot (same as CONT0). |
1736| "CONT0" | Draw a contour plot using surface colors to distinguish contours. |
1737| "CONT1" | Draw a contour plot using the line colors to distinguish contours. |
1738| "CONT2" | Draw a contour plot using the line styles (1 to 5) to distinguish contours. |
1739| "CONT3" | Draw a contour plot using the same line style for all contours. |
1740| "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0). |
1741| "CONT5" | Draw a contour plot using Delaunay triangles. |
1742
1743
1744
1745The following example shows a 2D histogram plotted with the option
1746`CONTZ`. The option `CONT` draws a contour plot using surface
1747colors to distinguish contours. Combined with the option `CONT` (or
1748`CONT0`), the option `Z` allows to display the color palette
1749defined by `gStyle->SetPalette()`.
1750
1751Begin_Macro(source)
1752{
1753 auto c1 = new TCanvas("c1","c1",600,400);
1754 auto hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1755 float px, py;
1756 for (Int_t i = 0; i < 25000; i++) {
1757 gRandom->Rannor(px,py);
1758 hcontz->Fill(px-1,5*py);
1759 hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1760 }
1761 hcontz->Draw("CONTZ");
1762}
1763End_Macro
1764
1765The following example shows a 2D histogram plotted with the option
1766`CONT1Z`. The option `CONT1` draws a contour plot using the
1767line colors to distinguish contours. Combined with the option `CONT1`,
1768the option `Z` allows to display the color palette defined by
1769`gStyle->SetPalette()`.
1770
1771Begin_Macro(source)
1772{
1773 auto c1 = new TCanvas("c1","c1",600,400);
1774 auto hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1775 float px, py;
1776 for (Int_t i = 0; i < 25000; i++) {
1777 gRandom->Rannor(px,py);
1778 hcont1->Fill(px-1,5*py);
1779 hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1780 }
1781 hcont1->Draw("CONT1Z");
1782}
1783End_Macro
1784
1785The following example shows a 2D histogram plotted with the option
1786`CONT2`. The option `CONT2` draws a contour plot using the
1787line styles (1 to 5) to distinguish contours.
1788
1789Begin_Macro(source)
1790{
1791 auto c1 = new TCanvas("c1","c1",600,400);
1792 auto hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1793 float px, py;
1794 for (Int_t i = 0; i < 25000; i++) {
1795 gRandom->Rannor(px,py);
1796 hcont2->Fill(px-1,5*py);
1797 hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1798 }
1799 hcont2->Draw("CONT2");
1800}
1801End_Macro
1802
1803The following example shows a 2D histogram plotted with the option
1804`CONT3`. The option `CONT3` draws contour plot using the same line style for
1805all contours.
1806
1807Begin_Macro(source)
1808{
1809 auto c1 = new TCanvas("c1","c1",600,400);
1810 auto hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1811 float px, py;
1812 for (Int_t i = 0; i < 25000; i++) {
1813 gRandom->Rannor(px,py);
1814 hcont3->Fill(px-1,5*py);
1815 hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1816 }
1817 hcont3->SetLineStyle(kDotted);
1818 hcont3->Draw("CONT3");
1819}
1820End_Macro
1821
1822The following example shows a 2D histogram plotted with the option
1823`CONT4`. The option `CONT4` draws a contour plot using surface
1824colors to distinguish contours (`SURF` option at theta = 0). Combined
1825with the option `CONT` (or `CONT0`), the option `Z`
1826allows to display the color palette defined by `gStyle->SetPalette()`.
1827
1828Begin_Macro(source)
1829{
1830 auto c1 = new TCanvas("c1","c1",600,400);
1831 auto hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1832 float px, py;
1833 for (Int_t i = 0; i < 25000; i++) {
1834 gRandom->Rannor(px,py);
1835 hcont4->Fill(px-1,5*py);
1836 hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1837 }
1838 hcont4->Draw("CONT4Z");
1839}
1840End_Macro
1841
1842The default number of contour levels is 20 equidistant levels and can be changed
1843with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1844
1845\anchor HP16a
1846#### The LIST option
1847
1848When option `LIST` is specified together with option
1849`CONT`, the points used to draw the contours are saved in
1850`TGraph` objects:
1851
1852 h->Draw("CONT LIST");
1853 gPad->Update();
1854
1855The contour are saved in `TGraph` objects once the pad is painted.
1856Therefore to use this functionality in a macro, `gPad->Update()`
1857should be performed after the histogram drawing. Once the list is
1858built, the contours are accessible in the following way:
1859
1860 TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
1861 Int_t ncontours = contours->GetSize();
1862 TList *list = (TList*)contours->At(i);
1863
1864Where `i` is a contour number, and list contains a list of
1865`TGraph` objects.
1866For one given contour, more than one disjoint polyline may be generated.
1867The number of TGraphs per contour is given by:
1868
1869 list->GetSize();
1870
1871To access the first graph in the list one should do:
1872
1873 TGraph *gr1 = (TGraph*)list->First();
1874
1875
1876The following example (ContourList.C) shows how to use this functionality.
1877
1878Begin_Macro(source)
1879../../../tutorials/hist/ContourList.C
1880End_Macro
1881
1882\anchor HP16b
1883#### The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options
1884
1885The following options select the `CONT4` option and are useful for
1886sky maps or exposure maps (earth.C).
1887
1888| Option | Description |
1889|--------------|---------------------------------------------------------------|
1890| "AITOFF" | Draw a contour via an AITOFF projection.|
1891| "MERCATOR" | Draw a contour via an Mercator projection.|
1892| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1893| "PARABOLIC" | Draw a contour via an Parabolic projection.|
1894
1895Begin_Macro(source)
1896../../../tutorials/graphics/earth.C
1897End_Macro
1898
1899
1900\anchor HP17
1901### The LEGO options
1902
1903
1904In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1905is proportional to the cell content. The lego aspect is control with the
1906following options:
1907
1908| Option | Description |
1909|----------|-------------------------------------------------------------------|
1910| "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1911| "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1912| "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1913| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1914| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1915| "0" | When used with any LEGO option, the empty bins are not drawn.|
1916
1917
1918See the limitations with [the option "SAME"](\ref HP060a).
1919
1920Line attributes can be used in lego plots to change the edges' style.
1921
1922The following example shows a 2D histogram plotted with the option
1923`LEGO`. The option `LEGO` draws a lego plot using the hidden
1924lines removal technique.
1925
1926Begin_Macro(source)
1927{
1928 auto c2 = new TCanvas("c2","c2",600,400);
1929 auto hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1930 float px, py;
1931 for (Int_t i = 0; i < 25000; i++) {
1932 gRandom->Rannor(px,py);
1933 hlego->Fill(px-1,5*py);
1934 hlego->Fill(2+0.5*px,2*py-10.,0.1);
1935 }
1936 hlego->Draw("LEGO");
1937}
1938End_Macro
1939
1940The following example shows a 2D histogram plotted with the option
1941`LEGO1`. The option `LEGO1` draws a lego plot using the
1942hidden surface removal technique. Combined with any `LEGOn` option, the
1943option `0` allows to not drawn the empty bins.
1944
1945Begin_Macro(source)
1946{
1947 auto c2 = new TCanvas("c2","c2",600,400);
1948 auto hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1949 float px, py;
1950 for (Int_t i = 0; i < 25000; i++) {
1951 gRandom->Rannor(px,py);
1952 hlego1->Fill(px-1,5*py);
1953 hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1954 }
1955 hlego1->SetFillColor(kYellow);
1956 hlego1->Draw("LEGO1 0");
1957}
1958End_Macro
1959
1960The following example shows a 2D histogram plotted with the option
1961`LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1962draws a lego plot using the hidden surface removal technique but doesn't draw
1963the border lines of each individual lego-bar. This is very useful for histograms
1964having many bins. With such histograms the option `LEGO1` gives a black
1965image because of the border lines. This option also works with stacked legos.
1966
1967Begin_Macro(source)
1968{
1969 auto c2 = new TCanvas("c2","c2",600,400);
1970 auto hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1971 float px, py;
1972 for (Int_t i = 0; i < 25000; i++) {
1973 gRandom->Rannor(px,py);
1974 hlego3->Fill(px-1,5*py);
1975 hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1976 }
1977 hlego3->SetFillColor(kRed);
1978 hlego3->Draw("LEGO3");
1979}
1980End_Macro
1981
1982The following example shows a 2D histogram plotted with the option
1983`LEGO2`. The option `LEGO2` draws a lego plot using colors to
1984show the cell contents. Combined with the option `LEGO2`, the option
1985`Z` allows to display the color palette defined by
1986`gStyle->SetPalette()`.
1987
1988Begin_Macro(source)
1989{
1990 auto c2 = new TCanvas("c2","c2",600,400);
1991 auto hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1992 float px, py;
1993 for (Int_t i = 0; i < 25000; i++) {
1994 gRandom->Rannor(px,py);
1995 hlego2->Fill(px-1,5*py);
1996 hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1997 }
1998 hlego2->Draw("LEGO2Z");
1999}
2000End_Macro
2001
2002
2003
2004\anchor HP18
2005### The "SURFace" options
2006
2007
2008In a surface plot, cell contents are represented as a mesh.
2009The height of the mesh is proportional to the cell content.
2010
2011| Option | Description |
2012|----------|-------------------------------------------------------------------|
2013| "SURF" | Draw a surface plot using the hidden line removal technique.|
2014| "SURF1" | Draw a surface plot using the hidden surface removal technique.|
2015| "SURF2" | Draw a surface plot using colors to show the cell contents.|
2016| "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
2017| "SURF4" | Draw a surface using the Gouraud shading technique.|
2018| "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
2019| "SURF6" | This option should not be used directly. It is used internally when the CONT is used with option the option SAME on a 3D plot.|
2020| "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
2021
2022
2023
2024See the limitations with [the option "SAME"](\ref HP060a).
2025
2026The following example shows a 2D histogram plotted with the option
2027`SURF`. The option `SURF` draws a lego plot using the hidden
2028lines removal technique.
2029
2030Begin_Macro(source)
2031{
2032 auto c2 = new TCanvas("c2","c2",600,400);
2033 auto hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
2034 float px, py;
2035 for (Int_t i = 0; i < 25000; i++) {
2036 gRandom->Rannor(px,py);
2037 hsurf->Fill(px-1,5*py);
2038 hsurf->Fill(2+0.5*px,2*py-10.,0.1);
2039 }
2040 hsurf->Draw("SURF");
2041}
2042End_Macro
2043
2044The following example shows a 2D histogram plotted with the option
2045`SURF1`. The option `SURF1` draws a surface plot using the
2046hidden surface removal technique. Combined with the option `SURF1`,
2047the option `Z` allows to display the color palette defined by
2048`gStyle->SetPalette()`.
2049
2050Begin_Macro(source)
2051{
2052 auto c2 = new TCanvas("c2","c2",600,400);
2053 auto hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
2054 float px, py;
2055 for (Int_t i = 0; i < 25000; i++) {
2056 gRandom->Rannor(px,py);
2057 hsurf1->Fill(px-1,5*py);
2058 hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
2059 }
2060 hsurf1->Draw("SURF1");
2061}
2062End_Macro
2063
2064The following example shows a 2D histogram plotted with the option
2065`SURF2`. The option `SURF2` draws a surface plot using colors
2066to show the cell contents. Combined with the option `SURF2`, the option
2067`Z` allows to display the color palette defined by
2068`gStyle->SetPalette()`.
2069
2070Begin_Macro(source)
2071{
2072 auto c2 = new TCanvas("c2","c2",600,400);
2073 auto hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
2074 float px, py;
2075 for (Int_t i = 0; i < 25000; i++) {
2076 gRandom->Rannor(px,py);
2077 hsurf2->Fill(px-1,5*py);
2078 hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2079 }
2080 hsurf2->Draw("SURF2");
2081}
2082End_Macro
2083
2084The following example shows a 2D histogram plotted with the option
2085`SURF3`. The option `SURF3` draws a surface plot using the
2086hidden line removal technique with, in addition, a filled contour view drawn on the
2087top. Combined with the option `SURF3`, the option `Z` allows
2088to display the color palette defined by `gStyle->SetPalette()`.
2089
2090Begin_Macro(source)
2091{
2092 auto c2 = new TCanvas("c2","c2",600,400);
2093 auto hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2094 float px, py;
2095 for (Int_t i = 0; i < 25000; i++) {
2096 gRandom->Rannor(px,py);
2097 hsurf3->Fill(px-1,5*py);
2098 hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2099 }
2100 hsurf3->Draw("SURF3");
2101}
2102End_Macro
2103
2104The following example shows a 2D histogram plotted with the option
2105`SURF4`. The option `SURF4` draws a surface using the Gouraud
2106shading technique.
2107
2108Begin_Macro(source)
2109{
2110 auto c2 = new TCanvas("c2","c2",600,400);
2111 auto hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2112 float px, py;
2113 for (Int_t i = 0; i < 25000; i++) {
2114 gRandom->Rannor(px,py);
2115 hsurf4->Fill(px-1,5*py);
2116 hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2117 }
2118 hsurf4->SetFillColor(kOrange);
2119 hsurf4->Draw("SURF4");
2120}
2121End_Macro
2122
2123The following example shows a 2D histogram plotted with the option
2124`SURF5 CYL`. Combined with the option `SURF5`, the option
2125`Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2126
2127Begin_Macro(source)
2128{
2129 auto c2 = new TCanvas("c2","c2",600,400);
2130 auto hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2131 float px, py;
2132 for (Int_t i = 0; i < 25000; i++) {
2133 gRandom->Rannor(px,py);
2134 hsurf5->Fill(px-1,5*py);
2135 hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2136 }
2137 hsurf5->Draw("SURF5 CYL");
2138}
2139End_Macro
2140
2141The following example shows a 2D histogram plotted with the option
2142`SURF7`. The option `SURF7` draws a surface plot using the
2143hidden surfaces removal technique with, in addition, a line contour view drawn on the
2144top. Combined with the option `SURF7`, the option `Z` allows
2145to display the color palette defined by `gStyle->SetPalette()`.
2146
2147Begin_Macro(source)
2148{
2149 auto c2 = new TCanvas("c2","c2",600,400);
2150 auto hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2151 float px, py;
2152 for (Int_t i = 0; i < 25000; i++) {
2153 gRandom->Rannor(px,py);
2154 hsurf7->Fill(px-1,5*py);
2155 hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2156 }
2157 hsurf7->Draw("SURF7");
2158}
2159End_Macro
2160
2161As shown in the following example, when a contour plot is painted on top of a
2162surface plot using the option `SAME`, the contours appear in 3D on the
2163surface.
2164
2165Begin_Macro(source)
2166{
2167 auto c20=new TCanvas("c20","c20",600,400);
2168 int NBins = 50;
2169 double d = 2;
2170 auto hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2171 for (int bx = 1; bx <= NBins; ++bx) {
2172 for (int by = 1; by <= NBins; ++by) {
2173 double x = hsc->GetXaxis()->GetBinCenter(bx);
2174 double y = hsc->GetYaxis()->GetBinCenter(by);
2175 hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2176 }
2177 }
2178 hsc->Draw("surf2");
2179 hsc->Draw("CONT1 SAME");
2180}
2181End_Macro
2182
2183
2184\anchor HP19
2185### Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2186
2187
2188Legos and surfaces plots are represented by default in Cartesian coordinates.
2189Combined with any `LEGOn` or `SURFn` options the following
2190options allow to draw a lego or a surface in other coordinates systems.
2191
2192| Option | Description |
2193|----------|-------------------------------------------------------------------|
2194| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2195| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2196| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2197| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2198
2199
2200
2201<b>WARNING:</b> Axis are not drawn with these options.
2202
2203The following example shows the same histogram as a lego plot is the four
2204different coordinates systems.
2205
2206Begin_Macro(source)
2207{
2208 auto c3 = new TCanvas("c3","c3",600,400);
2209 c3->Divide(2,2);
2210 auto hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2211 float px, py;
2212 for (Int_t i = 0; i < 25000; i++) {
2213 gRandom->Rannor(px,py);
2214 hlcc->Fill(px-1,5*py);
2215 hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2216 }
2217 hlcc->SetFillColor(kYellow);
2218 c3->cd(1); hlcc->Draw("LEGO1 CYL");
2219 c3->cd(2); auto hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2220 hlpc->SetTitle("Polar coordinates");
2221 c3->cd(3); auto hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2222 hlsc->SetTitle("Spherical coordinates");
2223 c3->cd(4); auto hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2224 hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2225}
2226End_Macro
2227
2228The following example shows the same histogram as a surface plot is the four different coordinates systems.
2229
2230Begin_Macro(source)
2231{
2232 auto c4 = new TCanvas("c4","c4",600,400);
2233 c4->Divide(2,2);
2234 auto hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2235 float px, py;
2236 for (Int_t i = 0; i < 25000; i++) {
2237 gRandom->Rannor(px,py);
2238 hscc->Fill(px-1,5*py);
2239 hscc->Fill(2+0.5*px,2*py-10.,0.1);
2240 }
2241 c4->cd(1); hscc->Draw("SURF1 CYL");
2242 c4->cd(2); auto hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2243 hspc->SetTitle("Polar coordinates");
2244 c4->cd(3); auto hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2245 hssc->SetTitle("Spherical coordinates");
2246 c4->cd(4); auto hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2247 hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2248}
2249End_Macro
2250
2251
2252\anchor HP20
2253### Base line for bar-charts and lego plots
2254
2255
2256By default the base line used to draw the boxes for bar-charts and lego plots is
2257the histogram minimum. It is possible to force this base line to be 0, using MIN0 draw
2258option or with the command:
2259
2260 gStyle->SetHistMinimumZero();
2261
2262Begin_Macro(source)
2263{
2264 auto c5 = new TCanvas("c5","c5",700,400);
2265 c5->Divide(2,1);
2266 auto hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2267 auto hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2268 Int_t i;
2269 double x,y;
2270 hz1->SetFillColor(kBlue);
2271 hz2->SetFillColor(kBlue);
2272 for (i=0;i<10000;i++) {
2273 x = gRandom->Gaus(0,1);
2274 y = gRandom->Gaus(0,1);
2275 if (x>0) {
2276 hz1->Fill(x,1);
2277 hz2->Fill(x,y,1);
2278 } else {
2279 hz1->Fill(x,-1);
2280 hz2->Fill(x,y,-2);
2281 }
2282 }
2283 c5->cd(1); hz1->Draw("bar2 min0");
2284 c5->cd(2); hz2->Draw("lego1 min0");
2285}
2286End_Macro
2287
2288This option also works for horizontal plots. The example given in the section
2289["The bar chart option"](\ref HP100) appears as follow:
2290
2291Begin_Macro(source)
2292{
2293 int i;
2294 const Int_t nx = 8;
2295 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2296 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2297 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2298
2299 auto cbh = new TCanvas("cbh","cbh",400,600);
2300 cbh->SetGrid();
2301
2302 auto h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2303 h1bh->SetFillColor(4);
2304 h1bh->SetBarWidth(0.4);
2305 h1bh->SetBarOffset(0.1);
2306 h1bh->SetStats(0);
2307 h1bh->SetMinimum(-5);
2308 h1bh->SetMaximum(5);
2309
2310 for (i=1; i<=nx; i++) {
2311 h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2312 h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2313 }
2314
2315 h1bh->Draw("hbar min0");
2316
2317 auto h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2318 h2bh->SetFillColor(38);
2319 h2bh->SetBarWidth(0.4);
2320 h2bh->SetBarOffset(0.5);
2321 h2bh->SetStats(0);
2322 for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2323
2324 h2bh->Draw("hbar min0 same");
2325}
2326End_Macro
2327
2328
2329\anchor HP20a
2330### TH2Poly Drawing
2331
2332
2333The following options are supported:
2334
2335| Option | Description |
2336|----------|-------------------------------------------------------------------|
2337| "SCAT" | Draw a scatter plot (default).|
2338| "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2339| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2340| "0" | When used with any COL options, the empty bins are not drawn.|
2341| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2342| "TEXTN" | Draw bin names as text.|
2343| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2344| "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2345| "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2346| "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2347
2348
2349
2350`TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2351shapes. The bins are defined as graphs. The following macro is a very simple
2352example showing how to book a TH2Poly and draw it.
2353
2354Begin_Macro(source)
2355{
2356 auto ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2357 auto h2p = new TH2Poly();
2358 h2p->SetName("h2poly_name");
2359 h2p->SetTitle("h2poly_title");
2360 double px1[] = {0, 5, 6};
2361 double py1[] = {0, 0, 5};
2362 double px2[] = {0, -1, -1, 0};
2363 double py2[] = {0, 0, -1, 3};
2364 double px3[] = {4, 3, 0, 1, 2.4};
2365 double py3[] = {4, 3.7, 1, 3.7, 2.5};
2366 h2p->AddBin(3, px1, py1);
2367 h2p->AddBin(4, px2, py2);
2368 h2p->AddBin(5, px3, py3);
2369 h2p->Fill(0.1, 0.01, 3);
2370 h2p->Fill(-0.5, -0.5, 7);
2371 h2p->Fill(-0.7, -0.5, 1);
2372 h2p->Fill(1, 3, 1.5);
2373 double fx[] = {0.1, -0.5, -0.7, 1};
2374 double fy[] = {0.01, -0.5, -0.5, 3};
2375 double fw[] = {3, 1, 1, 1.5};
2376 h2p->FillN(4, fx, fy, fw);
2377 h2p->Draw("col");
2378}
2379End_Macro
2380
2381Rectangular bins are a frequent case. The special version of
2382the `AddBin` method allows to define them more easily like
2383shown in the following example (th2polyBoxes.C).
2384
2385Begin_Macro(source)
2386../../../tutorials/hist/th2polyBoxes.C
2387End_Macro
2388
2389One `TH2Poly` bin can be a list of polygons. Such bins are defined
2390by calling `AddBin` with a `TMultiGraph`. The following example
2391shows a such case:
2392
2393Begin_Macro(source)
2394{
2395 auto ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2396
2397 Int_t i, bin;
2398 const Int_t nx = 48;
2399 const char *states [nx] = {
2400 "alabama", "arizona", "arkansas", "california",
2401 "colorado", "connecticut", "delaware", "florida",
2402 "georgia", "idaho", "illinois", "indiana",
2403 "iowa", "kansas", "kentucky", "louisiana",
2404 "maine", "maryland", "massachusetts", "michigan",
2405 "minnesota", "mississippi", "missouri", "montana",
2406 "nebraska", "nevada", "new_hampshire", "new_jersey",
2407 "new_mexico", "new_york", "north_carolina", "north_dakota",
2408 "ohio", "oklahoma", "oregon", "pennsylvania",
2409 "rhode_island", "south_carolina", "south_dakota", "tennessee",
2410 "texas", "utah", "vermont", "virginia",
2411 "washington", "west_virginia", "wisconsin", "wyoming"
2412 };
2413 Double_t pop[nx] = {
2414 4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2415 9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2416 1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2417 1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2418 11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2419 24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2420 };
2421
2422 Double_t lon1 = -130;
2423 Double_t lon2 = -65;
2424 Double_t lat1 = 24;
2425 Double_t lat2 = 50;
2426 auto p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2427
2428 TFile::SetCacheFileDir(".");
2429 auto f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2430
2431 TMultiGraph *mg;
2432 TKey *key;
2433 TIter nextkey(gDirectory->GetListOfKeys());
2434 while ((key = (TKey*)nextkey())) {
2435 TObject *obj = key->ReadObj();
2436 if (obj->InheritsFrom("TMultiGraph")) {
2437 mg = (TMultiGraph*)obj;
2438 bin = p->AddBin(mg);
2439 }
2440 }
2441
2442 for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2443
2444 gStyle->SetOptStat(11);
2445 p->Draw("COLZ L");
2446}
2447End_Macro
2448
2449`TH2Poly` histograms can also be plotted using the GL interface using
2450the option "GLLEGO".
2451
2452\since **ROOT version 6.09/01**
2453
2454In some cases it can be useful to not draw the empty bins. the option "0"
2455combined with the option "COL" et COLZ allows to do that.
2456
2457Begin_Macro(source)
2458{
2459 auto chc = new TCanvas("chc","chc",600,400);
2460
2461 auto hc = new TH2Poly();
2462 hc->Honeycomb(0,0,.1,25,25);
2463 hc->SetName("hc");
2464 hc->SetTitle("Option COLZ 0");
2465 TRandom ran;
2466 for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2467 hc->Draw("colz 0");
2468}
2469End_Macro
2470
2471\anchor HP21
2472### The SPEC option
2473
2474
2475This option allows to use the `TSpectrum2Painter` tools. See the full
2476documentation in `TSpectrum2Painter::PaintSpectrum`.
2477
2478
2479\anchor HP22
2480### Option "Z" : Adding the color palette on the right side of the pad
2481
2482
2483When this option is specified, a color palette with an axis indicating the value
2484of the corresponding color is drawn on the right side of the picture. In case,
2485not enough space is left, one can increase the size of the right margin by
2486calling `TPad::SetRightMargin()`. The attributes used to display the
2487palette axis values are taken from the Z axis of the object. For example, to
2488set the labels size on the palette axis do:
2489
2490 hist->GetZaxis()->SetLabelSize().
2491
2492<b>WARNING:</b> The palette axis is always drawn vertically.
2493
2494
2495\anchor HP23
2496### Setting the color palette
2497
2498
2499To change the color palette `TStyle::SetPalette` should be used, eg:
2500
2501 gStyle->SetPalette(ncolors,colors);
2502
2503For example the option `COL` draws a 2D histogram with cells
2504represented by a box filled with a color index which is a function
2505of the cell content.
2506If the cell content is N, the color index used will be the color number
2507in `colors[N]`, etc. If the maximum cell content is greater than
2508`ncolors`, all cell contents are scaled to `ncolors`.
2509
2510If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2511defined. This palette is recommended for pads, labels ...
2512
2513`if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2514Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2515palette.
2516
2517Other pre-defined palettes with 255 colors are available when `colors == 0`.
2518The following value of `ncolors` give access to:
2519
2520
2521 if ncolors = 51 and colors=0, a Deep Sea palette is used.
2522 if ncolors = 52 and colors=0, a Grey Scale palette is used.
2523 if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2524 if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2525 if ncolors = 55 and colors=0, a Rain Bow palette is used.
2526 if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2527
2528
2529If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2530
2531The default palette defines:
2532
2533- index 0 to 9 : shades of grey
2534- index 10 to 19 : shades of brown
2535- index 20 to 29 : shades of blue
2536- index 30 to 39 : shades of red
2537- index 40 to 49 : basic colors
2538
2539The color numbers specified in the palette can be viewed by selecting
2540the item `colors` in the `VIEW` menu of the canvas tool bar.
2541The red, green, and blue components of a color can be changed thanks to
2542`TColor::SetRGB()`.
2543
2544\since **ROOT version 6.19/01**
2545
2546As default labels and ticks are drawn by `TGAxis` at equidistant (lin or log)
2547points as controlled by SetNdivisions.
2548If option "CJUST" is given labels and ticks are justified at the
2549color boundaries defined by the contour levels.
2550For more details see `TPaletteAxis`
2551
2552\anchor HP24
2553### Drawing a sub-range of a 2D histogram; the [cutg] option
2554
2555
2556Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2557histogram. One must create a graphical cut (mouse or C++) and specify the name
2558of the cut between `[]` in the `Draw()` option.
2559For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2560
2561 myhist->Draw("surf1 [cutg]");
2562
2563To invert the cut, it is enough to put a `-` in front of its name:
2564
2565 myhist->Draw("surf1 [-cutg]");
2566
2567It is possible to apply several cuts (`,` means logical AND):
2568
2569 myhist->Draw("surf1 [cutg1,cutg2]");
2570
2571Begin_Macro(source)
2572../../../tutorials/fit/fit2a.C
2573End_Macro
2574
2575\anchor HP25
2576### Drawing options for 3D histograms
2577
2578
2579| Option | Description |
2580|----------|-------------------------------------------------------------------|
2581| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`|
2582| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2583| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2584| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2585| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2586| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2587
2588Note that instead of `BOX` one can also use `LEGO`.
2589
2590By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2591
2592The following example shows a 3D histogram plotted as a scatter plot.
2593
2594Begin_Macro(source)
2595{
2596 auto c06 = new TCanvas("c06","c06",600,400);
2597 gStyle->SetOptStat(kFALSE);
2598 auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2599 double x, y, z;
2600 for (Int_t i=0;i<10000;i++) {
2601 gRandom->Rannor(x, y);
2602 z = x*x + y*y;
2603 h3scat->Fill(x,y,z);
2604 }
2605 h3scat->Draw();
2606}
2607End_Macro
2608
2609The following example shows a 3D histogram plotted with the option `BOX`.
2610
2611Begin_Macro(source)
2612{
2613 auto c16 = new TCanvas("c16","c16",600,400);
2614 gStyle->SetOptStat(kFALSE);
2615 auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2616 double x, y, z;
2617 for (Int_t i=0;i<10000;i++) {
2618 gRandom->Rannor(x, y);
2619 z = x*x + y*y;
2620 h3box->Fill(x,y,z);
2621 }
2622 h3box->Draw("BOX");
2623}
2624End_Macro
2625
2626The following example shows a 3D histogram plotted with the option `BOX1`.
2627
2628Begin_Macro(source)
2629{
2630 auto c36 = new TCanvas("c36","c36",600,400);
2631 gStyle->SetOptStat(kFALSE);
2632 auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2633 double x, y, z;
2634 for (Int_t i=0;i<10000;i++) {
2635 gRandom->Rannor(x, y);
2636 z = abs(sin(x)/x + cos(y)*y);
2637 h3box->Fill(x,y,z);
2638 }
2639 h3box->SetFillColor(9);
2640 h3box->Draw("BOX1");
2641}
2642End_Macro
2643
2644The following example shows a 3D histogram plotted with the option `BOX2`.
2645
2646Begin_Macro(source)
2647{
2648 auto c56 = new TCanvas("c56","c56",600,400);
2649 gStyle->SetOptStat(kFALSE);
2650 auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2651 double x, y, z;
2652 for (Int_t i=0;i<10000;i++) {
2653 gRandom->Rannor(x, y);
2654 z = abs(sin(x)/x + cos(y)*y);
2655 h3box->Fill(x,y,z);
2656 }
2657 h3box->Draw("BOX2 Z");
2658}
2659End_Macro
2660
2661The following example shows a 3D histogram plotted with the option `BOX3`.
2662
2663Begin_Macro(source)
2664{
2665 auto c46 = new TCanvas("c46","c46",600,400);
2666 c46->SetFillColor(38);
2667 gStyle->SetOptStat(kFALSE);
2668 auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2669 double x, y, z;
2670 for (Int_t i=0;i<10000;i++) {
2671 gRandom->Rannor(x, y);
2672 z = x*x + y*y;
2673 h3box->Fill(x,y,z);
2674 }
2675 h3box->Draw("BOX3");
2676}
2677End_Macro
2678
2679For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2680to the absolute value of the bin content. The bins with a negative content are
2681drawn with a X on each face of the box as shown in the following example:
2682
2683Begin_Macro(source)
2684{
2685 auto c = new TCanvas("c","c",600,400);
2686 gStyle->SetOptStat(kFALSE);
2687 auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2688 h3box->Fill(0., 2., 2., 10.);
2689 h3box->Fill(2., 2., 2., 5.);
2690 h3box->Fill(2., 2., .5, 2.);
2691 h3box->Fill(2., 2., 3., -1.);
2692 h3box->Fill(3., 2., 2., -10.);
2693 h3box->SetFillColor(8);
2694 h3box->Draw("box1");
2695}
2696End_Macro
2697
2698The following example shows a 3D histogram plotted with the option `ISO`.
2699
2700Begin_Macro(source)
2701{
2702 auto c26 = new TCanvas("c26","c26",600,400);
2703 gStyle->SetOptStat(kFALSE);
2704 auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2705 double x, y, z;
2706 for (Int_t i=0;i<10000;i++) {
2707 gRandom->Rannor(x, y);
2708 z = x*x + y*y;
2709 h3iso->Fill(x,y,z);
2710 }
2711 h3iso->SetFillColor(kCyan);
2712 h3iso->Draw("ISO");
2713}
2714End_Macro
2715
2716
2717\anchor HP26
2718### Drawing option for histograms' stacks
2719
2720
2721Stacks of histograms are managed with the `THStack`. A `THStack`
2722is a collection of `TH1` (or derived) objects. For painting only the
2723`THStack` containing `TH1` only or
2724`THStack` containing `TH2` only will be considered.
2725
2726By default, histograms are shown stacked:
2727
27281. The first histogram is paint.
27292. The the sum of the first and second, etc...
2730
2731If the option `NOSTACK` is specified, the histograms are all paint in
2732the same pad as if the option `SAME` had been specified. This allows to
2733compute X and Y scales common to all the histograms, like
2734`TMultiGraph` does for graphs.
2735
2736If the option `PADS` is specified, the current pad/canvas is
2737subdivided into a number of pads equal to the number of histograms and each
2738histogram is paint into a separate pad.
2739
2740The following example shows various types of stacks (hstack.C).
2741
2742Begin_Macro(source)
2743../../../tutorials/hist/hstack.C
2744End_Macro
2745
2746The option `nostackb` allows to draw the histograms next to each
2747other as bar charts:
2748
2749Begin_Macro(source)
2750{
2751 auto cst0 = new TCanvas("cst0","cst0",600,400);
2752 auto hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2753
2754 auto h1 = new TH1F("h1","h1",10,-4,4);
2755 h1->FillRandom("gaus",20000);
2756 h1->SetFillColor(kRed);
2757 hs->Add(h1);
2758
2759 auto h2 = new TH1F("h2","h2",10,-4,4);
2760 h2->FillRandom("gaus",15000);
2761 h2->SetFillColor(kBlue);
2762 hs->Add(h2);
2763
2764 auto h3 = new TH1F("h3","h3",10,-4,4);
2765 h3->FillRandom("gaus",10000);
2766 h3->SetFillColor(kGreen);
2767 hs->Add(h3);
2768
2769 hs->Draw("nostackb");
2770 hs->GetXaxis()->SetNdivisions(-10);
2771 cst0->SetGridx();
2772}
2773End_Macro
2774
2775If at least one of the histograms in the stack has errors, the whole stack is
2776visualized by default with error bars. To visualize it without errors the
2777option `HIST` should be used.
2778
2779Begin_Macro(source)
2780{
2781 auto cst1 = new TCanvas("cst1","cst1",700,400);
2782 cst1->Divide(2,1);
2783
2784 auto hst11 = new TH1F("hst11", "", 20, -10, 10);
2785 hst11->Sumw2();
2786 hst11->FillRandom("gaus", 1000);
2787 hst11->SetFillColor(kViolet);
2788 hst11->SetLineColor(kViolet);
2789
2790 auto hst12 = new TH1F("hst12", "", 20, -10, 10);
2791 hst12->FillRandom("gaus", 500);
2792 hst12->SetFillColor(kBlue);
2793 hst12->SetLineColor(kBlue);
2794
2795 THStack st1("st1", "st1");
2796 st1.Add(hst11);
2797 st1.Add(hst12);
2798
2799 cst1->cd(1); st1.Draw();
2800 cst1->cd(2); st1.Draw("hist");
2801}
2802End_Macro
2803
2804\anchor HP27
2805### Drawing of 3D implicit functions
2806
2807
28083D implicit functions (`TF3`) can be drawn as iso-surfaces.
2809The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2810In the following example the options "FB" and "BB" suppress the
2811"Front Box" and "Back Box" around the plot.
2812
2813Begin_Macro(source)
2814{
2815 auto c2 = new TCanvas("c2","c2",600,400);
2816 auto f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2817 f3->SetClippingBoxOn(0,0,0);
2818 f3->SetFillColor(30);
2819 f3->SetLineColor(15);
2820 f3->Draw("FBBB");
2821}
2822End_Macro
2823
2824
2825\anchor HP28
2826### Associated functions drawing
2827
2828
2829An associated function is created by `TH1::Fit`. More than on fitted
2830function can be associated with one histogram (see `TH1::Fit`).
2831
2832A `TF1` object `f1` can be added to the list of associated
2833functions of an histogram `h` without calling `TH1::Fit`
2834simply doing:
2835
2836 h->GetListOfFunctions()->Add(f1);
2837
2838or
2839
2840 h->GetListOfFunctions()->Add(f1,someoption);
2841
2842To retrieve a function by name from this list, do:
2843
2844 TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2845
2846or
2847
2848 TF1 *f1 = h->GetFunction(name);
2849
2850Associated functions are automatically painted when an histogram is drawn.
2851To avoid the painting of the associated functions the option `HIST`
2852should be added to the list of the options used to paint the histogram.
2853
2854
2855\anchor HP29
2856### Drawing using OpenGL
2857
2858
2859The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2860graphics library. The plotting options start with `GL` keyword.
2861In addition, in order to inform canvases that OpenGL should be used to render
28623D representations, the following option should be set:
2863
2864 gStyle->SetCanvasPreferGL(true);
2865
2866
2867\anchor HP29a
2868#### General information: plot types and supported options
2869
2870The following types of plots are provided:
2871
2872For lego plots the supported options are:
2873
2874| Option | Description |
2875|----------|-------------------------------------------------------------------|
2876| "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2877| "GLLEGO2"| Bins with color levels.|
2878| "GLLEGO3"| Cylindrical bars.|
2879
2880
2881
2882Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2883In polar only Z axis can be logarithmic, in cylindrical only Y.
2884
2885For surface plots (`TF2` and `TH2`) the supported options are:
2886
2887| Option | Description |
2888|-----------|------------------------------------------------------------------|
2889| "GLSURF" | Draw a surface.|
2890| "GLSURF1" | Surface with color levels|
2891| "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2892| "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2893| "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2894
2895
2896
2897The surface painting in cartesian coordinates supports logarithmic scales along
2898X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2899in cylindrical coordinates only the Y axis.
2900
2901Additional options to SURF and LEGO - Coordinate systems:
2902
2903| Option | Description |
2904|----------|-------------------------------------------------------------------|
2905| " " | Default, cartesian coordinates system.|
2906| "POL" | Polar coordinates system.|
2907| "CYL" | Cylindrical coordinates system.|
2908| "SPH" | Spherical coordinates system.|
2909
2910
2911
2912\anchor HP290
2913#### TH3 as color boxes
2914
2915The supported option is:
2916
2917| Option | Description |
2918|----------|-------------------------------------------------------------------|
2919| "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2920
2921
2922
2923\anchor HP29b
2924#### TH3 as boxes (spheres)
2925
2926The supported options are:
2927
2928| Option | Description |
2929|----------|-------------------------------------------------------------------|
2930| "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2931| "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2932
2933
2934
2935\anchor HP29c
2936#### TH3 as iso-surface(s)
2937
2938The supported option is:
2939
2940| Option | Description |
2941|----------|-------------------------------------------------------------------|
2942| "GLISO" | TH3 is drawn using iso-surfaces.|
2943
2944
2945
2946\anchor HP29d
2947#### TF3 (implicit function)
2948
2949The supported option is:
2950
2951| Option | Description |
2952|----------|-------------------------------------------------------------------|
2953| "GL" | Draw a TF3.|
2954
2955
2956
2957\anchor HP29e
2958#### Parametric surfaces
2959
2960`$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2961equations and visualize the surface.
2962
2963\anchor HP29f
2964#### Interaction with the plots
2965
2966All the interactions are implemented via standard methods
2967`DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2968interactions with the OpenGL plots are possible only when the mouse cursor is
2969in the plot's area (the plot's area is the part of a the pad occupied by
2970gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2971pad interaction is performed.
2972
2973\anchor HP29g
2974#### Selectable parts
2975
2976Different parts of the plot can be selected:
2977
2978- xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2979 if the dynamic slicing by this plane is supported, and it's highlighted in red,
2980 if the dynamic slicing is not supported.
2981- The plot itself:
2982 On surfaces, the selected surface is outlined in red. (TF3 and
2983 ISO are not outlined). On lego plots, the selected bin is
2984 highlighted. The bin number and content are displayed in pad's
2985 status bar. In box plots, the box or sphere is highlighted and
2986 the bin info is displayed in pad's status bar.
2987
2988
2989\anchor HP29h
2990#### Rotation and zooming
2991
2992
2993- Rotation:
2994 When the plot is selected, it can be rotated by pressing and
2995 holding the left mouse button and move the cursor.
2996- Zoom/Unzoom:
2997 Mouse wheel or 'j', 'J', 'k', 'K' keys.
2998
2999
3000\anchor HP29i
3001#### Panning
3002
3003The selected plot can be moved in a pad's area by pressing and
3004holding the left mouse button and the shift key.
3005
3006\anchor HP29j
3007#### Box cut
3008
3009Surface, iso, box, TF3 and parametric painters support box cut by
3010pressing the 'c' or 'C' key when the mouse cursor is in a plot's
3011area. That will display a transparent box, cutting away part of the
3012surface (or boxes) in order to show internal part of plot. This box
3013can be moved inside the plot's area (the full size of the box is
3014equal to the plot's surrounding box) by selecting one of the box
3015cut axes and pressing the left mouse button to move it.
3016
3017\anchor HP29k
3018#### Plot specific interactions (dynamic slicing etc.)
3019
3020Currently, all gl-plots support some form of slicing. When back plane
3021is selected (and if it's highlighted in green) you can press and hold
3022left mouse button and shift key and move this back plane inside
3023plot's area, creating the slice. During this "slicing" plot becomes
3024semi-transparent. To remove all slices (and projected curves for
3025surfaces) double click with left mouse button in a plot's area.
3026
3027\anchor HP29l
3028#### Surface with option "GLSURF"
3029
3030The surface profile is displayed on the slicing plane.
3031The profile projection is drawn on the back plane
3032by pressing `'p'` or `'P'` key.
3033
3034\anchor HP29m
3035#### TF3
3036
3037The contour plot is drawn on the slicing plane. For TF3 the color
3038scheme can be changed by pressing 's' or 'S'.
3039
3040\anchor HP29n
3041#### Box
3042
3043The contour plot corresponding to slice plane position is drawn in real time.
3044
3045\anchor HP29o
3046#### Iso
3047
3048Slicing is similar to "GLBOX" option.
3049
3050\anchor HP29p
3051#### Parametric plot
3052
3053No slicing. Additional keys: 's' or 'S' to change color scheme -
3054about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
3055increase number of polygons ('l' for "level" of details), 'w' or 'W'
3056to show outlines ('w' for "wireframe").
3057
3058\anchor HP30
3059#### Highlight mode for histogram
3060
3061\since **ROOT version 6.15/01**
3062
3063\image html hlHisto3_top.gif "Highlight mode"
3064
3065Highlight mode is implemented for `TH1` (and for `TGraph`) class. When
3066highlight mode is on, mouse movement over the bin will be represented
3067graphically. Bin will be highlighted as "bin box" (presented by box
3068object). Moreover, any highlight (change of bin) emits signal
3069`TCanvas::Highlighted()` which allows the user to react and call their own
3070function. For a better understanding see also the tutorials
3071`$ROOTSYS/tutorials/hist/hlHisto*.C` files.
3072
3073Highlight mode is switched on/off by `TH1::SetHighlight()` function
3074or interactively from `TH1` context menu. `TH1::IsHighlight()` to verify
3075whether the highlight mode enabled or disabled, default it is disabled.
3076
3077~~~ {.cpp}
3078 root [0] .x $ROOTSYS/tutorials/hsimple.C
3079 root [1] hpx->SetHighlight(kTRUE) // or interactively from TH1 context menu
3080 root [2] hpx->IsHighlight()
3081 (bool) true
3082~~~
3083
3084\image html hlsimple_nofun.gif "Highlight mode for histogram"
3085
3086\anchor HP30a
3087#### Highlight mode and user function
3088
3089The user can use (connect) `TCanvas::Highlighted()` signal, which is always
3090emitted if there is a highlight bin and call user function via signal
3091and slot communication mechanism. `TCanvas::Highlighted()` is similar
3092`TCanvas::Picked()`
3093
3094- when selected object (histogram as a whole) is different from previous
3095then emit `Picked()` signal
3096- when selected (highlighted) bin from histogram is different from previous
3097then emit `Highlighted()` signal
3098
3099Any user function (or functions) has to be defined
3100`UserFunction(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)`.
3101In example (see below) has name `PrintInfo()`. All parameters of user
3102function are taken from
3103
3104 void TCanvas::Highlighted(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3105
3106- `pad` is pointer to pad with highlighted histogram
3107- `obj` is pointer to highlighted histogram
3108- `x` is highlighted x bin for 1D histogram
3109- `y` is highlighted y bin for 2D histogram (for 1D histogram not in use)
3110
3111Example how to create a connection from any `TCanvas` object to a user
3112`UserFunction()` slot (see also `TQObject::Connect()` for additional info)
3113
3114 TQObject::Connect("TCanvas", "Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
3115 0, 0, "UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3116
3117or use non-static "simplified" function
3118`TCanvas::HighlightConnect(const char *slot)`
3119
3120 c1->HighlightConnect("UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3121
3122NOTE the signal and slot string must have a form
3123"(TVirtualPad*,TObject*,Int_t,Int_t)"
3124
3125 root [0] .x $ROOTSYS/tutorials/hsimple.C
3126 root [1] hpx->SetHighlight(kTRUE)
3127 root [2] .x hlprint.C
3128
3129file `hlprint.C`
3130~~~ {.cpp}
3131void PrintInfo(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3132{
3133 auto h = (TH1F *)obj;
3134 if (!h->IsHighlight()) // after highlight disabled
3135 h->SetTitle("highlight disable");
3136 else
3137 h->SetTitle(TString::Format("bin[%03d] (%5.2f) content %g", x,
3138 h->GetBinCenter(x), h->GetBinContent(x)));
3139 pad->Update();
3140}
3141
3142void hlprint()
3143{
3144 if (!gPad) return;
3145 gPad->GetCanvas()->HighlightConnect("PrintInfo(TVirtualPad*,TObject*,Int_t,Int_t)");
3146}
3147~~~
3148
3149\image html hlsimple.gif "Highlight mode and simple user function"
3150
3151For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperature.C` file.
3152
3153*/
3154
3156
3159
3160const Int_t kNMAX = 2000;
3161
3162const Int_t kMAXCONTOUR = 104;
3164
3165static TBox *gXHighlightBox = 0; // highlight X box
3166static TBox *gYHighlightBox = 0; // highlight Y box
3167
3189
3191
3192////////////////////////////////////////////////////////////////////////////////
3193/// Default constructor.
3194
3196{
3197
3198 fH = 0;
3199 fXaxis = 0;
3200 fYaxis = 0;
3201 fZaxis = 0;
3202 fFunctions = 0;
3203 fXbuf = 0;
3204 fYbuf = 0;
3205 fNcuts = 0;
3206 fStack = 0;
3207 fLego = 0;
3208 fPie = 0;
3209 fGraph2DPainter = 0;
3210 fShowProjection = 0;
3211 fShowOption = "";
3212 for (int i=0; i<kMaxCuts; i++) {
3213 fCuts[i] = 0;
3214 fCutsOpt[i] = 0;
3215 }
3216 fXHighlightBin = -1;
3217 fYHighlightBin = -1;
3218 fCurrentF3 = nullptr;
3219
3220 gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
3221 gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
3222 gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
3223 gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
3224 gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3225 gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3226 gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3227 gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3228 gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3229 gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3230 gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3231 gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3232 gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3233 gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3234 gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3235 gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3236 gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3237 gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3238 gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3239 gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3240 gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3241}
3242
3243////////////////////////////////////////////////////////////////////////////////
3244/// Default destructor.
3245
3247{
3248 if (fPie) delete fPie;
3249}
3250
3251////////////////////////////////////////////////////////////////////////////////
3252/// Compute the distance from the point px,py to a line.
3253///
3254/// Compute the closest distance of approach from point px,py to elements of
3255/// an histogram. The distance is computed in pixels units.
3256///
3257/// Algorithm: Currently, this simple model computes the distance from the mouse
3258/// to the histogram contour only.
3259
3261{
3262
3263 Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3264
3265 const Int_t big = 9999;
3266 const Int_t kMaxDiff = 7;
3267
3268 if (fPie) return fPie->DistancetoPrimitive(px, py);
3269
3270 Double_t x = gPad->AbsPixeltoX(px);
3271 Double_t x1 = gPad->AbsPixeltoX(px+1);
3272
3273 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3274 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3275 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3276 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3277 Int_t curdist = big;
3278 Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3279 Bool_t dsame;
3280 TObject *PadPointer = gPad->GetPadPointer();
3281 if (!PadPointer) return 0;
3282 TString doption = PadPointer->GetDrawOption();
3283 Double_t factor = 1;
3284 if (fH->GetNormFactor() != 0) {
3285 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3286 }
3287 // return if point is not in the histogram area
3288
3289 // If a 3D view exists, check distance to axis
3290 TView *view = gPad->GetView();
3291 Int_t d1,d2,d3;
3292 if (view && Hoption.Contour != 14) {
3293 Double_t ratio;
3294 d3 = view->GetDistancetoAxis(3, px, py, ratio);
3295 if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3296 d1 = view->GetDistancetoAxis(1, px, py, ratio);
3297 if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3298 d2 = view->GetDistancetoAxis(2, px, py, ratio);
3299 if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3300 if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3301 goto FUNCTIONS;
3302 }
3303 // check if point is close to an axis
3304 doption.ToLower();
3305 dsame = kFALSE;
3306 if (doption.Contains("same")) dsame = kTRUE;
3307
3308 dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3309 if (doption.Contains("y+")) {
3310 xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3311 if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3312 if (!dsame) {
3313 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3314 else gPad->SetSelected(fXaxis);
3315 return 0;
3316 }
3317 }
3318 } else {
3319 xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3320 if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3321 if (!dsame) {
3322 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3323 else gPad->SetSelected(fXaxis);
3324 return 0;
3325 }
3326 }
3327 }
3328
3329 dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3330 if (doption.Contains("x+")) {
3331 yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3332 if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3333 if (!dsame) {
3334 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3335 else gPad->SetSelected(fYaxis);
3336 return 0;
3337 }
3338 }
3339 } else {
3340 yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3341 if (yxaxis < puymin) yxaxis = puymin;
3342 if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3343 if (!dsame) {
3344 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3345 else gPad->SetSelected(fYaxis);
3346 return 0;
3347 }
3348 }
3349 }
3350
3351 if (fH->IsHighlight()) { // only if highlight is enable
3352 if ((px > puxmin) && (py < puymin) && (px < puxmax) && (py > puymax))
3353 HighlightBin(px, py);
3354 }
3355
3356 // if object is 2D or 3D return this object
3357 if (fH->GetDimension() == 2) {
3358 if (fH->InheritsFrom(TH2Poly::Class())) {
3359 TH2Poly *th2 = (TH2Poly*)fH;
3361 gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3362 Double_t pxu = gPad->AbsPixeltoX(px);
3363 Double_t pyu = gPad->AbsPixeltoY(py);
3364 if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3365 curdist = big;
3366 goto FUNCTIONS;
3367 } else {
3368 Int_t bin = th2->FindBin(pxu, pyu);
3369 if (bin>0) curdist = 1;
3370 else curdist = big;
3371 goto FUNCTIONS;
3372 }
3373 }
3374 Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3375 if ( px > puxmin + delta2
3376 && px < puxmax - delta2
3377 && py > puymax + delta2
3378 && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3379 }
3380
3381 // point is inside histogram area. Find channel number
3382 if (gPad->IsVertical()) {
3383 Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3384 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3385 Double_t binval = factor*fH->GetBinContent(bin);
3386 Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3387 if (binval == 0 && pybin < puymin) pybin = 10000;
3388 // special case if more than one bin for the pixel
3389 if (binsup-bin>1) {
3390 Double_t binvalmin, binvalmax;
3391 binvalmin=binval;
3392 binvalmax=binval;
3393 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3394 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3395 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3396 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3397 }
3398 Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3399 Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3400 if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3401 }
3402 if (bin != binsup) { // Mouse on bin border
3403 Double_t binsupval = factor*fH->GetBinContent(binsup);
3404 Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3405 if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3406 }
3407 if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3408 } else {
3409 Double_t y = gPad->AbsPixeltoY(py);
3410 Double_t y1 = gPad->AbsPixeltoY(py+1);
3411 Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3412 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3413 Double_t binval = factor*fH->GetBinContent(bin);
3414 Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3415 if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3416 // special case if more than one bin for the pixel
3417 if (binsup-bin>1) {
3418 Double_t binvalmin, binvalmax;
3419 binvalmin=binval;
3420 binvalmax=binval;
3421 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3422 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3423 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3424 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3425 }
3426 Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3427 Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3428 if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3429 }
3430 if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3431 }
3432 // Loop on the list of associated functions and user objects
3433FUNCTIONS:
3434 TObject *f;
3435 TIter next(fFunctions);
3436 while ((f = (TObject*) next())) {
3437 Int_t dist;
3438 if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3439 else dist = f->DistancetoPrimitive(px,py);
3440 if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3441 }
3442 return curdist;
3443}
3444
3445////////////////////////////////////////////////////////////////////////////////
3446/// Display a panel with all histogram drawing options.
3447
3449{
3450
3451 gCurrentHist = fH;
3452 if (!gPad) {
3453 Error("DrawPanel", "need to draw histogram first");
3454 return;
3455 }
3457 editor->Show();
3458 gROOT->ProcessLine(Form("((TCanvas*)0x%zx)->Selected((TVirtualPad*)0x%zx,(TObject*)0x%zx,1)",
3459 (size_t)gPad->GetCanvas(), (size_t)gPad, (size_t)fH));
3460}
3461
3462////////////////////////////////////////////////////////////////////////////////
3463/// Execute the actions corresponding to `event`.
3464///
3465/// This function is called when a histogram is clicked with the locator at
3466/// the pixel position px,py.
3467
3469{
3470
3471 if (!gPad) return;
3472
3473 static Int_t bin, px1, py1, px2, py2, pyold;
3474 static TBox *zoombox = nullptr;
3475 Double_t zbx1,zbx2,zby1,zby2;
3476
3477 Int_t bin1, bin2;
3478 Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3479 Bool_t opaque = gPad->OpaqueMoving();
3480
3481 if (!gPad->IsEditable()) return;
3482
3483 if (fPie) {
3484 fPie->ExecuteEvent(event, px, py);
3485 return;
3486 }
3487 // come here if we have a lego/surface in the pad
3488 TView *view = gPad->GetView();
3489
3490 if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3491 view->ExecuteRotateView(event, px, py);
3492 return;
3493 }
3494
3495 TAxis *xaxis = fH->GetXaxis();
3496 TAxis *yaxis = fH->GetYaxis();
3497 Int_t dimension = fH->GetDimension();
3498
3499 // In case of option SAME the axis must be the ones of the first drawn histogram
3500 TString IsSame = fH->GetDrawOption();
3501 IsSame.ToLower();
3502 if (IsSame.Index("same")>=0) {
3503 TH1 *h1;
3504 TIter next(gPad->GetListOfPrimitives());
3505 while ((h1 = (TH1 *)next())) {
3506 if (!h1->InheritsFrom(TH1::Class())) continue;
3507 xaxis = h1->GetXaxis();
3508 yaxis = h1->GetYaxis();
3509 break;
3510 }
3511 }
3512
3513 Double_t factor = 1;
3514 if (fH->GetNormFactor() != 0) {
3515 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3516 }
3517
3518 switch (event) {
3519
3520 case kButton1Down:
3521
3522 if (!opaque) gVirtualX->SetLineColor(-1);
3523 fH->TAttLine::Modify();
3524
3525 if (opaque && dimension ==2) {
3526 zbx1 = gPad->AbsPixeltoX(px);
3527 zbx2 = gPad->AbsPixeltoX(px);
3528 zby1 = gPad->AbsPixeltoY(py);
3529 zby2 = gPad->AbsPixeltoY(py);
3530 px1 = px;
3531 py1 = py;
3532 if (gPad->GetLogx()) {
3533 zbx1 = TMath::Power(10,zbx1);
3534 zbx2 = TMath::Power(10,zbx2);
3535 }
3536 if (gPad->GetLogy()) {
3537 zby1 = TMath::Power(10,zby1);
3538 zby2 = TMath::Power(10,zby2);
3539 }
3540 if (zoombox) Error("ExecuteEvent", "Last zoom box was not deleted");
3541 zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3542 Int_t ci = TColor::GetColor("#7d7dff");
3543 TColor *zoomcolor = gROOT->GetColor(ci);
3544 if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3545 else zoomcolor->SetAlpha(0.5);
3546 zoombox->SetFillColor(ci);
3547 zoombox->Draw();
3548 gPad->Modified();
3549 gPad->Update();
3550 }
3551 // No break !!!
3552
3553 case kMouseMotion:
3554
3555 if (fShowProjection) {ShowProjection3(px,py); break;}
3556
3557 gPad->SetCursor(kPointer);
3558 if (dimension ==1) {
3559 if (Hoption.Bar) {
3560 baroffset = fH->GetBarOffset();
3561 barwidth = fH->GetBarWidth();
3562 } else {
3563 baroffset = 0;
3564 barwidth = 1;
3565 }
3566 x = gPad->AbsPixeltoX(px);
3567 bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3568 binwidth = fXaxis->GetBinWidth(bin);
3569 xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3570 xup = gPad->XtoPad(xlow + barwidth*binwidth);
3571 ylow = gPad->GetUymin();
3572 px1 = gPad->XtoAbsPixel(xlow);
3573 px2 = gPad->XtoAbsPixel(xup);
3574 py1 = gPad->YtoAbsPixel(ylow);
3575 py2 = py;
3576 pyold = py;
3577 if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3578 }
3579
3580 break;
3581
3582 case kButton1Motion:
3583
3584 if (dimension ==1) {
3585 if (gROOT->GetEditHistograms()) {
3586 if (!opaque) {
3587 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3588 py2 += py - pyold;
3589 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3590 pyold = py;
3591 } else {
3592 py2 += py - pyold;
3593 pyold = py;
3594 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3595 fH->SetBinContent(bin,binval);
3596 gPad->Modified(kTRUE);
3597 }
3598 }
3599 }
3600
3601 if (opaque && dimension ==2) {
3602 if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3603 zbx2 = gPad->AbsPixeltoX(px);
3604 zby2 = gPad->AbsPixeltoY(py);
3605 if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3606 if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3607 if (zoombox) {
3608 zoombox->SetX2(zbx2);
3609 zoombox->SetY2(zby2);
3610 }
3611 gPad->Modified();
3612 gPad->Update();
3613 }
3614 }
3615
3616 break;
3617
3618 case kWheelUp:
3619
3620 if (dimension ==2) {
3621 bin1 = xaxis->GetFirst()+1;
3622 bin2 = xaxis->GetLast()-1;
3623 bin1 = TMath::Max(bin1, 1);
3624 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3625 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3626 bin1 = yaxis->GetFirst()+1;
3627 bin2 = yaxis->GetLast()-1;
3628 bin1 = TMath::Max(bin1, 1);
3629 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3630 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3631 }
3632 gPad->Modified();
3633 gPad->Update();
3634
3635 break;
3636
3637 case kWheelDown:
3638
3639 if (dimension == 2) {
3640 bin1 = xaxis->GetFirst()-1;
3641 bin2 = xaxis->GetLast()+1;
3642 bin1 = TMath::Max(bin1, 1);
3643 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3644 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3645 bin1 = yaxis->GetFirst()-1;
3646 bin2 = yaxis->GetLast()+1;
3647 bin1 = TMath::Max(bin1, 1);
3648 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3649 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3650 }
3651 gPad->Modified();
3652 gPad->Update();
3653
3654 break;
3655
3656 case kButton1Up:
3657 if (dimension ==1) {
3658 if (gROOT->GetEditHistograms()) {
3659 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3660 fH->SetBinContent(bin,binval);
3661 PaintInit(); // recalculate Hparam structure and recalculate range
3662 }
3663
3664 // might resize pad pixmap so should be called before any paint routine
3666 }
3667 if (opaque && dimension ==2) {
3668 if (zoombox) {
3669 Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3670 Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3671 Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3672 Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3673 x1 = TMath::Max(x1,xaxis->GetXmin());
3674 x2 = TMath::Min(x2,xaxis->GetXmax());
3675 y1 = TMath::Max(y1,yaxis->GetXmin());
3676 y2 = TMath::Min(y2,yaxis->GetXmax());
3677 if (x1<x2 && y1<y2) {
3678 xaxis->SetRangeUser(x1, x2);
3679 yaxis->SetRangeUser(y1, y2);
3680 }
3681 zoombox->Delete();
3682 zoombox = nullptr;
3683 }
3684 }
3685 gPad->Modified(kTRUE);
3686 if (opaque) gVirtualX->SetLineColor(-1);
3687
3688 break;
3689
3690 case kButton1Locate:
3691
3692 ExecuteEvent(kButton1Down, px, py);
3693
3694 while (1) {
3695 px = py = 0;
3696 event = gVirtualX->RequestLocator(1, 1, px, py);
3697
3699
3700 if (event != -1) { // button is released
3701 ExecuteEvent(kButton1Up, px, py);
3702 return;
3703 }
3704 }
3705 }
3706}
3707
3708////////////////////////////////////////////////////////////////////////////////
3709/// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3710
3712{
3713
3714
3715
3716 // Check if fH contains a TGraphDelaunay2D
3717 TList *hl = fH->GetListOfFunctions();
3718 TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3719 // try with the old painter
3720 TGraphDelaunay *dtOld = nullptr;
3721 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3722
3723 if (!dt && !dtOld) return nullptr;
3724
3725 gCurrentHist = fH;
3726
3727 if (!fGraph2DPainter) {
3728 if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3729 else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3730 }
3731
3732 return fGraph2DPainter->GetContourList(contour);
3733}
3734
3735////////////////////////////////////////////////////////////////////////////////
3736/// Display the histogram info (bin number, contents, integral up to bin
3737/// corresponding to cursor position px,py.
3738
3740{
3741
3742 if (!gPad) return (char*)"";
3743
3744 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3745 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3746 Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3747 TString drawOption = fH->GetDrawOption();
3748 drawOption.ToLower();
3749 Double_t xmin, xmax, uxmin,uxmax;
3750 Double_t ymin, ymax, uymin,uymax;
3751 if (fH->GetDimension() == 2) {
3752 if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3753 uxmin=gPad->GetUxmin();
3754 uxmax=gPad->GetUxmax();
3757 x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3758 uymin=gPad->GetUymin();
3759 uymax=gPad->GetUymax();
3762 y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3763 }
3764 }
3765 Int_t binx,biny,binmin=0,binx1;
3766 if (gPad->IsVertical()) {
3767 binx = fXaxis->FindFixBin(x);
3768 if (drawOption.Index("same") >= 0) {
3769 TH1 *h1;
3770 TIter next(gPad->GetListOfPrimitives());
3771 while ((h1 = (TH1 *)next())) {
3772 if (!h1->InheritsFrom(TH1::Class())) continue;
3773 binmin = h1->GetXaxis()->GetFirst();
3774 break;
3775 }
3776 } else {
3777 binmin = fXaxis->GetFirst();
3778 }
3779 binx1 = fXaxis->FindFixBin(x1);
3780 // special case if more than 1 bin in x per pixel
3781 if (binx1-binx>1 && fH->GetDimension() == 1) {
3782 Double_t binval=fH->GetBinContent(binx);
3783 Int_t binnear=binx;
3784 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3785 Double_t binvaltmp = fH->GetBinContent(ibin);
3786 if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3787 binval=binvaltmp;
3788 binnear=ibin;
3789 }
3790 }
3791 binx = binnear;
3792 }
3793 } else {
3794 x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3795 binx = fXaxis->FindFixBin(y);
3796 if (drawOption.Index("same") >= 0) {
3797 TH1 *h1;
3798 TIter next(gPad->GetListOfPrimitives());
3799 while ((h1 = (TH1 *)next())) {
3800 if (!h1->InheritsFrom(TH1::Class())) continue;
3801 binmin = h1->GetXaxis()->GetFirst();
3802 break;
3803 }
3804 } else {
3805 binmin = fXaxis->GetFirst();
3806 }
3807 binx1 = fXaxis->FindFixBin(x1);
3808 // special case if more than 1 bin in x per pixel
3809 if (binx1-binx>1 && fH->GetDimension() == 1) {
3810 Double_t binval=fH->GetBinContent(binx);
3811 Int_t binnear=binx;
3812 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3813 Double_t binvaltmp = fH->GetBinContent(ibin);
3814 if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3815 binval=binvaltmp;
3816 binnear=ibin;
3817 }
3818 }
3819 binx = binnear;
3820 }
3821 }
3822 if (fH->GetDimension() == 1) {
3824 TProfile *tp = (TProfile*)fH;
3825 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3826 x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3827 (Int_t) tp->GetBinEntries(binx));
3828 }
3829 else {
3830 Double_t integ = 0;
3831 for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3832 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3833 x,y,binx,fH->GetBinContent(binx),integ);
3834 }
3835 } else if (fH->GetDimension() == 2) {
3836 if (fH->InheritsFrom(TH2Poly::Class())) {
3837 TH2Poly *th2 = (TH2Poly*)fH;
3838 biny = th2->FindBin(x,y);
3839 fObjectInfo.Form("%s (x=%g, y=%g, bin=%d, binc=%g)",
3840 th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3841 }
3842 else if (fH->InheritsFrom(TProfile2D::Class())) {
3843 TProfile2D *tp = (TProfile2D*)fH;
3844 biny = fYaxis->FindFixBin(y);
3845 Int_t bin = fH->GetBin(binx,biny);
3846 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3847 x, y, binx, biny, fH->GetBinContent(bin),
3848 fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3849 } else {
3850 biny = fYaxis->FindFixBin(y);
3851 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3852 x,y,binx,biny,fH->GetBinContent(binx,biny),
3853 fH->GetBinError(binx,biny));
3854 }
3855 } else {
3856 // 3d case: retrieving the x,y,z bin is not yet implemented
3857 // print just the x,y info
3858 fObjectInfo.Form("(x=%g, y=%g)",x,y);
3859 }
3860
3861 return (char *)fObjectInfo.Data();
3862}
3863
3864////////////////////////////////////////////////////////////////////////////////
3865/// Set highlight (enable/disable) mode for fH
3866
3868{
3869 if (fH->IsHighlight()) return;
3870
3871 fXHighlightBin = -1;
3872 fYHighlightBin = -1;
3873 // delete previous highlight box
3876 // emit Highlighted() signal (user can check on disabled)
3877 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3878}
3879
3880////////////////////////////////////////////////////////////////////////////////
3881/// Check on highlight bin
3882
3884{
3885 // call from DistancetoPrimitive (only if highlight is enable)
3886
3887 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3888 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3889 Int_t binx = fXaxis->FindFixBin(x);
3890 Int_t biny = fYaxis->FindFixBin(y);
3891 if (!gPad->IsVertical()) binx = fXaxis->FindFixBin(y);
3892
3893 Bool_t changedBin = kFALSE;
3894 if (binx != fXHighlightBin) {
3895 fXHighlightBin = binx;
3896 changedBin = kTRUE;
3897 } else if (fH->GetDimension() == 1) return;
3898 if (biny != fYHighlightBin) {
3899 fYHighlightBin = biny;
3900 changedBin = kTRUE;
3901 }
3902 if (!changedBin) return;
3903
3904 // Info("HighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3905 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3906
3907 // paint highlight bin as box (recursive calls PaintHighlightBin)
3908 gPad->Modified(kTRUE);
3909 gPad->Update();
3910
3911 // emit Highlighted() signal
3912 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3913}
3914
3915////////////////////////////////////////////////////////////////////////////////
3916/// Paint highlight bin as TBox object
3917
3919{
3920 // call from PaintTitle
3921
3922 if (!fH->IsHighlight()) return;
3923
3924 Double_t uxmin = gPad->GetUxmin();
3925 Double_t uxmax = gPad->GetUxmax();
3926 Double_t uymin = gPad->GetUymin();
3927 Double_t uymax = gPad->GetUymax();
3928 if (gPad->GetLogx()) {
3929 uxmin = TMath::Power(10.0, uxmin);
3930 uxmax = TMath::Power(10.0, uxmax);
3931 }
3932 if (gPad->GetLogy()) {
3933 uymin = TMath::Power(10.0, uymin);
3934 uymax = TMath::Power(10.0, uymax);
3935 }
3936
3937 // testing specific possibility (after zoom, draw with "same", log, etc.)
3938 Double_t hcenter;
3939 if (gPad->IsVertical()) {
3941 if ((hcenter < uxmin) || (hcenter > uxmax)) return;
3942 } else {
3944 if ((hcenter < uymin) || (hcenter > uymax)) return;
3945 }
3946 if (fH->GetDimension() == 2) {
3948 if ((hcenter < uymin) || (hcenter > uymax)) return;
3949 }
3950
3951 // paint X highlight bin (for 1D or 2D)
3952 Double_t hbx1, hbx2, hby1, hby2;
3953 if (gPad->IsVertical()) {
3956 hby1 = uymin;
3957 hby2 = uymax;
3958 } else {
3959 hbx1 = uxmin;
3960 hbx2 = uxmax;
3963 }
3964
3965 if (!gXHighlightBox) {
3966 gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3970 else gROOT->GetColor(gXHighlightBox->GetFillColor())->SetAlpha(0.5);
3971 }
3972 gXHighlightBox->SetX1(hbx1);
3973 gXHighlightBox->SetX2(hbx2);
3974 gXHighlightBox->SetY1(hby1);
3975 gXHighlightBox->SetY2(hby2);
3977
3978 // Info("PaintHighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3979 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3980
3981 // paint Y highlight bin (only for 2D)
3982 if (fH->GetDimension() != 2) return;
3983 hbx1 = uxmin;
3984 hbx2 = uxmax;
3987
3988 if (!gYHighlightBox) {
3989 gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3993 }
3994 gYHighlightBox->SetX1(hbx1);
3995 gYHighlightBox->SetX2(hbx2);
3996 gYHighlightBox->SetY1(hby1);
3997 gYHighlightBox->SetY2(hby2);
3999}
4000
4001////////////////////////////////////////////////////////////////////////////////
4002/// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
4003
4005{
4006
4007 for (Int_t i=0;i<fNcuts;i++) {
4010 if (fCutsOpt[i] > 0) {
4011 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
4012 } else {
4013 if (fCuts[i]->IsInside(x,y)) return kFALSE;
4014 }
4015 }
4016 return kTRUE;
4017}
4018
4019////////////////////////////////////////////////////////////////////////////////
4020/// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
4021
4023{
4024
4025 for (Int_t i=0;i<fNcuts;i++) {
4026 if (fCutsOpt[i] > 0) {
4027 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
4028 } else {
4029 if (fCuts[i]->IsInside(x,y)) return kFALSE;
4030 }
4031 }
4032 return kTRUE;
4033}
4034
4035////////////////////////////////////////////////////////////////////////////////
4036/// Decode string `choptin` and fill Hoption structure.
4037
4039{
4040
4041 char *l;
4042 char chopt[128];
4043 Int_t nch = strlen(choptin);
4044 strlcpy(chopt,choptin,128);
4045 Int_t hdim = fH->GetDimension();
4046
4054 Hoption.Candle = 0;
4055
4056 // special 2D options
4057 Hoption.List = 0;
4058 Hoption.Zscale = 0;
4059 Hoption.FrontBox = 1;
4060 Hoption.BackBox = 1;
4062
4063 Hoption.Zero = 0;
4064
4066
4067 //check for graphical cuts
4068 MakeCuts(chopt);
4069
4070 for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
4071 if (hdim > 1) Hoption.Scat = 1;
4072 if (!nch) Hoption.Hist = 1;
4073 if (fFunctions->First()) Hoption.Func = 1;
4074 if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
4075
4076 char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
4077 char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
4078 char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
4079 if (l1 || l2 || l3) {
4080 Int_t i = gPad->NextPaletteColor();
4081 if (l1) {memcpy(l1," ",3); fH->SetFillColor(i);}
4082 if (l2) {memcpy(l2," ",3); fH->SetLineColor(i);}
4083 if (l3) {memcpy(l3," ",3); fH->SetMarkerColor(i);}
4084 Hoption.Hist = 1; // Make sure something is drawn in case there is no drawing option specified.
4085 }
4086
4087 l = strstr(chopt,"MIN0");
4088 if (l) {
4089 Hoption.MinimumZero = 1;
4090 memcpy(l," ",4);
4091 }
4092
4093 l = strstr(chopt,"SPEC");
4094 if (l) {
4095 Hoption.Scat = 0;
4096 memcpy(l," ",4);
4097 Int_t bs=0;
4098 l = strstr(chopt,"BF(");
4099 if (l) {
4100 if (sscanf(&l[3],"%d",&bs) > 0) {
4101 Int_t i=0;
4102 while (l[i]!=')') {
4103 l[i] = ' ';
4104 i++;
4105 }
4106 l[i] = ' ';
4107 }
4108 }
4109 Hoption.Spec = TMath::Max(1600,bs);
4110 return 1;
4111 }
4112
4113 l = strstr(chopt,"GL");
4114 if (l) {
4115 memcpy(l," ",2);
4116 }
4117 l = strstr(chopt,"X+");
4118 if (l) {
4119 Hoption.AxisPos = 10;
4120 memcpy(l," ",2);
4121 }
4122 l = strstr(chopt,"Y+");
4123 if (l) {
4124 Hoption.AxisPos += 1;
4125 memcpy(l," ",2);
4126 }
4127 if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
4128 if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
4129
4130 l = strstr(chopt,"SAMES");
4131 if (l) {
4132 if (nch == 5) Hoption.Hist = 1;
4133 Hoption.Same = 2;
4134 memcpy(l," ",5);
4135 if (l[5] == '0') { Hoption.Same += 10; l[5] = ' '; }
4136 }
4137 l = strstr(chopt,"SAME");
4138 if (l) {
4139 if (nch == 4) Hoption.Hist = 1;
4140 Hoption.Same = 1;
4141 memcpy(l," ",4);
4142 if (l[4] == '0') { Hoption.Same += 10; l[4] = ' '; }
4143 }
4144
4145 l = strstr(chopt,"PIE");
4146 if (l) {
4147 Hoption.Pie = 1;
4148 memcpy(l," ",3);
4149 }
4150
4151
4152 l = strstr(chopt,"CANDLE");
4153 if (l) {
4154 TCandle candle;
4155 Hoption.Candle = candle.ParseOption(l);
4156 Hoption.Scat = 0;
4157 }
4158
4159 l = strstr(chopt,"VIOLIN");
4160 if (l) {
4161 TCandle candle;
4162 Hoption.Candle = candle.ParseOption(l);
4163 Hoption.Scat = 0;
4164 }
4165
4166 l = strstr(chopt,"LEGO");
4167 if (l) {
4168 Hoption.Scat = 0;
4169 Hoption.Lego = 1; memcpy(l," ",4);
4170 if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
4171 if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
4172 if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
4173 if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
4174 if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
4175 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4176 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4177 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4178 }
4179
4180 l = strstr(chopt,"SURF");
4181 if (l) {
4182 Hoption.Scat = 0;
4183 Hoption.Surf = 1; memcpy(l," ",4);
4184 if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
4185 if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
4186 if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
4187 if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
4188 if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
4189 if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
4190 if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
4191 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4192 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4193 }
4194
4195 l = strstr(chopt,"TF3");
4196 if (l) {
4197 memcpy(l," ",3);
4198 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4199 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4200 }
4201
4202 l = strstr(chopt,"ISO");
4203 if (l) {
4204 memcpy(l," ",3);
4205 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4206 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4207 }
4208
4209 l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; memcpy(l," ",4);}
4210
4211 l = strstr(chopt,"CONT");
4212 if (l) {
4213 memcpy(l," ",4);
4214 if (hdim>1) {
4215 Hoption.Scat = 0;
4216 Hoption.Contour = 1;
4217 if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
4218 if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
4219 if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
4220 if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
4221 if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
4222 } else {
4223 Hoption.Hist = 1;
4224 }
4225 }
4226 l = strstr(chopt,"HBAR");
4227 if (l) {
4228 Hoption.Hist = 0;
4229 Hoption.Bar = 20; memcpy(l," ",4);
4230 if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
4231 if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
4232 if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
4233 if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
4234 }
4235 l = strstr(chopt,"BAR");
4236 if (l) {
4237 Hoption.Hist = 0;
4238 Hoption.Bar = 10; memcpy(l," ",3);
4239 if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
4240 if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
4241 if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
4242 if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
4243 }
4244
4245 l = strstr(chopt,"ARR" );
4246 if (l) {
4247 memcpy(l," ", 3);
4248 if (hdim>1) {
4249 Hoption.Arrow = 1;
4250 Hoption.Scat = 0;
4251 l = strstr(chopt,"COL"); if (l) { Hoption.Arrow = 2; memcpy(l," ",3); }
4252 l = strstr(chopt,"Z"); if (l) { Hoption.Zscale = 1; memcpy(l," ",1); }
4253 } else {
4254 Hoption.Hist = 1;
4255 }
4256 }
4257 l = strstr(chopt,"BOX" );
4258 if (l) {
4259 memcpy(l," ", 3);
4260 if (hdim>1) {
4261 Hoption.Scat = 0;
4262 Hoption.Box = 1;
4263 if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
4264 if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
4265 if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
4266 } else {
4267 Hoption.Hist = 1;
4268 }
4269 }
4270 l = strstr(chopt,"COLZ");
4271 if (l) {
4272 memcpy(l," ",4);
4273 if (hdim>1) {
4274 Hoption.Color = 1;
4275 Hoption.Scat = 0;
4276 Hoption.Zscale = 1;
4277 if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
4278 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4279 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4280 } else {
4281 Hoption.Hist = 1;
4282 }
4283 }
4284 l = strstr(chopt,"COL" );
4285 if (l) {
4286 memcpy(l," ", 3);
4287 if (hdim>1) {
4288 Hoption.Color = 1;
4289 Hoption.Scat = 0;
4290 if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
4291 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4292 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4293 } else {
4294 Hoption.Hist = 1;
4295 }
4296 }
4297 l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; memcpy(l," ",4); Hoption.Hist = 0; }
4298 l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; memcpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
4299 l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; memcpy(l," ",4); }
4300 l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; memcpy(l," ",4); }
4301 l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; memcpy(l," ",4); }
4302 l = strstr(chopt,"TEXT");
4303 if (l) {
4304 Int_t angle;
4305 if (sscanf(&l[4],"%d",&angle) > 0) {
4306 if (angle < 0) angle=0;
4307 if (angle > 90) angle=90;
4308 Hoption.Text = 1000+angle;
4309 } else {
4310 Hoption.Text = 1;
4311 }
4312 memcpy(l," ", 4);
4313 l = strstr(chopt,"N");
4314 if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
4315 Hoption.Scat = 0;
4316 }
4317 l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; memcpy(l," ",3); }
4318 l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; memcpy(l," ",3); }
4319 l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; memcpy(l," ",3); }
4320 l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; memcpy(l," ",3); }
4321
4322 l = strstr(chopt,"TRI");
4323 if (l) {
4324 Hoption.Scat = 0;
4325 Hoption.Color = 0;
4326 Hoption.Tri = 1; memcpy(l," ",3);
4327 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4328 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4329 l = strstr(chopt,"ERR"); if (l) memcpy(l," ",3);
4330 }
4331
4332 l = strstr(chopt,"AITOFF");
4333 if (l) {
4334 Hoption.Proj = 1; memcpy(l," ",6); //Aitoff projection
4335 }
4336 l = strstr(chopt,"MERCATOR");
4337 if (l) {
4338 Hoption.Proj = 2; memcpy(l," ",8); //Mercator projection
4339 }
4340 l = strstr(chopt,"SINUSOIDAL");
4341 if (l) {
4342 Hoption.Proj = 3; memcpy(l," ",10); //Sinusoidal projection
4343 }
4344 l = strstr(chopt,"PARABOLIC");
4345 if (l) {
4346 Hoption.Proj = 4; memcpy(l," ",9); //Parabolic projection
4347 }
4348 if (Hoption.Proj > 0) {
4349 Hoption.Scat = 0;
4350 Hoption.Contour = 14;
4351 }
4352
4353 if (strstr(chopt,"A")) Hoption.Axis = -1;
4354 if (strstr(chopt,"B")) Hoption.Bar = 1;
4355 if (strstr(chopt,"C") && !strstr(chopt,"CJUST")) { Hoption.Curve =1; Hoption.Hist = -1;}
4356 if (strstr(chopt,"F")) Hoption.Fill =1;
4357 if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
4358 if (strstr(chopt,"F2")) Hoption.Fill =2;
4359 if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
4360 if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
4361 if (strstr(chopt,"Z")) Hoption.Zscale =1;
4362 if (strstr(chopt,"*")) Hoption.Star =1;
4363 if (strstr(chopt,"H")) Hoption.Hist =2;
4364 if (strstr(chopt,"P0")) Hoption.Mark =10;
4365
4366 if (fH->InheritsFrom(TH2Poly::Class())) {
4368 }
4369
4370 if (strstr(chopt,"E")) {
4371 if (hdim == 1) {
4372 Hoption.Error = 1;
4373 if (strstr(chopt,"E1")) Hoption.Error = 11;
4374 if (strstr(chopt,"E2")) Hoption.Error = 12;
4375 if (strstr(chopt,"E3")) Hoption.Error = 13;
4376 if (strstr(chopt,"E4")) Hoption.Error = 14;
4377 if (strstr(chopt,"E5")) Hoption.Error = 15;
4378 if (strstr(chopt,"E6")) Hoption.Error = 16;
4379 if (strstr(chopt,"E0")) Hoption.Error += 40;
4380 if (strstr(chopt,"X0")) {
4381 if (Hoption.Error == 1) Hoption.Error += 20;
4382 Hoption.Error += 10;
4383 }
4385 Hoption.Text += 2000;
4386 Hoption.Error = 0;
4387 }
4388 } else {
4389 if (Hoption.Error == 0) {
4390 Hoption.Error = 100;
4391 Hoption.Scat = 0;
4392 }
4393 if (Hoption.Text) {
4394 Hoption.Text += 2000;
4395 Hoption.Error = 0;
4396 }
4397 }
4398 }
4399
4400 if (Hoption.Surf == 15) {
4402 Hoption.Surf = 13;
4403 Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4404 }
4405 }
4406
4407 // Copy options from current style
4408 Hoption.Logx = gPad->GetLogx();
4409 Hoption.Logy = gPad->GetLogy();
4410 Hoption.Logz = gPad->GetLogz();
4411
4412 // Check options incompatibilities
4413 if (Hoption.Bar == 1) Hoption.Hist = -1;
4414 return 1;
4415}
4416
4417////////////////////////////////////////////////////////////////////////////////
4418/// Decode string `choptin` and fill Graphical cuts structure.
4419
4421{
4422
4423 fNcuts = 0;
4424 char *left = (char*)strchr(choptin,'[');
4425 if (!left) return 0;
4426 char *right = (char*)strchr(choptin,']');
4427 if (!right) return 0;
4428 Int_t nch = right-left;
4429 if (nch < 2) return 0;
4430 char *cuts = left+1;
4431 *right = 0;
4432 char *comma, *minus;
4433 Int_t i;
4434 while (1) {
4435 comma = strchr(cuts,',');
4436 if (comma) *comma = 0;
4437 minus = strchr(cuts,'-');
4438 if (minus) cuts = minus+1;
4439 while (*cuts == ' ') cuts++;
4440 Int_t nc = strlen(cuts);
4441 while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4442 TIter next(gROOT->GetListOfSpecials());
4443 TCutG *cut=0;
4444 TObject *obj;
4445 while ((obj = next())) {
4446 if (!obj->InheritsFrom(TCutG::Class())) continue;
4447 if (strcmp(obj->GetName(),cuts)) continue;
4448 cut = (TCutG*)obj;
4449 break;
4450 }
4451 if (cut) {
4452 fCuts[fNcuts] = cut;
4453 fCutsOpt[fNcuts] = 1;
4454 if (minus) fCutsOpt[fNcuts] = -1;
4455 fNcuts++;
4456 }
4457 if (!comma) break;
4458 cuts = comma+1;
4459 }
4460 for (i=0;i<=nch;i++) left[i] = ' ';
4461 return fNcuts;
4462}
4463
4464////////////////////////////////////////////////////////////////////////////////
4465/// [Control routine to paint any kind of histograms](\ref HP00)
4466
4468{
4469
4470 if (fH->GetBuffer()) fH->BufferEmpty(-1);
4471
4472 //For iOS: put the histogram on the top of stack of pickable objects.
4473 const TPickerStackGuard topPush(fH);
4474
4475 gPad->SetVertical(kTRUE);
4476
4477 TH1 *oldhist = gCurrentHist;
4478 gCurrentHist = fH;
4479 TH1 *hsave = fH;
4480 Double_t minsav = fH->GetMinimumStored();
4481
4482 if (!MakeChopt(option)) return; //check options and fill Hoption structure
4483
4484 // Paint using TSpectrum2Painter
4485 if (Hoption.Spec) {
4486 if (!TableInit()) return;
4487 if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4488 gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%zx,\"%s\",%d)",
4489 (size_t)fH, option, Hoption.Spec));
4490 return;
4491 }
4492
4493 // Deflate the labels in case of alphanumeric labels
4497
4498 if (Hoption.Pie) {
4499 if (fH->GetDimension() == 1) {
4500 if (!fPie) fPie = new TPie(fH);
4501 fPie->Paint(option);
4502 } else {
4503 Error("Paint", "Option PIE is for 1D histograms only");
4504 }
4505 return;
4506 } else {
4507 if (fPie) delete fPie;
4508 fPie = 0;
4509 }
4510
4511 fXbuf = new Double_t[kNMAX];
4512 fYbuf = new Double_t[kNMAX];
4513 if (fH->GetDimension() > 2) {
4514 PaintH3(option);
4515 fH->SetMinimum(minsav);
4516 if (Hoption.Func) {
4517 Hoption_t hoptsave = Hoption;
4518 Hparam_t hparsave = Hparam;
4519 PaintFunction(option);
4520 SetHistogram(hsave);
4521 Hoption = hoptsave;
4522 Hparam = hparsave;
4523 }
4524 gCurrentHist = oldhist;
4525 delete [] fXbuf; delete [] fYbuf;
4526 return;
4527 }
4528 TView *view = gPad->GetView();
4529 if (view) {
4530 if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4531 delete view;
4532 gPad->SetView(0);
4533 }
4534 }
4535 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4536 // In case of 1D histogram, Z axis becomes Y axis.
4537 Int_t logysav=0, logzsav=0;
4538 if (fH->GetDimension() == 1) {
4539 logysav = Hoption.Logy;
4540 logzsav = Hoption.Logz;
4541 Hoption.Logz = 0;
4542 if (Hoption.Logy) {
4543 Hoption.Logz = 1;
4544 Hoption.Logy = 0;
4545 }
4546 }
4547 PaintTable(option);
4548 if (Hoption.Func) {
4549 Hoption_t hoptsave = Hoption;
4550 Hparam_t hparsave = Hparam;
4551 PaintFunction(option);
4552 SetHistogram(hsave);
4553 Hoption = hoptsave;
4554 Hparam = hparsave;
4555 }
4556 fH->SetMinimum(minsav);
4557 gCurrentHist = oldhist;
4558 delete [] fXbuf; delete [] fYbuf;
4559 if (fH->GetDimension() == 1) {
4560 Hoption.Logy = logysav;
4561 Hoption.Logz = logzsav;
4562 }
4563 return;
4564 }
4565
4566 if (Hoption.Bar >= 20) {
4567 PaintBarH(option);
4568 delete [] fXbuf; delete [] fYbuf;
4569 return;
4570 }
4571
4572 // fill Hparam structure with histo parameters
4573 if (!PaintInit()) {
4574 delete [] fXbuf; delete [] fYbuf;
4575 return;
4576 }
4577
4578 // Picture surround (if new page) and page number (if requested).
4579 // Histogram surround (if not option "Same").
4580 PaintFrame();
4581
4582 // Paint histogram axis only
4583 Bool_t gridx = gPad->GetGridx();
4584 Bool_t gridy = gPad->GetGridy();
4585 if (Hoption.Axis > 0) {
4586 if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4587 else {
4588 if (gridx) gPad->SetGridx(0);
4589 if (gridy) gPad->SetGridy(0);
4591 if (gridx) gPad->SetGridx(1);
4592 if (gridy) gPad->SetGridy(1);
4593 }
4594 if ((Hoption.Same%10) ==1) Hoption.Same += 1;
4595 goto paintstat;
4596 }
4597 if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4598
4599 // test for options BAR or HBAR
4600 if (Hoption.Bar >= 10) {
4601 PaintBar(option);
4602 }
4603
4604 // do not draw histogram if error bars required
4605 if (!Hoption.Error) {
4606 if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4607 }
4608
4609 // test for error bars or option E
4610 if (Hoption.Error) {
4611 PaintErrors(option);
4612 if (Hoption.Hist == 2) PaintHist(option);
4613 }
4614
4615 if (Hoption.Text) PaintText(option);
4616
4617 // test for associated function
4618 if (Hoption.Func) {
4619 Hoption_t hoptsave = Hoption;
4620 Hparam_t hparsave = Hparam;
4621 PaintFunction(option);
4622 SetHistogram(hsave);
4623 Hoption = hoptsave;
4624 Hparam = hparsave;
4625 }
4626
4627 if (gridx) gPad->SetGridx(0);
4628 if (gridy) gPad->SetGridy(0);
4630 if (gridx) gPad->SetGridx(1);
4631 if (gridy) gPad->SetGridy(1);
4632
4633 PaintTitle(); // Draw histogram title
4634
4635 // Draw box with histogram statistics and/or fit parameters
4636paintstat:
4637 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4638 TIter next(fFunctions);
4639 TObject *obj = 0;
4640 while ((obj = next())) {
4641 if (obj->InheritsFrom(TF1::Class())) break;
4642 obj = 0;
4643 }
4644
4645 //Stat is painted twice (first, it will be in canvas' list of primitives),
4646 //second, it will be here, this is not required on iOS.
4647 //Condition is ALWAYS true on a platform different from iOS.
4648 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4649 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4650 }
4651 fH->SetMinimum(minsav);
4652 gCurrentHist = oldhist;
4653 delete [] fXbuf; fXbuf = 0;
4654 delete [] fYbuf; fYbuf = 0;
4655
4656}
4657
4658////////////////////////////////////////////////////////////////////////////////
4659/// [Control function to draw a table as an arrow plot](\ref HP12)
4660
4662{
4663 Double_t xk, xstep, yk, ystep;
4664 Double_t dx, dy, x1, x2, y1, y2, xc, yc, dxn, dyn;
4667 Double_t xrg = gPad->GetUxmin();
4668 Double_t yrg = gPad->GetUymin();
4669 Double_t xln = gPad->GetUxmax() - xrg;
4670 Double_t yln = gPad->GetUymax() - yrg;
4671 Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4672 Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4673 Double_t dn = 1.E-30;
4674
4675 auto arrow = new TArrow();
4676 arrow->SetAngle(30);
4677 arrow->SetFillStyle(1001);
4678 arrow->SetFillColor(fH->GetLineColor());
4679 arrow->SetLineColor(fH->GetLineColor());
4680 arrow->SetLineWidth(fH->GetLineWidth());
4681
4682 // Initialize the levels on the Z axis
4683 Int_t ncolors=0, ndivz=0;
4684 Double_t scale=0.;
4685 if (Hoption.Arrow>1) {
4686 ncolors = gStyle->GetNumberOfColors();
4687 Int_t ndiv = fH->GetContour();
4688 if (ndiv == 0 ) {
4689 ndiv = gStyle->GetNumberContours();
4690 fH->SetContour(ndiv);
4691 }
4692 ndivz = TMath::Abs(ndiv);
4693 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4694 scale = ndivz/(fH->GetMaximum()-fH->GetMinimum());
4695 }
4696
4697 for (Int_t id=1;id<=2;id++) {
4698 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4699 yk = fYaxis->GetBinLowEdge(j);
4700 ystep = fYaxis->GetBinWidth(j);
4701 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4702 xk = fXaxis->GetBinLowEdge(i);
4703 xstep = fXaxis->GetBinWidth(i);
4704 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4705 if (i == Hparam.xfirst) {
4706 dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4707 } else if (i == Hparam.xlast) {
4708 dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4709 } else {
4710 dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4711 }
4712 if (j == Hparam.yfirst) {
4713 dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4714 } else if (j == Hparam.ylast) {
4715 dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4716 } else {
4717 dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4718 }
4719 if (id == 1) {
4720 dn = TMath::Max(dn, TMath::Abs(dx));
4721 dn = TMath::Max(dn, TMath::Abs(dy));
4722 } else if (id == 2) {
4723 xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4724 dxn = cx*dx/dn;
4725 x1 = xc - dxn;
4726 x2 = xc + dxn;
4727 yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4728 dyn = cy*dy/dn;
4729 y1 = yc - dyn;
4730 y2 = yc + dyn;
4731 if (Hoption.Arrow>1) {
4732 int color = Int_t(0.01+(fH->GetBinContent(i, j)-fH->GetMinimum())*scale);
4733 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4734 if (theColor > ncolors-1) theColor = ncolors-1;
4735 arrow->SetFillColor(gStyle->GetColorPalette(theColor));
4736 arrow->SetLineColor(gStyle->GetColorPalette(theColor));
4737 }
4738 if (TMath::Abs(x2-x1) > 0. || TMath::Abs(y2-y1) > 0.) {
4739 arrow->PaintArrow(x1, y1, x2, y2, 0.015, "|>");
4740 } else {
4741 arrow->PaintArrow(x1, y1, x2, y2, 0.005, "|>");
4742 }
4743 }
4744 }
4745 }
4746 }
4747
4749}
4750
4751////////////////////////////////////////////////////////////////////////////////
4752/// Draw axis (2D case) of an histogram.
4753///
4754/// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4755/// to draw the grid and the axis separately. In `THistPainter::Paint` this
4756/// feature is used to make sure that the grid is drawn in the background and
4757/// the axis tick marks in the foreground of the pad.
4758
4760{
4761
4762 //On iOS, grid should not be pickable and can not be highlighted.
4763 //Condition is never true on a platform different from iOS.
4764 if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4765 return;
4766
4767 if (Hoption.Axis == -1) return;
4768 if (Hoption.Same && Hoption.Axis <= 0) return;
4769
4770 // Repainting alphanumeric labels axis on a plot done with
4771 // the option HBAR (horizontal) needs some adjustments.
4772 TAxis *xaxis = 0;
4773 TAxis *yaxis = 0;
4774 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4775 if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4776 TIter next(gPad->GetListOfPrimitives());
4777 TObject *obj;
4778 // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4779 while ((obj = next())) {
4780 if (!obj->InheritsFrom(TH1::Class()) &&
4781 !obj->InheritsFrom(THStack::Class())) continue;
4782 TString opt = obj->GetDrawOption();
4783 opt.ToLower();
4784 // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4785 if (strstr(opt,"hbar")) {
4786 gPad->SetVertical(kFALSE);
4787 xaxis = fXaxis;
4788 yaxis = fYaxis;
4789 if (!strcmp(xaxis->GetName(),"xaxis")) {
4790 fXaxis = yaxis;
4791 fYaxis = xaxis;
4792 }
4793 }
4794 break;
4795 }
4796 }
4797 }
4798
4799 static char chopt[10] = "";
4800 Double_t gridl = 0;
4801 Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4802 Int_t useHparam = 0;
4803 Double_t umin, umax, uminsave, umaxsave;
4804 Short_t xAxisPos = Hoption.AxisPos/10;
4805 Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4806
4807 Double_t axmin = gPad->GetUxmin();
4808 Double_t axmax = gPad->GetUxmax();
4809 Double_t aymin = gPad->GetUymin();
4810 Double_t aymax = gPad->GetUymax();
4811 char *cw = 0;
4812 TGaxis axis;
4813
4814 // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4815 // Hparam must be use for the axis limits.
4816 if (Hoption.Contour == 14) useHparam = 1;
4817 if (Hoption.Same) {
4818 TObject *obj;
4819 TIter next(gPad->GetListOfPrimitives());
4820 while ((obj=next())) {
4821 if (strstr(obj->GetDrawOption(),"cont4")) {
4822 useHparam = 1;
4823 break;
4824 }
4825 }
4826 }
4827
4828 // Paint X axis
4829
4830 //To make X-axis selectable on iOS device.
4831 if (gPad->PadInSelectionMode())
4832 gPad->PushSelectableObject(fXaxis);
4833
4834 //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4835 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4836 ndivx = fXaxis->GetNdivisions();
4837 if (ndivx > 1000) {
4838 nx2 = ndivx/100;
4839 nx1 = TMath::Max(1, ndivx%100);
4840 ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4841 }
4842 axis.SetTextAngle(0);
4844
4845 chopt[0] = 0;
4846 strlcat(chopt, "SDH",10);
4847 if (ndivx < 0) strlcat(chopt, "N",10);
4848 if (gPad->GetGridx()) {
4849 gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4850 strlcat(chopt, "W",10);
4851 }
4852
4853 // Define X-Axis limits
4854 if (Hoption.Logx) {
4855 strlcat(chopt, "G",10);
4856 ndiv = TMath::Abs(ndivx);
4857 if (useHparam) {
4858 umin = TMath::Power(10,Hparam.xmin);
4859 umax = TMath::Power(10,Hparam.xmax);
4860 } else {
4861 umin = TMath::Power(10,axmin);
4862 umax = TMath::Power(10,axmax);
4863 }
4864 } else {
4865 ndiv = TMath::Abs(ndivx);
4866 if (useHparam) {
4867 umin = Hparam.xmin;
4868 umax = Hparam.xmax;
4869 } else {
4870 umin = axmin;
4871 umax = axmax;
4872 }
4873 }
4874
4875 // Display axis as time
4876 if (fXaxis->GetTimeDisplay()) {
4877 strlcat(chopt,"t",10);
4878 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4880 }
4881 }
4882
4883 // The main X axis can be on the bottom or on the top of the pad
4884 Double_t xAxisYPos1, xAxisYPos2;
4885 if (xAxisPos == 1) {
4886 // Main X axis top
4887 xAxisYPos1 = aymax;
4888 xAxisYPos2 = aymin;
4889 } else {
4890 // Main X axis bottom
4891 xAxisYPos1 = aymin;
4892 xAxisYPos2 = aymax;
4893 }
4894
4895 // Paint the main X axis (always)
4896 uminsave = umin;
4897 umaxsave = umax;
4898 ndivsave = ndiv;
4899 axis.SetOption(chopt);
4900 if (xAxisPos) {
4901 strlcat(chopt, "-",10);
4902 gridl = -gridl;
4903 }
4904 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4905 axis.SetLabelSize(0.);
4906 axis.SetTitle("");
4907 }
4908 axis.PaintAxis(axmin, xAxisYPos1,
4909 axmax, xAxisYPos1,
4910 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4911
4912 // Paint additional X axis (if needed)
4913 // On iOS, this additional X axis is neither pickable, nor highlighted.
4914 // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4915 if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4916 if (xAxisPos) {
4917 cw=strstr(chopt,"-");
4918 *cw='z';
4919 } else {
4920 strlcat(chopt, "-",10);
4921 }
4922 if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4923 if ((cw=strstr(chopt,"W"))) *cw='z';
4924 axis.SetTitle("");
4925 axis.PaintAxis(axmin, xAxisYPos2,
4926 axmax, xAxisYPos2,
4927 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4928 }
4929 }//End of "if pad in selection mode etc".
4930
4931 // Paint Y axis
4932 //On iOS, Y axis must pushed into the stack of selectable objects.
4933 if (gPad->PadInSelectionMode())
4934 gPad->PushSelectableObject(fYaxis);
4935
4936 //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4937 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4938 ndivy = fYaxis->GetNdivisions();
4940
4941 chopt[0] = 0;
4942 strlcat(chopt, "SDH",10);
4943 if (ndivy < 0) strlcat(chopt, "N",10);
4944 if (gPad->GetGridy()) {
4945 gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4946 strlcat(chopt, "W",10);
4947 }
4948
4949 // Define Y-Axis limits
4950 if (Hoption.Logy) {
4951 strlcat(chopt, "G",10);
4952 ndiv = TMath::Abs(ndivy);
4953 if (useHparam) {
4954 umin = TMath::Power(10,Hparam.ymin);
4955 umax = TMath::Power(10,Hparam.ymax);
4956 } else {
4957 umin = TMath::Power(10,aymin);
4958 umax = TMath::Power(10,aymax);
4959 }
4960 } else {
4961 ndiv = TMath::Abs(ndivy);
4962 if (useHparam) {
4963 umin = Hparam.ymin;
4964 umax = Hparam.ymax;
4965 } else {
4966 umin = aymin;
4967 umax = aymax;
4968 }
4969 }
4970
4971 // Display axis as time
4972 if (fYaxis->GetTimeDisplay()) {
4973 strlcat(chopt,"t",10);
4974 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4976 }
4977 }
4978
4979 // The main Y axis can be on the left or on the right of the pad
4980 Double_t yAxisXPos1, yAxisXPos2;
4981 if (yAxisPos == 1) {
4982 // Main Y axis left
4983 yAxisXPos1 = axmax;
4984 yAxisXPos2 = axmin;
4985 } else {
4986 // Main Y axis right
4987 yAxisXPos1 = axmin;
4988 yAxisXPos2 = axmax;
4989 }
4990
4991 // Paint the main Y axis (always)
4992 uminsave = umin;
4993 umaxsave = umax;
4994 ndivsave = ndiv;
4995 axis.SetOption(chopt);
4996 if (yAxisPos) {
4997 strlcat(chopt, "+L",10);
4998 gridl = -gridl;
4999 }
5000 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
5001 axis.SetLabelSize(0.);
5002 axis.SetTitle("");
5003 }
5004 axis.PaintAxis(yAxisXPos1, aymin,
5005 yAxisXPos1, aymax,
5006 umin, umax, ndiv, chopt, gridl, drawGridOnly);
5007
5008 // Paint the additional Y axis (if needed)
5009 // Additional checks for pad mode are required on iOS: this "second" axis is
5010 // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
5011 if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
5012 if (gPad->GetTicky() < 2) {
5013 strlcat(chopt, "U",10);
5015 } else {
5016 strlcat(chopt, "+L",10);
5017 }
5018 if ((cw=strstr(chopt,"W"))) *cw='z';
5019 axis.SetTitle("");
5020 axis.PaintAxis(yAxisXPos2, aymin,
5021 yAxisXPos2, aymax,
5022 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
5023 }
5024 }//End of "if pad is in selection mode etc."
5025
5026 // Reset the axis if they have been inverted in case of option HBAR
5027 if (xaxis) {
5028 fXaxis = xaxis;
5029 fYaxis = yaxis;
5030 }
5031}
5032
5033////////////////////////////////////////////////////////////////////////////////
5034/// [Draw a bar-chart in a normal pad.](\ref HP10)
5035
5037{
5038
5039 Int_t bar = Hoption.Bar - 10;
5040 Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
5041 Double_t offset = fH->GetBarOffset();
5043 TBox box;
5044 Int_t hcolor = fH->GetFillColor();
5045 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5046 Int_t hstyle = fH->GetFillStyle();
5047 box.SetFillColor(hcolor);
5048 box.SetFillStyle(hstyle);
5049 box.SetLineStyle(fH->GetLineStyle());
5050 box.SetLineColor(fH->GetLineColor());
5051 box.SetLineWidth(fH->GetLineWidth());
5052 for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
5053 y = fH->GetBinContent(bin);
5054 xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
5055 xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
5056 ymin = gPad->GetUymin();
5057 ymax = gPad->YtoPad(y);
5058 if (ymax < gPad->GetUymin()) continue;
5059 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
5060 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
5061 if (Hoption.MinimumZero && ymin < 0)
5062 ymin=TMath::Min(0.,gPad->GetUymax());
5063 w = (xmax-xmin)*width;
5064 xmin += offset*(xmax-xmin);
5065 xmax = xmin + w;
5066 if (bar < 1) {
5067 box.PaintBox(xmin,ymin,xmax,ymax);
5068 } else {
5069 umin = xmin + bar*(xmax-xmin)/10.;
5070 umax = xmax - bar*(xmax-xmin)/10.;
5071 //box.SetFillColor(hcolor+150); //bright
5072 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5073 box.PaintBox(xmin,ymin,umin,ymax);
5074 box.SetFillColor(hcolor);
5075 box.PaintBox(umin,ymin,umax,ymax);
5076 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5077 box.PaintBox(umax,ymin,xmax,ymax);
5078 }
5079 }
5080}
5081
5082////////////////////////////////////////////////////////////////////////////////
5083/// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](\ref HP10)
5084
5086{
5087
5088 gPad->SetVertical(kFALSE);
5089
5090 PaintInitH();
5091
5092 TAxis *xaxis = fXaxis;
5093 TAxis *yaxis = fYaxis;
5094 if (!strcmp(xaxis->GetName(),"xaxis")) {
5095 fXaxis = yaxis;
5096 fYaxis = xaxis;
5097 }
5098
5099 PaintFrame();
5101
5102 Int_t bar = Hoption.Bar - 20;
5103 Double_t xmin,xmax,ymin,ymax,umin,umax,w;
5104 Double_t offset = fH->GetBarOffset();
5106 TBox box;
5107 Int_t hcolor = fH->GetFillColor();
5108 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5109 Int_t hstyle = fH->GetFillStyle();
5110 box.SetFillColor(hcolor);
5111 box.SetFillStyle(hstyle);
5112 box.SetLineStyle(fH->GetLineStyle());
5113 box.SetLineColor(fH->GetLineColor());
5114 box.SetLineWidth(fH->GetLineWidth());
5115 for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
5116 ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
5117 ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
5118 xmin = gPad->GetUxmin();
5119 xmax = gPad->XtoPad(fH->GetBinContent(bin));
5120 if (xmax < gPad->GetUxmin()) continue;
5121 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
5122 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
5123 if (Hoption.MinimumZero && xmin < 0)
5124 xmin=TMath::Min(0.,gPad->GetUxmax());
5125 w = (ymax-ymin)*width;
5126 ymin += offset*(ymax-ymin);
5127 ymax = ymin + w;
5128 if (bar < 1) {
5129 box.PaintBox(xmin,ymin,xmax,ymax);
5130 } else {
5131 umin = ymin + bar*(ymax-ymin)/10.;
5132 umax = ymax - bar*(ymax-ymin)/10.;
5133 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5134 box.PaintBox(xmin,ymin,xmax,umin);
5135 box.SetFillColor(hcolor);
5136 box.PaintBox(xmin,umin,xmax,umax);
5137 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5138 box.PaintBox(xmin,umax,xmax,ymax);
5139 }
5140 }
5141
5142 PaintTitle();
5143
5144 // Draw box with histogram statistics and/or fit parameters
5145 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5146 TIter next(fFunctions);
5147 TObject *obj = 0;
5148 while ((obj = next())) {
5149 if (obj->InheritsFrom(TF1::Class())) break;
5150 obj = 0;
5151 }
5152 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
5153 }
5154
5155 fXaxis = xaxis;
5156 fYaxis = yaxis;
5157}
5158
5159////////////////////////////////////////////////////////////////////////////////
5160/// [Control function to draw a 2D histogram as a box plot](\ref HP13)
5161
5163{
5164
5165 Style_t fillsav = fH->GetFillStyle();