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