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 "TClass.h"
20#include "TSystem.h"
21#include "THistPainter.h"
22#include "TH2.h"
23#include "TH2Poly.h"
24#include "TH3.h"
25#include "TProfile.h"
26#include "TProfile2D.h"
27#include "THStack.h"
28#include "TF2.h"
29#include "TF3.h"
30#include "TCutG.h"
31#include "TMatrixDBase.h"
32#include "TMatrixFBase.h"
33#include "TVectorD.h"
34#include "TVectorF.h"
35#include "TCanvas.h"
36#include "TPad.h"
37#include "TPaveStats.h"
38#include "TFrame.h"
39#include "TLatex.h"
40#include "TLine.h"
41#include "TPolyLine.h"
42#include "TPoints.h"
43#include "TStyle.h"
44#include "TGraph.h"
45#include "TMultiGraph.h"
46#include "TPie.h"
47#include "TGaxis.h"
48#include "TColor.h"
50#include "TGraph2DPainter.h"
51#include "TGraphDelaunay2D.h"
52#include "TView.h"
53#include "TMath.h"
54#include "TRandom2.h"
55#include "TObjArray.h"
56#include "TVectorD.h"
57#include "Hoption.h"
58#include "Hparam.h"
59#include "TPluginManager.h"
60#include "TPaletteAxis.h"
61#include "TCrown.h"
62#include "TArrow.h"
63#include "TVirtualPadEditor.h"
64#include "TEnv.h"
65#include "TPoint.h"
66#include "TImage.h"
67#include "TCandle.h"
68
69/*! \class THistPainter
70\ingroup Histpainter
71\brief The histogram painter class. Implements all histograms' drawing's options.
72
73- [Introduction](#HP00)
74- [Histograms' plotting options](#HP01)
75 - [Options supported for 1D and 2D histograms](#HP01a)
76 - [Options supported for 1D histograms](#HP01b)
77 - [Options supported for 2D histograms](#HP01c)
78 - [Options supported for 3D histograms](#HP01d)
79 - [Options supported for histograms' stacks (THStack)](#HP01e)
80- [Setting the Style](#HP02)
81- [Setting line, fill, marker, and text attributes](#HP03)
82- [Setting Tick marks on the histogram axis](#HP04)
83- [Giving titles to the X, Y and Z axis](#HP05)
84- [The option "SAME"](#HP060)
85 - [Limitations](#HP060a)
86- [Colors automatically picked in palette](#HP061)
87- [Superimposing two histograms with different scales in the same pad](#HP06)
88- [Statistics Display](#HP07)
89- [Fit Statistics](#HP08)
90- [The error bars options](#HP09)
91- [The bar chart option](#HP100)
92- [The "BAR" and "HBAR" options](#HP10)
93- [The SCATter plot option (default for 2D histograms)](#HP11)
94- [The ARRow option](#HP12)
95- [The BOX option](#HP13)
96- [The COLor option](#HP14)
97- [The CANDLE and VIOLIN options](#HP140)
98 - [The CANDLE option](#HP140a)
99 - [The VIOLIN option](#HP140b)
100- [The TEXT and TEXTnn Option](#HP15)
101- [The CONTour options](#HP16)
102 - [The LIST option](#HP16a)
103 - [The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options](#HP16b)
104- [The LEGO options](#HP17)
105- [The "SURFace" options](#HP18)
106- [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](#HP19)
107- [Base line for bar-charts and lego plots](#HP20)
108- [TH2Poly Drawing](#HP20a)
109- [The SPEC option](#HP21)
110- [Option "Z" : Adding the color palette on the right side of the pad](#HP22)
111- [Setting the color palette](#HP23)
112- [Drawing a sub-range of a 2-D histogram; the [cutg] option](#HP24)
113- [Drawing options for 3D histograms](#HP25)
114- [Drawing option for histograms' stacks](#HP26)
115- [Drawing of 3D implicit functions](#HP27)
116- [Associated functions drawing](#HP28)
117- [Drawing using OpenGL](#HP29)
118 - [General information: plot types and supported options](#HP29a)
119 - [TH3 as color boxes](#HP290)
120 - [TH3 as boxes (spheres)](#HP29b)
121 - [TH3 as iso-surface(s)](#HP29c)
122 - [TF3 (implicit function)](#HP29d)
123 - [Parametric surfaces](#HP29e)
124 - [Interaction with the plots](#HP29f)
125 - [Selectable parts](#HP29g)
126 - [Rotation and zooming](#HP29h)
127 - [Panning](#HP29i)
128 - [Box cut](#HP29j)
129 - [Plot specific interactions (dynamic slicing etc.)](#HP29k)
130 - [Surface with option "GLSURF"](#HP29l)
131 - [TF3](#HP29m)
132 - [Box](#HP29n)
133 - [Iso](#HP29o)
134 - [Parametric plot](#HP29p)
135- [Highlight mode for histogram](#HP30)
136 - [Highlight mode and user function](#HP30a)
137
138
139## <a name="HP00"></a> Introduction
140
141
142Histograms are drawn via the `THistPainter` class. Each histogram has a
143pointer to its own painter (to be usable in a multithreaded program). When the
144canvas has to be redrawn, the `Paint` function of each objects in the
145pad is called. In case of histograms, `TH1::Paint` invokes directly
146`THistPainter::Paint`.
147
148To draw a histogram `h` it is enough to do:
149
150 h->Draw();
151
152`h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
153be drawn, the `Draw()` method can be invoked with an option. For instance
154to draw a 2D histogram as a lego plot it is enough to do:
155
156 h->Draw("lego");
157
158`THistPainter` offers many options to paint 1D, 2D and 3D histograms.
159
160When the `Draw()` method of a histogram is called for the first time
161(`TH1::Draw`), it creates a `THistPainter` object and saves a
162pointer to this "painter" as a data member of the histogram. The
163`THistPainter` class specializes in the drawing of histograms. It is
164separated from the histogram so that one can have histograms without the
165graphics overhead, for example in a batch program. Each histogram having its own
166painter (rather than a central singleton painter painting all histograms), allows
167two histograms to be drawn in two threads without overwriting the painter's
168values.
169
170When a displayed histogram is filled again, there is no need to call the
171`Draw()` method again; the image will be refreshed the next time the
172pad will be updated.
173
174A pad is updated after one of these three actions:
175
1761. a carriage control on the ROOT command line,
1772. a click inside the pad,
1783. a call to `TPad::Update`.
179
180
181By default a call to `TH1::Draw()` clears the pad of all objects
182before drawing the new image of the histogram. One can use the `SAME`
183option to leave the previous display intact and superimpose the new histogram.
184The same histogram can be drawn with different graphics options in different
185pads.
186
187When a displayed histogram is deleted, its image is automatically removed
188from the pad.
189
190To create a copy of the histogram when drawing it, one can use
191`TH1::DrawClone()`. This will clone the histogram and allow to change
192and delete the original one without affecting the clone.
193
194
195### <a name="HP01"></a> Histograms' plotting options
196
197
198Most options can be concatenated with or without spaces or commas, for example:
199
200 h->Draw("E1 SAME");
201
202The options are not case sensitive:
203
204 h->Draw("e1 same");
205
206
207The default drawing option can be set with `TH1::SetOption` and retrieve
208using `TH1::GetOption`:
209
210 root [0] h->Draw(); // Draw "h" using the standard histogram representation.
211 root [1] h->Draw("E"); // Draw "h" using error bars
212 root [3] h->SetOption("E"); // Change the default drawing option for "h"
213 root [4] h->Draw(); // Draw "h" using error bars
214 root [5] h->GetOption(); // Retrieve the default drawing option for "h"
215 (const Option_t* 0xa3ff948)"E"
216
217
218#### <a name="HP01a"></a> Options supported for 1D and 2D histograms
219
220| Option | Description |
221|----------|-------------------------------------------------------------------|
222| "E" | Draw error bars. |
223| "AXIS" | Draw only axis. |
224| "AXIG" | Draw only grid (if the grid is requested). |
225| <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). |
226| "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
227| "SAME" | Superimpose on previous picture in the same pad. |
228| "SAMES" | Same as "SAME" and draw the statistics box|
229| "PFC" | Palette Fill Color: histogram's fill color is taken in the current palette. |
230| "PLC" | Palette Line Color: histogram's line color is taken in the current palette. |
231| "PMC" | Palette Marker Color: histogram's marker color is taken in the current palette. |
232| "LEGO" | Draw a lego plot with hidden line removal. |
233| "LEGO1" | Draw a lego plot with hidden surface removal. |
234| "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.|
235| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
236| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
237| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
238| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
239| "X+" | The X-axis is drawn on the top side of the plot. |
240| "Y+" | The Y-axis is drawn on the right side of the plot. |
241| "MIN0" | Set minimum value for the Y axis to 0, equivalent to gStyle->SetHistMinimumZero(). |
242
243#### <a name="HP01b"></a> Options supported for 1D histograms
244
245| Option | Description |
246|----------|-------------------------------------------------------------------|
247| " " | Default. |
248| "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.|
249| "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
250| "B" | Bar chart option.|
251| "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
252| "HBAR" | Like option "BAR", but bars are drawn horizontally.|
253| "C" | Draw a smooth Curve through the histogram bins.|
254| "E0" | Draw error bars. Markers are drawn for bins with 0 contents.|
255| "E1" | Draw error bars with perpendicular lines at the edges.|
256| "E2" | Draw error bars with rectangles.|
257| "E3" | Draw a fill area through the end points of the vertical error bars.|
258| "E4" | Draw a smoothed filled area through the end points of the error bars.|
259| "E5" | Like E3 but ignore the bins with 0 contents.|
260| "E6" | Like E4 but ignore the bins with 0 contents.|
261| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
262| "L" | Draw a line through the bin contents.|
263| "P" | Draw current marker at each bin except empty bins.|
264| "P0" | Draw current marker at each bin including empty bins.|
265| "PIE" | Draw histogram as a Pie Chart.|
266| "*H" | Draw histogram with a * at each bin.|
267| "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.|
268
269
270#### <a name="HP01c"></a> Options supported for 2D histograms
271
272| Option | Description |
273|-----------|------------------------------------------------------------------|
274| " " | Default (scatter plot).|
275| "ARR" | Arrow mode. Shows gradient between adjacent cells.|
276| "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.|
277| "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.|
278| "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.|
279| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
280| "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
281| "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
282| "Z CJUST" | In combination with colored options "COL","CONT0" etc: Justify labels in the color palette at color boudaries. For more details see `TPaletteAxis`|
283| "CANDLE" | Draw a candle plot along X axis.|
284| "CANDLEX" | Same as "CANDLE".|
285| "CANDLEY" | Draw a candle plot along Y axis.|
286| "CANDLEXn"| Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
287| "CANDLEYn"| Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
288| "VIOLIN" | Draw a violin plot along X axis.|
289| "VIOLINX" | Same as "VIOLIN".|
290| "VIOLINY" | Draw a violin plot along Y axis.|
291| "VIOLINXn"| Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
292| "VIOLINYn"| Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
293| "CONT" | Draw a contour plot (same as CONT0).|
294| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
295| "CONT1" | Draw a contour plot using line styles to distinguish contours.|
296| "CONT2" | Draw a contour plot using the same line style for all contours.|
297| "CONT3" | Draw a contour plot using fill area colors.|
298| "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
299| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
300| "LIST" | Generate a list of TGraph objects for each contour.|
301| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
302| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
303| "SAME0" | Same as "SAME" but do not use the z-axis range of the first plot. |
304| "SAMES0" | Same as "SAMES" but do not use the z-axis range of the first plot. |
305| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
306| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
307| "SURF" | Draw a surface plot with hidden line removal.|
308| "SURF1" | Draw a surface plot with hidden surface removal.|
309| "SURF2" | Draw a surface plot using colors to show the cell contents.|
310| "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
311| "SURF4" | Draw a surface using Gouraud shading.|
312| "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.|
313| "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
314| "FB" | With LEGO or SURFACE, suppress the Front-Box.|
315| "BB" | With LEGO or SURFACE, suppress the Back-Box.|
316| "A" | With LEGO or SURFACE, suppress the axis.|
317| "SCAT" | Draw a scatter-plot (default).|
318| "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
319
320
321#### <a name="HP01d"></a> Options supported for 3D histograms
322
323| Option | Description |
324|----------|-------------------------------------------------------------------|
325| " " | Default (scatter plot).|
326| "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)`.|
327| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
328| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
329| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
330| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
331| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
332| "LEGO" | Same as `BOX`.|
333
334
335#### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
336
337| Option | Description |
338|------------|-----------------------------------------------------------------|
339| " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
340| "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
341| "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
342| "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.|
343| "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
344| "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
345| "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
346
347
348
349### <a name="HP02"></a> Setting the Style
350
351
352Histograms use the current style (`gStyle`). When one changes the current
353style and would like to propagate the changes to the histogram,
354`TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
355each histogram is needed.
356
357To force all the histogram to use the current style use:
358
359 gROOT->ForceStyle();
360
361All the histograms read after this call will use the current style.
362
363
364### <a name="HP03"></a> Setting line, fill, marker, and text attributes
365
366
367The histogram classes inherit from the attribute classes:
368`TAttLine`, `TAttFill` and `TAttMarker`.
369See the description of these classes for the list of options.
370
371
372### <a name="HP04"></a> Setting Tick marks on the histogram axis
373
374
375The `TPad::SetTicks` method specifies the type of tick marks on the axis.
376If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
377
378 tx = 1; tick marks on top side are drawn (inside)
379 tx = 2; tick marks and labels on top side are drawn
380 ty = 1; tick marks on right side are drawn (inside)
381 ty = 2; tick marks and labels on right side are drawn
382
383By default only the left Y axis and X bottom axis are drawn
384(`tx = ty = 0`)
385
386`TPad::SetTicks(tx,ty)` allows to set these options.
387See also The `TAxis` functions to set specific axis attributes.
388
389In case multiple color filled histograms are drawn on the same pad, the fill
390area may hide the axis tick marks. One can force a redraw of the axis over all
391the histograms by calling:
392
393 gPad->RedrawAxis();
394
395
396### <a name="HP05"></a> Giving titles to the X, Y and Z axis
397
398
399 h->GetXaxis()->SetTitle("X axis title");
400 h->GetYaxis()->SetTitle("Y axis title");
401
402The histogram title and the axis titles can be any `TLatex` string.
403The titles are part of the persistent histogram.
404
405
406### <a name="HP060"></a> The option "SAME"
407
408
409By default, when an histogram is drawn, the current pad is cleared before
410drawing. In order to keep the previous drawing and draw on top of it the
411option `SAME` should be use. The histogram drawn with the option
412`SAME` uses the coordinates system available in the current pad.
413
414This option can be used alone or combined with any valid drawing option but
415some combinations must be use with care.
416
417#### <a name="HP060a"></a> Limitations
418
419- It does not work when combined with the `LEGO` and `SURF` options unless the
420 histogram plotted with the option `SAME` has exactly the same
421 ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
422 lego plots [histograms' stacks](#HP26) should be used.</li>
423
424
425### <a name="HP061"></a> Colors automatically picked in palette
426
427\since **ROOT version 6.09/01**
428
429When several histograms are painted in the same canvas thanks to the option "SAME"
430or via a `THStack` it might be useful to have an easy and automatic way to choose
431their color. The simplest way is to pick colors in the current active color
432palette. Palette coloring for histogram is activated thanks to the options `PFC`
433(Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
434When one of these options is given to `TH1::Draw` the histogram get its color
435from the current color palette defined by `gStyle->SetPalette(…)`. The color
436is determined according to the number of objects having palette coloring in
437the current pad.
438
439Begin_Macro(source)
440../../../tutorials/hist/histpalettecolor.C
441End_Macro
442
443Begin_Macro(source)
444../../../tutorials/hist/thstackpalettecolor.C
445End_Macro
446
447Begin_Macro(source)
448../../../tutorials/hist/thstack2palettecolor.C
449End_Macro
450
451### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
452
453
454The following example creates two histograms, the second histogram is the bins
455integral of the first one. It shows a procedure to draw the two histograms in
456the same pad and it draws the scale of the second histogram using a new vertical
457axis on the right side. See also the tutorial `transpad.C` for a variant
458of this example.
459
460Begin_Macro(source)
461{
462 auto c1 = new TCanvas("c1","c1",600,400);
463 // create/fill draw h1
464 gStyle->SetOptStat(kFALSE);
465 auto h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
466 Int_t i;
467 for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
468 h1->Draw();
469 c1->Update();
470
471 // create hint1 filled with the bins integral of h1
472 auto hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
473 float sum = 0.f;
474 for (i=1;i<=100;i++) {
475 sum += h1->GetBinContent(i);
476 hint1->SetBinContent(i,sum);
477 }
478
479 // scale hint1 to the pad coordinates
480 float rightmax = 1.1*hint1->GetMaximum();
481 float scale = gPad->GetUymax()/rightmax;
482 hint1->SetLineColor(kRed);
483 hint1->Scale(scale);
484 hint1->Draw("same");
485
486 // draw an axis on the right side
487 auto axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
488 gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
489 axis->SetLineColor(kRed);
490 axis->SetTextColor(kRed);
491 axis->Draw();
492}
493End_Macro
494
495
496### <a name="HP07"></a> Statistics Display
497
498
499The type of information shown in the histogram statistics box can be selected
500with:
501
502 gStyle->SetOptStat(mode);
503
504The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
505
506 mode = ksiourmen (default = 000001111)
507 k = 1; kurtosis printed
508 k = 2; kurtosis and kurtosis error printed
509 s = 1; skewness printed
510 s = 2; skewness and skewness error printed
511 i = 1; integral of bins printed
512 i = 2; integral of bins with option "width" printed
513 o = 1; number of overflows printed
514 u = 1; number of underflows printed
515 r = 1; standard deviation printed
516 r = 2; standard deviation and standard deviation error printed
517 m = 1; mean value printed
518 m = 2; mean and mean error values printed
519 e = 1; number of entries printed
520 n = 1; name of histogram is printed
521
522For example:
523
524 gStyle->SetOptStat(11);
525
526displays only the name of histogram and the number of entries, whereas:
527
528 gStyle->SetOptStat(1101);
529
530displays the name of histogram, mean value and standard deviation.
531
532<b>WARNING 1:</b> never do:
533
534 gStyle->SetOptStat(0001111);
535
536but instead do:
537
538 gStyle->SetOptStat(1111);
539
540because `0001111` will be taken as an octal number!
541
542<b>WARNING 2:</b> for backward compatibility with older versions
543
544 gStyle->SetOptStat(1);
545
546is taken as:
547
548 gStyle->SetOptStat(1111)
549
550To print only the name of the histogram do:
551
552 gStyle->SetOptStat(1000000001);
553
554<b>NOTE</b> that in case of 2D histograms, when selecting only underflow
555(10000) or overflow (100000), the statistics box will show all combinations
556of underflow/overflows and not just one single number.
557
558The parameter mode can be any combination of the letters `kKsSiIourRmMen`
559
560 k : kurtosis printed
561 K : kurtosis and kurtosis error printed
562 s : skewness printed
563 S : skewness and skewness error printed
564 i : integral of bins printed
565 I : integral of bins with option "width" printed
566 o : number of overflows printed
567 u : number of underflows printed
568 r : standard deviation printed
569 R : standard deviation and standard deviation error printed
570 m : mean value printed
571 M : mean value mean error values printed
572 e : number of entries printed
573 n : name of histogram is printed
574
575For example, to print only name of histogram and number of entries do:
576
577 gStyle->SetOptStat("ne");
578
579To print only the name of the histogram do:
580
581 gStyle->SetOptStat("n");
582
583The default value is:
584
585 gStyle->SetOptStat("nemr");
586
587When a histogram is painted, a `TPaveStats` object is created and added
588to the list of functions of the histogram. If a `TPaveStats` object
589already exists in the histogram list of functions, the existing object is just
590updated with the current histogram parameters.
591
592Once a histogram is painted, the statistics box can be accessed using
593`h->FindObject("stats")`. In the command line it is enough to do:
594
595 Root > h->Draw()
596 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
597
598because after `h->Draw()` the histogram is automatically painted. But
599in a script file the painting should be forced using `gPad->Update()`
600in order to make sure the statistics box is created:
601
602 h->Draw();
603 gPad->Update();
604 TPaveStats *st = (TPaveStats*)h->FindObject("stats");
605
606Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
607
608When a histogram is drawn with the option `SAME`, the statistics box
609is not drawn. To force the statistics box drawing with the option
610`SAME`, the option `SAMES` must be used.
611If the new statistics box hides the previous statistics box, one can change
612its position with these lines (`h` being the pointer to the histogram):
613
614 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
615 Root > st->SetX1NDC(newx1); //new x start position
616 Root > st->SetX2NDC(newx2); //new x end position
617
618To change the type of information for an histogram with an existing
619`TPaveStats` one should do:
620
621 st->SetOptStat(mode);
622
623Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
624(see above).
625
626One can delete the statistics box for a histogram `TH1* h` with:
627
628 h->SetStats(0)
629
630and activate it again with:
631
632 h->SetStats(1).
633
634Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
635`$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
636
637
638### <a name="HP08"></a> Fit Statistics
639
640
641The type of information about fit parameters printed in the histogram statistics
642box can be selected via the parameter mode. The parameter mode can be
643`= pcev` (default `= 0111`)
644
645 p = 1; print Probability
646 c = 1; print Chisquare/Number of degrees of freedom
647 e = 1; print errors (if e=1, v must be 1)
648 v = 1; print name/values of parameters
649
650Example:
651
652 gStyle->SetOptFit(1011);
653
654print fit probability, parameter names/values and errors.
655
6561. When `v" = 1` is specified, only the non-fixed parameters are shown.
6572. When `v" = 2` all parameters are shown.
658
659Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
660to `gStyle->SetOptFit(111)`
661
662
663### <a name="HP09"></a> The error bars options
664
665
666| Option | Description |
667|----------|-------------------------------------------------------------------|
668| "E" | Default. Shows only the error bars, not a marker.|
669| "E1" | Small lines are drawn at the end of the error bars.|
670| "E2" | Error rectangles are drawn.|
671| "E3" | A filled area is drawn through the end points of the vertical error bars.|
672| "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
673| "E0" | Draw also bins with null contents.|
674
675Begin_Macro(source)
676{
677 auto c1 = new TCanvas("c1","c1",600,400);
678 auto he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
679 for (int i=0; i<10000; i++) he->Fill(gRandom->Gaus(0,1));
680 gStyle->SetEndErrorSize(3);
681 gStyle->SetErrorX(1.);
682 he->SetMarkerStyle(20);
683 he->Draw("E1");
684}
685End_Macro
686
687The options "E3" and "E4" draw an error band through the end points of the
688vertical error bars. With "E4" the error band is smoothed. Because of the
689smoothing algorithm used some artefacts may appear at the end of the band
690like in the following example. In such cases "E3" should be used instead
691of "E4".
692
693Begin_Macro(source)
694{
695 auto ce4 = new TCanvas("ce4","ce4",600,400);
696 ce4->Divide(2,1);
697 auto he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
698 Int_t i;
699 for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
700 he4->SetFillColor(kRed);
701 he4->GetXaxis()->SetRange(40,48);
702 ce4->cd(1);
703 he4->Draw("E4");
704 ce4->cd(2);
705 auto he3 = (TH1F*)he4->DrawClone("E3");
706 he3->SetTitle("Distribution drawn option E3");
707}
708End_Macro
709
7102D histograms can be drawn with error bars as shown is the following example:
711
712Begin_Macro(source)
713{
714 auto c2e = new TCanvas("c2e","c2e",600,400);
715 auto h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
716 float px, py;
717 for (Int_t i = 0; i < 25000; i++) {
718 gRandom->Rannor(px,py);
719 h2e->Fill(px,5*py);
720 }
721 h2e->Draw("E");
722}
723End_Macro
724
725
726### <a name="HP100"></a> The bar chart option
727
728
729The option "B" allows to draw simple vertical bar charts.
730The bar width is controlled with `TH1::SetBarWidth()`,
731and the bar offset within the bin, with `TH1::SetBarOffset()`.
732These two settings are useful to draw several histograms on the
733same plot as shown in the following example:
734
735Begin_Macro(source)
736{
737 int i;
738 const Int_t nx = 8;
739 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
740 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
741 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
742
743 auto cb = new TCanvas("cb","cb",600,400);
744 cb->SetGrid();
745
746 gStyle->SetHistMinimumZero();
747
748 auto h1b = new TH1F("h1b","Option B example",nx,0,nx);
749 h1b->SetFillColor(4);
750 h1b->SetBarWidth(0.4);
751 h1b->SetBarOffset(0.1);
752 h1b->SetStats(0);
753 h1b->SetMinimum(-5);
754 h1b->SetMaximum(5);
755
756 for (i=1; i<=nx; i++) {
757 h1b->SetBinContent(i, d_35_0[i-1]);
758 h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
759 }
760
761 h1b->Draw("b");
762
763 auto h2b = new TH1F("h2b","h2b",nx,0,nx);
764 h2b->SetFillColor(38);
765 h2b->SetBarWidth(0.4);
766 h2b->SetBarOffset(0.5);
767 h2b->SetStats(0);
768 for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
769
770 h2b->Draw("b same");
771}
772End_Macro
773
774
775### <a name="HP10"></a> The "BAR" and "HBAR" options
776
777
778When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
779bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
780An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
781`hbar2`, `hbar3`, `hbar4` (hbars.C).
782
783- The bar is filled with the histogram fill color.
784- The left side of the bar is drawn with a light fill color.
785- The right side of the bar is drawn with a dark fill color.
786- The percentage of the bar drawn with either the light or dark color is:
787 - 0% for option "(h)bar" or "(h)bar0"
788 - 10% for option "(h)bar1"
789 - 20% for option "(h)bar2"
790 - 30% for option "(h)bar3"
791 - 40% for option "(h)bar4"
792
793When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
794
795Begin_Macro(source)
796../../../tutorials/hist/hbars.C
797End_Macro
798
799To control the bar width (default is the bin width) `TH1::SetBarWidth()`
800should be used.
801
802To control the bar offset (default is 0) `TH1::SetBarOffset()` should
803be used.
804
805These two parameters are useful when several histograms are plotted using
806the option `SAME`. They allow to plot the histograms next to each other.
807
808
809### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
810
811
812For each cell (i,j) a number of points proportional to the cell content is
813drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
814`kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
815If option is of the form `scat=ff`, (eg `scat=1.8`,
816`scat=1e-3`), then `ff` is used as a scale factor to compute the
817number of dots. `scat=1` is the default.
818
819By default the scatter plot is painted with a "dot marker" which not scalable
820(see the `TAttMarker` documentation). To change the marker size, a scalable marker
821type should be used. For instance a circle (marker style 20).
822
823Begin_Macro(source)
824{
825 auto c1 = new TCanvas("c1","c1",600,400);
826 auto hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
827 float px, py;
828 for (Int_t i = 0; i < 25000; i++) {
829 gRandom->Rannor(px,py);
830 hscat->Fill(px,5*py);
831 hscat->Fill(3+0.5*px,2*py-10.);
832 }
833 hscat->Draw("scat=0.5");
834}
835End_Macro
836
837
838### <a name="HP12"></a> The ARRow option
839
840
841Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
842The orientation of the arrow follows the cell gradient.
843
844Begin_Macro(source)
845{
846 auto c1 = new TCanvas("c1","c1",600,400);
847 auto harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
848 harr->SetLineColor(kRed);
849 float px, py;
850 for (Int_t i = 0; i < 25000; i++) {
851 gRandom->Rannor(px,py);
852 harr->Fill(px,5*py);
853 harr->Fill(3+0.5*px,2*py-10.,0.1);
854 }
855 harr->Draw("ARR");
856}
857End_Macro
858
859\since **ROOT version 6.17/01**
860
861The option `ARR` can be combined with the option `COL` or `COLZ`.
862
863Begin_Macro(source)
864{
865 auto c1 = new TCanvas("c1","c1",600,400);
866 auto harr = new TH2F("harr","Option ARR + COLZ example",20,-4,4,20,-20,20);
867 harr->SetStats(0);
868 float px, py;
869 for (Int_t i = 0; i < 25000; i++) {
870 gRandom->Rannor(px,py);
871 harr->Fill(px,5*py);
872 harr->Fill(3+0.5*px,2*py-10.,0.1);
873 }
874 harr->Draw("ARR COLZ");
875}
876End_Macro
877
878
879### <a name="HP13"></a> The BOX option
880
881
882For each cell (i,j) a box is drawn. The size (surface) of the box is
883proportional to the absolute value of the cell content.
884The cells with a negative content are drawn with a `X` on top of the box.
885
886Begin_Macro(source)
887{
888 auto c1 = new TCanvas("c1","c1",600,400);
889 auto hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
890 hbox->SetFillColor(42);
891 hbox->Fill(0.5, 0.5, 1.);
892 hbox->Fill(0.5, 1.5, 4.);
893 hbox->Fill(0.5, 2.5, 3.);
894 hbox->Fill(1.5, 0.5, 2.);
895 hbox->Fill(1.5, 1.5, 12.);
896 hbox->Fill(1.5, 2.5, -6.);
897 hbox->Fill(2.5, 0.5, -4.);
898 hbox->Fill(2.5, 1.5, 6.);
899 hbox->Fill(2.5, 2.5, 0.5);
900 hbox->Draw("BOX");
901}
902End_Macro
903
904With option `BOX1` a button is drawn for each cell with surface
905proportional to content's absolute value. A sunken button is drawn for
906negative values a raised one for positive.
907
908Begin_Macro(source)
909{
910 auto c1 = new TCanvas("c1","c1",600,400);
911 auto hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
912 hbox1->SetFillColor(42);
913 hbox1->Fill(0.5, 0.5, 1.);
914 hbox1->Fill(0.5, 1.5, 4.);
915 hbox1->Fill(0.5, 2.5, 3.);
916 hbox1->Fill(1.5, 0.5, 2.);
917 hbox1->Fill(1.5, 1.5, 12.);
918 hbox1->Fill(1.5, 2.5, -6.);
919 hbox1->Fill(2.5, 0.5, -4.);
920 hbox1->Fill(2.5, 1.5, 6.);
921 hbox1->Fill(2.5, 2.5, 0.5);
922 hbox1->Draw("BOX1");
923}
924End_Macro
925
926When the option `SAME` (or "SAMES") is used with the option `BOX`,
927the boxes' sizes are computing taking the previous plots into account. The range
928along the Z axis is imposed by the first plot (the one without option
929`SAME`); therefore the order in which the plots are done is relevant.
930
931Begin_Macro(source)
932{
933 auto c1 = new TCanvas("c1","c1",600,400);
934 auto hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
935 auto hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
936 auto hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
937 auto hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
938 for (Int_t i=0;i<1000;i++) {
939 double x,y;
940 gRandom->Rannor(x,y);
941 if (x>0 && y>0) hb1->Fill(x,y,4);
942 if (x<0 && y<0) hb2->Fill(x,y,3);
943 if (x>0 && y<0) hb3->Fill(x,y,2);
944 if (x<0 && y>0) hb4->Fill(x,y,1);
945 }
946 hb1->SetFillColor(1);
947 hb2->SetFillColor(2);
948 hb3->SetFillColor(3);
949 hb4->SetFillColor(4);
950 hb1->Draw("box");
951 hb2->Draw("box same");
952 hb3->Draw("box same");
953 hb4->Draw("box same");
954}
955End_Macro
956
957\since **ROOT version 6.17/01:**
958
959Sometimes the change of the range of the Z axis is unwanted, in which case, one
960can use `SAME0` (or `SAMES0`) option to opt out of this change.
961
962Begin_Macro(source)
963{
964 auto h2 = new TH2F("h2"," ",10,0,10,10,20,30);
965 auto hf = (TH2F*)h2->Clone("hf");
966 h2->SetBit(TH1::kNoStats);
967 hf->SetBit(TH1::kNoStats);
968 h2->Fill(5,22);
969 h2->Fill(5,23);
970 h2->Fill(6,22);
971 h2->Fill(6,23);
972 hf->Fill(6,23);
973 hf->Fill(6,23);
974 hf->Fill(6,23);
975 hf->Fill(6,23);
976 hf->Fill(5,23);
977
978 auto hf_copy1 = hf->Clone("hf_copy1");
979 auto lt = new TLatex();
980
981 auto cx = new TCanvas(); cx->Divide(2,1);
982
983 cx->cd(1);
984 h2->Draw("box");
985 hf->Draw("text colz same");
986 lt->DrawLatexNDC(0.3,0.5,"SAME");
987
988 cx->cd(2);
989 h2->Draw("box");
990 hf_copy1->Draw("text colz same0");
991 lt->DrawLatexNDC(0.3,0.5,"SAME0");
992}
993End_Macro
994
995
996### <a name="HP14"></a> The COLor option
997
998
999For each cell (i,j) a box is drawn with a color proportional to the cell
1000content.
1001
1002The color table used is defined in the current style.
1003
1004If the histogram's minimum and maximum are the same (flat histogram), the
1005mapping on colors is not possible, therefore nothing is painted. To paint a
1006flat histogram it is enough to set the histogram minimum
1007(`TH1::SetMinimum()`) different from the bins' content.
1008
1009The default number of color levels used to paint the cells is 20.
1010It can be changed with `TH1::SetContour()` or
1011`TStyle::SetNumberContours()`. The higher this number is, the smoother
1012is the color change between cells.
1013
1014The color palette in TStyle can be modified via `gStyle->SetPalette()`.
1015
1016All the non-empty bins are painted. Empty bins are not painted unless
1017some bins have a negative content because in that case the null bins
1018might be not empty.
1019
1020`TProfile2D` histograms are handled differently because, for this type of 2D
1021histograms, it is possible to know if an empty bin has been filled or not. So even
1022if all the bins' contents are positive some empty bins might be painted. And vice versa,
1023if some bins have a negative content some empty bins might be not painted.
1024
1025Combined with the option `COL`, the option `Z` allows to
1026display the color palette defined by `gStyle->SetPalette()`.
1027
1028In the following example, the histogram has only positive bins; the empty
1029bins (containing 0) are not drawn.
1030
1031Begin_Macro(source)
1032{
1033 auto c1 = new TCanvas("c1","c1",600,400);
1034 auto hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
1035 float px, py;
1036 for (Int_t i = 0; i < 25000; i++) {
1037 gRandom->Rannor(px,py);
1038 hcol1->Fill(px,5*py);
1039 }
1040 hcol1->Draw("COLZ");
1041}
1042End_Macro
1043
1044In the first plot of following example, the histogram has some negative bins;
1045the empty bins (containing 0) are drawn. In some cases one wants to not draw
1046empty bins (containing 0) of histograms having a negative minimum. The option
1047`1`, used to produce the second plot in the following picture, allows to do that.
1048
1049Begin_Macro(source)
1050{
1051 auto c1 = new TCanvas("c1","c1",600,600);
1052 c1->Divide(1,2);
1053 auto hcol23 = new TH2F("hcol23","Option COLZ example ",40,-4,4,40,-20,20);
1054 auto hcol24 = new TH2F("hcol24","Option COLZ1 example ",40,-4,4,40,-20,20);
1055 float px, py;
1056 for (Int_t i = 0; i < 25000; i++) {
1057 gRandom->Rannor(px,py);
1058 hcol23->Fill(px,5*py);
1059 hcol24->Fill(px,5*py);
1060 }
1061 hcol23->Fill(0.,0.,-200.);
1062 hcol24->Fill(0.,0.,-200.);
1063 c1->cd(1); hcol23->Draw("COLZ");
1064 c1->cd(2); hcol24->Draw("COLZ1");
1065}
1066End_Macro
1067
1068When the maximum of the histogram is set to a smaller value than the real maximum,
1069 the bins having a content between the new maximum and the real maximum are
1070painted with the color corresponding to the new maximum.
1071
1072When the minimum of the histogram is set to a greater value than the real minimum,
1073 the bins having a value between the real minimum and the new minimum are not drawn
1074 unless the option `0` is set.
1075
1076The following example illustrates the option `0` combined with the option `COL`.
1077
1078Begin_Macro(source)
1079{
1080 auto c1 = new TCanvas("c1","c1",600,600);
1081 c1->Divide(1,2);
1082 auto hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1083 auto hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1084 float px, py;
1085 for (Int_t i = 0; i < 25000; i++) {
1086 gRandom->Rannor(px,py);
1087 hcol21->Fill(px,5*py);
1088 hcol22->Fill(px,5*py);
1089 }
1090 hcol21->SetBit(TH1::kNoStats);
1091 hcol22->SetBit(TH1::kNoStats);
1092 c1->cd(1); hcol21->Draw("COLZ");
1093 c1->cd(2); hcol22->Draw("COLZ0");
1094 hcol22->SetMaximum(100);
1095 hcol22->SetMinimum(40);
1096}
1097End_Macro
1098
1099\since **ROOT version 6.09/01:**
1100
1101When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1102are computing taking the previous plots into account. The range along the Z axis
1103is imposed by the first plot (the one without option SAME); therefore the order
1104in which the plots are done is relevant. Same as [in the `BOX` option](#HP13), one can use
1105`SAME0` (or `SAMES0`) to opt out of this imposition.
1106
1107Begin_Macro(source)
1108{
1109 auto c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1110 auto h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1111 auto h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1112 auto h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1113 auto h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1114 h1->SetBit(TH1::kNoStats);
1115 for (Int_t i=0;i<5000;i++) {
1116 double x,y;
1117 gRandom->Rannor(x,y);
1118 if(x>0 && y>0) h1->Fill(x,y,4);
1119 if(x<0 && y<0) h2->Fill(x,y,3);
1120 if(x>0 && y<0) h3->Fill(x,y,2);
1121 if(x<0 && y>0) h4->Fill(x,y,1);
1122 }
1123 h1->Draw("colz");
1124 h2->Draw("col same");
1125 h3->Draw("col same");
1126 h4->Draw("col same");
1127}
1128End_Macro
1129
1130The option `COL` can be combined with the option `POL`:
1131
1132Begin_Macro(source)
1133{
1134 auto c1 = new TCanvas("c1","c1",600,400);
1135 auto hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1136 float px, py;
1137 for (Int_t i = 0; i < 25000; i++) {
1138 gRandom->Rannor(px,py);
1139 hcol1->Fill(px,py);
1140 }
1141 hcol1->Draw("COLZPOL");
1142}
1143End_Macro
1144
1145\since **ROOT version 6.07/03:**
1146
1147A second rendering technique is also available with the COL2 and COLZ2 options.
1148
1149These options provide potential performance improvements compared to the standard
1150COL option. The performance comparison of the COL2 to the COL option depends on
1151the histogram and the size of the rendering region in the current pad. In general,
1152a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1153faster with the COL option.
1154
1155However, for larger histograms (approx. more than 100 bins per axis)
1156that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1157For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1158faster with the COL2 option.
1159
1160The COL2 option will also scale its performance based on the size of the
1161pixmap the histogram image is being rendered into. It also is much better optimized for
1162sessions where the user is forwarding X11 windows through an `ssh` connection.
1163
1164For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1165and COLZ options. There is one major difference and that concerns the treatment of
1166bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1167
1168COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1169graphics file format like PostScript or PDF (an empty image will be generated). It can
1170be saved only in bitmap files like PNG format for instance.
1171
1172
1173### <a name="HP140"></a> The CANDLE and VIOLIN options
1174
1175The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1176implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1177the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1178vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1179(1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1180
1181Instead of using the predefined representations, the candle and violin parameters can be
1182changed individually. In that case the option have the following form:
1183
1184 CANDLEX(<option-string>)
1185 CANDLEY(<option-string>)
1186 VIOLINX(<option-string>)
1187 VIOLINY(<option-string>).
1188
1189All zeros at the beginning of `option-string` can be omitted.
1190
1191`option-string` consists eight values, defined as follow:
1192
1193 "CANDLEX(zhpawMmb)"
1194
1195Where:
1196
1197 - `b = 0`; no box drawn
1198 - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1199 makes sense in the very most cases to always draw the box
1200 - `b = 2`; draw a filled box with border
1201
1202 - `m = 0`; no median drawn
1203 - `m = 1`; median is drawn as a line
1204 - `m = 2`; median is drawn with errors (notches)
1205 - `m = 3`; median is drawn as a circle
1206
1207 - `M = 0`; no mean drawn
1208 - `M = 1`; mean is drawn as a dashed line
1209 - `M = 3`; mean is drawn as a circle
1210
1211 - `w = 0`; no whisker drawn
1212 - `w = 1`; whisker is drawn to end of distribution.
1213 - `w = 2`; whisker is drawn to max 1.5*iqr
1214
1215 - `a = 0`; no anchor drawn
1216 - `a = 1`; the anchors are drawn
1217
1218 - `p = 0`; no points drawn
1219 - `p = 1`; only outliers are drawn
1220 - `p = 2`; all datapoints are drawn
1221 - `p = 3`: all datapoints are drawn scattered
1222
1223 - `h = 0`; no histogram is drawn
1224 - `h = 1`; histogram at the left or bottom side is drawn
1225 - `h = 2`; histogram at the right or top side is drawn
1226 - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1227
1228 - `z = 0`; no zero indicator line is drawn
1229 - `z = 1`; zero indicator line is drawn.
1230
1231As one can see all individual options for both candle and violin plots can be accessed by this
1232mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1233meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1234vice versa, if you wish.
1235
1236Using a logarithmic x- or y-axis is possible for candle and violin charts.
1237
1238\since **ROOT version 6.11/01**
1239
1240a logarithmic z-axis is possible, too but will only affect violin charts of course.
1241
1242#### <a name="HP140a"></a> The CANDLE option
1243
1244<a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1245a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1246way to describe graphically a data distribution (D) with only five numbers:
1247
1248 1. The minimum value of the distribution D (bottom or left whisker).
1249 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1250 3. The median (M): 50% of the data points in D are less than M.
1251 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1252 5. The maximum value of the distribution D (top or right whisker).
1253
1254In this implementation a TH2 is considered as a collection of TH1 along
1255X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1256Each TH1 is represented as one candle.
1257
1258Begin_Macro(source)
1259../../../tutorials/hist/candleplotwhiskers.C
1260End_Macro
1261
1262The candle reduces the information coming from a whole distribution into few values.
1263Independently from the number of entries or the significance of the underlying distribution
1264a candle will always look like a candle. So candle plots should be used carefully in
1265particular with unknown distributions. The definition of a candle is based on
1266__unbinned data__. Here, candles are created from binned data. Because of this, the
1267deviation is connected to the bin width used. The calculation of the quantiles
1268normally done on unbinned data also. Because data are binned, this will
1269only work the best possible way within the resolution of one bin
1270
1271Because of all these facts one should take care that:
1272
1273 - there are enough points per candle
1274 - the bin width is small enough (more bins will increase the maximum
1275 available resolution of the quantiles although there will be some
1276 bins with no entries)
1277 - never make a candle-plot if the underlying distribution is double-distributed
1278 - only create candles of distributions that are more-or-less gaussian (the
1279 MPV should be not too far away from the mean).
1280
1281#### What a candle is made of
1282
1283\since **ROOT version 6.07/05**
1284
1285##### The box
1286The box displays the position of the inter-quantile-range of the underlying
1287distribution. The box contains 25% of the distribution below the median
1288and 25% of the distribution above the median. If the underlying distribution is large
1289enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1290(Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1291the position of the box can be modified by SetBarWidth() and SetBarOffset().
1292The +-25% quantiles are calculated by the GetQuantiles() methods.
1293
1294\since **ROOT version 6.11/01**
1295
1296Using the static function TCandle::SetBoxRange(double) the box definition will be
1297overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1298to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1299The static function will affect all candle-charts in the running program.
1300Default is 0.5.
1301
1302Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1303whole candle) can be influenced. Deactivated, the width is constant (to be set by
1304SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1305amount of data in the corresponding candle, the maximum width can be influenced by
1306SetBarWidth(). The static function will affect all candle-charts in the running program.
1307Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1308supported, yet
1309
1310##### The Median
1311For a sorted list of numbers, the median is the value in the middle of the list.
1312E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1313because it is in the middle of the list. If the number of entries is even the
1314average of the two values in the middle will be used. As histograms are binned
1315data, the situation is a bit more complex. The following example shows this:
1316
1317~~~ {.cpp}
1318void quantiles() {
1319 auto h = new TH1I("h","h",10,0,10);
1320 //h->Fill(3);
1321 //h->Fill(3);
1322 h->Fill(4);
1323 h->Draw();
1324 double p = 0.;
1325 double q = 0.;
1326 h->GetQuantiles(1,&q,&p);
1327
1328 cout << "Median is: " << q << std::endl;
1329}
1330~~~
1331
1332Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1333the example will return a calculated median of 4.5, because that's the bin center
1334of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1335commented out, it will return 3.75, because the algorithm tries to evenly distribute
1336the individual values of a bin with bin content > 0. It means the sorted list
1337would be "3.25, 3.75, 4.5".
1338
1339The consequence is a median of 3.75. This shows how important it is to use a
1340small enough bin-width when using candle-plots on binned data.
1341If the distribution is large enough and gaussian shaped the median will be exactly
1342equal to the mean.
1343The median can be shown as a line or as a circle or not shown at all.
1344
1345In order to show the significance of the median notched candle plots apply a "notch" or
1346narrowing of the box around the median. The significance is defined by
1347\f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1348(where iqr is the size of the box and N is the number of entries of the whole
1349distribution). Candle plots like these are usually called "notched candle plots".
1350
1351In case the significance of the median is greater that the size of the box, the
1352box will have an unnatural shape. Usually it means the chart has not enough data,
1353or that representing this uncertainty is not useful
1354
1355##### The Mean
1356The mean can be drawn as a dashed line or as a circle or not drawn at all.
1357The mean is the arithmetic average of the values in the distribution.
1358It is calculated using GetMean(). Because histograms are
1359binned data, the mean value can differ from a calculation on the raw-data.
1360If the distribution is large enough and gaussian shaped the mean will be
1361exactly the median.
1362
1363##### The Whiskers
1364The whiskers represent the part of the distribution not covered by the box.
1365The upper 25% and the lower 25% of the distribution are located within the whiskers.
1366Two representations are available.
1367
1368 - A simple one (using w=1) defining the lower whisker from the lowest data value
1369 to the bottom of the box, and the upper whisker from the top of the box to the
1370 highest data value. In this representation the whisker-lines are dashed.
1371 - A more complex one having a further restriction. The whiskers are still connected
1372 to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1373 be that the outermost part of the underlying distribution will not be covered
1374 by the whiskers. Usually these missing parts will be represented by the outliers
1375 (see points). Of course the upper and the lower whisker may differ in length.
1376 In this representation the whiskers are drawn as solid lines.
1377
1378\since **ROOT version 6.11/01**
1379
1380Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1381will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1382the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1383that candle. The static function will affect all candle-charts in the running program.
1384Default is 1.
1385
1386If the distribution is large enough and gaussian shaped, the maximum length of
1387the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
13881.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1389(see picture above). In that case 99.3% of the total distribution will be covered
1390by the box and the whiskers, whereas 0.7% are represented by the outliers.
1391
1392##### The Anchors
1393The anchors have no special meaning in terms of statistical calculation. They mark
1394the end of the whiskers and they have the width of the box. Both representation
1395with and without anchors are common.
1396
1397##### The Points
1398Depending on the configuration the points can have different meanings:
1399 - If p=1 the points represent the outliers. If they are shown, it means
1400 some parts of the underlying distribution are not covered by the whiskers.
1401 This can only occur when the whiskers are set to option w=2. Here the whiskers
1402 can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1403 whiskers will be drawn as outliers. The outliers will be represented by crosses.
1404 - If p=2 all points in the distribution will be painted as crosses. This is
1405 useful for small datasets only (up to 10 or 20 points per candle).
1406 The outliers are shown along the candle. Because the underlying distribution
1407 is binned, is frequently occurs that a bin contains more than one value.
1408 Because of this the points will be randomly scattered within their bin along
1409 the candle axis. If the bin content for a bin is exactly 1 (usually
1410 this happens for the outliers) if will be drawn in the middle of the bin along
1411 the candle axis. As the maximum number of points per candle is limited by kNMax/2
1412 on very large datasets scaling will be performed automatically. In that case one
1413 would loose all outliers because they have usually a bin content of 1 (and a
1414 bin content between 0 and 1 after the scaling). Because of this all bin contents
1415 between 0 and 1 - after the scaling - will be forced to be 1.
1416 - As the drawing of all values on large datasets can lead to big amounts of crosses,
1417 one can show all values as a scatter plot instead by choosing p=3. The points will be
1418 drawn as dots and will be scattered within the width of the candle. The color
1419 of the points will be the color of the candle-chart.
1420
1421##### Other Options
1422Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1423with a histogram.
1424
1425#### How to use the candle-plots drawing option
1426
1427There are six predefined candle-plot representations:
1428
1429 - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1430 - "CANDLEX2": Standard candle with better whisker definition + outliers.
1431 It is a good compromise
1432 - "CANDLEX3": Like candle2 but with a mean as a circle.
1433 It is easier to distinguish mean and median
1434 - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1435 (notched candle plots).
1436 For bigger datasets per candle
1437 - "CANDLEX5": Like candle2 but showing all data points.
1438 For very small datasets
1439 - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1440 For huge datasets
1441
1442
1443The following picture shows how the six predefined representations look.
1444
1445Begin_Macro
1446{
1447 auto c1 = new TCanvas("c1","c1",700,800);
1448 c1->Divide(2,3);
1449 gStyle->SetOptStat(kFALSE);
1450
1451 auto hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1452 float px, py;
1453 for (Int_t i = 0; i < 15000; i++) {
1454 gRandom->Rannor(px,py);
1455 hcandle->Fill(px,5*py);
1456 }
1457 hcandle->SetMarkerSize(0.5);
1458
1459 TH2F *h2;
1460 for (Int_t i=1; i<7; i++) {
1461 c1->cd(i);
1462 h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1463 h2->SetTitle(Form("CANDLE%d",i));
1464 }
1465}
1466End_Macro
1467
1468
1469#### Example 1
1470Box and improved whisker, no mean, no median, no anchor no outliers
1471
1472 h1->Draw("CANDLEX(2001)");
1473
1474#### Example 2
1475A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1476
1477 h1->Draw("CANDLEX(112111)");
1478
1479#### Example 3
1480The following example shows how several candle plots can be super-imposed using
1481the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1482Also the color, the line width, the size of the points and so on can be changed by the
1483standard attribute setting methods such as SetLineColor() SetLineWidth().
1484
1485Begin_Macro(source)
1486../../../tutorials/hist/candleplot.C
1487End_Macro
1488
1489#### <a name="HP140b"></a> The VIOLIN option
1490
1491<a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1492that also encodes the pdf information at each point.
1493
1494
1495Quartiles and mean are also represented at each point, with a marker
1496and two lines.
1497
1498In this implementation a TH2 is considered as a collection of TH1 along
1499X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1500
1501#### What a violin is made of
1502
1503\since **ROOT version 6.09/02**
1504
1505##### The histogram
1506The histogram is typically drawn to both directions with respect to the middle-line of the
1507corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1508one side (h=1, or h=2).
1509The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1510histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1511be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1512A solid fill style is recommended.
1513
1514\since **ROOT version 6.11/01**
1515
1516Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1517violin can be influenced. Activated, the height of the bins of the individual violins will be
1518scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1519Deactivated, the height of the bin with the maximum content of each individual violin is
1520set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1521in the running program. Default is true. Scaling between multiple violin-charts
1522(using "same" or THStack) is not supported, yet.
1523
1524##### The zero indicator line
1525Typical for violin charts is a line in the background over the whole histogram indicating
1526the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1527will always be the same as the fill-color of the histogram.
1528
1529##### The Mean
1530The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1531
1532##### Whiskers
1533The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1534difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1535the whiskers will be forced to be solid (usually hashed)
1536
1537##### Points
1538The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1539better whisker definition (w=2) and outliers (p=1).
1540
1541##### Other options
1542It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1543including a box-plot.
1544
1545#### How to use the violin-plots drawing option
1546
1547There are two predefined violin-plot representations:
1548 - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1549 zero indicator line)
1550 - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1551
1552A solid fill style is recommended for this plot (as opposed to a hollow or
1553hashed style).
1554
1555Begin_Macro(source)
1556{
1557 auto c1 = new TCanvas("c1","c1",600,400);
1558 Int_t nx(6), ny(40);
1559 double xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1560 auto hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1561 TF1 f1("f1", "gaus", +0,0 +4.0);
1562 double x,y;
1563 for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1564 double xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1565 f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1566 for(Int_t i=0; i<10000; ++i){
1567 x = xc;
1568 y = f1.GetRandom();
1569 hviolin->Fill(x, y);
1570 }
1571 }
1572 hviolin->SetFillColor(kGray);
1573 hviolin->SetMarkerStyle(20);
1574 hviolin->SetMarkerSize(0.5);
1575 hviolin->Draw("VIOLIN");
1576 c1->Update();
1577}
1578End_Macro
1579
1580The next example illustrates a time development of a certain value:
1581
1582Begin_Macro(source)
1583../../../tutorials/hist/candledecay.C
1584End_Macro
1585
1586
1587### <a name="HP15"></a> The TEXT and TEXTnn Option
1588
1589
1590For each bin the content is printed. The text attributes are:
1591
1592- text font = current TStyle font (`gStyle->SetTextFont()`).
1593- text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1594 with the option `TEXT` the marker size can be changed with
1595 `h->SetMarkerSize(markersize)`).
1596- text color = marker color.
1597
1598By default the format `g` is used. This format can be redefined
1599by calling `gStyle->SetPaintTextFormat()`.
1600
1601It is also possible to use `TEXTnn` in order to draw the text with
1602the angle `nn` (`0 < nn < 90`).
1603
1604For 2D histograms the text is plotted in the center of each non empty cells.
1605It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`
1606or providing MIN0 draw option. For 1D histogram the text is plotted at a y
1607position equal to the bin content.
1608
1609For 2D histograms when the option "E" (errors) is combined with the option
1610text ("TEXTE"), the error for each bin is also printed.
1611
1612Begin_Macro(source)
1613{
1614 auto c01 = new TCanvas("c01","c01",700,400);
1615 c01->Divide(2,1);
1616 auto htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1617 auto htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1618 float px, py;
1619 for (Int_t i = 0; i < 25000; i++) {
1620 gRandom->Rannor(px,py);
1621 htext1->Fill(px,0.1);
1622 htext2->Fill(px,5*py,0.1);
1623 }
1624 gStyle->SetPaintTextFormat("4.1f m");
1625 htext2->SetMarkerSize(1.8);
1626 c01->cd(1);
1627 htext2->Draw("TEXT45");
1628 c01->cd(2);
1629 htext1->Draw();
1630 htext1->Draw("HIST TEXT0 SAME");
1631}
1632End_Macro
1633
1634\since **ROOT version 6.07/07:**
1635
1636In case several histograms are drawn on top ot each other (using option `SAME`),
1637the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1638text position in each cell, in percentage of the bin width.
1639
1640Begin_Macro(source)
1641{
1642 auto c03 = new TCanvas("c03","c03",700,400);
1643 gStyle->SetOptStat(0);
1644 auto htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1645 auto htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1646 auto htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1647 float px, py;
1648 for (Int_t i = 0; i < 25000; i++) {
1649 gRandom->Rannor(px,py);
1650 htext3->Fill(4*px,20*py,0.1);
1651 htext4->Fill(4*px,20*py,0.5);
1652 htext5->Fill(4*px,20*py,1.0);
1653 }
1654 htext4->SetMarkerSize(1.8);
1655 htext5->SetMarkerSize(1.8);
1656 htext5->SetMarkerColor(kRed);
1657 htext3->Draw("COL");
1658 htext4->SetBarOffset(0.2);
1659 htext4->Draw("TEXT SAME");
1660 htext5->SetBarOffset(-0.2);
1661 htext5->Draw("TEXT SAME");
1662}
1663End_Macro
1664
1665In the case of profile histograms it is possible to print the number
1666of entries instead of the bin content. It is enough to combine the
1667option "E" (for entries) with the option "TEXT".
1668
1669Begin_Macro(source)
1670{
1671 auto c02 = new TCanvas("c02","c02",700,400);
1672 c02->Divide(2,1);
1673 gStyle->SetPaintTextFormat("g");
1674
1675 auto profile = new TProfile("profile","profile",10,0,10);
1676 profile->SetMarkerSize(2.2);
1677 profile->Fill(0.5,1);
1678 profile->Fill(1.5,2);
1679 profile->Fill(2.5,3);
1680 profile->Fill(3.5,4);
1681 profile->Fill(4.5,5);
1682 profile->Fill(5.5,5);
1683 profile->Fill(6.5,4);
1684 profile->Fill(7.5,3);
1685 profile->Fill(8.5,2);
1686 profile->Fill(9.5,1);
1687 c02->cd(1); profile->Draw("HIST TEXT0");
1688 c02->cd(2); profile->Draw("HIST TEXT0E");
1689}
1690End_Macro
1691
1692### <a name="HP16"></a> The CONTour options
1693
1694
1695The following contour options are supported:
1696
1697| Option | Description |
1698|----------|-------------------------------------------------------------------|
1699| "CONT" | Draw a contour plot (same as CONT0).|
1700| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1701| "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1702| "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1703| "CONT3" | Draw a contour plot solid lines for all contours.|
1704| "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1705| "CONT5" | Draw a contour plot using Delaunay triangles.|
1706
1707
1708
1709The following example shows a 2D histogram plotted with the option
1710`CONTZ`. The option `CONT` draws a contour plot using surface
1711colors to distinguish contours. Combined with the option `CONT` (or
1712`CONT0`), the option `Z` allows to display the color palette
1713defined by `gStyle->SetPalette()`.
1714
1715Begin_Macro(source)
1716{
1717 auto c1 = new TCanvas("c1","c1",600,400);
1718 auto hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1719 float px, py;
1720 for (Int_t i = 0; i < 25000; i++) {
1721 gRandom->Rannor(px,py);
1722 hcontz->Fill(px-1,5*py);
1723 hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1724 }
1725 hcontz->Draw("CONTZ");
1726}
1727End_Macro
1728
1729The following example shows a 2D histogram plotted with the option
1730`CONT1Z`. The option `CONT1` draws a contour plot using the
1731line colors to distinguish contours. Combined with the option `CONT1`,
1732the option `Z` allows to display the color palette defined by
1733`gStyle->SetPalette()`.
1734
1735Begin_Macro(source)
1736{
1737 auto c1 = new TCanvas("c1","c1",600,400);
1738 auto hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1739 float px, py;
1740 for (Int_t i = 0; i < 25000; i++) {
1741 gRandom->Rannor(px,py);
1742 hcont1->Fill(px-1,5*py);
1743 hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1744 }
1745 hcont1->Draw("CONT1Z");
1746}
1747End_Macro
1748
1749The following example shows a 2D histogram plotted with the option
1750`CONT2`. The option `CONT2` draws a contour plot using the
1751line styles to distinguish contours.
1752
1753Begin_Macro(source)
1754{
1755 auto c1 = new TCanvas("c1","c1",600,400);
1756 auto hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1757 float px, py;
1758 for (Int_t i = 0; i < 25000; i++) {
1759 gRandom->Rannor(px,py);
1760 hcont2->Fill(px-1,5*py);
1761 hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1762 }
1763 hcont2->Draw("CONT2");
1764}
1765End_Macro
1766
1767The following example shows a 2D histogram plotted with the option
1768`CONT3`. The option `CONT3` draws contour plot solid lines for
1769all contours.
1770
1771Begin_Macro(source)
1772{
1773 auto c1 = new TCanvas("c1","c1",600,400);
1774 auto hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1775 float px, py;
1776 for (Int_t i = 0; i < 25000; i++) {
1777 gRandom->Rannor(px,py);
1778 hcont3->Fill(px-1,5*py);
1779 hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1780 }
1781 hcont3->Draw("CONT3");
1782}
1783End_Macro
1784
1785The following example shows a 2D histogram plotted with the option
1786`CONT4`. The option `CONT4` draws a contour plot using surface
1787colors to distinguish contours (`SURF` option at theta = 0). Combined
1788with the option `CONT` (or `CONT0`), the option `Z`
1789allows to display the color palette defined by `gStyle->SetPalette()`.
1790
1791Begin_Macro(source)
1792{
1793 auto c1 = new TCanvas("c1","c1",600,400);
1794 auto hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1795 float px, py;
1796 for (Int_t i = 0; i < 25000; i++) {
1797 gRandom->Rannor(px,py);
1798 hcont4->Fill(px-1,5*py);
1799 hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1800 }
1801 hcont4->Draw("CONT4Z");
1802}
1803End_Macro
1804
1805The default number of contour levels is 20 equidistant levels and can be changed
1806with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1807
1808#### <a name="HP16a"></a> The LIST option
1809
1810When option `LIST` is specified together with option
1811`CONT`, the points used to draw the contours are saved in
1812`TGraph` objects:
1813
1814 h->Draw("CONT LIST");
1815 gPad->Update();
1816
1817The contour are saved in `TGraph` objects once the pad is painted.
1818Therefore to use this functionality in a macro, `gPad->Update()`
1819should be performed after the histogram drawing. Once the list is
1820built, the contours are accessible in the following way:
1821
1822 TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
1823 Int_t ncontours = contours->GetSize();
1824 TList *list = (TList*)contours->At(i);
1825
1826Where `i` is a contour number, and list contains a list of
1827`TGraph` objects.
1828For one given contour, more than one disjoint polyline may be generated.
1829The number of TGraphs per contour is given by:
1830
1831 list->GetSize();
1832
1833To access the first graph in the list one should do:
1834
1835 TGraph *gr1 = (TGraph*)list->First();
1836
1837
1838The following example (ContourList.C) shows how to use this functionality.
1839
1840Begin_Macro(source)
1841../../../tutorials/hist/ContourList.C
1842End_Macro
1843
1844#### <a name="HP16b"></a> The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options
1845
1846The following options select the `CONT4` option and are useful for
1847sky maps or exposure maps (earth.C).
1848
1849| Option | Description |
1850|--------------|---------------------------------------------------------------|
1851| "AITOFF" | Draw a contour via an AITOFF projection.|
1852| "MERCATOR" | Draw a contour via an Mercator projection.|
1853| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1854| "PARABOLIC" | Draw a contour via an Parabolic projection.|
1855
1856Begin_Macro(source)
1857../../../tutorials/graphics/earth.C
1858End_Macro
1859
1860
1861### <a name="HP17"></a> The LEGO options
1862
1863
1864In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1865is proportional to the cell content. The lego aspect is control with the
1866following options:
1867
1868| Option | Description |
1869|----------|-------------------------------------------------------------------|
1870| "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1871| "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1872| "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1873| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1874| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1875| "0" | When used with any LEGO option, the empty bins are not drawn.|
1876
1877
1878See the limitations with [the option "SAME"](#HP060a).
1879
1880Line attributes can be used in lego plots to change the edges' style.
1881
1882The following example shows a 2D histogram plotted with the option
1883`LEGO`. The option `LEGO` draws a lego plot using the hidden
1884lines removal technique.
1885
1886Begin_Macro(source)
1887{
1888 auto c2 = new TCanvas("c2","c2",600,400);
1889 auto hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1890 float px, py;
1891 for (Int_t i = 0; i < 25000; i++) {
1892 gRandom->Rannor(px,py);
1893 hlego->Fill(px-1,5*py);
1894 hlego->Fill(2+0.5*px,2*py-10.,0.1);
1895 }
1896 hlego->Draw("LEGO");
1897}
1898End_Macro
1899
1900The following example shows a 2D histogram plotted with the option
1901`LEGO1`. The option `LEGO1` draws a lego plot using the
1902hidden surface removal technique. Combined with any `LEGOn` option, the
1903option `0` allows to not drawn the empty bins.
1904
1905Begin_Macro(source)
1906{
1907 auto c2 = new TCanvas("c2","c2",600,400);
1908 auto hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1909 float px, py;
1910 for (Int_t i = 0; i < 25000; i++) {
1911 gRandom->Rannor(px,py);
1912 hlego1->Fill(px-1,5*py);
1913 hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1914 }
1915 hlego1->SetFillColor(kYellow);
1916 hlego1->Draw("LEGO1 0");
1917}
1918End_Macro
1919
1920The following example shows a 2D histogram plotted with the option
1921`LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1922draws a lego plot using the hidden surface removal technique but doesn't draw
1923the border lines of each individual lego-bar. This is very useful for histograms
1924having many bins. With such histograms the option `LEGO1` gives a black
1925image because of the border lines. This option also works with stacked legos.
1926
1927Begin_Macro(source)
1928{
1929 auto c2 = new TCanvas("c2","c2",600,400);
1930 auto hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1931 float px, py;
1932 for (Int_t i = 0; i < 25000; i++) {
1933 gRandom->Rannor(px,py);
1934 hlego3->Fill(px-1,5*py);
1935 hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1936 }
1937 hlego3->SetFillColor(kRed);
1938 hlego3->Draw("LEGO3");
1939}
1940End_Macro
1941
1942The following example shows a 2D histogram plotted with the option
1943`LEGO2`. The option `LEGO2` draws a lego plot using colors to
1944show the cell contents. Combined with the option `LEGO2`, the option
1945`Z` allows to display the color palette defined by
1946`gStyle->SetPalette()`.
1947
1948Begin_Macro(source)
1949{
1950 auto c2 = new TCanvas("c2","c2",600,400);
1951 auto hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1952 float px, py;
1953 for (Int_t i = 0; i < 25000; i++) {
1954 gRandom->Rannor(px,py);
1955 hlego2->Fill(px-1,5*py);
1956 hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1957 }
1958 hlego2->Draw("LEGO2Z");
1959}
1960End_Macro
1961
1962
1963
1964### <a name="HP18"></a> The "SURFace" options
1965
1966
1967In a surface plot, cell contents are represented as a mesh.
1968The height of the mesh is proportional to the cell content.
1969
1970| Option | Description |
1971|----------|-------------------------------------------------------------------|
1972| "SURF" | Draw a surface plot using the hidden line removal technique.|
1973| "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1974| "SURF2" | Draw a surface plot using colors to show the cell contents.|
1975| "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1976| "SURF4" | Draw a surface using the Gouraud shading technique.|
1977| "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1978| "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.|
1979| "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1980
1981
1982
1983See the limitations with [the option "SAME"](#HP060a).
1984
1985The following example shows a 2D histogram plotted with the option
1986`SURF`. The option `SURF` draws a lego plot using the hidden
1987lines removal technique.
1988
1989Begin_Macro(source)
1990{
1991 auto c2 = new TCanvas("c2","c2",600,400);
1992 auto hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1993 float px, py;
1994 for (Int_t i = 0; i < 25000; i++) {
1995 gRandom->Rannor(px,py);
1996 hsurf->Fill(px-1,5*py);
1997 hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1998 }
1999 hsurf->Draw("SURF");
2000}
2001End_Macro
2002
2003The following example shows a 2D histogram plotted with the option
2004`SURF1`. The option `SURF1` draws a surface plot using the
2005hidden surface removal technique. Combined with the option `SURF1`,
2006the option `Z` allows to display the color palette defined by
2007`gStyle->SetPalette()`.
2008
2009Begin_Macro(source)
2010{
2011 auto c2 = new TCanvas("c2","c2",600,400);
2012 auto hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
2013 float px, py;
2014 for (Int_t i = 0; i < 25000; i++) {
2015 gRandom->Rannor(px,py);
2016 hsurf1->Fill(px-1,5*py);
2017 hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
2018 }
2019 hsurf1->Draw("SURF1");
2020}
2021End_Macro
2022
2023The following example shows a 2D histogram plotted with the option
2024`SURF2`. The option `SURF2` draws a surface plot using colors
2025to show the cell contents. Combined with the option `SURF2`, the option
2026`Z` allows to display the color palette defined by
2027`gStyle->SetPalette()`.
2028
2029Begin_Macro(source)
2030{
2031 auto c2 = new TCanvas("c2","c2",600,400);
2032 auto hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
2033 float px, py;
2034 for (Int_t i = 0; i < 25000; i++) {
2035 gRandom->Rannor(px,py);
2036 hsurf2->Fill(px-1,5*py);
2037 hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2038 }
2039 hsurf2->Draw("SURF2");
2040}
2041End_Macro
2042
2043The following example shows a 2D histogram plotted with the option
2044`SURF3`. The option `SURF3` draws a surface plot using the
2045hidden line removal technique with, in addition, a filled contour view drawn on the
2046top. Combined with the option `SURF3`, the option `Z` allows
2047to display the color palette defined by `gStyle->SetPalette()`.
2048
2049Begin_Macro(source)
2050{
2051 auto c2 = new TCanvas("c2","c2",600,400);
2052 auto hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2053 float px, py;
2054 for (Int_t i = 0; i < 25000; i++) {
2055 gRandom->Rannor(px,py);
2056 hsurf3->Fill(px-1,5*py);
2057 hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2058 }
2059 hsurf3->Draw("SURF3");
2060}
2061End_Macro
2062
2063The following example shows a 2D histogram plotted with the option
2064`SURF4`. The option `SURF4` draws a surface using the Gouraud
2065shading technique.
2066
2067Begin_Macro(source)
2068{
2069 auto c2 = new TCanvas("c2","c2",600,400);
2070 auto hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2071 float px, py;
2072 for (Int_t i = 0; i < 25000; i++) {
2073 gRandom->Rannor(px,py);
2074 hsurf4->Fill(px-1,5*py);
2075 hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2076 }
2077 hsurf4->SetFillColor(kOrange);
2078 hsurf4->Draw("SURF4");
2079}
2080End_Macro
2081
2082The following example shows a 2D histogram plotted with the option
2083`SURF5 CYL`. Combined with the option `SURF5`, the option
2084`Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2085
2086Begin_Macro(source)
2087{
2088 auto c2 = new TCanvas("c2","c2",600,400);
2089 auto hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2090 float px, py;
2091 for (Int_t i = 0; i < 25000; i++) {
2092 gRandom->Rannor(px,py);
2093 hsurf5->Fill(px-1,5*py);
2094 hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2095 }
2096 hsurf5->Draw("SURF5 CYL");
2097}
2098End_Macro
2099
2100The following example shows a 2D histogram plotted with the option
2101`SURF7`. The option `SURF7` draws a surface plot using the
2102hidden surfaces removal technique with, in addition, a line contour view drawn on the
2103top. Combined with the option `SURF7`, the option `Z` allows
2104to display the color palette defined by `gStyle->SetPalette()`.
2105
2106Begin_Macro(source)
2107{
2108 auto c2 = new TCanvas("c2","c2",600,400);
2109 auto hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2110 float px, py;
2111 for (Int_t i = 0; i < 25000; i++) {
2112 gRandom->Rannor(px,py);
2113 hsurf7->Fill(px-1,5*py);
2114 hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2115 }
2116 hsurf7->Draw("SURF7");
2117}
2118End_Macro
2119
2120As shown in the following example, when a contour plot is painted on top of a
2121surface plot using the option `SAME`, the contours appear in 3D on the
2122surface.
2123
2124Begin_Macro(source)
2125{
2126 auto c20=new TCanvas("c20","c20",600,400);
2127 int NBins = 50;
2128 double d = 2;
2129 auto hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2130 for (int bx = 1; bx <= NBins; ++bx) {
2131 for (int by = 1; by <= NBins; ++by) {
2132 double x = hsc->GetXaxis()->GetBinCenter(bx);
2133 double y = hsc->GetYaxis()->GetBinCenter(by);
2134 hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2135 }
2136 }
2137 hsc->Draw("surf2");
2138 hsc->Draw("CONT1 SAME");
2139}
2140End_Macro
2141
2142
2143### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2144
2145
2146Legos and surfaces plots are represented by default in Cartesian coordinates.
2147Combined with any `LEGOn` or `SURFn` options the following
2148options allow to draw a lego or a surface in other coordinates systems.
2149
2150| Option | Description |
2151|----------|-------------------------------------------------------------------|
2152| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2153| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2154| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2155| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2156
2157
2158
2159<b>WARNING:</b> Axis are not drawn with these options.
2160
2161The following example shows the same histogram as a lego plot is the four
2162different coordinates systems.
2163
2164Begin_Macro(source)
2165{
2166 auto c3 = new TCanvas("c3","c3",600,400);
2167 c3->Divide(2,2);
2168 auto hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2169 float px, py;
2170 for (Int_t i = 0; i < 25000; i++) {
2171 gRandom->Rannor(px,py);
2172 hlcc->Fill(px-1,5*py);
2173 hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2174 }
2175 hlcc->SetFillColor(kYellow);
2176 c3->cd(1); hlcc->Draw("LEGO1 CYL");
2177 c3->cd(2); auto hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2178 hlpc->SetTitle("Polar coordinates");
2179 c3->cd(3); auto hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2180 hlsc->SetTitle("Spherical coordinates");
2181 c3->cd(4); auto hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2182 hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2183}
2184End_Macro
2185
2186The following example shows the same histogram as a surface plot is the four different coordinates systems.
2187
2188Begin_Macro(source)
2189{
2190 auto c4 = new TCanvas("c4","c4",600,400);
2191 c4->Divide(2,2);
2192 auto hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2193 float px, py;
2194 for (Int_t i = 0; i < 25000; i++) {
2195 gRandom->Rannor(px,py);
2196 hscc->Fill(px-1,5*py);
2197 hscc->Fill(2+0.5*px,2*py-10.,0.1);
2198 }
2199 c4->cd(1); hscc->Draw("SURF1 CYL");
2200 c4->cd(2); auto hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2201 hspc->SetTitle("Polar coordinates");
2202 c4->cd(3); auto hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2203 hssc->SetTitle("Spherical coordinates");
2204 c4->cd(4); auto hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2205 hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2206}
2207End_Macro
2208
2209
2210### <a name="HP20"></a> Base line for bar-charts and lego plots
2211
2212
2213By default the base line used to draw the boxes for bar-charts and lego plots is
2214the histogram minimum. It is possible to force this base line to be 0, using MIN0 draw
2215option or with the command:
2216
2217 gStyle->SetHistMinimumZero();
2218
2219Begin_Macro(source)
2220{
2221 auto c5 = new TCanvas("c5","c5",700,400);
2222 c5->Divide(2,1);
2223 auto hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2224 auto hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2225 Int_t i;
2226 double x,y;
2227 hz1->SetFillColor(kBlue);
2228 hz2->SetFillColor(kBlue);
2229 for (i=0;i<10000;i++) {
2230 x = gRandom->Gaus(0,1);
2231 y = gRandom->Gaus(0,1);
2232 if (x>0) {
2233 hz1->Fill(x,1);
2234 hz2->Fill(x,y,1);
2235 } else {
2236 hz1->Fill(x,-1);
2237 hz2->Fill(x,y,-2);
2238 }
2239 }
2240 c5->cd(1); hz1->Draw("bar2 min0");
2241 c5->cd(2); hz2->Draw("lego1 min0");
2242}
2243End_Macro
2244
2245This option also works for horizontal plots. The example given in the section
2246["The bar chart option"](#HP100) appears as follow:
2247
2248Begin_Macro(source)
2249{
2250 int i;
2251 const Int_t nx = 8;
2252 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2253 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2254 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2255
2256 auto cbh = new TCanvas("cbh","cbh",400,600);
2257 cbh->SetGrid();
2258
2259 auto h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2260 h1bh->SetFillColor(4);
2261 h1bh->SetBarWidth(0.4);
2262 h1bh->SetBarOffset(0.1);
2263 h1bh->SetStats(0);
2264 h1bh->SetMinimum(-5);
2265 h1bh->SetMaximum(5);
2266
2267 for (i=1; i<=nx; i++) {
2268 h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2269 h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2270 }
2271
2272 h1bh->Draw("hbar min0");
2273
2274 auto h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2275 h2bh->SetFillColor(38);
2276 h2bh->SetBarWidth(0.4);
2277 h2bh->SetBarOffset(0.5);
2278 h2bh->SetStats(0);
2279 for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2280
2281 h2bh->Draw("hbar min0 same");
2282}
2283End_Macro
2284
2285
2286### <a name="HP20a"></a> TH2Poly Drawing
2287
2288
2289The following options are supported:
2290
2291| Option | Description |
2292|----------|-------------------------------------------------------------------|
2293| "SCAT" | Draw a scatter plot (default).|
2294| "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2295| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2296| "0" | When used with any COL options, the empty bins are not drawn.|
2297| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2298| "TEXTN" | Draw bin names as text.|
2299| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2300| "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2301| "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2302| "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2303
2304
2305
2306`TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2307shapes. The bins are defined as graphs. The following macro is a very simple
2308example showing how to book a TH2Poly and draw it.
2309
2310Begin_Macro(source)
2311{
2312 auto ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2313 auto h2p = new TH2Poly();
2314 h2p->SetName("h2poly_name");
2315 h2p->SetTitle("h2poly_title");
2316 double px1[] = {0, 5, 6};
2317 double py1[] = {0, 0, 5};
2318 double px2[] = {0, -1, -1, 0};
2319 double py2[] = {0, 0, -1, 3};
2320 double px3[] = {4, 3, 0, 1, 2.4};
2321 double py3[] = {4, 3.7, 1, 3.7, 2.5};
2322 h2p->AddBin(3, px1, py1);
2323 h2p->AddBin(4, px2, py2);
2324 h2p->AddBin(5, px3, py3);
2325 h2p->Fill(0.1, 0.01, 3);
2326 h2p->Fill(-0.5, -0.5, 7);
2327 h2p->Fill(-0.7, -0.5, 1);
2328 h2p->Fill(1, 3, 1.5);
2329 double fx[] = {0.1, -0.5, -0.7, 1};
2330 double fy[] = {0.01, -0.5, -0.5, 3};
2331 double fw[] = {3, 1, 1, 1.5};
2332 h2p->FillN(4, fx, fy, fw);
2333 h2p->Draw("col");
2334}
2335End_Macro
2336
2337Rectangular bins are a frequent case. The special version of
2338the `AddBin` method allows to define them more easily like
2339shown in the following example (th2polyBoxes.C).
2340
2341Begin_Macro(source)
2342../../../tutorials/hist/th2polyBoxes.C
2343End_Macro
2344
2345One `TH2Poly` bin can be a list of polygons. Such bins are defined
2346by calling `AddBin` with a `TMultiGraph`. The following example
2347shows a such case:
2348
2349Begin_Macro(source)
2350{
2351 auto ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2352
2353 Int_t i, bin;
2354 const Int_t nx = 48;
2355 const char *states [nx] = {
2356 "alabama", "arizona", "arkansas", "california",
2357 "colorado", "connecticut", "delaware", "florida",
2358 "georgia", "idaho", "illinois", "indiana",
2359 "iowa", "kansas", "kentucky", "louisiana",
2360 "maine", "maryland", "massachusetts", "michigan",
2361 "minnesota", "mississippi", "missouri", "montana",
2362 "nebraska", "nevada", "new_hampshire", "new_jersey",
2363 "new_mexico", "new_york", "north_carolina", "north_dakota",
2364 "ohio", "oklahoma", "oregon", "pennsylvania",
2365 "rhode_island", "south_carolina", "south_dakota", "tennessee",
2366 "texas", "utah", "vermont", "virginia",
2367 "washington", "west_virginia", "wisconsin", "wyoming"
2368 };
2369 Double_t pop[nx] = {
2370 4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2371 9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2372 1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2373 1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2374 11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2375 24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2376 };
2377
2378 Double_t lon1 = -130;
2379 Double_t lon2 = -65;
2380 Double_t lat1 = 24;
2381 Double_t lat2 = 50;
2382 auto p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2383
2384 TFile::SetCacheFileDir(".");
2385 auto f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2386
2387 TMultiGraph *mg;
2388 TKey *key;
2389 TIter nextkey(gDirectory->GetListOfKeys());
2390 while ((key = (TKey*)nextkey())) {
2391 TObject *obj = key->ReadObj();
2392 if (obj->InheritsFrom("TMultiGraph")) {
2393 mg = (TMultiGraph*)obj;
2394 bin = p->AddBin(mg);
2395 }
2396 }
2397
2398 for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2399
2400 gStyle->SetOptStat(11);
2401 p->Draw("COLZ L");
2402}
2403End_Macro
2404
2405`TH2Poly` histograms can also be plotted using the GL interface using
2406the option "GLLEGO".
2407
2408\since **ROOT version 6.09/01**
2409
2410In some cases it can be useful to not draw the empty bins. the option "0"
2411combined with the option "COL" et COLZ allows to do that.
2412
2413Begin_Macro(source)
2414{
2415 auto chc = new TCanvas("chc","chc",600,400);
2416
2417 auto hc = new TH2Poly();
2418 hc->Honeycomb(0,0,.1,25,25);
2419 hc->SetName("hc");
2420 hc->SetTitle("Option COLZ 0");
2421 TRandom ran;
2422 for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2423 hc->Draw("colz 0");
2424}
2425End_Macro
2426
2427### <a name="HP21"></a> The SPEC option
2428
2429
2430This option allows to use the `TSpectrum2Painter` tools. See the full
2431documentation in `TSpectrum2Painter::PaintSpectrum`.
2432
2433
2434### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2435
2436
2437When this option is specified, a color palette with an axis indicating the value
2438of the corresponding color is drawn on the right side of the picture. In case,
2439not enough space is left, one can increase the size of the right margin by
2440calling `TPad::SetRightMargin()`. The attributes used to display the
2441palette axis values are taken from the Z axis of the object. For example, to
2442set the labels size on the palette axis do:
2443
2444 hist->GetZaxis()->SetLabelSize().
2445
2446<b>WARNING:</b> The palette axis is always drawn vertically.
2447
2448
2449### <a name="HP23"></a> Setting the color palette
2450
2451
2452To change the color palette `TStyle::SetPalette` should be used, eg:
2453
2454 gStyle->SetPalette(ncolors,colors);
2455
2456For example the option `COL` draws a 2D histogram with cells
2457represented by a box filled with a color index which is a function
2458of the cell content.
2459If the cell content is N, the color index used will be the color number
2460in `colors[N]`, etc. If the maximum cell content is greater than
2461`ncolors`, all cell contents are scaled to `ncolors`.
2462
2463If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2464defined. This palette is recommended for pads, labels ...
2465
2466`if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2467Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2468palette.
2469
2470Other pre-defined palettes with 255 colors are available when `colors == 0`.
2471The following value of `ncolors` give access to:
2472
2473
2474 if ncolors = 51 and colors=0, a Deep Sea palette is used.
2475 if ncolors = 52 and colors=0, a Grey Scale palette is used.
2476 if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2477 if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2478 if ncolors = 55 and colors=0, a Rain Bow palette is used.
2479 if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2480
2481
2482If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2483
2484The default palette defines:
2485
2486- index 0 to 9 : shades of grey
2487- index 10 to 19 : shades of brown
2488- index 20 to 29 : shades of blue
2489- index 30 to 39 : shades of red
2490- index 40 to 49 : basic colors
2491
2492The color numbers specified in the palette can be viewed by selecting
2493the item `colors` in the `VIEW` menu of the canvas tool bar.
2494The red, green, and blue components of a color can be changed thanks to
2495`TColor::SetRGB()`.
2496
2497\since **ROOT version 6.19/01**
2498
2499As default labels and ticks are drawn by `TGAxis` at equidistant (lin or log)
2500points as controlled by SetNdivisions.
2501If option "CJUST" is given labels and ticks are justified at the
2502color boundaries defined by the contour levels.
2503For more details see `TPaletteAxis`
2504
2505### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2506
2507
2508Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2509histogram. One must create a graphical cut (mouse or C++) and specify the name
2510of the cut between `[]` in the `Draw()` option.
2511For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2512
2513 myhist->Draw("surf1 [cutg]");
2514
2515To invert the cut, it is enough to put a `-` in front of its name:
2516
2517 myhist->Draw("surf1 [-cutg]");
2518
2519It is possible to apply several cuts (`,` means logical AND):
2520
2521 myhist->Draw("surf1 [cutg1,cutg2]");
2522
2523Begin_Macro(source)
2524../../../tutorials/fit/fit2a.C
2525End_Macro
2526
2527### <a name="HP25"></a> Drawing options for 3D histograms
2528
2529
2530| Option | Description |
2531|----------|-------------------------------------------------------------------|
2532| "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)`|
2533| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2534| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2535| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2536| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2537| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2538
2539Note that instead of `BOX` one can also use `LEGO`.
2540
2541By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2542
2543The following example shows a 3D histogram plotted as a scatter plot.
2544
2545Begin_Macro(source)
2546{
2547 auto c06 = new TCanvas("c06","c06",600,400);
2548 gStyle->SetOptStat(kFALSE);
2549 auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2550 double x, y, z;
2551 for (Int_t i=0;i<10000;i++) {
2552 gRandom->Rannor(x, y);
2553 z = x*x + y*y;
2554 h3scat->Fill(x,y,z);
2555 }
2556 h3scat->Draw();
2557}
2558End_Macro
2559
2560The following example shows a 3D histogram plotted with the option `BOX`.
2561
2562Begin_Macro(source)
2563{
2564 auto c16 = new TCanvas("c16","c16",600,400);
2565 gStyle->SetOptStat(kFALSE);
2566 auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2567 double x, y, z;
2568 for (Int_t i=0;i<10000;i++) {
2569 gRandom->Rannor(x, y);
2570 z = x*x + y*y;
2571 h3box->Fill(x,y,z);
2572 }
2573 h3box->Draw("BOX");
2574}
2575End_Macro
2576
2577The following example shows a 3D histogram plotted with the option `BOX1`.
2578
2579Begin_Macro(source)
2580{
2581 auto c36 = new TCanvas("c36","c36",600,400);
2582 gStyle->SetOptStat(kFALSE);
2583 auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2584 double x, y, z;
2585 for (Int_t i=0;i<10000;i++) {
2586 gRandom->Rannor(x, y);
2587 z = abs(sin(x)/x + cos(y)*y);
2588 h3box->Fill(x,y,z);
2589 }
2590 h3box->SetFillColor(9);
2591 h3box->Draw("BOX1");
2592}
2593End_Macro
2594
2595The following example shows a 3D histogram plotted with the option `BOX2`.
2596
2597Begin_Macro(source)
2598{
2599 auto c56 = new TCanvas("c56","c56",600,400);
2600 gStyle->SetOptStat(kFALSE);
2601 auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2602 double x, y, z;
2603 for (Int_t i=0;i<10000;i++) {
2604 gRandom->Rannor(x, y);
2605 z = abs(sin(x)/x + cos(y)*y);
2606 h3box->Fill(x,y,z);
2607 }
2608 h3box->Draw("BOX2 Z");
2609}
2610End_Macro
2611
2612The following example shows a 3D histogram plotted with the option `BOX3`.
2613
2614Begin_Macro(source)
2615{
2616 auto c46 = new TCanvas("c46","c46",600,400);
2617 c46->SetFillColor(38);
2618 gStyle->SetOptStat(kFALSE);
2619 auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2620 double x, y, z;
2621 for (Int_t i=0;i<10000;i++) {
2622 gRandom->Rannor(x, y);
2623 z = x*x + y*y;
2624 h3box->Fill(x,y,z);
2625 }
2626 h3box->Draw("BOX3");
2627}
2628End_Macro
2629
2630For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2631to the absolute value of the bin content. The bins with a negative content are
2632drawn with a X on each face of the box as shown in the following example:
2633
2634Begin_Macro(source)
2635{
2636 auto c = new TCanvas("c","c",600,400);
2637 gStyle->SetOptStat(kFALSE);
2638 auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2639 h3box->Fill(0., 2., 2., 10.);
2640 h3box->Fill(2., 2., 2., 5.);
2641 h3box->Fill(2., 2., .5, 2.);
2642 h3box->Fill(2., 2., 3., -1.);
2643 h3box->Fill(3., 2., 2., -10.);
2644 h3box->SetFillColor(8);
2645 h3box->Draw("box1");
2646}
2647End_Macro
2648
2649The following example shows a 3D histogram plotted with the option `ISO`.
2650
2651Begin_Macro(source)
2652{
2653 auto c26 = new TCanvas("c26","c26",600,400);
2654 gStyle->SetOptStat(kFALSE);
2655 auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2656 double x, y, z;
2657 for (Int_t i=0;i<10000;i++) {
2658 gRandom->Rannor(x, y);
2659 z = x*x + y*y;
2660 h3iso->Fill(x,y,z);
2661 }
2662 h3iso->SetFillColor(kCyan);
2663 h3iso->Draw("ISO");
2664}
2665End_Macro
2666
2667
2668### <a name="HP26"></a> Drawing option for histograms' stacks
2669
2670
2671Stacks of histograms are managed with the `THStack`. A `THStack`
2672is a collection of `TH1` (or derived) objects. For painting only the
2673`THStack` containing `TH1` only or
2674`THStack` containing `TH2` only will be considered.
2675
2676By default, histograms are shown stacked:
2677
26781. The first histogram is paint.
26792. The the sum of the first and second, etc...
2680
2681If the option `NOSTACK` is specified, the histograms are all paint in
2682the same pad as if the option `SAME` had been specified. This allows to
2683compute X and Y scales common to all the histograms, like
2684`TMultiGraph` does for graphs.
2685
2686If the option `PADS` is specified, the current pad/canvas is
2687subdivided into a number of pads equal to the number of histograms and each
2688histogram is paint into a separate pad.
2689
2690The following example shows various types of stacks (hstack.C).
2691
2692Begin_Macro(source)
2693../../../tutorials/hist/hstack.C
2694End_Macro
2695
2696The option `nostackb` allows to draw the histograms next to each
2697other as bar charts:
2698
2699Begin_Macro(source)
2700{
2701 auto cst0 = new TCanvas("cst0","cst0",600,400);
2702 auto hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2703
2704 auto h1 = new TH1F("h1","h1",10,-4,4);
2705 h1->FillRandom("gaus",20000);
2706 h1->SetFillColor(kRed);
2707 hs->Add(h1);
2708
2709 auto h2 = new TH1F("h2","h2",10,-4,4);
2710 h2->FillRandom("gaus",15000);
2711 h2->SetFillColor(kBlue);
2712 hs->Add(h2);
2713
2714 auto h3 = new TH1F("h3","h3",10,-4,4);
2715 h3->FillRandom("gaus",10000);
2716 h3->SetFillColor(kGreen);
2717 hs->Add(h3);
2718
2719 hs->Draw("nostackb");
2720 hs->GetXaxis()->SetNdivisions(-10);
2721 cst0->SetGridx();
2722}
2723End_Macro
2724
2725If at least one of the histograms in the stack has errors, the whole stack is
2726visualized by default with error bars. To visualize it without errors the
2727option `HIST` should be used.
2728
2729Begin_Macro(source)
2730{
2731 auto cst1 = new TCanvas("cst1","cst1",700,400);
2732 cst1->Divide(2,1);
2733
2734 auto hst11 = new TH1F("hst11", "", 20, -10, 10);
2735 hst11->Sumw2();
2736 hst11->FillRandom("gaus", 1000);
2737 hst11->SetFillColor(kViolet);
2738 hst11->SetLineColor(kViolet);
2739
2740 auto hst12 = new TH1F("hst12", "", 20, -10, 10);
2741 hst12->FillRandom("gaus", 500);
2742 hst12->SetFillColor(kBlue);
2743 hst12->SetLineColor(kBlue);
2744
2745 THStack st1("st1", "st1");
2746 st1.Add(hst11);
2747 st1.Add(hst12);
2748
2749 cst1->cd(1); st1.Draw();
2750 cst1->cd(2); st1.Draw("hist");
2751}
2752End_Macro
2753
2754### <a name="HP27"></a> Drawing of 3D implicit functions
2755
2756
27573D implicit functions (`TF3`) can be drawn as iso-surfaces.
2758The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2759In the following example the options "FB" and "BB" suppress the
2760"Front Box" and "Back Box" around the plot.
2761
2762Begin_Macro(source)
2763{
2764 auto c2 = new TCanvas("c2","c2",600,400);
2765 auto f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2766 f3->SetClippingBoxOn(0,0,0);
2767 f3->SetFillColor(30);
2768 f3->SetLineColor(15);
2769 f3->Draw("FBBB");
2770}
2771End_Macro
2772
2773
2774### <a name="HP28"></a> Associated functions drawing
2775
2776
2777An associated function is created by `TH1::Fit`. More than on fitted
2778function can be associated with one histogram (see `TH1::Fit`).
2779
2780A `TF1` object `f1` can be added to the list of associated
2781functions of an histogram `h` without calling `TH1::Fit`
2782simply doing:
2783
2784 h->GetListOfFunctions()->Add(f1);
2785
2786or
2787
2788 h->GetListOfFunctions()->Add(f1,someoption);
2789
2790To retrieve a function by name from this list, do:
2791
2792 TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2793
2794or
2795
2796 TF1 *f1 = h->GetFunction(name);
2797
2798Associated functions are automatically painted when an histogram is drawn.
2799To avoid the painting of the associated functions the option `HIST`
2800should be added to the list of the options used to paint the histogram.
2801
2802
2803### <a name="HP29"></a> Drawing using OpenGL
2804
2805
2806The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2807graphics library. The plotting options start with `GL` keyword.
2808In addition, in order to inform canvases that OpenGL should be used to render
28093D representations, the following option should be set:
2810
2811 gStyle->SetCanvasPreferGL(true);
2812
2813
2814#### <a name="HP29a"></a> General information: plot types and supported options
2815
2816The following types of plots are provided:
2817
2818For lego plots the supported options are:
2819
2820| Option | Description |
2821|----------|-------------------------------------------------------------------|
2822| "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2823| "GLLEGO2"| Bins with color levels.|
2824| "GLLEGO3"| Cylindrical bars.|
2825
2826
2827
2828Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2829In polar only Z axis can be logarithmic, in cylindrical only Y.
2830
2831For surface plots (`TF2` and `TH2`) the supported options are:
2832
2833| Option | Description |
2834|-----------|------------------------------------------------------------------|
2835| "GLSURF" | Draw a surface.|
2836| "GLSURF1" | Surface with color levels|
2837| "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2838| "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2839| "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2840
2841
2842
2843The surface painting in cartesian coordinates supports logarithmic scales along
2844X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2845in cylindrical coordinates only the Y axis.
2846
2847Additional options to SURF and LEGO - Coordinate systems:
2848
2849| Option | Description |
2850|----------|-------------------------------------------------------------------|
2851| " " | Default, cartesian coordinates system.|
2852| "POL" | Polar coordinates system.|
2853| "CYL" | Cylindrical coordinates system.|
2854| "SPH" | Spherical coordinates system.|
2855
2856
2857
2858#### <a name="HP290"></a> TH3 as color boxes
2859
2860The supported option is:
2861
2862| Option | Description |
2863|----------|-------------------------------------------------------------------|
2864| "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2865
2866
2867
2868#### <a name="HP29b"></a> TH3 as boxes (spheres)
2869
2870The supported options are:
2871
2872| Option | Description |
2873|----------|-------------------------------------------------------------------|
2874| "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2875| "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2876
2877
2878
2879#### <a name="HP29c"></a> TH3 as iso-surface(s)
2880
2881The supported option is:
2882
2883| Option | Description |
2884|----------|-------------------------------------------------------------------|
2885| "GLISO" | TH3 is drawn using iso-surfaces.|
2886
2887
2888
2889#### <a name="HP29d"></a> TF3 (implicit function)
2890
2891The supported option is:
2892
2893| Option | Description |
2894|----------|-------------------------------------------------------------------|
2895| "GLTF3" | Draw a TF3.|
2896
2897
2898
2899#### <a name="HP29e"></a> Parametric surfaces
2900
2901`$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2902equations and visualize the surface.
2903
2904#### <a name="HP29f"></a> Interaction with the plots
2905
2906All the interactions are implemented via standard methods
2907`DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2908interactions with the OpenGL plots are possible only when the mouse cursor is
2909in the plot's area (the plot's area is the part of a the pad occupied by
2910gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2911pad interaction is performed.
2912
2913#### <a name="HP29g"></a> Selectable parts
2914
2915Different parts of the plot can be selected:
2916
2917- xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2918 if the dynamic slicing by this plane is supported, and it's highlighted in red,
2919 if the dynamic slicing is not supported.
2920- The plot itself:
2921 On surfaces, the selected surface is outlined in red. (TF3 and
2922 ISO are not outlined). On lego plots, the selected bin is
2923 highlighted. The bin number and content are displayed in pad's
2924 status bar. In box plots, the box or sphere is highlighted and
2925 the bin info is displayed in pad's status bar.
2926
2927
2928#### <a name="HP29h"></a> Rotation and zooming
2929
2930
2931- Rotation:
2932 When the plot is selected, it can be rotated by pressing and
2933 holding the left mouse button and move the cursor.
2934- Zoom/Unzoom:
2935 Mouse wheel or 'j', 'J', 'k', 'K' keys.
2936
2937
2938#### <a name="HP29i"></a> Panning
2939
2940The selected plot can be moved in a pad's area by pressing and
2941holding the left mouse button and the shift key.
2942
2943#### <a name="HP29j"></a> Box cut
2944
2945Surface, iso, box, TF3 and parametric painters support box cut by
2946pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2947area. That will display a transparent box, cutting away part of the
2948surface (or boxes) in order to show internal part of plot. This box
2949can be moved inside the plot's area (the full size of the box is
2950equal to the plot's surrounding box) by selecting one of the box
2951cut axes and pressing the left mouse button to move it.
2952
2953#### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2954
2955Currently, all gl-plots support some form of slicing. When back plane
2956is selected (and if it's highlighted in green) you can press and hold
2957left mouse button and shift key and move this back plane inside
2958plot's area, creating the slice. During this "slicing" plot becomes
2959semi-transparent. To remove all slices (and projected curves for
2960surfaces) double click with left mouse button in a plot's area.
2961
2962#### <a name="HP29l"></a> Surface with option "GLSURF"
2963
2964The surface profile is displayed on the slicing plane.
2965The profile projection is drawn on the back plane
2966by pressing `'p'` or `'P'` key.
2967
2968#### <a name="HP29m"></a> TF3
2969
2970The contour plot is drawn on the slicing plane. For TF3 the color
2971scheme can be changed by pressing 's' or 'S'.
2972
2973#### <a name="HP29n"></a> Box
2974
2975The contour plot corresponding to slice plane position is drawn in real time.
2976
2977#### <a name="HP29o"></a> Iso
2978
2979Slicing is similar to "GLBOX" option.
2980
2981#### <a name="HP29p"></a> Parametric plot
2982
2983No slicing. Additional keys: 's' or 'S' to change color scheme -
2984about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2985increase number of polygons ('l' for "level" of details), 'w' or 'W'
2986to show outlines ('w' for "wireframe").
2987
2988#### <a name="HP30"></a> Highlight mode for histogram
2989
2990\since **ROOT version 6.15/01**
2991
2992\image html hlHisto3_top.gif "Highlight mode"
2993
2994Highlight mode is implemented for `TH1` (and for `TGraph`) class. When
2995highlight mode is on, mouse movement over the bin will be represented
2996graphically. Bin will be highlighted as "bin box" (presented by box
2997object). Moreover, any highlight (change of bin) emits signal
2998`TCanvas::Highlighted()` which allows the user to react and call their own
2999function. For a better understanding see also the tutorials
3000`$ROOTSYS/tutorials/hist/hlHisto*.C` files.
3001
3002Highlight mode is switched on/off by `TH1::SetHighlight()` function
3003or interactively from `TH1` context menu. `TH1::IsHighlight()` to verify
3004whether the highlight mode enabled or disabled, default it is disabled.
3005
3006~~~ {.cpp}
3007 root [0] .x $ROOTSYS/tutorials/hsimple.C
3008 root [1] hpx->SetHighlight(kTRUE) // or interactively from TH1 context menu
3009 root [2] hpx->IsHighlight()
3010 (bool) true
3011~~~
3012
3013\image html hlsimple_nofun.gif "Highlight mode for histogram"
3014
3015#### <a name="HP30a"></a> Highlight mode and user function
3016
3017The user can use (connect) `TCanvas::Highlighted()` signal, which is always
3018emitted if there is a highlight bin and call user function via signal
3019and slot communication mechanism. `TCanvas::Highlighted()` is similar
3020`TCanvas::Picked()`
3021
3022- when selected object (histogram as a whole) is different from previous
3023then emit `Picked()` signal
3024- when selected (highlighted) bin from histogram is different from previous
3025then emit `Highlighted()` signal
3026
3027Any user function (or functions) has to be defined
3028`UserFunction(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)`.
3029In example (see below) has name `PrintInfo()`. All parameters of user
3030function are taken from
3031
3032 void TCanvas::Highlighted(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3033
3034- `pad` is pointer to pad with highlighted histogram
3035- `obj` is pointer to highlighted histogram
3036- `x` is highlighted x bin for 1D histogram
3037- `y` is highlighted y bin for 2D histogram (for 1D histogram not in use)
3038
3039Example how to create a connection from any `TCanvas` object to a user
3040`UserFunction()` slot (see also `TQObject::Connect()` for additional info)
3041
3042 TQObject::Connect("TCanvas", "Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
3043 0, 0, "UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3044
3045or use non-static "simplified" function
3046`TCanvas::HighlightConnect(const char *slot)`
3047
3048 c1->HighlightConnect("UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3049
3050NOTE the signal and slot string must have a form
3051"(TVirtualPad*,TObject*,Int_t,Int_t)"
3052
3053 root [0] .x $ROOTSYS/tutorials/hsimple.C
3054 root [1] hpx->SetHighlight(kTRUE)
3055 root [2] .x hlprint.C
3056
3057file `hlprint.C`
3058~~~ {.cpp}
3059void PrintInfo(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3060{
3061 auto h = (TH1F *)obj;
3062 if (!h->IsHighlight()) // after highlight disabled
3063 h->SetTitle("highlight disable");
3064 else
3065 h->SetTitle(TString::Format("bin[%03d] (%5.2f) content %g", x,
3066 h->GetBinCenter(x), h->GetBinContent(x)));
3067 pad->Update();
3068}
3069
3070void hlprint()
3071{
3072 if (!gPad) return;
3073 gPad->GetCanvas()->HighlightConnect("PrintInfo(TVirtualPad*,TObject*,Int_t,Int_t)");
3074}
3075~~~
3076
3077\image html hlsimple.gif "Highlight mode and simple user function"
3078
3079For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperature.C` file.
3080
3081*/
3082
3084
3087
3088const Int_t kNMAX = 2000;
3089
3090const Int_t kMAXCONTOUR = 104;
3092
3093static TBox *gXHighlightBox = 0; // highlight X box
3094static TBox *gYHighlightBox = 0; // highlight Y box
3095
3117
3119
3120////////////////////////////////////////////////////////////////////////////////
3121/// Default constructor.
3122
3124{
3125
3126 fH = 0;
3127 fXaxis = 0;
3128 fYaxis = 0;
3129 fZaxis = 0;
3130 fFunctions = 0;
3131 fXbuf = 0;
3132 fYbuf = 0;
3133 fNcuts = 0;
3134 fStack = 0;
3135 fLego = 0;
3136 fPie = 0;
3137 fGraph2DPainter = 0;
3138 fShowProjection = 0;
3139 fShowOption = "";
3140 for (int i=0; i<kMaxCuts; i++) {
3141 fCuts[i] = 0;
3142 fCutsOpt[i] = 0;
3143 }
3144 fXHighlightBin = -1;
3145 fYHighlightBin = -1;
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}
3176
3177////////////////////////////////////////////////////////////////////////////////
3178/// Compute the distance from the point px,py to a line.
3179///
3180/// Compute the closest distance of approach from point px,py to elements of
3181/// an histogram. The distance is computed in pixels units.
3182///
3183/// Algorithm: Currently, this simple model computes the distance from the mouse
3184/// to the histogram contour only.
3185
3187{
3188
3189 Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3190
3191 const Int_t big = 9999;
3192 const Int_t kMaxDiff = 7;
3193
3194 if (fPie) return fPie->DistancetoPrimitive(px, py);
3195
3196 Double_t x = gPad->AbsPixeltoX(px);
3197 Double_t x1 = gPad->AbsPixeltoX(px+1);
3198
3199 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3200 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3201 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3202 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3203 Int_t curdist = big;
3204 Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3205 Bool_t dsame;
3206 TObject *PadPointer = gPad->GetPadPointer();
3207 if (!PadPointer) return 0;
3208 TString doption = PadPointer->GetDrawOption();
3209 Double_t factor = 1;
3210 if (fH->GetNormFactor() != 0) {
3211 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3212 }
3213 // return if point is not in the histogram area
3214
3215 // If a 3D view exists, check distance to axis
3216 TView *view = gPad->GetView();
3217 Int_t d1,d2,d3;
3218 if (view && Hoption.Contour != 14) {
3219 Double_t ratio;
3220 d3 = view->GetDistancetoAxis(3, px, py, ratio);
3221 if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3222 d1 = view->GetDistancetoAxis(1, px, py, ratio);
3223 if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3224 d2 = view->GetDistancetoAxis(2, px, py, ratio);
3225 if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3226 if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3227 goto FUNCTIONS;
3228 }
3229 // check if point is close to an axis
3230 doption.ToLower();
3231 dsame = kFALSE;
3232 if (doption.Contains("same")) dsame = kTRUE;
3233
3234 dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3235 if (doption.Contains("y+")) {
3236 xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3237 if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3238 if (!dsame) {
3239 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3240 else gPad->SetSelected(fXaxis);
3241 return 0;
3242 }
3243 }
3244 } else {
3245 xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3246 if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3247 if (!dsame) {
3248 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3249 else gPad->SetSelected(fXaxis);
3250 return 0;
3251 }
3252 }
3253 }
3254
3255 dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3256 if (doption.Contains("x+")) {
3257 yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3258 if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3259 if (!dsame) {
3260 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3261 else gPad->SetSelected(fYaxis);
3262 return 0;
3263 }
3264 }
3265 } else {
3266 yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3267 if (yxaxis < puymin) yxaxis = puymin;
3268 if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3269 if (!dsame) {
3270 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3271 else gPad->SetSelected(fYaxis);
3272 return 0;
3273 }
3274 }
3275 }
3276
3277 if (fH->IsHighlight()) { // only if highlight is enable
3278 if ((px > puxmin) && (py < puymin) && (px < puxmax) && (py > puymax))
3279 HighlightBin(px, py);
3280 }
3281
3282 // if object is 2D or 3D return this object
3283 if (fH->GetDimension() == 2) {
3284 if (fH->InheritsFrom(TH2Poly::Class())) {
3285 TH2Poly *th2 = (TH2Poly*)fH;
3287 gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3288 Double_t pxu = gPad->AbsPixeltoX(px);
3289 Double_t pyu = gPad->AbsPixeltoY(py);
3290 if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3291 curdist = big;
3292 goto FUNCTIONS;
3293 } else {
3294 Int_t bin = th2->FindBin(pxu, pyu);
3295 if (bin>0) curdist = 1;
3296 else curdist = big;
3297 goto FUNCTIONS;
3298 }
3299 }
3300 Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3301 if ( px > puxmin + delta2
3302 && px < puxmax - delta2
3303 && py > puymax + delta2
3304 && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3305 }
3306
3307 // point is inside histogram area. Find channel number
3308 if (gPad->IsVertical()) {
3309 Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3310 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3311 Double_t binval = factor*fH->GetBinContent(bin);
3312 Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3313 if (binval == 0 && pybin < puymin) pybin = 10000;
3314 // special case if more than one bin for the pixel
3315 if (binsup-bin>1) {
3316 Double_t binvalmin, binvalmax;
3317 binvalmin=binval;
3318 binvalmax=binval;
3319 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3320 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3321 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3322 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3323 }
3324 Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3325 Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3326 if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3327 }
3328 if (bin != binsup) { // Mouse on bin border
3329 Double_t binsupval = factor*fH->GetBinContent(binsup);
3330 Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3331 if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3332 }
3333 if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3334 } else {
3335 Double_t y = gPad->AbsPixeltoY(py);
3336 Double_t y1 = gPad->AbsPixeltoY(py+1);
3337 Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3338 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3339 Double_t binval = factor*fH->GetBinContent(bin);
3340 Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3341 if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3342 // special case if more than one bin for the pixel
3343 if (binsup-bin>1) {
3344 Double_t binvalmin, binvalmax;
3345 binvalmin=binval;
3346 binvalmax=binval;
3347 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3348 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3349 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3350 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3351 }
3352 Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3353 Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3354 if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3355 }
3356 if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3357 }
3358 // Loop on the list of associated functions and user objects
3359FUNCTIONS:
3360 TObject *f;
3361 TIter next(fFunctions);
3362 while ((f = (TObject*) next())) {
3363 Int_t dist;
3364 if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3365 else dist = f->DistancetoPrimitive(px,py);
3366 if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3367 }
3368 return curdist;
3369}
3370
3371////////////////////////////////////////////////////////////////////////////////
3372/// Display a panel with all histogram drawing options.
3373
3375{
3376
3377 gCurrentHist = fH;
3378 if (!gPad) {
3379 Error("DrawPanel", "need to draw histogram first");
3380 return;
3381 }
3383 editor->Show();
3384 gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3385 (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3386}
3387
3388////////////////////////////////////////////////////////////////////////////////
3389/// Execute the actions corresponding to `event`.
3390///
3391/// This function is called when a histogram is clicked with the locator at
3392/// the pixel position px,py.
3393
3395{
3396
3397 if (!gPad) return;
3398
3399 static Int_t bin, px1, py1, px2, py2, pyold;
3400 static TBox *zoombox;
3401 Double_t zbx1,zbx2,zby1,zby2;
3402
3403 Int_t bin1, bin2;
3404 Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3405 Bool_t opaque = gPad->OpaqueMoving();
3406
3407 if (!gPad->IsEditable()) return;
3408
3409 if (fPie) {
3410 fPie->ExecuteEvent(event, px, py);
3411 return;
3412 }
3413 // come here if we have a lego/surface in the pad
3414 TView *view = gPad->GetView();
3415
3416 if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3417 view->ExecuteRotateView(event, px, py);
3418 return;
3419 }
3420
3421 TAxis *xaxis = fH->GetXaxis();
3422 TAxis *yaxis = fH->GetYaxis();
3423 Int_t dimension = fH->GetDimension();
3424
3425 // In case of option SAME the axis must be the ones of the first drawn histogram
3426 TString IsSame = fH->GetDrawOption();
3427 IsSame.ToLower();
3428 if (IsSame.Index("same")>=0) {
3429 TH1 *h1;
3430 TIter next(gPad->GetListOfPrimitives());
3431 while ((h1 = (TH1 *)next())) {
3432 if (!h1->InheritsFrom(TH1::Class())) continue;
3433 xaxis = h1->GetXaxis();
3434 yaxis = h1->GetYaxis();
3435 break;
3436 }
3437 }
3438
3439 Double_t factor = 1;
3440 if (fH->GetNormFactor() != 0) {
3441 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3442 }
3443
3444 switch (event) {
3445
3446 case kButton1Down:
3447
3448 if (!opaque) gVirtualX->SetLineColor(-1);
3449 fH->TAttLine::Modify();
3450
3451 if (opaque && dimension ==2) {
3452 zbx1 = gPad->AbsPixeltoX(px);
3453 zbx2 = gPad->AbsPixeltoX(px);
3454 zby1 = gPad->AbsPixeltoY(py);
3455 zby2 = gPad->AbsPixeltoY(py);
3456 px1 = px;
3457 py1 = py;
3458 if (gPad->GetLogx()) {
3459 zbx1 = TMath::Power(10,zbx1);
3460 zbx2 = TMath::Power(10,zbx2);
3461 }
3462 if (gPad->GetLogy()) {
3463 zby1 = TMath::Power(10,zby1);
3464 zby2 = TMath::Power(10,zby2);
3465 }
3466 zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3467 Int_t ci = TColor::GetColor("#7d7dff");
3468 TColor *zoomcolor = gROOT->GetColor(ci);
3469 if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3470 else zoomcolor->SetAlpha(0.5);
3471 zoombox->SetFillColor(ci);
3472 zoombox->Draw();
3473 gPad->Modified();
3474 gPad->Update();
3475 }
3476 // No break !!!
3477
3478 case kMouseMotion:
3479
3480 if (fShowProjection) {ShowProjection3(px,py); break;}
3481
3482 gPad->SetCursor(kPointer);
3483 if (dimension ==1) {
3484 if (Hoption.Bar) {
3485 baroffset = fH->GetBarOffset();
3486 barwidth = fH->GetBarWidth();
3487 } else {
3488 baroffset = 0;
3489 barwidth = 1;
3490 }
3491 x = gPad->AbsPixeltoX(px);
3492 bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3493 binwidth = fXaxis->GetBinWidth(bin);
3494 xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3495 xup = gPad->XtoPad(xlow + barwidth*binwidth);
3496 ylow = gPad->GetUymin();
3497 px1 = gPad->XtoAbsPixel(xlow);
3498 px2 = gPad->XtoAbsPixel(xup);
3499 py1 = gPad->YtoAbsPixel(ylow);
3500 py2 = py;
3501 pyold = py;
3502 if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3503 }
3504
3505 break;
3506
3507 case kButton1Motion:
3508
3509 if (dimension ==1) {
3510 if (gROOT->GetEditHistograms()) {
3511 if (!opaque) {
3512 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3513 py2 += py - pyold;
3514 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3515 pyold = py;
3516 } else {
3517 py2 += py - pyold;
3518 pyold = py;
3519 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3520 fH->SetBinContent(bin,binval);
3521 gPad->Modified(kTRUE);
3522 }
3523 }
3524 }
3525
3526 if (opaque && dimension ==2) {
3527 if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3528 zbx2 = gPad->AbsPixeltoX(px);
3529 zby2 = gPad->AbsPixeltoY(py);
3530 if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3531 if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3532 zoombox->SetX2(zbx2);
3533 zoombox->SetY2(zby2);
3534 gPad->Modified();
3535 gPad->Update();
3536 }
3537 }
3538
3539 break;
3540
3541 case kWheelUp:
3542
3543 if (dimension ==2) {
3544 bin1 = xaxis->GetFirst()+1;
3545 bin2 = xaxis->GetLast()-1;
3546 bin1 = TMath::Max(bin1, 1);
3547 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3548 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3549 bin1 = yaxis->GetFirst()+1;
3550 bin2 = yaxis->GetLast()-1;
3551 bin1 = TMath::Max(bin1, 1);
3552 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3553 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3554 }
3555 gPad->Modified();
3556 gPad->Update();
3557
3558 break;
3559
3560 case kWheelDown:
3561
3562 if (dimension == 2) {
3563 bin1 = xaxis->GetFirst()-1;
3564 bin2 = xaxis->GetLast()+1;
3565 bin1 = TMath::Max(bin1, 1);
3566 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3567 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3568 bin1 = yaxis->GetFirst()-1;
3569 bin2 = yaxis->GetLast()+1;
3570 bin1 = TMath::Max(bin1, 1);
3571 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3572 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3573 }
3574 gPad->Modified();
3575 gPad->Update();
3576
3577 break;
3578
3579 case kButton1Up:
3580 if (dimension ==1) {
3581 if (gROOT->GetEditHistograms()) {
3582 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3583 fH->SetBinContent(bin,binval);
3584 PaintInit(); // recalculate Hparam structure and recalculate range
3585 }
3586
3587 // might resize pad pixmap so should be called before any paint routine
3589 }
3590 if (opaque && dimension ==2) {
3591 if (zoombox) {
3592 Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3593 Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3594 Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3595 Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3596 x1 = TMath::Max(x1,xaxis->GetXmin());
3597 x2 = TMath::Min(x2,xaxis->GetXmax());
3598 y1 = TMath::Max(y1,yaxis->GetXmin());
3599 y2 = TMath::Min(y2,yaxis->GetXmax());
3600 if (x1<x2 && y1<y2) {
3601 xaxis->SetRangeUser(x1, x2);
3602 yaxis->SetRangeUser(y1, y2);
3603 }
3604 zoombox->Delete();
3605 zoombox = 0;
3606 }
3607 }
3608 gPad->Modified(kTRUE);
3609 if (opaque) gVirtualX->SetLineColor(-1);
3610
3611 break;
3612
3613 case kButton1Locate:
3614
3615 ExecuteEvent(kButton1Down, px, py);
3616
3617 while (1) {
3618 px = py = 0;
3619 event = gVirtualX->RequestLocator(1, 1, px, py);
3620
3622
3623 if (event != -1) { // button is released
3624 ExecuteEvent(kButton1Up, px, py);
3625 return;
3626 }
3627 }
3628 }
3629}
3630
3631////////////////////////////////////////////////////////////////////////////////
3632/// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3633
3635{
3636
3637
3638
3639 // Check if fH contains a TGraphDelaunay2D
3640 TList *hl = fH->GetListOfFunctions();
3641 TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3642 // try with the old painter
3643 TGraphDelaunay *dtOld = nullptr;
3644 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3645
3646 if (!dt && !dtOld) return nullptr;
3647
3648 gCurrentHist = fH;
3649
3650 if (!fGraph2DPainter) {
3651 if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3652 else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3653 }
3654
3655 return fGraph2DPainter->GetContourList(contour);
3656}
3657
3658////////////////////////////////////////////////////////////////////////////////
3659/// Display the histogram info (bin number, contents, integral up to bin
3660/// corresponding to cursor position px,py.
3661
3663{
3664
3665 if (!gPad) return (char*)"";
3666
3667 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3668 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3669 Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3670 TString drawOption = fH->GetDrawOption();
3671 drawOption.ToLower();
3672 Double_t xmin, xmax, uxmin,uxmax;
3673 Double_t ymin, ymax, uymin,uymax;
3674 if (fH->GetDimension() == 2) {
3675 if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3676 uxmin=gPad->GetUxmin();
3677 uxmax=gPad->GetUxmax();
3680 x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3681 uymin=gPad->GetUymin();
3682 uymax=gPad->GetUymax();
3685 y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3686 }
3687 }
3688 Int_t binx,biny,binmin=0,binx1;
3689 if (gPad->IsVertical()) {
3690 binx = fXaxis->FindFixBin(x);
3691 if (drawOption.Index("same") >= 0) {
3692 TH1 *h1;
3693 TIter next(gPad->GetListOfPrimitives());
3694 while ((h1 = (TH1 *)next())) {
3695 if (!h1->InheritsFrom(TH1::Class())) continue;
3696 binmin = h1->GetXaxis()->GetFirst();
3697 break;
3698 }
3699 } else {
3700 binmin = fXaxis->GetFirst();
3701 }
3702 binx1 = fXaxis->FindFixBin(x1);
3703 // special case if more than 1 bin in x per pixel
3704 if (binx1-binx>1 && fH->GetDimension() == 1) {
3705 Double_t binval=fH->GetBinContent(binx);
3706 Int_t binnear=binx;
3707 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3708 Double_t binvaltmp = fH->GetBinContent(ibin);
3709 if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3710 binval=binvaltmp;
3711 binnear=ibin;
3712 }
3713 }
3714 binx = binnear;
3715 }
3716 } else {
3717 x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3718 binx = fXaxis->FindFixBin(y);
3719 if (drawOption.Index("same") >= 0) {
3720 TH1 *h1;
3721 TIter next(gPad->GetListOfPrimitives());
3722 while ((h1 = (TH1 *)next())) {
3723 if (!h1->InheritsFrom(TH1::Class())) continue;
3724 binmin = h1->GetXaxis()->GetFirst();
3725 break;
3726 }
3727 } else {
3728 binmin = fXaxis->GetFirst();
3729 }
3730 binx1 = fXaxis->FindFixBin(x1);
3731 // special case if more than 1 bin in x per pixel
3732 if (binx1-binx>1 && fH->GetDimension() == 1) {
3733 Double_t binval=fH->GetBinContent(binx);
3734 Int_t binnear=binx;
3735 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3736 Double_t binvaltmp = fH->GetBinContent(ibin);
3737 if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3738 binval=binvaltmp;
3739 binnear=ibin;
3740 }
3741 }
3742 binx = binnear;
3743 }
3744 }
3745 if (fH->GetDimension() == 1) {
3747 TProfile *tp = (TProfile*)fH;
3748 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3749 x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3750 (Int_t) tp->GetBinEntries(binx));
3751 }
3752 else {
3753 Double_t integ = 0;
3754 for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3755 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3756 x,y,binx,fH->GetBinContent(binx),integ);
3757 }
3758 } else if (fH->GetDimension() == 2) {
3759 if (fH->InheritsFrom(TH2Poly::Class())) {
3760 TH2Poly *th2 = (TH2Poly*)fH;
3761 biny = th2->FindBin(x,y);
3762 fObjectInfo.Form("%s (x=%g, y=%g, bin=%d, binc=%g)",
3763 th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3764 }
3765 else if (fH->InheritsFrom(TProfile2D::Class())) {
3766 TProfile2D *tp = (TProfile2D*)fH;
3767 biny = fYaxis->FindFixBin(y);
3768 Int_t bin = fH->GetBin(binx,biny);
3769 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3770 x, y, binx, biny, fH->GetBinContent(bin),
3771 fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3772 } else {
3773 biny = fYaxis->FindFixBin(y);
3774 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3775 x,y,binx,biny,fH->GetBinContent(binx,biny),
3776 fH->GetBinError(binx,biny));
3777 }
3778 } else {
3779 // 3d case: retrieving the x,y,z bin is not yet implemented
3780 // print just the x,y info
3781 fObjectInfo.Form("(x=%g, y=%g)",x,y);
3782 }
3783
3784 return (char *)fObjectInfo.Data();
3785}
3786
3787////////////////////////////////////////////////////////////////////////////////
3788/// Set highlight (enable/disable) mode for fH
3789
3791{
3792 if (fH->IsHighlight()) return;
3793
3794 fXHighlightBin = -1;
3795 fYHighlightBin = -1;
3796 // delete previous highlight box
3799 // emit Highlighted() signal (user can check on disabled)
3800 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3801}
3802
3803////////////////////////////////////////////////////////////////////////////////
3804/// Check on highlight bin
3805
3807{
3808 // call from DistancetoPrimitive (only if highlight is enable)
3809
3810 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3811 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3812 Int_t binx = fXaxis->FindFixBin(x);
3813 Int_t biny = fYaxis->FindFixBin(y);
3814 if (!gPad->IsVertical()) binx = fXaxis->FindFixBin(y);
3815
3816 Bool_t changedBin = kFALSE;
3817 if (binx != fXHighlightBin) {
3818 fXHighlightBin = binx;
3819 changedBin = kTRUE;
3820 } else if (fH->GetDimension() == 1) return;
3821 if (biny != fYHighlightBin) {
3822 fYHighlightBin = biny;
3823 changedBin = kTRUE;
3824 }
3825 if (!changedBin) return;
3826
3827 // Info("HighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3828 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3829
3830 // paint highlight bin as box (recursive calls PaintHighlightBin)
3831 gPad->Modified(kTRUE);
3832 gPad->Update();
3833
3834 // emit Highlighted() signal
3835 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3836}
3837
3838////////////////////////////////////////////////////////////////////////////////
3839/// Paint highlight bin as TBox object
3840
3842{
3843 // call from PaintTitle
3844
3845 if (!fH->IsHighlight()) return;
3846
3847 Double_t uxmin = gPad->GetUxmin();
3848 Double_t uxmax = gPad->GetUxmax();
3849 Double_t uymin = gPad->GetUymin();
3850 Double_t uymax = gPad->GetUymax();
3851 if (gPad->GetLogx()) {
3852 uxmin = TMath::Power(10.0, uxmin);
3853 uxmax = TMath::Power(10.0, uxmax);
3854 }
3855 if (gPad->GetLogy()) {
3856 uymin = TMath::Power(10.0, uymin);
3857 uymax = TMath::Power(10.0, uymax);
3858 }
3859
3860 // testing specific possibility (after zoom, draw with "same", log, etc.)
3861 Double_t hcenter;
3862 if (gPad->IsVertical()) {
3864 if ((hcenter < uxmin) || (hcenter > uxmax)) return;
3865 } else {
3867 if ((hcenter < uymin) || (hcenter > uymax)) return;
3868 }
3869 if (fH->GetDimension() == 2) {
3871 if ((hcenter < uymin) || (hcenter > uymax)) return;
3872 }
3873
3874 // paint X highlight bin (for 1D or 2D)
3875 Double_t hbx1, hbx2, hby1, hby2;
3876 if (gPad->IsVertical()) {
3879 hby1 = uymin;
3880 hby2 = uymax;
3881 } else {
3882 hbx1 = uxmin;
3883 hbx2 = uxmax;
3886 }
3887
3888 if (!gXHighlightBox) {
3889 gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3893 else gROOT->GetColor(gXHighlightBox->GetFillColor())->SetAlpha(0.5);
3894 }
3895 gXHighlightBox->SetX1(hbx1);
3896 gXHighlightBox->SetX2(hbx2);
3897 gXHighlightBox->SetY1(hby1);
3898 gXHighlightBox->SetY2(hby2);
3900
3901 // Info("PaintHighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3902 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3903
3904 // paint Y highlight bin (only for 2D)
3905 if (fH->GetDimension() != 2) return;
3906 hbx1 = uxmin;
3907 hbx2 = uxmax;
3910
3911 if (!gYHighlightBox) {
3912 gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3916 }
3917 gYHighlightBox->SetX1(hbx1);
3918 gYHighlightBox->SetX2(hbx2);
3919 gYHighlightBox->SetY1(hby1);
3920 gYHighlightBox->SetY2(hby2);
3922}
3923
3924////////////////////////////////////////////////////////////////////////////////
3925/// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3926
3928{
3929
3930 for (Int_t i=0;i<fNcuts;i++) {
3933 if (fCutsOpt[i] > 0) {
3934 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3935 } else {
3936 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3937 }
3938 }
3939 return kTRUE;
3940}
3941
3942////////////////////////////////////////////////////////////////////////////////
3943/// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3944
3946{
3947
3948 for (Int_t i=0;i<fNcuts;i++) {
3949 if (fCutsOpt[i] > 0) {
3950 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3951 } else {
3952 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3953 }
3954 }
3955 return kTRUE;
3956}
3957
3958////////////////////////////////////////////////////////////////////////////////
3959/// Decode string `choptin` and fill Hoption structure.
3960
3962{
3963
3964 char *l;
3965 char chopt[128];
3966 Int_t nch = strlen(choptin);
3967 strlcpy(chopt,choptin,128);
3968 Int_t hdim = fH->GetDimension();
3969
3978
3979 // special 2D options
3980 Hoption.List = 0;
3981 Hoption.Zscale = 0;
3982 Hoption.FrontBox = 1;
3983 Hoption.BackBox = 1;
3985
3986 Hoption.Zero = 0;
3987
3989
3990 //check for graphical cuts
3991 MakeCuts(chopt);
3992
3993 for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3994 if (hdim > 1) Hoption.Scat = 1;
3995 if (!nch) Hoption.Hist = 1;
3996 if (fFunctions->First()) Hoption.Func = 1;
3997 if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3998
3999 char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
4000 char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
4001 char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
4002 if (l1 || l2 || l3) {
4003 Int_t i = gPad->NextPaletteColor();
4004 if (l1) {memcpy(l1," ",3); fH->SetFillColor(i);}
4005 if (l2) {memcpy(l2," ",3); fH->SetLineColor(i);}
4006 if (l3) {memcpy(l3," ",3); fH->SetMarkerColor(i);}
4007 Hoption.Hist = 1; // Make sure something is drawn in case there is no drawing option specified.
4008 }
4009
4010 l = strstr(chopt,"MIN0");
4011 if (l) {
4012 Hoption.MinimumZero = 1;
4013 memcpy(l," ",4);
4014 }
4015
4016 l = strstr(chopt,"SPEC");
4017 if (l) {
4018 Hoption.Scat = 0;
4019 memcpy(l," ",4);
4020 Int_t bs=0;
4021 l = strstr(chopt,"BF(");
4022 if (l) {
4023 if (sscanf(&l[3],"%d",&bs) > 0) {
4024 Int_t i=0;
4025 while (l[i]!=')') {
4026 l[i] = ' ';
4027 i++;
4028 }
4029 l[i] = ' ';
4030 }
4031 }
4032 Hoption.Spec = TMath::Max(1600,bs);
4033 return 1;
4034 }
4035
4036 l = strstr(chopt,"GL");
4037 if (l) {
4038 memcpy(l," ",2);
4039 }
4040 l = strstr(chopt,"X+");
4041 if (l) {
4042 Hoption.AxisPos = 10;
4043 memcpy(l," ",2);
4044 }
4045 l = strstr(chopt,"Y+");
4046 if (l) {
4047 Hoption.AxisPos += 1;
4048 memcpy(l," ",2);
4049 }
4050 if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
4051 if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
4052
4053 l = strstr(chopt,"SAMES");
4054 if (l) {
4055 if (nch == 5) Hoption.Hist = 1;
4056 Hoption.Same = 2;
4057 memcpy(l," ",5);
4058 if (l[5] == '0') { Hoption.Same += 10; l[5] = ' '; }
4059 }
4060 l = strstr(chopt,"SAME");
4061 if (l) {
4062 if (nch == 4) Hoption.Hist = 1;
4063 Hoption.Same = 1;
4064 memcpy(l," ",4);
4065 if (l[4] == '0') { Hoption.Same += 10; l[4] = ' '; }
4066 }
4067
4068 l = strstr(chopt,"PIE");
4069 if (l) {
4070 Hoption.Pie = 1;
4071 memcpy(l," ",3);
4072 }
4073
4074
4075 l = strstr(chopt,"CANDLE");
4076 if (l) {
4077 TCandle candle;
4078 Hoption.Candle = candle.ParseOption(l);
4079 Hoption.Scat = 0;
4080 }
4081
4082 l = strstr(chopt,"VIOLIN");
4083 if (l) {
4084 TCandle candle;
4085 Hoption.Candle = candle.ParseOption(l);
4086 Hoption.Scat = 0;
4087 }
4088
4089 l = strstr(chopt,"LEGO");
4090 if (l) {
4091 Hoption.Scat = 0;
4092 Hoption.Lego = 1; memcpy(l," ",4);
4093 if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
4094 if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
4095 if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
4096 if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
4097 if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
4098 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4099 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4100 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4101 }
4102
4103 l = strstr(chopt,"SURF");
4104 if (l) {
4105 Hoption.Scat = 0;
4106 Hoption.Surf = 1; memcpy(l," ",4);
4107 if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
4108 if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
4109 if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
4110 if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
4111 if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
4112 if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
4113 if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
4114 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4115 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4116 }
4117
4118 l = strstr(chopt,"TF3");
4119 if (l) {
4120 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4121 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4122 }
4123
4124 l = strstr(chopt,"ISO");
4125 if (l) {
4126 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4127 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4128 }
4129
4130 l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; memcpy(l," ",4);}
4131
4132 l = strstr(chopt,"CONT");
4133 if (l) {
4134 memcpy(l," ",4);
4135 if (hdim>1) {
4136 Hoption.Scat = 0;
4137 Hoption.Contour = 1;
4138 if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
4139 if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
4140 if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
4141 if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
4142 if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
4143 } else {
4144 Hoption.Hist = 1;
4145 }
4146 }
4147 l = strstr(chopt,"HBAR");
4148 if (l) {
4149 Hoption.Hist = 0;
4150 Hoption.Bar = 20; memcpy(l," ",4);
4151 if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
4152 if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
4153 if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
4154 if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
4155 }
4156 l = strstr(chopt,"BAR");
4157 if (l) {
4158 Hoption.Hist = 0;
4159 Hoption.Bar = 10; memcpy(l," ",3);
4160 if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
4161 if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
4162 if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
4163 if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
4164 }
4165
4166 l = strstr(chopt,"ARR" );
4167 if (l) {
4168 memcpy(l," ", 3);
4169 if (hdim>1) {
4170 Hoption.Arrow = 1;
4171 Hoption.Scat = 0;
4172 l = strstr(chopt,"COL"); if (l) { Hoption.Arrow = 2; memcpy(l," ",3); }
4173 l = strstr(chopt,"Z"); if (l) { Hoption.Zscale = 1; memcpy(l," ",1); }
4174 } else {
4175 Hoption.Hist = 1;
4176 }
4177 }
4178 l = strstr(chopt,"BOX" );
4179 if (l) {
4180 memcpy(l," ", 3);
4181 if (hdim>1) {
4182 Hoption.Scat = 0;
4183 Hoption.Box = 1;
4184 if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
4185 if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
4186 if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
4187 } else {
4188 Hoption.Hist = 1;
4189 }
4190 }
4191 l = strstr(chopt,"COLZ");
4192 if (l) {
4193 memcpy(l," ",4);
4194 if (hdim>1) {
4195 Hoption.Color = 1;
4196 Hoption.Scat = 0;
4197 Hoption.Zscale = 1;
4198 if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
4199 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4200 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4201 } else {
4202 Hoption.Hist = 1;
4203 }
4204 }
4205 l = strstr(chopt,"COL" );
4206 if (l) {
4207 memcpy(l," ", 3);
4208 if (hdim>1) {
4209 Hoption.Color = 1;
4210 Hoption.Scat = 0;
4211 if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
4212 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4213 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4214 } else {
4215 Hoption.Hist = 1;
4216 }
4217 }
4218 l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; memcpy(l," ",4); Hoption.Scat = 0; }
4219 l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; memcpy(l," ",4); Hoption.Hist = 0; }
4220 l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; memcpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
4221 l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; memcpy(l," ",4); }
4222 l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; memcpy(l," ",4); }
4223 l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; memcpy(l," ",4); }
4224 l = strstr(chopt,"TEXT");
4225 if (l) {
4226 Int_t angle;
4227 if (sscanf(&l[4],"%d",&angle) > 0) {
4228 if (angle < 0) angle=0;
4229 if (angle > 90) angle=90;
4230 Hoption.Text = 1000+angle;
4231 } else {
4232 Hoption.Text = 1;
4233 }
4234 memcpy(l," ", 4);
4235 l = strstr(chopt,"N");
4236 if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
4237 Hoption.Scat = 0;
4238 }
4239 l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; memcpy(l," ",3); }
4240 l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; memcpy(l," ",3); }
4241 l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; memcpy(l," ",3); }
4242 l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; memcpy(l," ",3); }
4243
4244 l = strstr(chopt,"TRI");
4245 if (l) {
4246 Hoption.Scat = 0;
4247 Hoption.Color = 0;
4248 Hoption.Tri = 1; memcpy(l," ",3);
4249 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4250 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4251 l = strstr(chopt,"ERR"); if (l) memcpy(l," ",3);
4252 }
4253
4254 l = strstr(chopt,"AITOFF");
4255 if (l) {
4256 Hoption.Proj = 1; memcpy(l," ",6); //Aitoff projection
4257 }
4258 l = strstr(chopt,"MERCATOR");
4259 if (l) {
4260 Hoption.Proj = 2; memcpy(l," ",8); //Mercator projection
4261 }
4262 l = strstr(chopt,"SINUSOIDAL");
4263 if (l) {
4264 Hoption.Proj = 3; memcpy(l," ",10); //Sinusoidal projection
4265 }
4266 l = strstr(chopt,"PARABOLIC");
4267 if (l) {
4268 Hoption.Proj = 4; memcpy(l," ",9); //Parabolic projection
4269 }
4270 if (Hoption.Proj > 0) {
4271 Hoption.Scat = 0;
4272 Hoption.Contour = 14;
4273 }
4274
4275 if (strstr(chopt,"A")) Hoption.Axis = -1;
4276 if (strstr(chopt,"B")) Hoption.Bar = 1;
4277 if (strstr(chopt,"C") && !strstr(chopt,"CJUST")) { Hoption.Curve =1; Hoption.Hist = -1;}
4278 if (strstr(chopt,"F")) Hoption.Fill =1;
4279 if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
4280 if (strstr(chopt,"F2")) Hoption.Fill =2;
4281 if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
4282 if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
4283 if (strstr(chopt,"Z")) Hoption.Zscale =1;
4284 if (strstr(chopt,"*")) Hoption.Star =1;
4285 if (strstr(chopt,"H")) Hoption.Hist =2;
4286 if (strstr(chopt,"P0")) Hoption.Mark =10;
4287
4288 if (fH->InheritsFrom(TH2Poly::Class())) {
4290 }
4291
4292 if (strstr(chopt,"E")) {
4293 if (hdim == 1) {
4294 Hoption.Error = 1;
4295 if (strstr(chopt,"E0")) Hoption.Error = 10;
4296 if (strstr(chopt,"E1")) Hoption.Error = 11;
4297 if (strstr(chopt,"E2")) Hoption.Error = 12;
4298 if (strstr(chopt,"E3")) Hoption.Error = 13;
4299 if (strstr(chopt,"E4")) Hoption.Error = 14;
4300 if (strstr(chopt,"E5")) Hoption.Error = 15;
4301 if (strstr(chopt,"E6")) Hoption.Error = 16;
4302 if (strstr(chopt,"X0")) {
4303 if (Hoption.Error == 1) Hoption.Error += 20;
4304 Hoption.Error += 10;
4305 }
4307 Hoption.Text += 2000;
4308 Hoption.Error = 0;
4309 }
4310 } else {
4311 if (Hoption.Error == 0) {
4312 Hoption.Error = 100;
4313 Hoption.Scat = 0;
4314 }
4315 if (Hoption.Text) {
4316 Hoption.Text += 2000;
4317 Hoption.Error = 0;
4318 }
4319 }
4320 }
4321
4322 if (Hoption.Surf == 15) {
4324 Hoption.Surf = 13;
4325 Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4326 }
4327 }
4328
4329 // Copy options from current style
4330 Hoption.Logx = gPad->GetLogx();
4331 Hoption.Logy = gPad->GetLogy();
4332 Hoption.Logz = gPad->GetLogz();
4333
4334 // Check options incompatibilities
4335 if (Hoption.Bar == 1) Hoption.Hist = -1;
4336 return 1;
4337}
4338
4339////////////////////////////////////////////////////////////////////////////////
4340/// Decode string `choptin` and fill Graphical cuts structure.
4341
4343{
4344
4345 fNcuts = 0;
4346 char *left = (char*)strchr(choptin,'[');
4347 if (!left) return 0;
4348 char *right = (char*)strchr(choptin,']');
4349 if (!right) return 0;
4350 Int_t nch = right-left;
4351 if (nch < 2) return 0;
4352 char *cuts = left+1;
4353 *right = 0;
4354 char *comma, *minus;
4355 Int_t i;
4356 while (1) {
4357 comma = strchr(cuts,',');
4358 if (comma) *comma = 0;
4359 minus = strchr(cuts,'-');
4360 if (minus) cuts = minus+1;
4361 while (*cuts == ' ') cuts++;
4362 Int_t nc = strlen(cuts);
4363 while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4364 TIter next(gROOT->GetListOfSpecials());
4365 TCutG *cut=0;
4366 TObject *obj;
4367 while ((obj = next())) {
4368 if (!obj->InheritsFrom(TCutG::Class())) continue;
4369 if (strcmp(obj->GetName(),cuts)) continue;
4370 cut = (TCutG*)obj;
4371 break;
4372 }
4373 if (cut) {
4374 fCuts[fNcuts] = cut;
4375 fCutsOpt[fNcuts] = 1;
4376 if (minus) fCutsOpt[fNcuts] = -1;
4377 fNcuts++;
4378 }
4379 if (!comma) break;
4380 cuts = comma+1;
4381 }
4382 for (i=0;i<=nch;i++) left[i] = ' ';
4383 return fNcuts;
4384}
4385
4386////////////////////////////////////////////////////////////////////////////////
4387/// [Control routine to paint any kind of histograms](#HP00)
4388
4390{
4391
4392 if (fH->GetBuffer()) fH->BufferEmpty(-1);
4393
4394 //For iOS: put the histogram on the top of stack of pickable objects.
4395 const TPickerStackGuard topPush(fH);
4396
4397 gPad->SetVertical(kTRUE);
4398
4399 TH1 *oldhist = gCurrentHist;
4400 gCurrentHist = fH;
4401 TH1 *hsave = fH;
4402 Double_t minsav = fH->GetMinimumStored();
4403
4404 if (!MakeChopt(option)) return; //check options and fill Hoption structure
4405
4406 // Paint using TSpectrum2Painter
4407 if (Hoption.Spec) {
4408 if (!TableInit()) return;
4409 if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4410 gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
4411 (ULong_t)fH, option, Hoption.Spec));
4412 return;
4413 }
4414
4415 if (Hoption.Pie) {
4416 if (fH->GetDimension() == 1) {
4417 if (!fPie) fPie = new TPie(fH);
4418 fPie->Paint(option);
4419 } else {
4420 Error("Paint", "Option PIE is for 1D histograms only");
4421 }
4422 return;
4423 } else {
4424 if (fPie) delete fPie;
4425 fPie = 0;
4426 }
4427
4428 fXbuf = new Double_t[kNMAX];
4429 fYbuf = new Double_t[kNMAX];
4430 if (fH->GetDimension() > 2) {
4431 PaintH3(option);
4432 fH->SetMinimum(minsav);
4433 if (Hoption.Func) {
4434 Hoption_t hoptsave = Hoption;
4435 Hparam_t hparsave = Hparam;
4436 PaintFunction(option);
4437 SetHistogram(hsave);
4438 Hoption = hoptsave;
4439 Hparam = hparsave;
4440 }
4441 gCurrentHist = oldhist;
4442 delete [] fXbuf; delete [] fYbuf;
4443 return;
4444 }
4445 TView *view = gPad->GetView();
4446 if (view) {
4447 if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4448 delete view;
4449 gPad->SetView(0);
4450 }
4451 }
4452 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4453 // In case of 1D histogram, Z axis becomes Y axis.
4454 Int_t logysav=0, logzsav=0;
4455 if (fH->GetDimension() == 1) {
4456 logysav = Hoption.Logy;
4457 logzsav = Hoption.Logz;
4458 Hoption.Logz = 0;
4459 if (Hoption.Logy) {
4460 Hoption.Logz = 1;
4461 Hoption.Logy = 0;
4462 }
4463 }
4464 PaintTable(option);
4465 if (Hoption.Func) {
4466 Hoption_t hoptsave = Hoption;
4467 Hparam_t hparsave = Hparam;
4468 PaintFunction(option);
4469 SetHistogram(hsave);
4470 Hoption = hoptsave;
4471 Hparam = hparsave;
4472 }
4473 fH->SetMinimum(minsav);
4474 gCurrentHist = oldhist;
4475 delete [] fXbuf; delete [] fYbuf;
4476 if (fH->GetDimension() == 1) {
4477 Hoption.Logy = logysav;
4478 Hoption.Logz = logzsav;
4479 }
4480 return;
4481 }
4482
4483 if (Hoption.Bar >= 20) {
4484 PaintBarH(option);
4485 delete [] fXbuf; delete [] fYbuf;
4486 return;
4487 }
4488
4489 // fill Hparam structure with histo parameters
4490 if (!PaintInit()) {
4491 delete [] fXbuf; delete [] fYbuf;
4492 return;
4493 }
4494
4495 // Picture surround (if new page) and page number (if requested).
4496 // Histogram surround (if not option "Same").
4497 PaintFrame();
4498
4499 // Paint histogram axis only
4500 Bool_t gridx = gPad->GetGridx();
4501 Bool_t gridy = gPad->GetGridy();
4502 if (Hoption.Axis > 0) {
4503 if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4504 else {
4505 if (gridx) gPad->SetGridx(0);
4506 if (gridy) gPad->SetGridy(0);
4508 if (gridx) gPad->SetGridx(1);
4509 if (gridy) gPad->SetGridy(1);
4510 }
4511 if ((Hoption.Same%10) ==1) Hoption.Same += 1;
4512 goto paintstat;
4513 }
4514 if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4515
4516 // test for options BAR or HBAR
4517 if (Hoption.Bar >= 10) {
4518 PaintBar(option);
4519 }
4520
4521 // do not draw histogram if error bars required
4522 if (!Hoption.Error) {
4523 if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4524 }
4525
4526 // test for error bars or option E
4527 if (Hoption.Error) {
4528 PaintErrors(option);
4529 if (Hoption.Hist == 2) PaintHist(option);
4530 }
4531
4532 if (Hoption.Text) PaintText(option);
4533
4534 // test for associated function
4535 if (Hoption.Func) {
4536 Hoption_t hoptsave = Hoption;
4537 Hparam_t hparsave = Hparam;
4538 PaintFunction(option);
4539 SetHistogram(hsave);
4540 Hoption = hoptsave;
4541 Hparam = hparsave;
4542 }
4543
4544 if (gridx) gPad->SetGridx(0);
4545 if (gridy) gPad->SetGridy(0);
4547 if (gridx) gPad->SetGridx(1);
4548 if (gridy) gPad->SetGridy(1);
4549
4550 PaintTitle(); // Draw histogram title
4551
4552 // Draw box with histogram statistics and/or fit parameters
4553paintstat:
4554 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4555 TIter next(fFunctions);
4556 TObject *obj = 0;
4557 while ((obj = next())) {
4558 if (obj->InheritsFrom(TF1::Class())) break;
4559 obj = 0;
4560 }
4561
4562 //Stat is painted twice (first, it will be in canvas' list of primitives),
4563 //second, it will be here, this is not required on iOS.
4564 //Condition is ALWAYS true on a platform different from iOS.
4565 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4566 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4567 }
4568 fH->SetMinimum(minsav);
4569 gCurrentHist = oldhist;
4570 delete [] fXbuf; fXbuf = 0;
4571 delete [] fYbuf; fYbuf = 0;
4572
4573}
4574
4575////////////////////////////////////////////////////////////////////////////////
4576/// [Control function to draw a table as an arrow plot](#HP12)
4577
4579{
4580 Double_t xk, xstep, yk, ystep;
4581 Double_t dx, dy, x1, x2, y1, y2, xc, yc, dxn, dyn;
4584 Double_t xrg = gPad->GetUxmin();
4585 Double_t yrg = gPad->GetUymin();
4586 Double_t xln = gPad->GetUxmax() - xrg;
4587 Double_t yln = gPad->GetUymax() - yrg;
4588 Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4589 Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4590 Double_t dn = 1.E-30;
4591
4592 auto arrow = new TArrow();
4593 arrow->SetAngle(30);
4594 arrow->SetFillStyle(1001);
4595 arrow->SetFillColor(fH->GetLineColor());
4596 arrow->SetLineColor(fH->GetLineColor());
4597 arrow->SetLineWidth(fH->GetLineWidth());
4598
4599 // Initialize the levels on the Z axis
4600 Int_t ncolors=0, ndivz=0;
4601 Double_t scale=0.;
4602 if (Hoption.Arrow>1) {
4603 ncolors = gStyle->GetNumberOfColors();
4604 Int_t ndiv = fH->GetContour();
4605 if (ndiv == 0 ) {
4606 ndiv = gStyle->GetNumberContours();
4607 fH->SetContour(ndiv);
4608 }
4609 ndivz = TMath::Abs(ndiv);
4610 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4611 scale = ndivz/(fH->GetMaximum()-fH->GetMinimum());
4612 }
4613
4614 for (Int_t id=1;id<=2;id++) {
4615 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4616 yk = fYaxis->GetBinLowEdge(j);
4617 ystep = fYaxis->GetBinWidth(j);
4618 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4619 xk = fXaxis->GetBinLowEdge(i);
4620 xstep = fXaxis->GetBinWidth(i);
4621 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4622 if (i == Hparam.xfirst) {
4623 dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4624 } else if (i == Hparam.xlast) {
4625 dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4626 } else {
4627 dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4628 }
4629 if (j == Hparam.yfirst) {
4630 dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4631 } else if (j == Hparam.ylast) {
4632 dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4633 } else {
4634 dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4635 }
4636 if (id == 1) {
4637 dn = TMath::Max(dn, TMath::Abs(dx));
4638 dn = TMath::Max(dn, TMath::Abs(dy));
4639 } else if (id == 2) {
4640 xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4641 dxn = cx*dx/dn;
4642 x1 = xc - dxn;
4643 x2 = xc + dxn;
4644 yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4645 dyn = cy*dy/dn;
4646 y1 = yc - dyn;
4647 y2 = yc + dyn;
4648 if (Hoption.Arrow>1) {
4649 int color = Int_t(0.01+(fH->GetBinContent(i, j)-fH->GetMinimum())*scale);
4650 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4651 if (theColor > ncolors-1) theColor = ncolors-1;
4652 arrow->SetFillColor(gStyle->GetColorPalette(theColor));
4653 arrow->SetLineColor(gStyle->GetColorPalette(theColor));
4654 }
4655 if (TMath::Abs(x2-x1) > 0. || TMath::Abs(y2-y1) > 0.) {
4656 arrow->PaintArrow(x1, y1, x2, y2, 0.015, "|>");
4657 } else {
4658 arrow->PaintArrow(x1, y1, x2, y2, 0.005, "|>");
4659 }
4660 }
4661 }
4662 }
4663 }
4664
4666}
4667
4668////////////////////////////////////////////////////////////////////////////////
4669/// Draw axis (2D case) of an histogram.
4670///
4671/// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4672/// to draw the grid and the axis separately. In `THistPainter::Paint` this
4673/// feature is used to make sure that the grid is drawn in the background and
4674/// the axis tick marks in the foreground of the pad.
4675
4677{
4678
4679 //On iOS, grid should not be pickable and can not be highlighted.
4680 //Condition is never true on a platform different from iOS.
4681 if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4682 return;
4683
4684 if (Hoption.Axis == -1) return;
4685 if (Hoption.Same && Hoption.Axis <= 0) return;
4686
4687 // Repainting alphanumeric labels axis on a plot done with
4688 // the option HBAR (horizontal) needs some adjustments.
4689 TAxis *xaxis = 0;
4690 TAxis *yaxis = 0;
4691 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4692 if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4693 TIter next(gPad->GetListOfPrimitives());
4694 TObject *obj;
4695 // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4696 while ((obj = next())) {
4697 if (!obj->InheritsFrom(TH1::Class()) &&
4698 !obj->InheritsFrom(THStack::Class())) continue;
4699 TString opt = obj->GetDrawOption();
4700 opt.ToLower();
4701 // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4702 if (strstr(opt,"hbar")) {
4703 gPad->SetVertical(kFALSE);
4704 xaxis = fXaxis;
4705 yaxis = fYaxis;
4706 if (!strcmp(xaxis->GetName(),"xaxis")) {
4707 fXaxis = yaxis;
4708 fYaxis = xaxis;
4709 }
4710 }
4711 break;
4712 }
4713 }
4714 }
4715
4716 static char chopt[10] = "";
4717 Double_t gridl = 0;
4718 Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4719 Int_t useHparam = 0;
4720 Double_t umin, umax, uminsave, umaxsave;
4721 Short_t xAxisPos = Hoption.AxisPos/10;
4722 Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4723
4724 Double_t axmin = gPad->GetUxmin();
4725 Double_t axmax = gPad->GetUxmax();
4726 Double_t aymin = gPad->GetUymin();
4727 Double_t aymax = gPad->GetUymax();
4728 char *cw = 0;
4729 TGaxis axis;
4730
4731 // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4732 // Hparam must be use for the axis limits.
4733 if (Hoption.Contour == 14) useHparam = 1;
4734 if (Hoption.Same) {
4735 TObject *obj;
4736 TIter next(gPad->GetListOfPrimitives());
4737 while ((obj=next())) {
4738 if (strstr(obj->GetDrawOption(),"cont4")) {
4739 useHparam = 1;
4740 break;
4741 }
4742 }
4743 }
4744
4745 // Paint X axis
4746
4747 //To make X-axis selectable on iOS device.
4748 if (gPad->PadInSelectionMode())
4749 gPad->PushSelectableObject(fXaxis);
4750
4751 //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4752 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4753 ndivx = fXaxis->GetNdivisions();
4754 if (ndivx > 1000) {
4755 nx2 = ndivx/100;
4756 nx1 = TMath::Max(1, ndivx%100);
4757 ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4758 }
4759 axis.SetTextAngle(0);
4761
4762 chopt[0] = 0;
4763 strlcat(chopt, "SDH",10);
4764 if (ndivx < 0) strlcat(chopt, "N",10);
4765 if (gPad->GetGridx()) {
4766 gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4767 strlcat(chopt, "W",10);
4768 }
4769
4770 // Define X-Axis limits
4771 if (Hoption.Logx) {
4772 strlcat(chopt, "G",10);
4773 ndiv = TMath::Abs(ndivx);
4774 if (useHparam) {
4775 umin = TMath::Power(10,Hparam.xmin);
4776 umax = TMath::Power(10,Hparam.xmax);
4777 } else {
4778 umin = TMath::Power(10,axmin);
4779 umax = TMath::Power(10,axmax);
4780 }
4781 } else {
4782 ndiv = TMath::Abs(ndivx);
4783 if (useHparam) {
4784 umin = Hparam.xmin;
4785 umax = Hparam.xmax;
4786 } else {
4787 umin = axmin;
4788 umax = axmax;
4789 }
4790 }
4791
4792 // Display axis as time
4793 if (fXaxis->GetTimeDisplay()) {
4794 strlcat(chopt,"t",10);
4795 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4797 }
4798 }
4799
4800 // The main X axis can be on the bottom or on the top of the pad
4801 Double_t xAxisYPos1, xAxisYPos2;
4802 if (xAxisPos == 1) {
4803 // Main X axis top
4804 xAxisYPos1 = aymax;
4805 xAxisYPos2 = aymin;
4806 } else {
4807 // Main X axis bottom
4808 xAxisYPos1 = aymin;
4809 xAxisYPos2 = aymax;
4810 }
4811
4812 // Paint the main X axis (always)
4813 uminsave = umin;
4814 umaxsave = umax;
4815 ndivsave = ndiv;
4816 axis.SetOption(chopt);
4817 if (xAxisPos) {
4818 strlcat(chopt, "-",10);
4819 gridl = -gridl;
4820 }
4821 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4822 axis.SetLabelSize(0.);
4823 axis.SetTitle("");
4824 }
4825 axis.PaintAxis(axmin, xAxisYPos1,
4826 axmax, xAxisYPos1,
4827 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4828
4829 // Paint additional X axis (if needed)
4830 // On iOS, this additional X axis is neither pickable, nor highlighted.
4831 // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4832 if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4833 if (xAxisPos) {
4834 cw=strstr(chopt,"-");
4835 *cw='z';
4836 } else {
4837 strlcat(chopt, "-",10);
4838 }
4839 if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4840 if ((cw=strstr(chopt,"W"))) *cw='z';
4841 axis.SetTitle("");
4842 axis.PaintAxis(axmin, xAxisYPos2,
4843 axmax, xAxisYPos2,
4844 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4845 }
4846 }//End of "if pad in selection mode etc".
4847
4848 // Paint Y axis
4849 //On iOS, Y axis must pushed into the stack of selectable objects.
4850 if (gPad->PadInSelectionMode())
4851 gPad->PushSelectableObject(fYaxis);
4852
4853 //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4854 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4855 ndivy = fYaxis->GetNdivisions();
4857
4858 chopt[0] = 0;
4859 strlcat(chopt, "SDH",10);
4860 if (ndivy < 0) strlcat(chopt, "N",10);
4861 if (gPad->GetGridy()) {
4862 gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4863 strlcat(chopt, "W",10);
4864 }
4865
4866 // Define Y-Axis limits
4867 if (Hoption.Logy) {
4868 strlcat(chopt, "G",10);
4869 ndiv = TMath::Abs(ndivy);
4870 if (useHparam) {
4871 umin = TMath::Power(10,Hparam.ymin);
4872 umax = TMath::Power(10,Hparam.ymax);
4873 } else {
4874 umin = TMath::Power(10,aymin);
4875 umax = TMath::Power(10,aymax);
4876 }
4877 } else {
4878 ndiv = TMath::Abs(ndivy);
4879 if (useHparam) {
4880 umin = Hparam.ymin;
4881 umax = Hparam.ymax;
4882 } else {
4883 umin = aymin;
4884 umax = aymax;
4885 }
4886 }
4887
4888 // Display axis as time
4889 if (fYaxis->GetTimeDisplay()) {
4890 strlcat(chopt,"t",10);
4891 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4893 }
4894 }
4895
4896 // The main Y axis can be on the left or on the right of the pad
4897 Double_t yAxisXPos1, yAxisXPos2;
4898 if (yAxisPos == 1) {
4899 // Main Y axis left
4900 yAxisXPos1 = axmax;
4901 yAxisXPos2 = axmin;
4902 } else {
4903 // Main Y axis right
4904 yAxisXPos1 = axmin;
4905 yAxisXPos2 = axmax;
4906 }
4907
4908 // Paint the main Y axis (always)
4909 uminsave = umin;
4910 umaxsave = umax;
4911 ndivsave = ndiv;
4912 axis.SetOption(chopt);
4913 if (yAxisPos) {
4914 strlcat(chopt, "+L",10);
4915 gridl = -gridl;
4916 }
4917 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4918 axis.SetLabelSize(0.);
4919 axis.SetTitle("");
4920 }
4921 axis.PaintAxis(yAxisXPos1, aymin,
4922 yAxisXPos1, aymax,
4923 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4924
4925 // Paint the additional Y axis (if needed)
4926 // Additional checks for pad mode are required on iOS: this "second" axis is
4927 // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4928 if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4929 if (gPad->GetTicky() < 2) {
4930 strlcat(chopt, "U",10);
4932 } else {
4933 strlcat(chopt, "+L",10);
4934 }
4935 if ((cw=strstr(chopt,"W"))) *cw='z';
4936 axis.SetTitle("");
4937 axis.PaintAxis(yAxisXPos2, aymin,
4938 yAxisXPos2, aymax,
4939 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4940 }
4941 }//End of "if pad is in selection mode etc."
4942
4943 // Reset the axis if they have been inverted in case of option HBAR
4944 if (xaxis) {
4945 fXaxis = xaxis;
4946 fYaxis = yaxis;
4947 }
4948}
4949
4950////////////////////////////////////////////////////////////////////////////////
4951/// [Draw a bar-chart in a normal pad.](#HP10)
4952
4954{
4955
4956 Int_t bar = Hoption.Bar - 10;
4957 Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4958 Double_t offset = fH->GetBarOffset();
4960 TBox box;
4961 Int_t hcolor = fH->GetFillColor();
4962 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4963 Int_t hstyle = fH->GetFillStyle();
4964 box.SetFillColor(hcolor);
4965 box.SetFillStyle(hstyle);
4966 box.SetLineStyle(fH->GetLineStyle());
4967 box.SetLineColor(fH->GetLineColor());
4968 box.SetLineWidth(fH->GetLineWidth());
4969 for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4970 y = fH->GetBinContent(bin);
4971 xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4972 xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4973 ymin = gPad->GetUymin();
4974 ymax = gPad->YtoPad(y);
4975 if (ymax < gPad->GetUymin()) continue;
4976 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4977 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4978 if (Hoption.MinimumZero && ymin < 0)
4979 ymin=TMath::Min(0.,gPad->GetUymax());
4980 w = (xmax-xmin)*width;
4981 xmin += offset*(xmax-xmin);
4982 xmax = xmin + w;
4983 if (bar < 1) {
4984 box.PaintBox(xmin,ymin,xmax,ymax);
4985 } else {
4986 umin = xmin + bar*(xmax-xmin)/10.;
4987 umax = xmax - bar*(xmax-xmin)/10.;
4988 //box.SetFillColor(hcolor+150); //bright
4989 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4990 box.PaintBox(xmin,ymin,umin,ymax);
4991 box.SetFillColor(hcolor);
4992 box.PaintBox(umin,ymin,umax,ymax);
4993 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4994 box.PaintBox(umax,ymin,xmax,ymax);
4995 }
4996 }
4997}
4998
4999////////////////////////////////////////////////////////////////////////////////
5000/// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
5001
5003{
5004
5005 gPad->SetVertical(kFALSE);
5006
5007 PaintInitH();
5008
5009 TAxis *xaxis = fXaxis;
5010 TAxis *yaxis = fYaxis;
5011 if (!strcmp(xaxis->GetName(),"xaxis")) {
5012 fXaxis = yaxis;
5013 fYaxis = xaxis;
5014 }
5015
5016 PaintFrame();
5018
5019 Int_t bar = Hoption.Bar - 20;
5020 Double_t xmin,xmax,ymin,ymax,umin,umax,w;
5021 Double_t offset = fH->GetBarOffset();
5023 TBox box;
5024 Int_t hcolor = fH->GetFillColor();
5025 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5026 Int_t hstyle = fH->GetFillStyle();
5027 box.SetFillColor(hcolor);
5028 box.SetFillStyle(hstyle);
5029 box.SetLineStyle(fH->GetLineStyle());
5030 box.SetLineColor(fH->GetLineColor());
5031 box.SetLineWidth(fH->GetLineWidth());
5032 for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
5033 ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
5034 ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
5035 xmin = gPad->GetUxmin();
5036 xmax = gPad->XtoPad(fH->GetBinContent(bin));
5037 if (xmax < gPad->GetUxmin()) continue;
5038 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
5039 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
5040 if (Hoption.MinimumZero && xmin < 0)
5041 xmin=TMath::Min(0.,gPad->GetUxmax());
5042 w = (ymax-ymin)*width;
5043 ymin += offset*(ymax-ymin);
5044 ymax = ymin + w;
5045 if (bar < 1) {
5046 box.PaintBox(xmin,ymin,xmax,ymax);
5047 } else {
5048 umin = ymin + bar*(ymax-ymin)/10.;
5049 umax = ymax - bar*(ymax-ymin)/10.;
5050 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5051 box.PaintBox(xmin,ymin,xmax,umin);
5052 box.SetFillColor(hcolor);
5053 box.PaintBox(xmin,umin,xmax,umax);
5054 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5055 box.PaintBox(xmin,umax,xmax,ymax);
5056 }
5057 }
5058
5059 PaintTitle();
5060
5061 // Draw box with histogram statistics and/or fit parameters
5062 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5063 TIter next(fFunctions);
5064 TObject *obj = 0;
5065 while ((obj = next())) {
5066 if (obj->InheritsFrom(TF1::Class())) break;
5067 obj = 0;
5068 }
5069 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
5070 }
5071
5072 fXaxis = xaxis;
5073 fYaxis = yaxis;
5074}
5075
5076////////////////////////////////////////////////////////////////////////////////
5077/// [Control function to draw a 2D histogram as a box plot](#HP13)
5078
5080{
5081
5082 Style_t fillsav = fH->GetFillStyle();
5083 Style_t colsav = fH->GetFillColor();
5084 if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
5085 if (Hoption.Box == 11) fH->SetFillStyle(1001);
5086 fH->TAttLine::Modify();
5087 fH->TAttFill::Modify();
5088
5089 Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
5090 Double_t ux1 = gPad->PixeltoX(1);
5091 Double_t ux0 = gPad->PixeltoX(0);
5092 Double_t uy1 = gPad->PixeltoY(1);
5093 Double_t uy0 = gPad->PixeltoY(0);
5094 Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
5095 Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
5096
5097 Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
5100 Double_t zminlin = zmin, zmaxlin = zmax;
5101
5102 // In case of option SAME, zmin and zmax values are taken from the
5103 // first plotted 2D histogram.
5104 if (Hoption.Same > 0 && Hoption.Same < 10) {
5105 TH2 *h2;
5106 TIter next(gPad->GetListOfPrimitives());
5107 while ((h2 = (TH2 *)next())) {
5108 if (!h2->InheritsFrom(TH2::Class())) continue;
5109 zmin = TMath::Max(h2->GetMinimum(), 0.);
5110 zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
5111 TMath::Abs(h2->GetMinimum()));
5112 zminlin = zmin;
5113 zmaxlin = zmax;
5114 if (Hoption.Logz) {
5115 if (zmin <= 0) {
5116 zmin = TMath::Log10(zmax*0.001);
5117 } else {
5118 zmin = TMath::Log10(zmin);
5119 }
5120 zmax = TMath::Log10(zmax);
5121 }
5122 break;
5123 }
5124 } else {
5125 if (Hoption.Logz) {
5126 if (zmin > 0) {
5127 zmin = TMath::Log10(zmin);
5128 zmax = TMath::Log10(zmax);
5129 } else {
5130 return;
5131 }
5132 }
5133 }
5134
5135 Double_t zratio, dz = zmax - zmin;
5136 Bool_t kZminNeg = kFALSE;
5137 if (fH->GetMinimum()<0) kZminNeg = kTRUE;
5138 Bool_t kZNeg = kFALSE;
5139
5140 // Define the dark and light colors the "button style" boxes.
5141 Color_t color = fH->GetFillColor();
5142 Color_t light=0, dark=0;
5143 if (Hoption.Box == 11) {
5144 light = TColor::GetColorBright(color);
5145 dark = TColor::GetColorDark(color);
5146 }
5147
5148 // Loop over all the bins and draw the boxes
5149 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5150 yk = fYaxis->GetBinLowEdge(j);
5151 ystep = fYaxis->GetBinWidth(j);
5152 ycent = 0.5*ystep;
5153 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5154 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5155 xk = fXaxis->GetBinLowEdge(i);
5156 xstep = fXaxis->GetBinWidth(i);
5157 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5158 xcent = 0.5*xstep;
5159 z = Hparam.factor*fH->GetBinContent(bin);
5160 kZNeg = kFALSE;
5161
5162 if (TMath::Abs(z) < zminlin) continue; // Can be the case with ...
5163 if (TMath::Abs(z) > zmaxlin) z = zmaxlin; // ... option Same
5164 if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with netgative bins.
5165
5166 if (z < 0) {
5167 if (Hoption.Logz) continue;
5168 z = -z;
5169 kZNeg = kTRUE;
5170 }
5171 if (Hoption.Logz) {
5172 if (z != 0) z = TMath::Log10(z);
5173 else z = zmin;
5174 }
5175
5176 if (dz == 0) continue;
5177 zratio = TMath::Sqrt((z-zmin)/dz);
5178 if (zratio == 0) continue;
5179
5180 xup = xcent*zratio + xk + xcent;
5181 xlow = 2*(xk + xcent) - xup;
5182 if (xup-xlow < dxmin) xup = xlow+dxmin;
5183 if (Hoption.Logx) {
5184 if (xup > 0) xup = TMath::Log10(xup);
5185 else continue;
5186 if (xlow > 0) xlow = TMath::Log10(xlow);
5187 else continue;
5188 }
5189
5190 yup = ycent*zratio + yk + ycent;
5191 ylow = 2*(yk + ycent) - yup;
5192 if (yup-ylow < dymin) yup = ylow+dymin;
5193 if (Hoption.Logy) {
5194 if (yup > 0) yup = TMath::Log10(yup);
5195 else continue;
5196 if (ylow > 0) ylow = TMath::Log10(ylow);
5197 else continue;
5198 }
5199
5200 xlow = TMath::Max(xlow, gPad->GetUxmin());
5201 ylow = TMath::Max(ylow, gPad->GetUymin());
5202 xup = TMath::Min(xup , gPad->GetUxmax());
5203 yup = TMath::Min(yup , gPad->GetUymax());
5204
5205 if (xlow >= xup) continue;
5206 if (ylow >= yup) continue;
5207
5208 if (Hoption.Box == 1) {
5209 fH->SetFillColor(color);
5210 fH->TAttFill::Modify();
5211 gPad->PaintBox(xlow, ylow, xup, yup);
5212 if (kZNeg) {
5213 gPad->PaintLine(xlow, ylow, xup, yup);
5214 gPad->PaintLine(xlow, yup, xup, ylow);
5215 }
5216 } else if (Hoption.Box == 11) {
5217 // Draw the center of the box
5218 fH->SetFillColor(color);
5219 fH->TAttFill::Modify();
5220 gPad->PaintBox(xlow, ylow, xup, yup);
5221
5222 // Draw top&left part of the box
5223 Double_t x[7], y[7];
5224 Double_t bwidth = 0.1;
5225 x[0] = xlow; y[0] = ylow;
5226 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5227 x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
5228 x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
5229 x[4] = xup; y[4] = yup;
5230 x[5] = xlow; y[5] = yup;
5231 x[6] = xlow; y[6] = ylow;
5232 if (kZNeg) fH->SetFillColor(dark);
5233 else fH->SetFillColor(light);
5234 fH->TAttFill::Modify();
5235 gPad->PaintFillArea(7, x, y);
5236
5237 // Draw bottom&right part of the box
5238 x[0] = xlow; y[0] = ylow;
5239 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5240 x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
5241 x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
5242 x[4] = xup; y[4] = yup;
5243 x[5] = xup; y[5] = ylow;
5244 x[6] = xlow; y[6] = ylow;
5245 if (kZNeg) fH->SetFillColor(light);
5246 else fH->SetFillColor(dark);
5247 fH->TAttFill::Modify();
5248 gPad->PaintFillArea(7, x, y);
5249 }
5250 }
5251 }
5252
5254 fH->SetFillStyle(fillsav);
5255 fH->SetFillColor(colsav);
5256 fH->TAttFill::Modify();
5257}
5258
5259
5260
5261////////////////////////////////////////////////////////////////////////////////
5262/// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](#HP14)
5263
5265{
5266 TH1D *hproj;
5267 TH2D *h2 = (TH2D*)fH;
5268
5269 TCandle myCandle;
5271 myCandle.SetMarkerColor(fH->GetLineColor());
5272 myCandle.SetLineColor(fH->GetLineColor());
5273 myCandle.SetLineWidth(fH->GetLineWidth());
5274 myCandle.SetFillColor(fH->GetFillColor());
5275 myCandle.SetFillStyle(fH->GetFillStyle());
5276 myCandle.SetMarkerSize(fH->GetMarkerSize());
5277 myCandle.SetMarkerStyle(fH->GetMarkerStyle());
5279
5280 Bool_t swapXY = myCandle.IsHorizontal();
5281 const Double_t standardCandleWidth = 0.66;
5282 const Double_t standardHistoWidth = 0.8;
5283
5284 double allMaxContent = h2->GetBinContent(h2->GetMaximumBin());
5285 double allMaxIntegral = 0;
5286
5287 if (!swapXY) { // Vertical candle
5288 //Determining the slice with the maximum content
5289 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5290 hproj = h2->ProjectionY("_px", i, i);
5291 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5292 }
5293 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5294 Double_t binPosX = fXaxis->GetBinLowEdge(i);
5295 Double_t binWidth = fXaxis->GetBinWidth(i);
5296 hproj = h2->ProjectionY("_px", i, i);
5297 if (hproj->GetEntries() !=0) {
5298 Double_t candleWidth = fH->GetBarWidth();
5299 Double_t offset = fH->GetBarOffset()*binWidth;
5300 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5301 double myIntegral = hproj->Integral();
5302 Double_t histoWidth = candleWidth;
5303 if (candleWidth > 0.999 && candleWidth < 1.001) {
5304 candleWidth = standardCandleWidth;
5305 histoWidth = standardHistoWidth;
5306 }
5307 if (Hoption.Logz && myMaxContent > 0) {
5308 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5309 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5310 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5311 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5312
5313 myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
5314 myCandle.SetCandleWidth(candleWidth*binWidth);
5315 myCandle.SetHistoWidth(histoWidth*binWidth);
5316 myCandle.SetHistogram(hproj);
5317 myCandle.Paint();
5318 }
5319 }
5320 } else { // Horizontal candle
5321 //Determining the slice with the maximum content
5322 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5323 hproj = h2->ProjectionX("_py", i, i);
5324 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5325 }
5326 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5327 Double_t binPosY = fYaxis->GetBinLowEdge(i);
5328 Double_t binWidth = fYaxis->GetBinWidth(i);
5329 hproj = h2->ProjectionX("_py", i, i);
5330 if (hproj->GetEntries() !=0) {
5331 Double_t candleWidth = fH->GetBarWidth();
5332 Double_t offset = fH->GetBarOffset()*binWidth;
5333 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5334 double myIntegral = hproj->Integral();
5335 Double_t histoWidth = candleWidth;
5336 if (candleWidth > 0.999 && candleWidth < 1.001) {
5337 candleWidth = standardCandleWidth;
5338 histoWidth = standardHistoWidth;
5339 }
5340 if (Hoption.Logz && myMaxContent > 0) {
5341 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5342 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5343 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5344 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5345
5346 myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
5347 myCandle.SetCandleWidth(candleWidth*binWidth);
5348 myCandle.SetHistoWidth(histoWidth*binWidth);
5349 myCandle.SetHistogram(hproj);
5350 myCandle.Paint();
5351 }
5352 }
5353 }
5354}
5355
5356
5357
5358////////////////////////////////////////////////////////////////////////////////
5359/// Returns the rendering regions for an axis to use in the COL2 option
5360///
5361/// The algorithm analyses the size of the axis compared to the size of
5362/// the rendering region. It figures out the boundaries to use for each color
5363/// of the rendering region. Only one axis is computed here.
5364///
5365/// This allows for a single computation of the boundaries before iterating
5366/// through all of the bins.
5367///
5368/// \param pAxis the axis to consider
5369/// \param nPixels the number of pixels to render axis into
5370/// \param isLog whether the axis is log scale
5371
5372std::vector<THistRenderingRegion>
5374{
5375 std::vector<THistRenderingRegion> regions;
5376
5377 enum STRATEGY { Bins, Pixels } strategy;
5378
5379 Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
5380
5381 if (nBins >= nPixels) {
5382 // more bins than pixels... we should loop over pixels and sample
5383 strategy = Pixels;
5384 } else {
5385 // fewer bins than pixels... we should loop over bins
5386 strategy = Bins;
5387 }
5388
5389 if (isLog) {
5390
5391 Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5392 Int_t binOffset=0;
5393 while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5394 binOffset++;
5395 xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5396 }
5397 if (xMin <= 0) {
5398 // this should cause an error if we have
5399 return regions;
5400 }
5401 Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5402
5403 if (strategy == Bins) {
5404 // logarithmic plot. we find the pixel for the bin
5405 // pixel = eta * log10(V) - alpha
5406 // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5407 // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5408 // and V is axis value
5409 Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5410 Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5411
5412 for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5413
5414 // linear plot. we simply need to find the appropriate bin
5415 // for the
5416 Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5417 Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5418 Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5419 Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5420 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5421 std::make_pair(bin, bin+1)};
5422 regions.push_back(region);
5423 }
5424
5425 } else {
5426
5427 // loop over pixels
5428
5429 Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5430
5431 for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5432 // linear plot
5433 Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5434 Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5435 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5436 std::make_pair(binLow, binHigh)};
5437 regions.push_back(region);
5438 }
5439 }
5440 } else {
5441 // standard linear plot
5442
5443 if (strategy == Bins) {
5444 // loop over bins
5445 for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5446
5447 // linear plot. we simply need to find the appropriate bin
5448 // for the
5449 Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5450 Int_t xPx1 = xPx0 + nPixels/nBins;
5451
5452 // make sure we don't compute beyond our bounds
5453 if (xPx1>= nPixels) xPx1 = nPixels-1;
5454
5455 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5456 std::make_pair(bin, bin+1)};
5457 regions.push_back(region);
5458 }
5459 } else {
5460 // loop over pixels
5461 for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5462 // linear plot
5463 Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5464 Int_t binHigh = binLow + nBins/nPixels;
5465 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5466 std::make_pair(binLow, binHigh)};
5467 regions.push_back(region);
5468 }
5469 }
5470 }
5471
5472 return regions;
5473}
5474
5475////////////////////////////////////////////////////////////////////////////////
5476/// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
5477
5479{
5480
5481 if (Hoption.System != kCARTESIAN) {
5482 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5483 "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5484 PaintColorLevels(nullptr);
5485 return;
5486 }
5487
5488 Double_t z;
5489
5490 // Use existing max or min values. If either is already set
5491 // the appropriate value to use.
5492 Double_t zmin = fH->GetMinimumStored();
5493 Double_t zmax = fH->GetMaximumStored();
5494 Double_t originalZMin = zmin;
5495 Double_t originalZMax = zmax;
5496 if ((zmin == -1111) && (zmax == -1111)) {
5497 fH->GetMinimumAndMaximum(zmin, zmax);
5498 fH->SetMinimum(zmin);
5499 fH->SetMaximum(zmax);
5500 } else if (zmin == -1111) {
5501 zmin = fH->GetMinimum();
5502 fH->SetMinimum(zmin);
5503 } else if (zmax == -1111) {
5504 zmax = fH->GetMaximum();
5505 fH->SetMaximum(zmax);
5506 }
5507
5508 Double_t dz = zmax - zmin;
5509 if (dz <= 0) { // Histogram filled with a constant value
5510 zmax += 0.1*TMath::Abs(zmax);
5511 zmin -= 0.1*TMath::Abs(zmin);
5512 dz = zmax - zmin;
5513 }
5514
5515 if (Hoption.Logz) {
5516 if (zmin > 0) {
5517 zmin = TMath::Log10(zmin);
5518 zmax = TMath::Log10(zmax);
5519 dz = zmax - zmin;
5520 } else {
5521 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5522 "Cannot plot logz because bin content is less than 0.");
5523 return;
5524 }
5525 }
5526
5527 // Initialize the levels on the Z axis
5528 Int_t ndiv = fH->GetContour();
5529 if (ndiv == 0 ) {
5530 ndiv = gStyle->GetNumberContours();
5531 fH->SetContour(ndiv);
5532 }
5533 std::vector<Double_t> colorBounds(ndiv);
5534 std::vector<Double_t> contours(ndiv, 0);
5535 if (fH->TestBit(TH1::kUserContour) == 0) {
5536 fH->SetContour(ndiv);
5537 } else {
5538 fH->GetContour(contours.data());
5539 }
5540
5541 Double_t step = 1.0/ndiv;
5542 for (Int_t i=0; i<ndiv; ++i) {
5543 colorBounds[i] = step*i;
5544 }
5545
5546 auto pFrame = gPad->GetFrame();
5547 Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5548 Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5549 Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5550 Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5551 Int_t nXPixels = px1-px0;
5552 Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5553
5554 std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5555
5556 auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5557 auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5558 if (xRegions.size() == 0 || yRegions.size() == 0) {
5559 Error("THistPainter::PaintColorLevelFast(Option_t*)",
5560 "Encountered error while computing rendering regions.");
5561 return;
5562 }
5563
5564 Bool_t minExists = kFALSE;
5565 Bool_t maxExists = kFALSE;
5566 Double_t minValue = 1.;
5567 Double_t maxValue = 0.;
5568 for (auto& yRegion : yRegions) {
5569 for (auto& xRegion : xRegions ) {
5570
5571 const auto& xBinRange = xRegion.fBinRange;
5572 const auto& yBinRange = yRegion.fBinRange;
5573
5574 // sample the range
5575 z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5576
5577 if (Hoption.Logz) {
5578 if (z > 0) z = TMath::Log10(z);
5579 else z = zmin;
5580 }
5581
5582 // obey the user's max and min values if they were set
5583 if (z > zmax) z = zmax;
5584 if (z < zmin) z = zmin;
5585
5586 if (fH->TestBit(TH1::kUserContour) == 1) {
5587 // contours are absolute values
5588 auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5589 z = colorBounds[index];
5590 } else {
5591 Int_t index = 0;
5592 if (dz != 0) {
5593 index = 0.001 + ((z - zmin)/dz)*ndiv;
5594 }
5595
5596 if (index == static_cast<Int_t>(colorBounds.size())) {
5597 index--;
5598 }
5599
5600 // Do a little bookkeeping to use later for getting libAfterImage to produce
5601 // the correct colors
5602 if (index == 0) {
5603 minExists = kTRUE;
5604 } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5605 maxExists = kTRUE;
5606 }
5607
5608 z = colorBounds[index];
5609
5610 if (z < minValue) {
5611 minValue = z;
5612 }
5613 if (z > maxValue) {
5614 maxValue = z;
5615 }
5616 }
5617
5618 // fill in the actual pixels
5619 const auto& xPixelRange = xRegion.fPixelRange;
5620 const auto& yPixelRange = yRegion.fPixelRange;
5621 for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5622 for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5623 Int_t pixel = yPx*nXPixels + xPx;
5624 buffer[pixel] = z;
5625 }
5626 }
5627 } // end px loop
5628 } // end py loop
5629
5630 // This is a bit of a hack to ensure that we span the entire color range and
5631 // don't screw up the colors for a sparse histogram. No one will notice that I set a
5632 // single pixel on the edge of the image to a different color. This is even more
5633 // true because the chosen pixels will be covered by the axis.
5634 if (minValue != maxValue) {
5635 if ( !minExists) {
5636 buffer.front() = 0;
5637 }
5638
5639 if ( !maxExists) {
5640 buffer[buffer.size()-nXPixels] = 0.95;
5641 }
5642 }
5643
5644 // Generate the TImage
5646 TImage* pImage = TImage::Create();
5648 pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5649 delete pPalette;
5650
5651 Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5652 pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5653 delete pImage;
5654
5656
5657 // Reset the maximum and minimum values to their original values
5658 // when this function was called. If we don't do this, an initial
5659 // value of -1111 will be replaced with the true max or min values.
5660 fH->SetMinimum(originalZMin);
5661 fH->SetMaximum(originalZMax);
5662}
5663
5664////////////////////////////////////////////////////////////////////////////////
5665/// [Control function to draw a 2D histogram as a color plot.](#HP14)
5666
5668{
5669 Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5670
5671 Double_t zmin = fH->GetMinimum();
5672 Double_t zmax = fH->GetMaximum();
5673
5674 Double_t dz = zmax - zmin;
5675 if (dz <= 0) { // Histogram filled with a constant value
5676 zmax += 0.1*TMath::Abs(zmax);
5677 zmin -= 0.1*TMath::Abs(zmin);
5678 dz = zmax - zmin;
5679 }
5680
5681 // In case of option SAME, zmin and zmax values are taken from the
5682 // first plotted 2D histogram.
5683 if (Hoption.Same > 0 && Hoption.Same < 10) {
5684 TH2 *h2;
5685 TIter next(gPad->GetListOfPrimitives());
5686 while ((h2 = (TH2 *)next())) {
5687 if (!h2->InheritsFrom(TH2::Class())) continue;
5688 zmin = h2->GetMinimum();
5689 zmax = h2->GetMaximum();
5690 fH->SetMinimum(zmin);
5691 fH->SetMaximum(zmax);
5692 if (Hoption.Logz) {
5693 if (zmin <= 0) {
5694 zmin = TMath::Log10(zmax*0.001);
5695 } else {
5696 zmin = TMath::Log10(zmin);
5697 }
5698 zmax = TMath::Log10(zmax);
5699 }
5700 dz = zmax - zmin;
5701 break;
5702 }
5703 } else {
5704 if (Hoption.Logz) {
5705 if (zmin > 0) {
5706 zmin = TMath::Log10(zmin);
5707 zmax = TMath::Log10(zmax);
5708 dz = zmax - zmin;
5709 } else {
5710 return;
5711 }
5712 }
5713 }
5714
5715 Style_t fillsav = fH->GetFillStyle();
5716 Style_t colsav = fH->GetFillColor();
5717 fH->SetFillStyle(1001);
5718 fH->TAttFill::Modify();
5719
5720 // Initialize the levels on the Z axis
5721 Int_t ncolors = gStyle->GetNumberOfColors();
5722 Int_t ndiv = fH->GetContour();
5723 if (ndiv == 0 ) {
5724 ndiv = gStyle->GetNumberContours();
5725 fH->SetContour(ndiv);
5726 }
5727 Int_t ndivz = TMath::Abs(ndiv);
5728 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5729 Double_t scale = (dz ? ndivz / dz : 1.0);
5730
5731 Int_t color;
5732 TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5733 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5734 yk = fYaxis->GetBinLowEdge(j);
5735 ystep = fYaxis->GetBinWidth(j);
5736 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5737 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5738 xk = fXaxis->GetBinLowEdge(i);
5739 xstep = fXaxis->GetBinWidth(i);
5740 if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5741 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5742 z = fH->GetBinContent(bin);
5743 // if fH is a profile histogram do not draw empty bins
5744 if (prof2d) {
5745 const Double_t binEntries = prof2d->GetBinEntries(bin);
5746 if (binEntries == 0)
5747 continue;
5748 } else {
5749 // don't draw the empty bins for non-profile histograms
5750 // with positive content
5751 if (z == 0) {
5752 if (zmin >= 0 || Hoption.Logz) continue;
5753 if (Hoption.Color == 2) continue;
5754 }
5755 }
5756
5757 if (Hoption.Logz) {
5758 if (z > 0) z = TMath::Log10(z);
5759 else z = zmin;
5760 }
5761 if (z < zmin && !Hoption.Zero) continue;
5762 xup = xk + xstep;
5763 xlow = xk;
5764 if (Hoption.Logx) {
5765 if (xup > 0) xup = TMath::Log10(xup);
5766 else continue;
5767 if (xlow > 0) xlow = TMath::Log10(xlow);
5768 else continue;
5769 }
5770 yup = yk + ystep;
5771 ylow = yk;
5772 if (Hoption.System != kPOLAR) {
5773 if (Hoption.Logy) {
5774 if (yup > 0) yup = TMath::Log10(yup);
5775 else continue;
5776 if (ylow > 0) ylow = TMath::Log10(ylow);
5777 else continue;
5778 }
5779 if (xup < gPad->GetUxmin()) continue;
5780 if (yup < gPad->GetUymin()) continue;
5781 if (xlow > gPad->GetUxmax()) continue;
5782 if (ylow > gPad->GetUymax()) continue;
5783 if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5784 if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5785 if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5786 if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5787 }
5788
5790 zc = fH->GetContourLevelPad(0);
5791 if (z < zc) continue;
5792 color = -1;
5793 for (Int_t k=0; k<ndiv; k++) {
5794 zc = fH->GetContourLevelPad(k);
5795 if (z < zc) {
5796 continue;
5797 } else {
5798 color++;
5799 }
5800 }
5801 } else {
5802 color = Int_t(0.01+(z-zmin)*scale);
5803 }
5804
5805 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5806 if (theColor > ncolors-1) theColor = ncolors-1;
5808 fH->TAttFill::Modify();
5809 if (Hoption.System != kPOLAR) {
5810 gPad->PaintBox(xlow, ylow, xup, yup);
5811 } else {
5812 TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5813 crown.SetFillColor(gStyle->GetColorPalette(theColor));
5814 crown.Paint();
5815 }
5816 }
5817 }
5818
5820
5821 fH->SetFillStyle(fillsav);
5822 fH->SetFillColor(colsav);
5823 fH->TAttFill::Modify();
5824
5825}
5826
5827////////////////////////////////////////////////////////////////////////////////
5828/// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5829
5831{
5832
5833 Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5834 Int_t itars, mode, ir[4];
5835 Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5836
5837 if (Hoption.Contour == 14) {
5838 Hoption.Surf = 12;
5839 Hoption.Axis = 1;
5840 thesave = gPad->GetTheta();
5841 phisave = gPad->GetPhi();
5842 gPad->SetPhi(0.);
5843 gPad->SetTheta(90.);
5844 PaintSurface(option);
5845 gPad->SetPhi(phisave);
5846 gPad->SetTheta(thesave);
5847 TView *view = gPad->GetView();
5848 if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5849 PaintAxis();
5850 return;
5851 }
5852
5853 if (Hoption.Same) {
5854 // If the contour is painted on a 3d plot, the contour lines are
5855 // paint in 3d too.
5856 TObject *obj;
5857 TIter next(gPad->GetListOfPrimitives());
5858 while ((obj=next())) {
5859 if (strstr(obj->GetDrawOption(),"surf") ||
5860 strstr(obj->GetDrawOption(),"lego") ||
5861 strstr(obj->GetDrawOption(),"tri")) {
5862 Hoption.Surf = 16;
5863 PaintSurface(option);
5864 return;
5865 }
5866 }
5867 }
5868
5869 if (Hoption.Contour == 15) {
5870 TGraphDelaunay2D *dt = nullptr;
5871 TGraphDelaunay *dtOld = nullptr;
5872 TList *hl = fH->GetListOfFunctions();
5873 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5874 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5875 if (!dt && !dtOld) return;
5876 if (!fGraph2DPainter) {
5877 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5878 else fGraph2DPainter = new TGraph2DPainter(dtOld);
5879 }
5880 fGraph2DPainter->Paint(option);
5881 return;
5882 }
5883
5884 gPad->SetBit(TGraph::kClipFrame);
5885
5886 Double_t *levels = new Double_t[2*kMAXCONTOUR];
5887 Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5888 Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5889 Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5890
5891 Int_t npmax = 0;
5892 for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5893
5894 ncontour = fH->GetContour();
5895 if (ncontour == 0) {
5896 ncontour = gStyle->GetNumberContours();
5897 fH->SetContour(ncontour);
5898 }
5899 if (ncontour > kMAXCONTOUR) {
5900 Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5901 kMAXCONTOUR, ncontour);
5902 ncontour = kMAXCONTOUR-1;
5903 }
5904 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5905
5906 for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5907 Int_t linesav = fH->GetLineStyle();
5908 Int_t colorsav = fH->GetLineColor();
5909 Int_t fillsav = fH->GetFillColor();
5910 if (Hoption.Contour == 13) {
5911 fH->TAttLine::Modify();
5912 }
5913
5914 TPolyLine **polys = 0;
5915 TPolyLine *poly=0;
5916 TObjArray *contours = 0;
5917 TList *list = 0;
5918 TGraph *graph = 0;
5919 Int_t *np = 0;
5920 if (Hoption.Contour == 1) {
5921 np = new Int_t[ncontour];
5922 for (i=0;i<ncontour;i++) np[i] = 0;
5923 polys = new TPolyLine*[ncontour];
5924 for (i=0;i<ncontour;i++) {
5925 polys[i] = new TPolyLine(100);
5926 }
5927 if (Hoption.List == 1) {
5928 contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5929 if (contours) {
5930 gROOT->GetListOfSpecials()->Remove(contours);
5931 count = contours->GetSize();
5932 for (i=0;i<count;i++) {
5933 list = (TList*)contours->At(i);
5934 if (list) list->Delete();
5935 }
5936 }
5937 contours = new TObjArray(ncontour);
5938 contours->SetName("contours");
5939 gROOT->GetListOfSpecials()->Add(contours);
5940 for (i=0;i<ncontour;i++) {
5941 list = new TList();
5942 contours->Add(list);
5943 }
5944 }
5945 }
5946 Int_t theColor;
5947 Int_t ncolors = gStyle->GetNumberOfColors();
5948 Int_t ndivz = TMath::Abs(ncontour);
5949
5950 Int_t k,ipoly;
5951 for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5952 y[0] = fYaxis->GetBinCenter(j);
5953 y[1] = y[0];
5954 y[2] = fYaxis->GetBinCenter(j+1);
5955 y[3] = y[2];
5956 for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5957 zc[0] = fH->GetBinContent(i, j);
5958 zc[1] = fH->GetBinContent(i+1, j);
5959 zc[2] = fH->GetBinContent(i+1, j+1);
5960 zc[3] = fH->GetBinContent(i, j+1);
5961 if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5962 if (Hoption.Logz) {
5963 if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5964 else zc[0] = Hparam.zmin;
5965 if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5966 else zc[1] = Hparam.zmin;
5967 if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5968 else zc[2] = Hparam.zmin;
5969 if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5970 else zc[3] = Hparam.zmin;
5971 }
5972 for (k=0;k<4;k++) {
5973 ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5974 }
5975 if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5976 x[0] = fXaxis->GetBinCenter(i);
5977 x[3] = x[0];
5978 x[1] = fXaxis->GetBinCenter(i+1);
5979 x[2] = x[1];
5980 if (zc[0] <= zc[1]) n = 0; else n = 1;
5981 if (zc[2] <= zc[3]) m = 2; else m = 3;
5982 if (zc[n] > zc[m]) n = m;
5983 n++;
5984 lj=1;
5985 for (ix=1;ix<=4;ix++) {
5986 m = n%4 + 1;
5987 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5988 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5989 lj += 2*ljfill;
5990 n = m;
5991 }
5992
5993 if (zc[0] <= zc[1]) n = 0; else n = 1;
5994 if (zc[2] <= zc[3]) m = 2; else m = 3;
5995 if (zc[n] > zc[m]) n = m;
5996 n++;
5997 lj=2;
5998 for (ix=1;ix<=4;ix++) {
5999 if (n == 1) m = 4;
6000 else m = n-1;
6001 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
6002 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
6003 lj += 2*ljfill;
6004 n = m;
6005 }
6006
6007 // Re-order endpoints
6008
6009 count = 0;
6010 for (ix=1; ix<=lj-5; ix +=2) {
6011 //count = 0;
6012 while (itarr[ix-1] != itarr[ix]) {
6013 xsave = xarr[ix];
6014 ysave = yarr[ix];
6015 itars = itarr[ix];
6016 for (jx=ix; jx<=lj-5; jx +=2) {
6017 xarr[jx] = xarr[jx+2];
6018 yarr[jx] = yarr[jx+2];
6019 itarr[jx] = itarr[jx+2];
6020 }
6021 xarr[lj-3] = xsave;
6022 yarr[lj-3] = ysave;
6023 itarr[lj-3] = itars;
6024 if (count > 100) break;
6025 count++;
6026 }
6027 }
6028
6029 if (count > 100) continue;
6030 for (ix=1; ix<=lj-2; ix +=2) {
6031 theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
6032 icol = gStyle->GetColorPalette(theColor);
6033 if (Hoption.Contour == 11) {
6034 fH->SetLineColor(icol);
6035 }
6036 if (Hoption.Contour == 12) {
6037 mode = icol%5;
6038 if (mode == 0) mode = 5;
6039 fH->SetLineStyle(mode);
6040 }
6041 if (Hoption.Contour != 1) {
6042 fH->TAttLine::Modify();
6043 gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
6044 continue;
6045 }
6046
6047 ipoly = itarr[ix-1];
6048 if (ipoly >=0 && ipoly <ncontour) {
6049 poly = polys[ipoly];
6050 poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
6051 poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
6052 np[ipoly] += 2;
6053 if (npmax < np[ipoly]) npmax = np[ipoly];
6054 }
6055 }
6056 } // end of if (ir[0]
6057 } //end of for (i
6058 } //end of for (j
6059
6061 Double_t *xp, *yp;
6062 Int_t nadd,iminus,iplus;
6063 Double_t *xx, *yy;
6064 Int_t istart;
6065 Int_t first = ncontour;
6066 Int_t *polysort = 0;
6067 Int_t contListNb;
6068 if (Hoption.Contour != 1) goto theEND;
6069
6070 //The 2 points line generated above are now sorted/merged to generate
6071 //a list of consecutive points.
6072 // If the option "List" has been specified, the list of points is saved
6073 // in the form of TGraph objects in the ROOT list of special objects.
6074 xmin = gPad->GetUxmin();
6075 ymin = gPad->GetUymin();
6076 xp = new Double_t[2*npmax];
6077 yp = new Double_t[2*npmax];
6078 polysort = new Int_t[ncontour];
6079 //find first positive contour
6080 for (ipoly=0;ipoly<ncontour;ipoly++) {
6081 if (levels[ipoly] >= 0) {first = ipoly; break;}
6082 }
6083 //store negative contours from 0 to minimum, then all positive contours
6084 k = 0;
6085 for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
6086 for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
6087 // we can now draw sorted contours
6088 contListNb = 0;
6089 fH->SetFillStyle(1001);
6090 for (k=0;k<ncontour;k++) {
6091 ipoly = polysort[k];
6092 if (np[ipoly] == 0) continue;
6093 if (Hoption.List) list = (TList*)contours->At(contListNb);
6094 contListNb++;
6095 poly = polys[ipoly];
6096 xx = poly->GetX();
6097 yy = poly->GetY();
6098 istart = 0;
6099 while (1) {
6100 iminus = npmax;
6101 iplus = iminus+1;
6102 xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
6103 xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
6104 xx[istart] = xmin; yy[istart] = ymin;
6105 xx[istart+1] = xmin; yy[istart+1] = ymin;
6106 while (1) {
6107 nadd = 0;
6108 for (i=2;i<np[ipoly];i+=2) {
6109 if ((iplus < 2*npmax-1) && (xx[i] == xp[iplus]) && (yy[i] == yp[iplus])) {
6110 iplus++;
6111 xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
6112 xx[i] = xmin; yy[i] = ymin;
6113 xx[i+1] = xmin; yy[i+1] = ymin;
6114 nadd++;
6115 }
6116 if ((iminus > 0) && (xx[i+1] == xp[iminus]) && (yy[i+1] == yp[iminus])) {
6117 iminus--;
6118 xp[iminus] = xx[i]; yp[iminus] = yy[i];
6119 xx[i] = xmin; yy[i] = ymin;
6120 xx[i+1] = xmin; yy[i+1] = ymin;
6121 nadd++;
6122 }
6123 }
6124 if (nadd == 0) break;
6125 }
6126 theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
6127 icol = gStyle->GetColorPalette(theColor);
6128 if (ndivz > 1) fH->SetFillColor(icol);
6129 fH->TAttFill::Modify();
6130 gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6131 if (Hoption.List) {
6132 graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6133 graph->SetFillColor(icol);
6134 graph->SetLineWidth(fH->GetLineWidth());
6135 list->Add(graph);
6136 }
6137 //check if more points are left
6138 istart = 0;
6139 for (i=2;i<np[ipoly];i+=2) {
6140 if (xx[i] != xmin && yy[i] != ymin) {
6141 istart = i;
6142 break;
6143 }
6144 }
6145 if (istart == 0) break;
6146 }
6147 }
6148
6149 for (i=0;i<ncontour;i++) delete polys[i];
6150 delete [] polys;
6151 delete [] xp;
6152 delete [] yp;
6153 delete [] polysort;
6154
6155theEND:
6156 gPad->ResetBit(TGraph::kClipFrame);
6158 fH->SetLineStyle(linesav);
6159 fH->SetLineColor(colorsav);
6160 fH->SetFillColor(fillsav);
6161 if (np) delete [] np;
6162 delete [] xarr;
6163 delete [] yarr;
6164 delete [] itarr;
6165 delete [] levels;
6166}
6167
6168////////////////////////////////////////////////////////////////////////////////
6169/// Fill the matrix `xarr` and `yarr` for Contour Plot.
6170
6172 Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
6173 Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
6174{
6175
6176 Bool_t vert;
6177 Double_t tlen, tdif, elev, diff, pdif, xlen;
6178 Int_t n, i, icount;
6179
6180 if (x1 == x2) {
6181 vert = kTRUE;
6182 tlen = y2 - y1;
6183 } else {
6184 vert = kFALSE;
6185 tlen = x2 - x1;
6186 }
6187
6188 n = icont1 +1;
6189 tdif = elev2 - elev1;
6190 i = 0;
6191 icount = 0;
6192 while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
6193 //elev = fH->GetContourLevel(n);
6194 elev = levels[n];
6195 diff = elev - elev1;
6196 pdif = diff/tdif;
6197 xlen = tlen*pdif;
6198 if (vert) {
6199 if (Hoption.Logx)
6200 xarr[i] = TMath::Log10(x1);
6201 else
6202 xarr[i] = x1;
6203 if (Hoption.Logy)
6204 yarr[i] = TMath::Log10(y1 + xlen);
6205 else
6206 yarr[i] = y1 + xlen;
6207 } else {
6208 if (Hoption.Logx)
6209 xarr[i] = TMath::Log10(x1 + xlen);
6210 else
6211 xarr[i] = x1 + xlen;
6212 if (Hoption.Logy)
6213 yarr[i] = TMath::Log10(y1);
6214 else
6215 yarr[i] = y1;
6216 }
6217 itarr[i] = n;
6218 icount++;
6219 i +=2;
6220 n++;
6221 }
6222 return icount;
6223}
6224
6225////////////////////////////////////////////////////////////////////////////////
6226/// [Draw 1D histograms error bars.](#HP09)
6227
6229{
6230
6231 // On iOS, we do not highlight histogram, if it's not picked at the moment
6232 // (but part of histogram (axis or pavestat) was picked, that's why this code
6233 // is called at all. This conditional statement never executes on non-iOS platform.
6234 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
6235
6236 const Int_t kBASEMARKER=8;
6237 Double_t xp, yp, ex1, ex2, ey1, ey2;
6238 Double_t delta;
6239 Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
6240 Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
6242 Double_t logxmin = 0;
6243 Double_t logymin = 0;
6244 Double_t offset = 0.;
6245 Double_t width = 0.;
6246 Int_t i, k, npoints, first, last, fixbin;
6247 Int_t if1 = 0;
6248 Int_t if2 = 0;
6249 Int_t drawmarker, errormarker;
6250 Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
6251
6252 Double_t *xline = 0;
6253 Double_t *yline = 0;
6254 option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
6255 if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
6256 if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
6257 if (Hoption.Error == 10) option0 = 1;
6258 if (Hoption.Error == 11) option1 = 1;
6259 if (Hoption.Error == 12) option2 = 1;
6260 if (Hoption.Error == 13) option3 = 1;
6261 if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
6262 if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
6263 if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
6264 if (option2+option3 == 0) optionE = 1;
6265 if (Hoption.Error == 0) optionE = 0;
6266 if (fXaxis->GetXbins()->fN) fixbin = 0;
6267 else fixbin = 1;
6268
6269 offset = fH->GetBarOffset();
6270 width = fH->GetBarWidth();
6271
6272 errormarker = fH->GetMarkerStyle();
6273 if (optionEX0) {
6274 xerror = 0;
6275 } else {
6276 xerror = gStyle->GetErrorX();
6277 }
6278 symbolsize = fH->GetMarkerSize();
6279 if (errormarker == 1) symbolsize = 0.01;
6280 sbase = symbolsize*kBASEMARKER;
6281 // set the graphics attributes
6282
6283 fH->TAttLine::Modify();
6284 fH->TAttFill::Modify();
6285 fH->TAttMarker::Modify();
6286
6287 // set the first and last bin
6288
6289 Double_t factor = Hparam.factor;
6291 last = Hparam.xlast;
6292 npoints = last - first +1;
6293 xmin = gPad->GetUxmin();
6294 xmax = gPad->GetUxmax();
6295 ymin = gPad->GetUymin();
6296 ymax = gPad->GetUymax();
6297
6298
6299 if (option3) {
6300 xline = new Double_t[2*npoints];
6301 yline = new Double_t[2*npoints];
6302 if (!xline || !yline) {
6303 Error("PaintErrors", "too many points, out of memory");
6304 return;
6305 }
6306 if1 = 1;
6307 if2 = 2*npoints;
6308 }
6309
6310 // compute the offset of the error bars due to the symbol size
6311 s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
6312 s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
6313
6314 // compute size of the lines at the end of the error bars
6315 Int_t dxend = Int_t(gStyle->GetEndErrorSize());
6316 bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
6317 bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
6318
6319
6320 if (fixbin) {
6321 if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
6322 else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
6323 } else {
6324 delta = fH->GetBinWidth(first);
6325 xp = fH->GetBinLowEdge(first) + 0.5*delta;
6326 }
6327
6328 // if errormarker = 0 or symbolsize = 0. no symbol is drawn
6329 if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
6330 if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
6331
6332 // ---------------------- Loop over the points---------------------
6333 for (k=first; k<=last; k++) {
6334
6335 // get the data
6336 // xp = X position of the current point
6337 // yp = Y position of the current point
6338 // ex1 = Low X error
6339 // ex2 = Up X error
6340 // ey1 = Low Y error
6341 // ey2 = Up Y error
6342 // (xi,yi) = Error bars coordinates
6343
6344 // apply offset on errors for bar histograms
6345 Double_t xminTmp = gPad->XtoPad(fXaxis->GetBinLowEdge(k));
6346 Double_t xmaxTmp = gPad->XtoPad(fXaxis->GetBinUpEdge(k));
6347 if (Hoption.Logx) {
6348 xminTmp = TMath::Power(10, xminTmp);
6349 xmaxTmp = TMath::Power(10, xmaxTmp);
6350 }
6351 Double_t w = (xmaxTmp-xminTmp)*width;
6352 xminTmp += offset*(xmaxTmp-xminTmp);
6353 xmaxTmp = xminTmp + w;
6354 xp = (xminTmp+xmaxTmp)/2.;
6355
6356 if (Hoption.Logx) {
6357 if (xp <= 0) goto L30;
6358 if (xp < logxmin) goto L30;
6359 if (xp > TMath::Power(10,xmax)) break;
6360 } else {
6361 if (xp < xmin) goto L30;
6362 if (xp > xmax) break;
6363 }
6364 yp = factor*fH->GetBinContent(k);
6365 if (optionI0 && yp==0) goto L30;
6366 if (fixbin) {
6367 ex1 = xerror*Hparam.xbinsize;
6368 } else {
6369 delta = fH->GetBinWidth(k);
6370 ex1 = xerror*delta;
6371 }
6372 if (fH->GetBinErrorOption() == TH1::kNormal) {
6373 ey1 = factor*fH->GetBinError(k);
6374 ey2 = ey1;
6375 } else {
6376 ey1 = factor*fH->GetBinErrorLow(k);
6377 ey2 = factor*fH->GetBinErrorUp(k);
6378 }
6379 ex2 = ex1;
6380
6381 xi4 = xp;
6382 xi3 = xp;
6383 xi2 = xp + ex2;
6384 xi1 = xp - ex1;
6385
6386 yi1 = yp;
6387 yi2 = yp;
6388 yi3 = yp - ey1;
6389 yi4 = yp + ey2;
6390
6391 // take the LOG if necessary
6392 if (Hoption.Logx) {
6393 xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
6394 xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
6395 xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
6396 xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
6397 }
6398 if (Hoption.Logy) {
6399 yi1 = TMath::Log10(TMath::Max(yi1,logymin));
6400 yi2 = TMath::Log10(TMath::Max(yi2,logymin));
6401 yi3 = TMath::Log10(TMath::Max(yi3,logymin));
6402 yi4 = TMath::Log10(TMath::Max(yi4,logymin));
6403 }
6404
6405 // test if error bars are not outside the limits
6406 // otherwise they are truncated
6407
6408 xi1 = TMath::Max(xi1,xmin);
6409 xi2 = TMath::Min(xi2,xmax);
6410 yi3 = TMath::Max(yi3,ymin);
6411 yi4 = TMath::Min(yi4,ymax);
6412
6413 // test if the marker is on the frame limits. If "Yes", the
6414 // marker will not be drawn and the error bars will be readjusted.
6415
6416 drawmarker = kTRUE;
6417 if (!option0 && !option3) {
6418 if (Hoption.Logy && yp < logymin) goto L30;
6419 if (yi1 < ymin || yi1 > ymax) goto L30;
6420 if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6421 }
6422 if (!symbolsize || !errormarker) drawmarker = kFALSE;
6423
6424 // draw the error rectangles
6425 if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
6426
6427 // keep points for fill area drawing
6428 if (option3) {
6429 xline[if1-1] = xi3;
6430 xline[if2-1] = xi3;
6431 yline[if1-1] = yi4;
6432 yline[if2-1] = yi3;
6433 if1++;
6434 if2--;
6435 }
6436
6437 // draw the error bars
6438 if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6439 if (optionE && drawmarker) {
6440 if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6441 if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6442 // don't duplicate the horizontal line
6443 if (Hoption.Hist != 2) {
6444 if (yi1<ymax && yi1>ymin) {
6445 if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6446 if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6447 }
6448 }
6449 }
6450 if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6451 if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6452 if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6453 // don't duplicate the horizontal line
6454 if (Hoption.Hist != 2) {
6455 if (yi1<ymax && yi1>ymin) {
6456 if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6457 if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6458 }
6459 }
6460 }
6461
6462 // draw line at the end of the error bars
6463
6464 if (option1 && drawmarker) {
6465 if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
6466 if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
6467 if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
6468 if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
6469 }
6470
6471 // draw the marker
6472
6473 if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6474
6475L30:
6476 if (fixbin) xp += Hparam.xbinsize;
6477 else {
6478 if (k < last) {
6479 delta = fH->GetBinWidth(k+1);
6480 xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6481 }
6482 }
6483 } //end of for loop
6484
6485 // draw the filled area
6486
6487 if (option3) {
6488 TGraph graph;
6489 graph.SetLineStyle(fH->GetLineStyle());
6490 graph.SetLineColor(fH->GetLineColor());
6491 graph.SetLineWidth(fH->GetLineWidth());
6492 graph.SetFillStyle(fH->GetFillStyle());
6493 graph.SetFillColor(fH->GetFillColor());
6494 Int_t logx = gPad->GetLogx();
6495 Int_t logy = gPad->GetLogy();
6496 gPad->SetLogx(0);
6497 gPad->SetLogy(0);
6498
6499 // In some cases the number of points in the fill area is smaller than
6500 // 2*npoints. In such cases the array xline and yline must be arranged
6501 // before being plotted. The next loop does that.
6502 if (if2 > npoints) {
6503 for (i=1; i<if1; i++) {
6504 xline[if1-2+i] = xline[if2-1+i];
6505 yline[if1-2+i] = yline[if2-1+i];
6506 }
6507 npoints = if1-1;
6508 }
6509 if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6510 else graph.PaintGraph(2*npoints,xline,yline,"F");
6511 gPad->SetLogx(logx);
6512 gPad->SetLogy(logy);
6513 delete [] xline;
6514 delete [] yline;
6515 }
6516}
6517
6518////////////////////////////////////////////////////////////////////////////////
6519/// Draw 2D histograms errors.
6520
6522{
6523
6524 fH->TAttMarker::Modify();
6525 fH->TAttLine::Modify();
6526
6527 // Define the 3D view
6528 fXbuf[0] = Hparam.xmin;
6529 fYbuf[0] = Hparam.xmax;
6530 fXbuf[1] = Hparam.ymin;
6531 fYbuf[1] = Hparam.ymax;
6532 fXbuf[2] = Hparam.zmin;
6533 fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6535 TView *view = gPad->GetView();
6536 if (!view) {
6537 Error("Paint2DErrors", "no TView in current pad");
6538 return;
6539 }
6540 Double_t thedeg = 90 - gPad->GetTheta();
6541 Double_t phideg = -90 - gPad->GetPhi();
6542 Double_t psideg = view->GetPsi();
6543 Int_t irep;
6544 view->SetView(phideg, thedeg, psideg, irep);
6545
6546 // Set color/style for back box
6547 fLego->SetFillStyle(gPad->GetFrameFillStyle());
6548 fLego->SetFillColor(gPad->GetFrameFillColor());
6549 fLego->TAttFill::Modify();
6550 Int_t backcolor = gPad->GetFrameFillColor();
6551 if (Hoption.System != kCARTESIAN) backcolor = 0;
6552 view->PadRange(backcolor);
6555 fLego->TAttFill::Modify();
6556
6557 // Paint the Back Box if needed
6558 if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6559 fLego->InitMoveScreen(-1.1,1.1);
6562 fLego->BackBox(90);
6563 }
6564
6565 // Paint the Errors
6566 Double_t x, ex, x1, x2;
6567 Double_t y, ey, y1, y2;
6568 Double_t z, ez1, ez2, z1, z2;
6569 Double_t temp1[3],temp2[3];
6570 Double_t xyerror;
6571 if (Hoption.Error == 110) {
6572 xyerror = 0;
6573 } else {
6574 xyerror = gStyle->GetErrorX();
6575 }
6576
6577 Double_t xk, xstep, yk, ystep;
6578 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6579 y = fYaxis->GetBinCenter(j);
6580 ey = fYaxis->GetBinWidth(j)*xyerror;
6581 y1 = y-ey;
6582 y2 = y+ey;
6583 if (Hoption.Logy) {
6584 if (y > 0) y = TMath::Log10(y);
6585 else continue;
6586 if (y1 > 0) y1 = TMath::Log10(y1);
6587 else y1 = Hparam.ymin;
6588 if (y2 > 0) y2 = TMath::Log10(y2);
6589 else y2 = Hparam.ymin;
6590 }
6591 yk = fYaxis->GetBinLowEdge(j);
6592 ystep = fYaxis->GetBinWidth(j);
6593 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6594 xk = fXaxis->GetBinLowEdge(i);
6595 xstep = fXaxis->GetBinWidth(i);
6596 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6597 Int_t bin = fH->GetBin(i,j);
6598 x = fXaxis->GetBinCenter(i);
6599 ex = fXaxis->GetBinWidth(i)*xyerror;
6600 x1 = x-ex;
6601 x2 = x+ex;
6602 if (Hoption.Logx) {
6603 if (x > 0) x = TMath::Log10(x);
6604 else continue;
6605 if (x1 > 0) x1 = TMath::Log10(x1);
6606 else x1 = Hparam.xmin;
6607 if (x2 > 0) x2 = TMath::Log10(x2);
6608 else x2 = Hparam.xmin;
6609 }
6610 z = fH->GetBinContent(bin);
6611 if (fH->GetBinErrorOption() == TH1::kNormal) {
6612 ez1 = fH->GetBinError(bin);
6613 ez2 = ez1;
6614 }
6615 else {
6616 ez1 = fH->GetBinErrorLow(bin);
6617 ez2 = fH->GetBinErrorUp(bin);
6618 }
6619 z1 = z - ez1;
6620 z2 = z + ez2;
6621 if (Hoption.Logz) {
6622 if (z > 0) z = TMath::Log10(z);
6623 else z = Hparam.zmin;
6624 if (z1 > 0) z1 = TMath::Log10(z1);
6625 else z1 = Hparam.zmin;
6626 if (z2 > 0) z2 = TMath::Log10(z2);
6627 else z2 = Hparam.zmin;
6628
6629 }
6630 if (z <= Hparam.zmin) continue;
6631 if (z > Hparam.zmax) z = Hparam.zmax;
6632
6633 temp1[0] = x1;
6634 temp1[1] = y;
6635 temp1[2] = z;
6636 temp2[0] = x2;
6637 temp2[1] = y;
6638 temp2[2] = z;
6639 gPad->PaintLine3D(temp1, temp2);
6640 temp1[0] = x;
6641 temp1[1] = y1;
6642 temp1[2] = z;
6643 temp2[0] = x;
6644 temp2[1] = y2;
6645 temp2[2] = z;
6646 gPad->PaintLine3D(temp1, temp2);
6647 temp1[0] = x;
6648 temp1[1] = y;
6649 temp1[2] = z1;
6650 temp2[0] = x;
6651 temp2[1] = y;
6652 temp2[2] = z2;
6653 gPad->PaintLine3D(temp1, temp2);
6654 temp1[0] = x;
6655 temp1[1] = y;
6656 temp1[2] = z;
6657 view->WCtoNDC(temp1, &temp2[0]);
6658 gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6659 }
6660 }
6661
6662 // Paint the Front Box if needed
6663 if (Hoption.FrontBox) {
6664 fLego->InitMoveScreen(-1.1,1.1);
6666 fLego->FrontBox(90);
6667 }
6668
6669 // Paint the Axis if needed
6670 if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6671 TGaxis *axis = new TGaxis();
6672 PaintLegoAxis(axis, 90);
6673 delete axis;
6674 }
6675
6676 delete fLego; fLego = 0;
6677}
6678
6679////////////////////////////////////////////////////////////////////////////////
6680/// Calculate range and clear pad (canvas).
6681
6683{
6684
6685 if (Hoption.Same) return;
6686
6688
6689 if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6690 Hoption.Contour == 14 || Hoption.Error >= 100) {
6691 TObject *frame = gPad->FindObject("TFrame");
6692 if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6693 return;
6694 }
6695
6696 //The next statement is always executed on non-iOS platform,
6697 //on iOS depends on pad mode.
6698 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6699 gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6700}
6701
6702////////////////////////////////////////////////////////////////////////////////
6703/// [Paint functions associated to an histogram.](#HP28")
6704
6706{
6707
6709 TObject *obj;
6710
6711 while (lnk) {
6712 obj = lnk->GetObject();
6713 TVirtualPad *padsave = gPad;
6714 if (obj->InheritsFrom(TF2::Class())) {
6715 if (obj->TestBit(TF2::kNotDraw) == 0) {
6716 if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) {
6717 TF2 *f2 = (TF2*)obj;
6718 f2->SetMinimum(fH->GetMinimum());
6719 f2->SetMaximum(fH->GetMaximum());
6720 f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6721 f2->Paint("surf same");
6722 } else {
6723 obj->Paint("cont3 same");
6724 }
6725 }
6726 } else if (obj->InheritsFrom(TF1::Class())) {
6727 if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6728 } else {
6729 //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6730 gPad->PushSelectableObject(obj);
6731
6732 //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6733 //and picked object.
6734 if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6735 obj->Paint(lnk->GetOption());
6736 }
6737 lnk = (TObjOptLink*)lnk->Next();
6738 padsave->cd();
6739 }
6740}
6741
6742////////////////////////////////////////////////////////////////////////////////
6743/// [Control routine to draw 1D histograms](#HP01b)
6744
6746{
6747
6748 //On iOS: do not highlight hist, if part of it was selected.
6749 //Never executes on non-iOS platform.
6750 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6751 return;
6752
6753 static char chopth[17];
6754
6755 Int_t htype, oldhtype;
6756 Int_t i, j, first, last, nbins, fixbin;
6757 Double_t c1, yb;
6758 yb = 0;
6759
6760 strlcpy(chopth, " ",17);
6761
6764 Double_t baroffset = fH->GetBarOffset();
6765 Double_t barwidth = fH->GetBarWidth();
6766 Double_t baroffsetsave = gStyle->GetBarOffset();
6767 Double_t barwidthsave = gStyle->GetBarWidth();
6768 gStyle->SetBarOffset(baroffset);
6769 gStyle->SetBarWidth(barwidth);
6770
6771 // Create "LIFE" structure to keep current histogram status
6772
6774 last = Hparam.xlast;
6775 nbins = last - first + 1;
6776
6777 Double_t *keepx = 0;
6778 Double_t *keepy = 0;
6779 if (fXaxis->GetXbins()->fN) fixbin = 0;
6780 else fixbin = 1;
6781 if (fixbin) keepx = new Double_t[2];
6782 else keepx = new Double_t[nbins+1];
6783 keepy = new Double_t[nbins];
6784 Double_t logymin = 0;
6785 if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6786
6787 // Loop on histogram bins
6788
6789 for (j=first; j<=last;j++) {
6791 if (TMath::Abs(ymax-ymin) > 0) {
6792 if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6793 else yb = c1;
6794 }
6795 if (!Hoption.Line) {
6796 yb = TMath::Max(yb, ymin);
6797 yb = TMath::Min(yb, ymax);
6798 }
6799 keepy[j-first] = yb;
6800 }
6801
6802 // Draw histogram according to value of FillStyle and FillColor
6803
6804 if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6805 else {
6806 for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6807 keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6808 }
6809
6810 // Prepare Fill area (systematic with option "Bar").
6811
6812 oldhtype = fH->GetFillStyle();
6813 htype = oldhtype;
6814 if (Hoption.Bar) {
6815 if (htype == 0 || htype == 1000) htype = 1001;
6816 }
6817
6818 Width_t lw = (Width_t)fH->GetLineWidth();
6819
6820 // Code option for GrapHist
6821
6822 if (Hoption.Line) chopth[0] = 'L';
6823 if (Hoption.Star) chopth[1] = '*';
6824 if (Hoption.Mark) chopth[2] = 'P';
6825 if (Hoption.Mark == 10) chopth[3] = '0';
6827 if (Hoption.Curve) chopth[3] = 'C';
6828 if (Hoption.Hist > 0) chopth[4] = 'H';
6829 else if (Hoption.Bar) chopth[5] = 'B';
6830 if (fH->GetFillColor() && htype) {
6831 if (Hoption.Logy) {
6832 chopth[6] = '1';
6833 }
6834 if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6835 chopth[7] = 'F';
6836 }
6837 }
6838 }
6839 if (!fixbin && strlen(chopth)) {
6840 chopth[8] = 'N';
6841 }
6842
6843 if (Hoption.Fill == 2) chopth[13] = '2';
6844
6845 // Option LOGX
6846
6847 if (Hoption.Logx) {
6848 chopth[9] = 'G';
6849 chopth[10] = 'X';
6850 if (fixbin) {
6851 keepx[0] = TMath::Power(10,keepx[0]);
6852 keepx[1] = TMath::Power(10,keepx[1]);
6853 }
6854 }
6855
6856 if (Hoption.Off) {
6857 chopth[11] = ']';
6858 chopth[12] = '[';
6859 }
6860
6861 // Draw the histogram
6862
6863 TGraph graph;
6864 graph.SetLineWidth(lw);
6865 graph.SetLineStyle(fH->GetLineStyle());
6866 graph.SetLineColor(fH->GetLineColor());
6867 graph.SetFillStyle(htype);
6868 graph.SetFillColor(fH->GetFillColor());
6869 graph.SetMarkerStyle(fH->GetMarkerStyle());
6870 graph.SetMarkerSize(fH->GetMarkerSize());
6871 graph.SetMarkerColor(fH->GetMarkerColor());
6872 if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6873
6874 graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6875
6876 delete [] keepx;
6877 delete [] keepy;
6878 gStyle->SetBarOffset(baroffsetsave);
6879 gStyle->SetBarWidth(barwidthsave);
6880
6881 htype=oldhtype;
6882}
6883
6884////////////////////////////////////////////////////////////////////////////////
6885/// [Control function to draw a 3D histograms.](#HP01d)
6886
6888{
6889
6890 char *cmd;
6891 TString opt = option;
6892 opt.ToLower();
6893 Int_t irep;
6894
6895 if (Hoption.Box || Hoption.Lego) {
6896 if (Hoption.Box == 11 || Hoption.Lego == 11) {
6897 PaintH3Box(1);
6898 } else if (Hoption.Box == 12 || Hoption.Lego == 12) {
6899 PaintH3Box(2);
6900 } else if (Hoption.Box == 13 || Hoption.Lego == 13) {
6901 PaintH3Box(3);
6902 } else {
6904 }
6905 return;
6906 } else if (strstr(opt,"iso")) {
6907 PaintH3Iso();
6908 return;
6909 } else if (strstr(opt,"tf3")) {
6910 PaintTF3();
6911 return;
6912 } else {
6913 cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6914 }
6915
6916 if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6917 if (strstr(opt,"bb")) Hoption.BackBox = 0;
6918
6919 TView *view = gPad->GetView();
6920 if (!view) return;
6921 Double_t thedeg = 90 - gPad->GetTheta();
6922 Double_t phideg = -90 - gPad->GetPhi();
6923 Double_t psideg = view->GetPsi();
6924 view->SetView(phideg, thedeg, psideg, irep);
6925
6926 // Paint the data
6927 gROOT->ProcessLine(cmd);
6928
6929 if (Hoption.Same) return;
6930
6931 // Draw axis
6932 view->SetOutlineToCube();
6933 TSeqCollection *ol = view->GetOutline();
6934 if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6936 TGaxis *axis = new TGaxis();
6937 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6938 delete axis;
6939
6940 // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6941 // be painted with the option colz.
6942 if (fH->GetDrawOption() && strstr(opt,"colz")) {
6943 Int_t ndiv = fH->GetContour();
6944 if (ndiv == 0 ) {
6945 ndiv = gStyle->GetNumberContours();
6946 fH->SetContour(ndiv);
6947 }
6948 PaintPalette();
6949 }
6950
6951 // Draw title
6952 PaintTitle();
6953
6954 //Draw stats and fit results
6955 TF1 *fit = 0;
6956 TIter next(fFunctions);
6957 TObject *obj;
6958 while ((obj = next())) {
6959 if (obj->InheritsFrom(TF1::Class())) {
6960 fit = (TF1*)obj;
6961 break;
6962 }
6963 }
6964 if ((Hoption.Same%10) != 1) {
6965 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6967 }
6968 }
6969
6970}
6971
6972////////////////////////////////////////////////////////////////////////////////
6973/// Compute histogram parameters used by the drawing routines.
6974
6976{
6977
6978 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6979
6980 Int_t i;
6981 static const char *where = "PaintInit";
6982 Double_t yMARGIN = gStyle->GetHistTopMargin();
6983 Int_t maximum = 0;
6984 Int_t minimum = 0;
6985 if (fH->GetMaximumStored() != -1111) maximum = 1;
6986 if (fH->GetMinimumStored() != -1111) minimum = 1;
6987
6988 // Compute X axis parameters
6989
6990 Int_t last = fXaxis->GetLast();
6994 Hparam.xlast = last;
6998
6999 // if log scale in X, replace xmin,max by the log
7000 if (Hoption.Logx) {
7001 if (Hparam.xmax<=0) {
7002 Error(where, "cannot set X axis to log scale");
7003 return 0;
7004 }
7005 if (Hparam.xlowedge <=0 ) {
7006 if (Hoption.Same) {
7007 Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
7008 } else {
7009 for (i=first; i<=last; i++) {
7010 Double_t binLow = fXaxis->GetBinLowEdge(i);
7011 if (binLow>0) {
7012 Hparam.xlowedge = binLow;
7013 break;
7014 }
7015 if (binLow == 0 && fH->GetBinContent(i) !=0) {
7016 Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
7017 break;
7018 }
7019 }
7020 if (Hparam.xlowedge<=0) {
7021 Error(where, "cannot set X axis to log scale");
7022 return 0;
7023 }
7024 }
7026 }
7031 if (Hparam.xlast > last) Hparam.xlast = last;
7033 }
7034
7035 // Compute Y axis parameters
7036 Double_t bigp = TMath::Power(10,32);
7037 Double_t ymax = -bigp;
7038 Double_t ymin = bigp;
7039 Double_t c1, e1;
7040 Double_t xv[1];
7041 Double_t fval;
7042 TObject *f;
7043 TF1 *f1;
7044 Double_t allchan = 0;
7045 Int_t nonNullErrors = 0;
7046 TIter next(fFunctions);
7047 for (i=first; i<=last;i++) {
7048 c1 = fH->GetBinContent(i);
7050 if (Hoption.Logy) {
7051 if (c1 > 0) ymin = TMath::Min(ymin,c1);
7052 } else {
7054 }
7055 if (Hoption.Error) {
7057 e1 = fH->GetBinError(i);
7058 else
7059 e1 = fH->GetBinErrorUp(i);
7060 if (e1 > 0) nonNullErrors++;
7061 ymax = TMath::Max(ymax,c1+e1);
7063 e1 = fH->GetBinErrorLow(i);
7064
7065 if (Hoption.Logy) {
7066 if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
7067 } else {
7068 ymin = TMath::Min(ymin,c1-e1);
7069 }
7070 }
7071 if (Hoption.Func) {
7072 xv[0] = fXaxis->GetBinCenter(i);
7073 while ((f = (TObject*) next())) {
7074 if (f->IsA() == TF1::Class()) {
7075 f1 = (TF1*)f;
7076 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7077 fval = f1->Eval(xv[0],0,0);
7078 if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
7079 ymax = TMath::Max(ymax,fval);
7080 if (Hoption.Logy) {
7081 if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
7082 }
7083 }
7084 }
7085 next.Reset();
7086 }
7087 allchan += c1;
7088 }
7089 if (!nonNullErrors) {
7090 if (Hoption.Error) {
7091 if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
7092 Hoption.Error=0;
7093 }
7094 }
7095
7096
7097 // Take into account maximum , minimum
7098
7099 if (Hoption.Logy && ymin <= 0) {
7100 if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
7101 else ymin = 0.001*ymax;
7102 }
7103
7104 Double_t xm = ymin;
7105 if (maximum) ymax = fH->GetMaximumStored();
7106 if (minimum) xm = fH->GetMinimumStored();
7107 if (Hoption.Logy && xm < 0) {
7108 Error(where, "log scale requested with a negative argument (%f)", xm);
7109 return 0;
7110 } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
7111 ymin = 0.01;
7112 ymax = 10.;
7113 } else {
7114 ymin = xm;
7115 }
7116
7117 if (ymin >= ymax) {
7118 if (Hoption.Logy) {
7119 if (ymax > 0) ymin = 0.001*ymax;
7120 else {
7121 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
7122 return 0;
7123 }
7124 }
7125 else {
7126 if (ymin > 0) {
7127 ymin = 0;
7128 ymax *= 2;
7129 } else if (ymin < 0) {
7130 ymax = 0;
7131 ymin *= 2;
7132 } else {
7133 ymin = 0;
7134 ymax = 1;
7135 }
7136 }
7137 }
7138
7139 // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
7140 if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
7141 ymin = ymin*(1-1E-14);
7142 ymax = ymax*(1+1E-14);
7143 }
7144
7145 // take into account normalization factor
7146 Hparam.allchan = allchan;
7147 Double_t factor = allchan;
7148 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7149 if (allchan) factor /= allchan;
7150 if (factor == 0) factor = 1;
7151 Hparam.factor = factor;
7152 ymax = factor*ymax;
7153 ymin = factor*ymin;
7154 //just in case the norm factor is negative
7155 // this may happen with a positive norm factor and a negative integral !
7156 if (ymax < ymin) {
7157 Double_t temp = ymax;
7158 ymax = ymin;
7159 ymin = temp;
7160 }
7161
7162 // For log scales, histogram coordinates are LOG10(ymin) and
7163 // LOG10(ymax). Final adjustment (if not option "Same"
7164 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7165 // Maximum and Minimum are not defined.
7166 if (Hoption.Logy) {
7167 if (ymin <=0 || ymax <=0) {
7168 Error(where, "Cannot set Y axis to log scale");
7169 return 0;
7170 }
7172 if (!minimum) ymin += TMath::Log10(0.5);
7174 if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
7175 if (!Hoption.Same) {
7176 Hparam.ymin = ymin;
7177 Hparam.ymax = ymax;
7178 }
7179 return 1;
7180 }
7181
7182 // final adjustment of ymin for linear scale.
7183 // if minimum is not set , then ymin is set to zero if >0
7184 // or to ymin - margin if <0.
7185 if (!minimum) {
7186 if (Hoption.MinimumZero) {
7187 if (ymin >= 0) ymin = 0;
7188 else ymin -= yMARGIN*(ymax-ymin);
7189 } else {
7190 Double_t dymin = yMARGIN*(ymax-ymin);
7191 if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
7192 else ymin -= dymin;
7193 }
7194 }
7195
7196 // final adjustment of YMAXI for linear scale (if not option "Same"):
7197 // decrease histogram height to MAX% of allowed height if HMAXIM
7198 // has not been called.
7199 if (!maximum) {
7200 ymax += yMARGIN*(ymax-ymin);
7201 }
7202
7203 Hparam.ymin = ymin;
7204 Hparam.ymax = ymax;
7205 return 1;
7206}
7207
7208////////////////////////////////////////////////////////////////////////////////
7209/// Compute histogram parameters used by the drawing routines for a rotated pad.
7210
7212{
7213
7214 static const char *where = "PaintInitH";
7215 Double_t yMARGIN = gStyle->GetHistTopMargin();
7216 Int_t maximum = 0;
7217 Int_t minimum = 0;
7218 if (fH->GetMaximumStored() != -1111) maximum = 1;
7219 if (fH->GetMinimumStored() != -1111) minimum = 1;
7220
7221 // Compute X axis parameters
7222
7223 Int_t last = fXaxis->GetLast();
7227 Hparam.xlast = last;
7231
7232 // if log scale in Y, replace ymin,max by the log
7233 if (Hoption.Logy) {
7234 if (Hparam.xlowedge <=0 ) {
7237 }
7238 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
7239 Error(where, "cannot set Y axis to log scale");
7240 return 0;
7241 }
7246 if (Hparam.xlast > last) Hparam.xlast = last;
7247 }
7248
7249 // Compute Y axis parameters
7250 Double_t bigp = TMath::Power(10,32);
7251 Double_t xmax = -bigp;
7252 Double_t xmin = bigp;
7253 Double_t c1, e1;
7254 Double_t xv[1];
7255 Double_t fval;
7256 Int_t i;
7257 TObject *f;
7258 TF1 *f1;
7259 Double_t allchan = 0;
7260 TIter next(fFunctions);
7261 for (i=first; i<=last;i++) {
7262 c1 = fH->GetBinContent(i);
7265 if (Hoption.Error) {
7266 e1 = fH->GetBinError(i);
7267 xmax = TMath::Max(xmax,c1+e1);
7268 xmin = TMath::Min(xmin,c1-e1);
7269 }
7270 if (Hoption.Func) {
7271 xv[0] = fXaxis->GetBinCenter(i);
7272 while ((f = (TObject*) next())) {
7273 if (f->IsA() == TF1::Class()) {
7274 f1 = (TF1*)f;
7275 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7276 fval = f1->Eval(xv[0],0,0);
7277 xmax = TMath::Max(xmax,fval);
7278 if (Hoption.Logy) {
7279 if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
7280 }
7281 }
7282 }
7283 next.Reset();
7284 }
7285 allchan += c1;
7286 }
7287
7288 // Take into account maximum , minimum
7289
7290 if (Hoption.Logx && xmin <= 0) {
7291 if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
7292 else xmin = 0.001*xmax;
7293 }
7294 Double_t xm = xmin;
7295 if (maximum) xmax = fH->GetMaximumStored();
7296 if (minimum) xm = fH->GetMinimumStored();
7297 if (Hoption.Logx && xm <= 0) {
7298 Error(where, "log scale requested with zero or negative argument (%f)", xm);
7299 return 0;
7300 }
7301 else xmin = xm;
7302 if (xmin >= xmax) {
7303 if (Hoption.Logx) {
7304 if (xmax > 0) xmin = 0.001*xmax;
7305 else {
7306 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
7307 return 0;
7308 }
7309 }
7310 else {
7311 if (xmin > 0) {
7312 xmin = 0;
7313 xmax *= 2;
7314 } else if (xmin < 0) {
7315 xmax = 0;
7316 xmin *= 2;
7317 } else {
7318 xmin = -1;
7319 xmax = 1;
7320 }
7321 }
7322 }
7323
7324 // take into account normalization factor
7325 Hparam.allchan = allchan;
7326 Double_t factor = allchan;
7327 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7328 if (allchan) factor /= allchan;
7329 if (factor == 0) factor = 1;
7330 Hparam.factor = factor;
7331 xmax = factor*xmax;
7332 xmin = factor*xmin;
7333
7334 // For log scales, histogram coordinates are LOG10(ymin) and
7335 // LOG10(ymax). Final adjustment (if not option "Same"
7336 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7337 // Maximum and Minimum are not defined.
7338 if (Hoption.Logx) {
7339 if (xmin <=0 || xmax <=0) {
7340 Error(where, "Cannot set Y axis to log scale");
7341 return 0;
7342 }
7344 if (!minimum) xmin += TMath::Log10(0.5);
7346 if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
7347 if (!Hoption.Same) {
7348 Hparam.xmin = xmin;
7349 Hparam.xmax = xmax;
7350 }
7351 return 1;
7352 }
7353
7354 // final adjustment of ymin for linear scale.
7355 // if minimum is not set , then ymin is set to zero if >0
7356 // or to ymin - margin if <0.
7357 if (!minimum) {
7358 if (xmin >= 0) xmin = 0;
7359 else xmin -= yMARGIN*(xmax-xmin);
7360 }
7361
7362 // final adjustment of YMAXI for linear scale (if not option "Same"):
7363 // decrease histogram height to MAX% of allowed height if HMAXIM
7364 // has not been called.
7365 if (!maximum) {
7366 xmax += yMARGIN*(xmax-xmin);
7367 }
7368 Hparam.xmin = xmin;
7369 Hparam.xmax = xmax;
7370 return 1;
7371}
7372
7373////////////////////////////////////////////////////////////////////////////////
7374/// [Control function to draw a 3D histogram with boxes.](#HP25)
7375
7377{
7378 // Predefined box structure
7379 Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
7380 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
7381 Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
7382 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
7383
7384 // Define dimensions of world space
7385 TGaxis *axis = new TGaxis();
7386 TAxis *xaxis = fH->GetXaxis();
7387 TAxis *yaxis = fH->GetYaxis();
7388 TAxis *zaxis = fH->GetZaxis();
7389
7390 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7391 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7392 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7393 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7394 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7395 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7396
7398
7399 // Set view
7400 TView *view = gPad->GetView();
7401 if (!view) {
7402 Error("PaintH3", "no TView in current pad");
7403 return;
7404 }
7405 Double_t thedeg = 90 - gPad->GetTheta();
7406 Double_t phideg = -90 - gPad->GetPhi();
7407 Double_t psideg = view->GetPsi();
7408 Int_t irep;
7409 view->SetView(phideg, thedeg, psideg, irep);
7410
7411 Int_t backcolor = gPad->GetFrameFillColor();
7412 view->PadRange(backcolor);
7413
7414 // Draw back surfaces of frame box
7415 fLego->InitMoveScreen(-1.1,1.1);
7416 if (Hoption.BackBox) {
7419 fLego->BackBox(90);
7420 }
7421
7423
7424 // Define order of drawing
7425 Double_t *tnorm = view->GetTnorm();
7426 if (!tnorm) return;
7427 Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7428 Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7429 Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7430 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7431 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7432 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7433 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7434 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7435 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7436
7437 // Set graphic attributes (colour, style, etc.)
7438 Style_t fillsav = fH->GetFillStyle();
7439 Style_t colsav = fH->GetFillColor();
7440 Style_t coldark = TColor::GetColorDark(colsav);
7441 Style_t colbright = TColor::GetColorBright(colsav);
7442
7443 fH->SetFillStyle(1001);
7444 fH->TAttFill::Modify();
7445 fH->TAttLine::Modify();
7446 Int_t ncolors = gStyle->GetNumberOfColors();
7447 Int_t theColor;
7448
7449 // Create bin boxes and draw
7450 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7453
7454 Double_t pmin[3], pmax[3], sxyz[8][3];
7455 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7456 pmin[0] = xaxis->GetBinLowEdge(ix);
7457 pmax[0] = xaxis->GetBinUpEdge(ix);
7458 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7459 pmin[1] = yaxis->GetBinLowEdge(iy);
7460 pmax[1] = yaxis->GetBinUpEdge(iy);
7461 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7462 pmin[2] = zaxis->GetBinLowEdge(iz);
7463 pmax[2] = zaxis->GetBinUpEdge(iz);
7464 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7465 Bool_t neg = kFALSE;
7466 Int_t n = 5;
7467 if (w<0) {
7468 w = -w;
7469 neg = kTRUE;
7470 }
7471 if (w < wmin) continue;
7472 if (w > wmax) w = wmax;
7473 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7474 if (scale == 0) continue;
7475 for (Int_t i=0; i<3; ++i) {
7476 Double_t c = (pmax[i] + pmin[i])*0.5;
7477 Double_t d = (pmax[i] - pmin[i])*scale;
7478 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7479 sxyz[k][i] = wxyz[k][i]*d + c;
7480 }
7481 }
7482 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7483 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7484 }
7485 Double_t x[8], y[8]; // draw bin box faces
7486 for (Int_t k=0; k<6; ++k) {
7487 for (Int_t i=0; i<4; ++i) {
7488 Int_t iv = iface[k][i];
7489 x[i] = sxyz[iv][0];
7490 y[i] = sxyz[iv][1];
7491 }
7492 x[4] = x[0] ; y[4] = y[0];
7493 if (neg) {
7494 x[5] = x[2] ; y[5] = y[2];
7495 x[6] = x[3] ; y[6] = y[3];
7496 x[7] = x[1] ; y[7] = y[1];
7497 n = 8;
7498 } else {
7499 n = 5;
7500 }
7501 Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7502 if (z <= 0.) continue;
7503 if (iopt == 2) {
7504 theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7506 } else {
7507 if (k == 3 || k == 5) {
7508 fH->SetFillColor(coldark);
7509 } else if (k == 0 || k == 1) {
7510 fH->SetFillColor(colbright);
7511 } else {
7512 fH->SetFillColor(colsav);
7513 }
7514 }
7515 fH->TAttFill::Modify();
7516 gPad->PaintFillArea(4, x, y);
7517 if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7518 }
7519 }
7520 }
7521 }
7522
7523 // Draw front surfaces of frame box
7524 if (Hoption.FrontBox) fLego->FrontBox(90);
7525
7526 // Draw axis and title
7527 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7528 PaintTitle();
7529
7530 // Draw palette. if needed.
7531 if (Hoption.Zscale) {
7532 Int_t ndiv = fH->GetContour();
7533 if (ndiv == 0 ) {
7534 ndiv = gStyle->GetNumberContours();
7535 fH->SetContour(ndiv);
7536 }
7537 PaintPalette();
7538 }
7539
7540 delete axis;
7541 delete fLego; fLego = 0;
7542
7543 fH->SetFillStyle(fillsav);
7544 fH->SetFillColor(colsav);
7545 fH->TAttFill::Modify();
7546}
7547
7548////////////////////////////////////////////////////////////////////////////////
7549/// [Control function to draw a 3D histogram with boxes.](#HP25)
7550
7552{
7553 // Predefined box structure
7554 Double_t wxyz[8][3] = {
7555 {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7556 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7557 };
7558 Int_t iface[6][4] = {
7559 {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7560 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7561 };
7562 Double_t normal[6][3] = {
7563 {0,0,-1}, {0,0,1}, // Z-, Z+
7564 {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7565 };
7566
7567 // Define dimensions of world space
7568 TGaxis *axis = new TGaxis();
7569 TAxis *xaxis = fH->GetXaxis();
7570 TAxis *yaxis = fH->GetYaxis();
7571 TAxis *zaxis = fH->GetZaxis();
7572
7573 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7574 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7575 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7576 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7577 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7578 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7579
7581
7582 // Set view
7583 TView *view = gPad->GetView();
7584 if (!view) {
7585 Error("PaintH3", "no TView in current pad");
7586 return;
7587 }
7588 Double_t thedeg = 90 - gPad->GetTheta();
7589 Double_t phideg = -90 - gPad->GetPhi();
7590 Double_t psideg = view->GetPsi();
7591 Int_t irep;
7592 view->SetView(phideg, thedeg, psideg, irep);
7593
7594 Int_t backcolor = gPad->GetFrameFillColor();
7595 view->PadRange(backcolor);
7596
7597 // Draw front surfaces of frame box
7598 if (Hoption.FrontBox) {
7599 fLego->InitMoveScreen(-1.1,1.1);
7601 }
7602
7603 // Initialize hidden line removal algorithm "raster screen"
7604 fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7605
7606 // Define order of drawing
7607 Double_t *tnorm = view->GetTnorm();
7608 if (!tnorm) return;
7609 Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7610 Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7611 Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7612 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7613 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7614 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7615 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7616 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7617 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7618
7619 // Set line attributes (colour, style, etc.)
7620 fH->TAttLine::Modify();
7621
7622 // Create bin boxes and draw
7623 const Int_t NTMAX = 100;
7624 Double_t tt[NTMAX][2];
7625 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7628 Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7629 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7630 pmin[0] = xaxis->GetBinLowEdge(ix);
7631 pmax[0] = xaxis->GetBinUpEdge(ix);
7632 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7633 pmin[1] = yaxis->GetBinLowEdge(iy);
7634 pmax[1] = yaxis->GetBinUpEdge(iy);
7635 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7636 pmin[2] = zaxis->GetBinLowEdge(iz);
7637 pmax[2] = zaxis->GetBinUpEdge(iz);
7638 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7639 Bool_t neg = kFALSE;
7640 if (w<0) {
7641 w = -w;
7642 neg = kTRUE;
7643 }
7644 if (w < wmin) continue;
7645 if (w > wmax) w = wmax;
7646 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7647 if (scale == 0) continue;
7648 for (Int_t i=0; i<3; ++i) {
7649 Double_t c = (pmax[i] + pmin[i])*0.5;
7650 Double_t d = (pmax[i] - pmin[i])*scale;
7651 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7652 sxyz[k][i] = wxyz[k][i]*d + c;
7653 }
7654 }
7655 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7656 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7657 }
7658 for (Int_t k=0; k<6; ++k) { // draw box faces
7659 Double_t zn;
7660 view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7661 if (zn <= 0) continue;
7662 for (Int_t i=0; i<4; ++i) {
7663 Int_t ip = iface[k][i];
7664 pp[i][0] = sxyz[ip][0];
7665 pp[i][1] = sxyz[ip][1];
7666 }
7667 for (Int_t i=0; i<4; ++i) {
7668 Int_t i1 = i;
7669 Int_t i2 = (i == 3) ? 0 : i + 1;
7670 Int_t nt;
7671 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7672 Double_t xdel = pp[i2][0] - pp[i1][0];
7673 Double_t ydel = pp[i2][1] - pp[i1][1];
7674 Double_t x[2], y[2];
7675 for (Int_t it = 0; it < nt; ++it) {
7676 x[0] = pp[i1][0] + xdel*tt[it][0];
7677 y[0] = pp[i1][1] + ydel*tt[it][0];
7678 x[1] = pp[i1][0] + xdel*tt[it][1];
7679 y[1] = pp[i1][1] + ydel*tt[it][1];
7680 gPad->PaintPolyLine(2, x, y);
7681 }
7682 }
7683 if (neg) {
7684 Int_t i1 = 0;
7685 Int_t i2 = 2;
7686 Int_t nt;
7687 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7688 Double_t xdel = pp[i2][0] - pp[i1][0];
7689 Double_t ydel = pp[i2][1] - pp[i1][1];
7690 Double_t x[2], y[2];
7691 for (Int_t it = 0; it < nt; ++it) {
7692 x[0] = pp[i1][0] + xdel*tt[it][0];
7693 y[0] = pp[i1][1] + ydel*tt[it][0];
7694 x[1] = pp[i1][0] + xdel*tt[it][1];
7695 y[1] = pp[i1][1] + ydel*tt[it][1];
7696 gPad->PaintPolyLine(2, x, y);
7697 }
7698 i1 = 1;
7699 i2 = 3;
7700 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7701 xdel = pp[i2][0] - pp[i1][0];
7702 ydel = pp[i2][1] - pp[i1][1];
7703 for (Int_t it = 0; it < nt; ++it) {
7704 x[0] = pp[i1][0] + xdel*tt[it][0];
7705 y[0] = pp[i1][1] + ydel*tt[it][0];
7706 x[1] = pp[i1][0] + xdel*tt[it][1];
7707 y[1] = pp[i1][1] + ydel*tt[it][1];
7708 gPad->PaintPolyLine(2, x, y);
7709 }
7710 }
7711 fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7712 }
7713 }
7714 }
7715 }
7716
7717 // Draw frame box
7718 if (Hoption.BackBox) {
7721 fLego->BackBox(90);
7722 }
7723
7724 if (Hoption.FrontBox) fLego->FrontBox(90);
7725
7726 // Draw axis and title
7727 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7728 PaintTitle();
7729
7730 delete axis;
7731 delete fLego; fLego = 0;
7732}
7733
7734////////////////////////////////////////////////////////////////////////////////
7735/// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
7736
7738{
7739
7740 const Double_t ydiff = 1;
7741 const Double_t yligh1 = 10;
7742 const Double_t qa = 0.15;
7743 const Double_t qd = 0.15;
7744 const Double_t qs = 0.8;
7745 Double_t fmin, fmax;
7746 Int_t i, irep;
7747 Int_t nbcol = 28;
7748 Int_t icol1 = 201;
7749 Int_t ic1 = icol1;
7750 Int_t ic2 = ic1+nbcol;
7751 Int_t ic3 = ic2+nbcol;
7752
7753 TGaxis *axis = new TGaxis();
7754 TAxis *xaxis = fH->GetXaxis();
7755 TAxis *yaxis = fH->GetYaxis();
7756 TAxis *zaxis = fH->GetZaxis();
7757
7758 Int_t nx = fH->GetNbinsX();
7759 Int_t ny = fH->GetNbinsY();
7760 Int_t nz = fH->GetNbinsZ();
7761
7762 Double_t *x = new Double_t[nx];
7763 Double_t *y = new Double_t[ny];
7764 Double_t *z = new Double_t[nz];
7765
7766 for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7767 for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7768 for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7769
7770 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7771 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7772 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7773 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7774 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7775 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7776
7777 Double_t s[3];
7778 s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7779 s[1] = 0.5*s[0];
7780 s[2] = 1.5*s[0];
7781
7783
7784 TView *view = gPad->GetView();
7785 if (!view) {
7786 Error("PaintH3Iso", "no TView in current pad");
7787 delete [] x;
7788 delete [] y;
7789 delete [] z;
7790 return;
7791 }
7792 Double_t thedeg = 90 - gPad->GetTheta();
7793 Double_t phideg = -90 - gPad->GetPhi();
7794 Double_t psideg = view->GetPsi();
7795 view->SetView(phideg, thedeg, psideg, irep);
7796
7797 Int_t backcolor = gPad->GetFrameFillColor();
7798 if (Hoption.System != kCARTESIAN) backcolor = 0;
7799 view->PadRange(backcolor);
7800
7801 Double_t dcol = 0.5/Double_t(nbcol);
7802 TColor *colref = gROOT->GetColor(fH->GetFillColor());
7803 if (!colref) {
7804 delete [] x;
7805 delete [] y;
7806 delete [] z;
7807 return;
7808 }
7809 Float_t r, g, b, hue, light, satur;
7810 colref->GetRGB(r,g,b);
7811 TColor::RGBtoHLS(r,g,b,hue,light,satur);
7812 TColor *acol;
7813 for (Int_t col=0;col<nbcol;col++) {
7814 acol = gROOT->GetColor(col+icol1);
7815 TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7816 if (acol) acol->SetRGB(r, g, b);
7817 }
7818
7819 fLego->InitMoveScreen(-1.1,1.1);
7820
7821 if (Hoption.BackBox) {
7824 fLego->BackBox(90);
7825 }
7826
7827 fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7828 fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7829 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7830 fmin = ydiff*qa;
7831 fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7832 fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7833
7834 fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7835
7836 if (Hoption.FrontBox) {
7837 fLego->InitMoveScreen(-1.1,1.1);
7839 fLego->FrontBox(90);
7840 }
7841 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7842
7843 PaintTitle();
7844
7845 delete axis;
7846 delete fLego; fLego = 0;
7847 delete [] x;
7848 delete [] y;
7849 delete [] z;
7850}
7851
7852////////////////////////////////////////////////////////////////////////////////
7853/// [Control function to draw a 2D histogram as a lego plot.](#HP17)
7854
7856{
7857
7858 Int_t raster = 1;
7859 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7860 Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7861 Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7862 Double_t zmin = Hparam.zmin;
7863 Double_t zmax = Hparam.zmax;
7864 Double_t xlab1 = Hparam.xmin;
7865 Double_t xlab2 = Hparam.xmax;
7866 Double_t ylab1 = Hparam.ymin;
7867 Double_t ylab2 = Hparam.ymax;
7868 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7869 Double_t deltaz = TMath::Abs(zmin);
7870 if (deltaz == 0) deltaz = 1;
7871 if (zmin >= zmax) {
7872 zmin -= 0.5*deltaz;
7873 zmax += 0.5*deltaz;
7874 }
7875 Double_t z1c = zmin;
7876 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7877
7878 // Compute the lego limits and instantiate a lego object
7879 fXbuf[0] = -1;
7880 fYbuf[0] = 1;
7881 fXbuf[1] = -1;
7882 fYbuf[1] = 1;
7883 if (Hoption.System == kPOLAR) {
7884 fXbuf[2] = z1c;
7885 fYbuf[2] = z2c;
7886 } else if (Hoption.System == kCYLINDRICAL) {
7887 if (Hoption.Logy) {
7888 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7889 else fXbuf[2] = 0;
7890 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7891 else fYbuf[2] = 0;
7892 } else {
7893 fXbuf[2] = ylab1;
7894 fYbuf[2] = ylab2;
7895 }
7896 z1c = 0; z2c = 1;
7897 } else if (Hoption.System == kSPHERICAL) {
7898 fXbuf[2] = -1;
7899 fYbuf[2] = 1;
7900 z1c = 0; z2c = 1;
7901 } else if (Hoption.System == kRAPIDITY) {
7902 fXbuf[2] = -1/TMath::Tan(dangle);
7903 fYbuf[2] = 1/TMath::Tan(dangle);
7904 } else {
7905 fXbuf[0] = xlab1;
7906 fYbuf[0] = xlab2;
7907 fXbuf[1] = ylab1;
7908 fYbuf[1] = ylab2;
7909 fXbuf[2] = z1c;
7910 fYbuf[2] = z2c;
7911 raster = 0;
7912 }
7913
7915
7916 Int_t nids = -1;
7917 TH1 * hid = NULL;
7918 Color_t colormain = -1, colordark = -1;
7919 Bool_t drawShadowsInLego1 = kTRUE;
7920
7921 // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7922 if (Hoption.Lego == 13) {
7923 Hoption.Lego = 11;
7924 fLego->SetMesh(0);
7925 }
7926 // LEGO4 is like LEGO1 except no shadows are drawn.
7927 if (Hoption.Lego == 14) {
7928 Hoption.Lego = 11;
7929 drawShadowsInLego1 = kFALSE;
7930 }
7931
7932 // Create axis object
7933
7934 TGaxis *axis = new TGaxis();
7935
7936 // Initialize the levels on the Z axis
7937 Int_t ndiv = fH->GetContour();
7938 if (ndiv == 0 ) {
7939 ndiv = gStyle->GetNumberContours();
7940 fH->SetContour(ndiv);
7941 }
7942 Int_t ndivz = TMath::Abs(ndiv);
7943 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7944
7945 // Initialize colors
7946 if (!fStack) {
7948 } else {
7949 for (Int_t id=0;id<=fStack->GetSize();id++) {
7950 hid = (TH1*)fStack->At((id==0)?id:id-1);
7952 }
7953 }
7954
7955 if (Hoption.Lego == 11) {
7956 nids = 1;
7957 if (fStack) nids = fStack->GetSize();
7958 hid = fH;
7959 for (Int_t id=0;id<=nids;id++) {
7960 if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7961 colormain = hid->GetFillColor();
7962 if (colormain == 1) colormain = 17; //avoid drawing with black
7963 if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7964 else colordark = colormain;
7965 fLego->SetColorMain(colormain,id);
7966 fLego->SetColorDark(colordark,id);
7967 if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7968 if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7969 }
7970 }
7971
7972 // Now ready to draw the lego plot
7973 Int_t irep = 0;
7974
7975 TView *view = gPad->GetView();
7976 if (!view) {
7977 Error("PaintLego", "no TView in current pad");
7978 return;
7979 }
7980
7981 Double_t thedeg = 90 - gPad->GetTheta();
7982 Double_t phideg = -90 - gPad->GetPhi();
7983 Double_t psideg = view->GetPsi();
7984 view->SetView(phideg, thedeg, psideg, irep);
7985
7986 fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7988
7989 // Set color/style for back box
7990 fLego->SetFillStyle(gPad->GetFrameFillStyle());
7991 fLego->SetFillColor(gPad->GetFrameFillColor());
7992 fLego->TAttFill::Modify();
7993
7994 Int_t backcolor = gPad->GetFrameFillColor();
7995 if (Hoption.System != kCARTESIAN) backcolor = 0;
7996 view->PadRange(backcolor);
7997
8000 fLego->TAttFill::Modify();
8001
8003
8004 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
8005 else fLego->InitMoveScreen(-1.1,1.1);
8006
8007 if (Hoption.Lego == 19) {
8009 if (Hoption.BackBox) fLego->BackBox(90);
8010 if (Hoption.FrontBox) fLego->FrontBox(90);
8011 if (!Hoption.Axis) PaintLegoAxis(axis, 90);
8012 return;
8013 }
8014
8015 if (Hoption.Lego == 11 || Hoption.Lego == 12) {
8018 fLego->BackBox(90);
8019 }
8020 }
8021
8022 if (Hoption.Lego == 12) DefineColorLevels(ndivz);
8023
8028 if (Hoption.System == kPOLAR) {
8029 if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
8030 if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
8031 if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
8032 } else if (Hoption.System == kCYLINDRICAL) {
8033 if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
8034 if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
8035 if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
8036 } else if (Hoption.System == kSPHERICAL) {
8037 if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
8038 if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
8039 if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
8040 } else if (Hoption.System == kRAPIDITY) {
8041 if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
8042 if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
8043 if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
8044 } else {
8045 if (Hoption.Lego == 1) {
8047 fLego->LegoCartesian(90,nx,ny,"FB");}
8048 if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
8049 if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
8050 }
8051
8052 if (Hoption.Lego == 1 || Hoption.Lego == 11) {
8055 fLego->BackBox(90);
8056 }
8057 }
8058 if (Hoption.System == kCARTESIAN) {
8059 fLego->InitMoveScreen(-1.1,1.1);
8061 if (Hoption.FrontBox) fLego->FrontBox(90);
8062 }
8063 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8065 delete axis;
8066 delete fLego; fLego = 0;
8067}
8068
8069////////////////////////////////////////////////////////////////////////////////
8070/// Draw the axis for legos and surface plots.
8071
8073{
8074
8075 static Double_t epsil = 0.001;
8076
8077 Double_t cosa, sina;
8078 Double_t bmin, bmax;
8079 Double_t r[24] /* was [3][8] */;
8080 Int_t ndivx, ndivy, ndivz, i;
8081 Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
8082 static char chopax[8], chopay[8], chopaz[8];
8083 Int_t ix1, ix2, iy1, iy2, iz1, iz2;
8084 Double_t rad;
8085
8086 TView *view = gPad->GetView();
8087 if (!view) {
8088 Error("PaintLegoAxis", "no TView in current pad");
8089 return;
8090 }
8091
8092 // In polar coordinates, draw a short line going from the external circle
8093 // corresponding to r = 1 up to r = 1.1
8094 if (Hoption.System == kPOLAR) {
8095 r[0] = 1;
8096 r[1] = 0;
8097 r[2] = 0;
8098 view->WCtoNDC(r, x1);
8099 r[0] = 1.1;
8100 r[1] = 0;
8101 r[2] = 0;
8102 view->WCtoNDC(r, x2);
8103 gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
8104 return;
8105 }
8106
8107 if (Hoption.System != kCARTESIAN) return;
8108
8109 rad = TMath::ATan(1.) * 4. /180.;
8110 cosa = TMath::Cos(ang*rad);
8111 sina = TMath::Sin(ang*rad);
8112
8113 view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
8114 for (i = 1; i <= 8; ++i) {
8115 r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
8116 r[i*3 - 2] = av[i*3 - 2]*sina;
8117 r[i*3 - 1] = av[i*3 - 1];
8118 }
8119
8120 view->WCtoNDC(&r[ix1*3 - 3], x1);
8121 view->WCtoNDC(&r[ix2*3 - 3], x2);
8122 view->WCtoNDC(&r[iy1*3 - 3], y1);
8123 view->WCtoNDC(&r[iy2*3 - 3], y2);
8124 view->WCtoNDC(&r[iz1*3 - 3], z1);
8125 view->WCtoNDC(&r[iz2*3 - 3], z2);
8126
8127 view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
8128
8129 Double_t *rmin = view->GetRmin();
8130 Double_t *rmax = view->GetRmax();
8131 if (!rmin || !rmax) return;
8132
8133 // Initialize the axis options
8134 if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
8135 else strlcpy(chopax, "SDH=-",8);
8136 if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
8137 else strlcpy(chopay, "SDH=-",8);
8138 if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
8139 else strlcpy(chopaz, "SDH=-",8);
8140
8141 // Option LOG is required ?
8142 if (Hoption.Logx) strlcat(chopax,"G",8);
8143 if (Hoption.Logy) strlcat(chopay,"G",8);
8144 if (Hoption.Logz) strlcat(chopaz,"G",8);
8145
8146 // Initialize the number of divisions. If the
8147 // number of divisions is negative, option 'N' is required.
8148 ndivx = fXaxis->GetNdivisions();
8149 ndivy = fYaxis->GetNdivisions();
8150 ndivz = fZaxis->GetNdivisions();
8151 if (ndivx < 0) {
8152 ndivx = TMath::Abs(ndivx);
8153 strlcat(chopax, "N",8);
8154 }
8155 if (ndivy < 0) {
8156 ndivy = TMath::Abs(ndivy);
8157 strlcat(chopay, "N",8);
8158 }
8159 if (ndivz < 0) {
8160 ndivz = TMath::Abs(ndivz);
8161 strlcat(chopaz, "N",8);
8162 }
8163
8164 // Set Axis attributes.
8165 // The variable SCALE rescales the VSIZ
8166 // in order to have the same label size for all angles.
8167
8168 axis->SetLineWidth(1);
8169
8170 // X axis drawing
8171 if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
8174 if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
8175 bmin = TMath::Power(10, rmin[0]);
8176 bmax = TMath::Power(10, rmax[0]);
8177 } else {
8178 bmin = rmin[0];
8179 bmax = rmax[0];
8180 }
8181 // Option time display is required ?
8182 if (fXaxis->GetTimeDisplay()) {
8183 strlcat(chopax,"t",8);
8184 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
8185 axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
8186 } else {
8188 }
8189 }
8190 axis->SetOption(chopax);
8191 axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
8192 }
8193
8194 // Y axis drawing
8195 if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
8198 if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
8199
8200 if (fH->GetDimension() < 2) {
8201 strlcpy(chopay, "V=+UN",8);
8202 ndivy = 0;
8203 }
8204 if (TMath::Abs(y1[0] - y2[0]) < epsil) {
8205 y2[0] = y1[0];
8206 }
8207 if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
8208 bmin = TMath::Power(10, rmin[1]);
8209 bmax = TMath::Power(10, rmax[1]);
8210 } else {
8211 bmin = rmin[1];
8212 bmax = rmax[1];
8213 }
8214 // Option time display is required ?
8215 if (fYaxis->GetTimeDisplay()) {
8216 strlcat(chopay,"t",8);
8217 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
8218 axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
8219 } else {
8221 }
8222 }
8223 axis->SetOption(chopay);
8224 axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
8225 }
8226
8227 // Z axis drawing
8228 if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
8230 if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
8231 bmin = TMath::Power(10, rmin[2]);
8232 bmax = TMath::Power(10, rmax[2]);
8233 } else {
8234 bmin = rmin[2];
8235 bmax = rmax[2];
8236 }
8237 // Option time display is required ?
8238 if (fZaxis->GetTimeDisplay()) {
8239 strlcat(chopaz,"t",8);
8240 if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
8241 axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
8242 } else {
8244 }
8245 }
8246 axis->SetOption(chopaz);
8247 axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
8248 }
8249
8250 //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
8251}
8252
8253////////////////////////////////////////////////////////////////////////////////
8254/// [Paint the color palette on the right side of the pad.](#HP22)
8255
8257{
8258
8259 TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
8260 TView *view = gPad->GetView();
8261 if (palette) {
8262 if (view) {
8263 if (!palette->TestBit(TPaletteAxis::kHasView)) {
8264 fFunctions->Remove(palette);
8265 delete palette; palette = 0;
8266 }
8267 } else {
8268 if (palette->TestBit(TPaletteAxis::kHasView)) {
8269 fFunctions->Remove(palette);
8270 delete palette; palette = 0;
8271 }
8272 }
8273 // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
8274 if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
8275 }
8276
8277 if (!palette) {
8278 Double_t xup = gPad->GetUxmax();
8279 Double_t x2 = gPad->PadtoX(gPad->GetX2());
8280 Double_t ymin = gPad->PadtoY(gPad->GetUymin());
8281 Double_t ymax = gPad->PadtoY(gPad->GetUymax());
8282 Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
8283 Double_t xmin = gPad->PadtoX(xup +0.1*xr);
8284 Double_t xmax = gPad->PadtoX(xup + xr);
8285 if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
8286 palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
8287 fFunctions->AddFirst(palette);
8288 palette->Paint();
8289 }
8290}
8291
8292////////////////////////////////////////////////////////////////////////////////
8293/// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
8294
8296{
8297
8298 fH->TAttMarker::Modify();
8299
8300 Int_t k, marker;
8301 Double_t dz, z, xk,xstep, yk, ystep;
8302 Double_t scale = 1;
8303 Bool_t ltest = kFALSE;
8304 Double_t zmax = fH->GetMaximum();
8305 Double_t zmin = fH->GetMinimum();
8306 if (zmin == 0 && zmax == 0) return;
8307 if (zmin == zmax) {
8308 zmax += 0.1*TMath::Abs(zmax);
8309 zmin -= 0.1*TMath::Abs(zmin);
8310 }
8312 if (Hoption.Logz) {
8313 if (zmin > 0) zmin = TMath::Log10(zmin);
8314 else zmin = 0;
8315 if (zmax > 0) zmax = TMath::Log10(zmax);
8316 else zmax = 0;
8317 if (zmin == 0 && zmax == 0) return;
8318 dz = zmax - zmin;
8319 scale = 100/dz;
8320 if (ncells > 10000) scale /= 5;
8321 ltest = kTRUE;
8322 } else {
8323 dz = zmax - zmin;
8324 if (dz >= kNMAX || zmax < 1) {
8325 scale = (kNMAX-1)/dz;
8326 if (ncells > 10000) scale /= 5;
8327 ltest = kTRUE;
8328 }
8329 }
8330 if (fH->GetMinimumStored() == -1111) {
8331 Double_t yMARGIN = gStyle->GetHistTopMargin();
8332 if (Hoption.MinimumZero) {
8333 if (zmin >= 0) zmin = 0;
8334 else zmin -= yMARGIN*(zmax-zmin);
8335 } else {
8336 Double_t dzmin = yMARGIN*(zmax-zmin);
8337 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
8338 else zmin -= dzmin;
8339 }
8340 }
8341
8342 TString opt = option;
8343 opt.ToLower();
8344 if (opt.Contains("scat=")) {
8345 char optscat[100];
8346 strlcpy(optscat,opt.Data(),100);
8347 char *oscat = strstr(optscat,"scat=");
8348 char *blank = strstr(oscat," "); if (blank) *blank = 0;
8349 sscanf(oscat+5,"%lg",&scale);
8350 }
8351 // use an independent instance of a random generator
8352 // instead of gRandom to avoid conflicts and
8353 // to get same random numbers when drawing the same histogram
8354 TRandom2 random;
8355 marker=0;
8356 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8357 yk = fYaxis->GetBinLowEdge(j);
8358 ystep = fYaxis->GetBinWidth(j);
8359 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8360 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8361 xk = fXaxis->GetBinLowEdge(i);
8362 xstep = fXaxis->GetBinWidth(i);
8363 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
8364 z = fH->GetBinContent(bin);
8365 if (z < zmin) z = zmin;
8366 if (z > zmax) z = zmax;
8367 if (Hoption.Logz) {
8368 if (z > 0) z = TMath::Log10(z) - zmin;
8369 } else {
8370 z -= zmin;
8371 }
8372 if (z <= 0) continue;
8373 k = Int_t(z*scale);
8374 if (ltest) k++;
8375 if (k > 0) {
8376 for (Int_t loop=0; loop<k; loop++) {
8377 if (k+marker >= kNMAX) {
8378 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8379 marker=0;
8380 }
8381 fXbuf[marker] = (random.Rndm()*xstep) + xk;
8382 fYbuf[marker] = (random.Rndm()*ystep) + yk;
8383 if (Hoption.Logx) {
8384 if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
8385 else break;
8386 }
8387 if (Hoption.Logy) {
8388 if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
8389 else break;
8390 }
8391 if (fXbuf[marker] < gPad->GetUxmin()) break;
8392 if (fYbuf[marker] < gPad->GetUymin()) break;
8393 if (fXbuf[marker] > gPad->GetUxmax()) break;
8394 if (fYbuf[marker] > gPad->GetUymax()) break;
8395 marker++;
8396 }
8397 }
8398 }
8399 }
8400 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8401
8403}
8404
8405////////////////////////////////////////////////////////////////////////////////
8406/// Static function to paint special objects like vectors and matrices.
8407/// This function is called via `gROOT->ProcessLine` to paint these objects
8408/// without having a direct dependency of the graphics or histogramming
8409/// system.
8410
8412{
8413
8414 if (!obj) return;
8417
8418 if (obj->InheritsFrom(TMatrixFBase::Class())) {
8419 // case TMatrixF
8420 TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
8421 R__TMatrixFBase->SetBit(kCanDelete);
8422 R__TMatrixFBase->Draw(option);
8423
8424 } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
8425 // case TMatrixD
8426 TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8427 R__TMatrixDBase->SetBit(kCanDelete);
8428 R__TMatrixDBase->Draw(option);
8429
8430 } else if (obj->InheritsFrom(TVectorF::Class())) {
8431 //case TVectorF
8432 TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8433 R__TVectorF->SetBit(kCanDelete);
8434 R__TVectorF->Draw(option);
8435
8436 } else if (obj->InheritsFrom(TVectorD::Class())) {
8437 //case TVectorD
8438 TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8439 R__TVectorD->SetBit(kCanDelete);
8440 R__TVectorD->Draw(option);
8441 }
8442
8443 TH1::AddDirectory(status);
8444}
8445
8446////////////////////////////////////////////////////////////////////////////////
8447/// [Draw the statistics box for 1D and profile histograms.](#HP07)
8448
8450{
8451
8452 TString tt, tf;
8453 Int_t dofit;
8454 TPaveStats *stats = 0;
8455 TIter next(fFunctions);
8456 TObject *obj;
8457 while ((obj = next())) {
8458 if (obj->InheritsFrom(TPaveStats::Class())) {
8459 stats = (TPaveStats*)obj;
8460 break;
8461 }
8462 }
8463
8464 if (stats && dostat) {
8465 dofit = stats->GetOptFit();
8466 dostat = stats->GetOptStat();
8467 } else {
8468 dofit = gStyle->GetOptFit();
8469 }
8470 if (!dofit) fit = 0;
8471 if (dofit == 1) dofit = 111;
8472 if (dostat == 1) dostat = 1111;
8473 Int_t print_name = dostat%10;
8474 Int_t print_entries = (dostat/10)%10;
8475 Int_t print_mean = (dostat/100)%10;
8476 Int_t print_stddev = (dostat/1000)%10;
8477 Int_t print_under = (dostat/10000)%10;
8478 Int_t print_over = (dostat/100000)%10;
8479 Int_t print_integral= (dostat/1000000)%10;
8480 Int_t print_skew = (dostat/10000000)%10;
8481 Int_t print_kurt = (dostat/100000000)%10;
8482 Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8483 print_under + print_over + print_integral +
8484 print_skew + print_kurt;
8485 Int_t print_fval = dofit%10;
8486 Int_t print_ferrors = (dofit/10)%10;
8487 Int_t print_fchi2 = (dofit/100)%10;
8488 Int_t print_fprob = (dofit/1000)%10;
8489 Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8490 if (fit) {
8491 if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8492 else nlinesf += fit->GetNpar();
8493 }
8494 if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8495
8496 // Pavetext with statistics
8497 Bool_t done = kFALSE;
8498 if (!dostat && !fit) {
8499 if (stats) { fFunctions->Remove(stats); delete stats;}
8500 return;
8501 }
8502 Double_t statw = gStyle->GetStatW();
8503 if (fit) statw = 1.8*gStyle->GetStatW();
8504 Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8505 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8506 stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8507 }
8508 if (stats) {
8509 stats->Clear();
8510 done = kTRUE;
8511 } else {
8512 stats = new TPaveStats(
8513 gStyle->GetStatX()-statw,
8514 gStyle->GetStatY()-stath,
8515 gStyle->GetStatX(),
8516 gStyle->GetStatY(),"brNDC");
8517
8518 stats->SetParent(fH);
8519 stats->SetOptFit(dofit);
8520 stats->SetOptStat(dostat);
8521 stats->SetFillColor(gStyle->GetStatColor());
8522 stats->SetFillStyle(gStyle->GetStatStyle());
8524 stats->SetTextFont(gStyle->GetStatFont());
8525 if (gStyle->GetStatFont()%10 > 2)
8527 stats->SetFitFormat(gStyle->GetFitFormat());
8529 stats->SetName("stats");
8530
8532 stats->SetTextAlign(12);
8533 stats->SetBit(kCanDelete);
8534 stats->SetBit(kMustCleanup);
8535 }
8536 if (print_name) stats->AddText(fH->GetName());
8537 if (print_entries) {
8538 if (fH->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8539 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8540 stats->AddText(tt.Data());
8541 }
8542 if (print_mean) {
8543 if (print_mean == 1) {
8544 tf.Form("%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8545 tt.Form(tf.Data(),fH->GetMean(1));
8546 } else {
8547 tf.Form("%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8548 ,"%",stats->GetStatFormat());
8549 tt.Form(tf.Data(),fH->GetMean(1),fH->GetMeanError(1));
8550 }
8551 stats->AddText(tt.Data());
8553 if (print_mean == 1) {
8554 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8555 tt.Form(tf.Data(),fH->GetMean(2));
8556 } else {
8557 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8558 ,"%",stats->GetStatFormat());
8559 tt.Form(tf.Data(),fH->GetMean(2),fH->GetMeanError(2));
8560 }
8561 stats->AddText(tt.Data());
8562 }
8563 }
8564 if (print_stddev) {
8565 if (print_stddev == 1) {
8566 tf.Form("%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8567 tt.Form(tf.Data(),fH->GetStdDev(1));
8568 } else {
8569 tf.Form("%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8570 ,"%",stats->GetStatFormat());
8571 tt.Form(tf.Data(),fH->GetStdDev(1),fH->GetStdDevError(1));
8572 }
8573 stats->AddText(tt.Data());
8575 if (print_stddev == 1) {
8576 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8577 tt.Form(tf.Data(),fH->GetStdDev(2));
8578 } else {
8579 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8580 ,"%",stats->GetStatFormat());
8581 tt.Form(tf.Data(),fH->GetStdDev(2),fH->GetStdDevError(2));
8582 }
8583 stats->AddText(tt.Data());
8584 }
8585 }
8586 if (print_under) {
8587 tf.Form("%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8588 tt.Form(tf.Data(),fH->GetBinContent(0));
8589 stats->AddText(tt.Data());
8590 }
8591 if (print_over) {
8592 tf.Form("%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8593 tt.Form(tf.Data(),fH->GetBinContent(fXaxis->GetNbins()+1));
8594 stats->AddText(tt.Data());
8595 }
8596 if (print_integral) {
8597 if (print_integral == 1) {
8598 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8599 tt.Form(tf.Data(),fH->Integral());
8600 } else {
8601 tf.Form("%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8602 tt.Form(tf.Data(),fH->Integral("width"));
8603 }
8604 stats->AddText(tt.Data());
8605 }
8606 if (print_skew) {
8607 if (print_skew == 1) {
8608 tf.Form("%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8609 tt.Form(tf.Data(),fH->GetSkewness(1));
8610 } else {
8611 tf.Form("%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8612 ,"%",stats->GetStatFormat());
8613 tt.Form(tf.Data(),fH->GetSkewness(1),fH->GetSkewness(11));
8614 }
8615 stats->AddText(tt.Data());
8616 }
8617 if (print_kurt) {
8618 if (print_kurt == 1) {
8619 tf.Form("%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8620 tt.Form(tf.Data(),fH->GetKurtosis(1));
8621 } else {
8622 tf.Form("%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8623 ,"%",stats->GetStatFormat());
8624 tt.Form(tf.Data(),fH->GetKurtosis(1),fH->GetKurtosis(11));
8625 }
8626 stats->AddText(tt.Data());
8627 }
8628
8629 // Draw Fit parameters
8630 if (fit) {
8631 Int_t ndf = fit->GetNDF();
8632 tf.Form("#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8633 tt.Form(tf.Data(),(Float_t)fit->GetChisquare());
8634 if (print_fchi2) stats->AddText(tt.Data());
8635 if (print_fprob) {
8636 tf.Form("Prob = %s%s","%",stats->GetFitFormat());
8637 tt.Form(tf.Data(),(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8638 stats->AddText(tt.Data());
8639 }
8640 if (print_fval || print_ferrors) {
8641 Double_t parmin,parmax;
8642 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8643 fit->GetParLimits(ipar,parmin,parmax);
8644 if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8645 if (print_ferrors) {
8646 tf.Form("%-8s = %s%s #pm %s ", fit->GetParName(ipar), "%",stats->GetFitFormat(),
8647 GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8648 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar)
8649 ,(Float_t)fit->GetParError(ipar));
8650 } else {
8651 tf.Form("%-8s = %s%s ",fit->GetParName(ipar), "%",stats->GetFitFormat());
8652 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar));
8653 }
8654 stats->AddText(tt.Data());
8655 }
8656 }
8657 }
8658
8659 if (!done) fFunctions->Add(stats);
8660 stats->Paint();
8661}
8662
8663////////////////////////////////////////////////////////////////////////////////
8664/// [Draw the statistics box for 2D histograms.](#HP07)
8665
8667{
8668
8669 if (fH->GetDimension() != 2) return;
8670 TH2 *h2 = (TH2*)fH;
8671
8672 TString tt, tf;
8673 Int_t dofit;
8674 TPaveStats *stats = 0;
8675 TIter next(fFunctions);
8676 TObject *obj;
8677 while ((obj = next())) {
8678 if (obj->InheritsFrom(TPaveStats::Class())) {
8679 stats = (TPaveStats*)obj;
8680 break;
8681 }
8682 }
8683 if (stats && dostat) {
8684 dofit = stats->GetOptFit();
8685 dostat = stats->GetOptStat();
8686 } else {
8687 dofit = gStyle->GetOptFit();
8688 }
8689 if (dostat == 1) dostat = 1111;
8690 Int_t print_name = dostat%10;
8691 Int_t print_entries = (dostat/10)%10;
8692 Int_t print_mean = (dostat/100)%10;
8693 Int_t print_stddev = (dostat/1000)%10;
8694 Int_t print_under = (dostat/10000)%10;
8695 Int_t print_over = (dostat/100000)%10;
8696 Int_t print_integral= (dostat/1000000)%10;
8697 Int_t print_skew = (dostat/10000000)%10;
8698 Int_t print_kurt = (dostat/100000000)%10;
8699 Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8700 if (print_under || print_over) nlines += 3;
8701
8702 // Pavetext with statistics
8703 if (!gStyle->GetOptFit()) fit = 0;
8704 Bool_t done = kFALSE;
8705 if (!dostat && !fit) {
8706 if (stats) { fFunctions->Remove(stats); delete stats;}
8707 return;
8708 }
8709 Double_t statw = gStyle->GetStatW();
8710 if (fit) statw = 1.8*gStyle->GetStatW();
8711 Double_t stath = nlines*gStyle->GetStatFontSize();
8712 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8713 stath = 0.25*nlines*gStyle->GetStatH();
8714 }
8715 if (fit) stath += gStyle->GetStatH();
8716 if (stats) {
8717 stats->Clear();
8718 done = kTRUE;
8719 } else {
8720 stats = new TPaveStats(
8721 gStyle->GetStatX()-statw,
8722 gStyle->GetStatY()-stath,
8723 gStyle->GetStatX(),
8724 gStyle->GetStatY(),"brNDC");
8725
8726 stats->SetParent(fH);
8727 stats->SetOptFit(dofit);
8728 stats->SetOptStat(dostat);
8729 stats->SetFillColor(gStyle->GetStatColor());
8730 stats->SetFillStyle(gStyle->GetStatStyle());
8732 stats->SetName("stats");
8733
8735 stats->SetTextAlign(12);
8736 stats->SetTextFont(gStyle->GetStatFont());
8737 if (gStyle->GetStatFont()%10 > 2)
8739 stats->SetFitFormat(gStyle->GetFitFormat());
8741 stats->SetBit(kCanDelete);
8742 stats->SetBit(kMustCleanup);
8743 }
8744 if (print_name) stats->AddText(h2->GetName());
8745 if (print_entries) {
8746 if (h2->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8747 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8748 stats->AddText(tt.Data());
8749 }
8750 if (print_mean) {
8751 if (print_mean == 1) {
8752 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8753 tt.Form(tf.Data(),h2->GetMean(1));
8754 stats->AddText(tt.Data());
8755 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8756 tt.Form(tf.Data(),h2->GetMean(2));
8757 stats->AddText(tt.Data());
8758 } else {
8759 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8760 ,"%",stats->GetStatFormat());
8761 tt.Form(tf.Data(),h2->GetMean(1),h2->GetMeanError(1));
8762 stats->AddText(tt.Data());
8763 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8764 ,"%",stats->GetStatFormat());
8765 tt.Form(tf.Data(),h2->GetMean(2),h2->GetMeanError(2));
8766 stats->AddText(tt.Data());
8767 }
8768 }
8769 if (print_stddev) {
8770 if (print_stddev == 1) {
8771 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8772 tt.Form(tf.Data(),h2->GetStdDev(1));
8773 stats->AddText(tt.Data());
8774 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8775 tt.Form(tf.Data(),h2->GetStdDev(2));
8776 stats->AddText(tt.Data());
8777 } else {
8778 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8779 ,"%",stats->GetStatFormat());
8780 tt.Form(tf.Data(),h2->GetStdDev(1),h2->GetStdDevError(1));
8781 stats->AddText(tt.Data());
8782 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8783 ,"%",stats->GetStatFormat());
8784 tt.Form(tf.Data(),h2->GetStdDev(2),h2->GetStdDevError(2));
8785 stats->AddText(tt.Data());
8786 }
8787 }
8788 if (print_integral) {
8789 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8790 tt.Form(tf.Data(),fH->Integral());
8791 stats->AddText(tt.Data());
8792 }
8793 if (print_skew) {
8794 if (print_skew == 1) {
8795 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8796 tt.Form(tf.Data(),h2->GetSkewness(1));
8797 stats->AddText(tt.Data());
8798 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8799 tt.Form(tf.Data(),h2->GetSkewness(2));
8800 stats->AddText(tt.Data());
8801 } else {
8802 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8803 ,"%",stats->GetStatFormat());
8804 tt.Form(tf.Data(),h2->GetSkewness(1),h2->GetSkewness(11));
8805 stats->AddText(tt.Data());
8806 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8807 ,"%",stats->GetStatFormat());
8808 tt.Form(tf.Data(),h2->GetSkewness(2),h2->GetSkewness(12));
8809 stats->AddText(tt.Data());
8810 }
8811 }
8812 if (print_kurt) {
8813 if (print_kurt == 1) {
8814 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8815 tt.Form(tf.Data(),h2->GetKurtosis(1));
8816 stats->AddText(tt.Data());
8817 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8818 tt.Form(tf.Data(),h2->GetKurtosis(2));
8819 stats->AddText(tt.Data());
8820 } else {
8821 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8822 ,"%",stats->GetStatFormat());
8823 tt.Form(tf.Data(),h2->GetKurtosis(1),h2->GetKurtosis(11));
8824 stats->AddText(tt.Data());
8825 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8826 ,"%",stats->GetStatFormat());
8827 tt.Form(tf.Data(),h2->GetKurtosis(2),h2->GetKurtosis(12));
8828 stats->AddText(tt.Data());
8829 }
8830 }
8831 if (print_under || print_over) {
8832 //get 3*3 under/overflows for 2d hist
8833 Double_t unov[9];
8834
8835 Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8836 Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8837 Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8838 Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8839 Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8840 Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8841
8842 unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8843 unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8844 unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8845 unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8846 unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8847 unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8848 unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8849 unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8850 unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8851
8852 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8853 stats->AddText(tt.Data());
8854 if (TMath::Abs(unov[4]) < 1.e7)
8855 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8856 else
8857 tt.Form(" %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8858 stats->AddText(tt.Data());
8859 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8860 stats->AddText(tt.Data());
8861 }
8862
8863 // Draw Fit parameters
8864 if (fit) {
8865 Int_t ndf = fit->GetNDF();
8866 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8867 stats->AddText(tt.Data());
8868 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8869 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8870 ,(Float_t)fit->GetParameter(ipar)
8871 ,(Float_t)fit->GetParError(ipar));
8872 stats->AddText(tt.Data());
8873 }
8874 }
8875
8876 if (!done) fFunctions->Add(stats);
8877 stats->Paint();
8878}
8879
8880////////////////////////////////////////////////////////////////////////////////
8881/// [Draw the statistics box for 3D histograms.](#HP07)
8882
8884{
8885
8886 if (fH->GetDimension() != 3) return;
8887 TH3 *h3 = (TH3*)fH;
8888
8889 TString tt, tf;
8890 Int_t dofit;
8891 TPaveStats *stats = 0;
8892 TIter next(fFunctions);
8893 TObject *obj;
8894 while ((obj = next())) {
8895 if (obj->InheritsFrom(TPaveStats::Class())) {
8896 stats = (TPaveStats*)obj;
8897 break;
8898 }
8899 }
8900 if (stats && dostat) {
8901 dofit = stats->GetOptFit();
8902 dostat = stats->GetOptStat();
8903 } else {
8904 dofit = gStyle->GetOptFit();
8905 }
8906 if (dostat == 1) dostat = 1111;
8907 Int_t print_name = dostat%10;
8908 Int_t print_entries = (dostat/10)%10;
8909 Int_t print_mean = (dostat/100)%10;
8910 Int_t print_stddev = (dostat/1000)%10;
8911 Int_t print_under = (dostat/10000)%10;
8912 Int_t print_over = (dostat/100000)%10;
8913 Int_t print_integral= (dostat/1000000)%10;
8914 Int_t print_skew = (dostat/10000000)%10;
8915 Int_t print_kurt = (dostat/100000000)%10;
8916 Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
8917 if (print_under || print_over) nlines += 3;
8918
8919 // Pavetext with statistics
8920 if (!gStyle->GetOptFit()) fit = 0;
8921 Bool_t done = kFALSE;
8922 if (!dostat && !fit) {
8923 if (stats) { fFunctions->Remove(stats); delete stats;}
8924 return;
8925 }
8926 Double_t statw = gStyle->GetStatW();
8927 if (fit) statw = 1.8*gStyle->GetStatW();
8928 Double_t stath = nlines*gStyle->GetStatFontSize();
8929 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8930 stath = 0.25*nlines*gStyle->GetStatH();
8931 }
8932 if (fit) stath += gStyle->GetStatH();
8933 if (stats) {
8934 stats->Clear();
8935 done = kTRUE;
8936 } else {
8937 stats = new TPaveStats(
8938 gStyle->GetStatX()-statw,
8939 gStyle->GetStatY()-stath,
8940 gStyle->GetStatX(),
8941 gStyle->GetStatY(),"brNDC");
8942
8943 stats->SetParent(fH);
8944 stats->SetOptFit(dofit);
8945 stats->SetOptStat(dostat);
8946 stats->SetFillColor(gStyle->GetStatColor());
8947 stats->SetFillStyle(gStyle->GetStatStyle());
8949 stats->SetName("stats");
8950
8952 stats->SetTextAlign(12);
8953 stats->SetTextFont(gStyle->GetStatFont());
8954 stats->SetFitFormat(gStyle->GetFitFormat());
8956 stats->SetBit(kCanDelete);
8957 stats->SetBit(kMustCleanup);
8958 }
8959 if (print_name) stats->AddText(h3->GetName());
8960 if (print_entries) {
8961 if (h3->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8962 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8963 stats->AddText(tt.Data());
8964 }
8965 if (print_mean) {
8966 if (print_mean == 1) {
8967 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8968 tt.Form(tf.Data(),h3->GetMean(1));
8969 stats->AddText(tt.Data());
8970 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8971 tt.Form(tf.Data(),h3->GetMean(2));
8972 stats->AddText(tt.Data());
8973 tf.Form("%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8974 tt.Form(tf.Data(),h3->GetMean(3));
8975 stats->AddText(tt.Data());
8976 } else {
8977 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8978 ,"%",stats->GetStatFormat());
8979 tt.Form(tf.Data(),h3->GetMean(1),h3->GetMeanError(1));
8980 stats->AddText(tt.Data());
8981 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8982 ,"%",stats->GetStatFormat());
8983 tt.Form(tf.Data(),h3->GetMean(2),h3->GetMeanError(2));
8984 stats->AddText(tt.Data());
8985 tf.Form("%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8986 ,"%",stats->GetStatFormat());
8987 tt.Form(tf.Data(),h3->GetMean(3),h3->GetMeanError(3));
8988 stats->AddText(tt.Data());
8989 }
8990 }
8991 if (print_stddev) {
8992 if (print_stddev == 1) {
8993 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8994 tt.Form(tf.Data(),h3->GetStdDev(1));
8995 stats->AddText(tt.Data());
8996 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8997 tt.Form(tf.Data(),h3->GetStdDev(2));
8998 stats->AddText(tt.Data());
8999 tf.Form("%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
9000 tt.Form(tf.Data(),h3->GetStdDev(3));
9001 stats->AddText(tt.Data());
9002 } else {
9003 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
9004 ,"%",stats->GetStatFormat());
9005 tt.Form(tf.Data(),h3->GetStdDev(1),h3->GetStdDevError(1));
9006 stats->AddText(tt.Data());
9007 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
9008 ,"%",stats->GetStatFormat());
9009 tt.Form(tf.Data(),h3->GetStdDev(2),h3->GetStdDevError(2));
9010 stats->AddText(tt.Data());
9011 tf.Form("%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
9012 ,"%",stats->GetStatFormat());
9013 tt.Form(tf.Data(),h3->GetStdDev(3),h3->GetStdDevError(3));
9014 stats->AddText(tt.Data());
9015 }
9016 }
9017 if (print_integral) {
9018 tt.Form("%s = %6.4g",gStringIntegral.Data(),h3->Integral());
9019 stats->AddText(tt.Data());
9020 }
9021 if (print_skew) {
9022 if (print_skew == 1) {
9023 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
9024 tt.Form(tf.Data(),h3->GetSkewness(1));
9025 stats->AddText(tt.Data());
9026 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
9027 tt.Form(tf.Data(),h3->GetSkewness(2));
9028 stats->AddText(tt.Data());
9029 tf.Form("%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
9030 tt.Form(tf.Data(),h3->GetSkewness(3));
9031 stats->AddText(tt.Data());
9032 } else {
9033 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
9034 ,"%",stats->GetStatFormat());
9035 tt.Form(tf.Data(),h3->GetSkewness(1),h3->GetSkewness(11));
9036 stats->AddText(tt.Data());
9037 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
9038 ,"%",stats->GetStatFormat());
9039 tt.Form(tf.Data(),h3->GetSkewness(2),h3->GetSkewness(12));
9040 stats->AddText(tt.Data());
9041 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
9042 ,"%",stats->GetStatFormat());
9043 tt.Form(tf.Data(),h3->GetSkewness(3),h3->GetSkewness(13));
9044 stats->AddText(tt.Data());
9045 }
9046 }
9047 if (print_kurt) {
9048 if (print_kurt == 1) {
9049 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
9050 tt.Form(tf.Data(),h3->GetKurtosis(1));
9051 stats->AddText(tt.Data());
9052 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
9053 tt.Form(tf.Data(),h3->GetKurtosis(2));
9054 stats->AddText(tt.Data());
9055 tf.Form("%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
9056 tt.Form(tf.Data(),h3->GetKurtosis(3));
9057 stats->AddText(tt.Data());
9058 } else {
9059 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
9060 ,"%",stats->GetStatFormat());
9061 tt.Form(tf.Data(),h3->GetKurtosis(1),h3->GetKurtosis(11));
9062 stats->AddText(tt.Data());
9063 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
9064 ,"%",stats->GetStatFormat());
9065 tt.Form(tf.Data(),h3->GetKurtosis(2),h3->GetKurtosis(12));
9066 stats->AddText(tt.Data());
9067 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
9068 ,"%",stats->GetStatFormat());
9069 tt.Form(tf.Data(),h3->GetKurtosis(3),h3->GetKurtosis(13));
9070 stats->AddText(tt.Data());
9071 }
9072 }
9073 if (print_under || print_over) {
9074 // no underflow - overflow printing for a 3D histogram
9075 // one would need a 3D table
9076 }
9077
9078 // Draw Fit parameters
9079 if (fit) {
9080 Int_t ndf = fit->GetNDF();
9081 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
9082 stats->AddText(tt.Data());
9083 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
9084 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
9085 ,(Float_t)fit->GetParameter(ipar)
9086 ,(Float_t)fit->GetParError(ipar));
9087 stats->AddText(tt.Data());
9088 }
9089 }
9090
9091 if (!done) fFunctions->Add(stats);
9092 stats->Paint();
9093}
9094
9095////////////////////////////////////////////////////////////////////////////////
9096/// [Control function to draw a 2D histogram as a surface plot.](#HP18)
9097
9099{
9100
9101 const Double_t ydiff = 1;
9102 const Double_t yligh1 = 10;
9103 const Double_t qa = 0.15;
9104 const Double_t qd = 0.15;
9105 const Double_t qs = 0.8;
9106 Double_t fmin, fmax;
9107 Int_t raster = 0;
9108 Int_t irep = 0;
9109
9110 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9113 Double_t zmin = Hparam.zmin;
9114 Double_t zmax = Hparam.zmax;
9115 Double_t xlab1 = Hparam.xmin;
9116 Double_t xlab2 = Hparam.xmax;
9117 Double_t ylab1 = Hparam.ymin;
9118 Double_t ylab2 = Hparam.ymax;
9119 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
9120 Double_t deltaz = TMath::Abs(zmin);
9121 if (deltaz == 0) deltaz = 1;
9122 if (zmin >= zmax) {
9123 zmin -= 0.5*deltaz;
9124 zmax += 0.5*deltaz;
9125 }
9126 Double_t z1c = zmin;
9127 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
9128 // Compute the lego limits and instantiate a lego object
9129 fXbuf[0] = -1;
9130 fYbuf[0] = 1;
9131 fXbuf[1] = -1;
9132 fYbuf[1] = 1;
9133 if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
9134 if (Hoption.System == kPOLAR) {
9135 fXbuf[2] = z1c;
9136 fYbuf[2] = z2c;
9137 } else if (Hoption.System == kCYLINDRICAL) {
9138 if (Hoption.Logy) {
9139 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
9140 else fXbuf[2] = 0;
9141 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
9142 else fYbuf[2] = 0;
9143 } else {
9144 fXbuf[2] = ylab1;
9145 fYbuf[2] = ylab2;
9146 }
9147 z1c = 0; z2c = 1;
9148 } else if (Hoption.System == kSPHERICAL) {
9149 fXbuf[2] = -1;
9150 fYbuf[2] = 1;
9151 z1c = 0; z2c = 1;
9152 } else if (Hoption.System == kRAPIDITY) {
9153 fXbuf[2] = -1/TMath::Tan(dangle);
9154 fYbuf[2] = 1/TMath::Tan(dangle);
9155 } else {
9156 fXbuf[0] = xlab1;
9157 fYbuf[0] = xlab2;
9158 fXbuf[1] = ylab1;
9159 fYbuf[1] = ylab2;
9160 fXbuf[2] = z1c;
9161 fYbuf[2] = z2c;
9162 }
9163
9167
9168 // Create axis object
9169
9170 TGaxis *axis = new TGaxis();
9171
9172 // Initialize the levels on the Z axis
9173 Int_t ndiv = fH->GetContour();
9174 if (ndiv == 0 ) {
9175 ndiv = gStyle->GetNumberContours();
9176 fH->SetContour(ndiv);
9177 }
9178 Int_t ndivz = TMath::Abs(ndiv);
9179 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9180
9181 if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
9182 if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
9183
9184 // Close the surface in case of non cartesian coordinates.
9185
9186 if (Hoption.System != kCARTESIAN) {nx++; ny++;}
9187
9188 // Now ready to draw the surface plot
9189
9190 TView *view = gPad->GetView();
9191 if (!view) {
9192 Error("PaintSurface", "no TView in current pad");
9193 return;
9194 }
9195
9196 Double_t thedeg = 90 - gPad->GetTheta();
9197 Double_t phideg = -90 - gPad->GetPhi();
9198 Double_t psideg = view->GetPsi();
9199 view->SetView(phideg, thedeg, psideg, irep);
9200
9201 // Set color/style for back box
9202 if (Hoption.Same) {
9203 fLego->SetFillStyle(0);
9204 fLego->SetFillColor(1);
9205 } else {
9206 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9207 fLego->SetFillColor(gPad->GetFrameFillColor());
9208 }
9209 fLego->TAttFill::Modify();
9210
9211 Int_t backcolor = gPad->GetFrameFillColor();
9212 if (Hoption.System != kCARTESIAN) backcolor = 0;
9213 view->PadRange(backcolor);
9214
9217 fLego->TAttFill::Modify();
9218
9219 // Draw the filled contour on top
9220 Int_t icol1 = fH->GetFillColor();
9221
9222 Int_t hoption35 = Hoption.Surf;
9223 if (Hoption.Surf == 13 || Hoption.Surf == 15) {
9224 DefineColorLevels(ndivz);
9225 Hoption.Surf = 23;
9228 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9229 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9230 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9231 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9232 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9233 Hoption.Surf = hoption35;
9234 fLego->SetMesh(1);
9235 }
9236
9237 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
9238 else fLego->InitMoveScreen(-1.1,1.1);
9239
9240 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
9244 fLego->BackBox(90);
9245 }
9246 }
9247
9248 // Gouraud Shading surface
9249 if (Hoption.Surf == 14) {
9250 // Set light sources
9251 fLego->LightSource(0, ydiff, 0,0,0,irep);
9252 fLego->LightSource(1, yligh1 ,1,1,1,irep);
9253 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
9254 fmin = ydiff*qa;
9255 fmax = fmin + (yligh1+0.1)*(qd+qs);
9256 Int_t nbcol = 28;
9257 icol1 = 201;
9258 Double_t dcol = 0.5/Double_t(nbcol);
9259 TColor *colref = gROOT->GetColor(fH->GetFillColor());
9260 if (!colref) return;
9261 Float_t r,g,b,hue,light,satur;
9262 colref->GetRGB(r,g,b);
9263 TColor::RGBtoHLS(r,g,b,hue,light,satur);
9264 TColor *acol;
9265 for (Int_t col=0;col<nbcol;col++) {
9266 acol = gROOT->GetColor(col+icol1);
9267 TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
9268 if (acol) acol->SetRGB(r,g,b);
9269 }
9270 fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
9273 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9274 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9275 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9276 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9277 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9278 } else if (Hoption.Surf == 15) {
9279 // The surface is not drawn in this case.
9280 } else {
9281 // Draw the surface
9282 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
9283 DefineColorLevels(ndivz);
9284 } else {
9286 }
9290 if (Hoption.System == kPOLAR) {
9291 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
9292 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
9293 } else if (Hoption.System == kCYLINDRICAL) {
9294 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9295 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9296 } else if (Hoption.System == kSPHERICAL) {
9297 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9298 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9299 } else if (Hoption.System == kRAPIDITY) {
9300 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9301 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9302 } else {
9305 if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
9306 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
9307 }
9308 }
9309
9310 // Paint the line contour on top for option SURF7
9311 if (Hoption.Surf == 17) {
9312 fLego->InitMoveScreen(-1.1,1.1);
9314 Hoption.Surf = 23;
9317 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
9318 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9319 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9320 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9321 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
9322 }
9323
9324 if ((!Hoption.Same) &&
9325 (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
9328 fLego->BackBox(90);
9329 }
9330 }
9331 if (Hoption.System == kCARTESIAN) {
9332 fLego->InitMoveScreen(-1.1,1.1);
9334 if (Hoption.FrontBox) fLego->FrontBox(90);
9335 }
9336 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9337
9339
9340 delete axis;
9341 delete fLego; fLego = 0;
9342}
9343
9344////////////////////////////////////////////////////////////////////////////////
9345/// Control function to draw a table using Delaunay triangles.
9346
9348{
9349
9350 TGraphDelaunay2D *dt = nullptr;
9351 TGraphDelaunay *dtOld = nullptr;
9352
9353 // Check if fH contains a TGraphDelaunay2D
9354 TList *hl = fH->GetListOfFunctions();
9355 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
9356 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
9357 if (!dt && !dtOld) return;
9358
9359 // If needed, create a TGraph2DPainter
9360 if (!fGraph2DPainter) {
9361 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
9362 else fGraph2DPainter = new TGraph2DPainter(dtOld);
9363 }
9364
9365 // Define the 3D view
9366 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9367 if (Hoption.Same) {
9368 TView *viewsame = gPad->GetView();
9369 if (!viewsame) {
9370 Error("PaintTriangles", "no TView in current pad, do not use option SAME");
9371 return;
9372 }
9373 Double_t *rmin = viewsame->GetRmin();
9374 Double_t *rmax = viewsame->GetRmax();
9375 if (!rmin || !rmax) return;
9376 fXbuf[0] = rmin[0];
9377 fYbuf[0] = rmax[0];
9378 fXbuf[1] = rmin[1];
9379 fYbuf[1] = rmax[1];
9380 fXbuf[2] = rmin[2];
9381 fYbuf[2] = rmax[2];
9382 } else {
9383 fXbuf[0] = Hparam.xmin;
9384 fYbuf[0] = Hparam.xmax;
9385 fXbuf[1] = Hparam.ymin;
9386 fYbuf[1] = Hparam.ymax;
9387 fXbuf[2] = Hparam.zmin;
9388 fYbuf[2] = Hparam.zmax;
9389 }
9390
9392 TView *view = gPad->GetView();
9393 if (!view) {
9394 Error("PaintTriangles", "no TView in current pad");
9395 return;
9396 }
9397 Double_t thedeg = 90 - gPad->GetTheta();
9398 Double_t phideg = -90 - gPad->GetPhi();
9399 Double_t psideg = view->GetPsi();
9400 Int_t irep;
9401 view->SetView(phideg, thedeg, psideg, irep);
9402
9403 // Set color/style for back box
9404 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9405 fLego->SetFillColor(gPad->GetFrameFillColor());
9406 fLego->TAttFill::Modify();
9407 Int_t backcolor = gPad->GetFrameFillColor();
9408 if (Hoption.System != kCARTESIAN) backcolor = 0;
9409 view->PadRange(backcolor);
9412 fLego->TAttFill::Modify();
9413
9414 // Paint the Back Box if needed
9415 if (Hoption.BackBox && !Hoption.Same) {
9416 fLego->InitMoveScreen(-1.1,1.1);
9419 fLego->BackBox(90);
9420 }
9421
9422 // Paint the triangles
9423 fGraph2DPainter->Paint(option);
9424
9425 // Paint the Front Box if needed
9426 if (Hoption.FrontBox) {
9427 fLego->InitMoveScreen(-1.1,1.1);
9429 fLego->FrontBox(90);
9430 }
9431
9432 // Paint the Axis if needed
9433 if (!Hoption.Axis && !Hoption.Same) {
9434 TGaxis *axis = new TGaxis();
9435 PaintLegoAxis(axis, 90);
9436 delete axis;
9437 }
9438
9440
9441 delete fLego; fLego = 0;
9442}
9443
9444////////////////////////////////////////////////////////////////////////////////
9445/// Define the color levels used to paint legos, surfaces etc..
9446
9448{
9449
9450 Int_t i, irep;
9451
9452 // Initialize the color levels
9453 if (ndivz >= 100) {
9454 Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
9455 ndivz = 8;
9456 }
9457 Double_t *funlevel = new Double_t[ndivz+1];
9458 Int_t *colorlevel = new Int_t[ndivz+1];
9459 Int_t theColor;
9460 Int_t ncolors = gStyle->GetNumberOfColors();
9461 for (i = 0; i < ndivz; ++i) {
9462 funlevel[i] = fH->GetContourLevelPad(i);
9463 theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9464 colorlevel[i] = gStyle->GetColorPalette(theColor);
9465 }
9466 colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9467 fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9468 delete [] colorlevel;
9469 delete [] funlevel;
9470}
9471
9472////////////////////////////////////////////////////////////////////////////////
9473/// [Control function to draw 2D/3D histograms (tables).](#HP01c)
9474
9476{
9477
9478 // Fill Hparam structure with histo parameters
9479 if (!TableInit()) return;
9480
9481 // Draw histogram frame
9482 PaintFrame();
9483
9484 // If palette option not specified, delete a possible existing palette
9485 if (!Hoption.Zscale) {
9486 TObject *palette = fFunctions->FindObject("palette");
9487 if (palette) { fFunctions->Remove(palette); delete palette;}
9488 }
9489
9490 // Do not draw the histogram. Only the attached functions will be drawn.
9491 if (Hoption.Func == 2) {
9492 if (Hoption.Zscale) {
9493 Int_t ndiv = fH->GetContour();
9494 if (ndiv == 0 ) {
9495 ndiv = gStyle->GetNumberContours();
9496 fH->SetContour(ndiv);
9497 }
9498 PaintPalette();
9499 }
9500
9501 // Draw the histogram according to the option
9502 } else {
9503 if (fH->InheritsFrom(TH2Poly::Class())) {
9504 if (Hoption.Fill) PaintTH2PolyBins("f");
9507 if (Hoption.Text) PaintTH2PolyText(option);
9508 if (Hoption.Line) PaintTH2PolyBins("l");
9509 if (Hoption.Mark) PaintTH2PolyBins("P");
9510 } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9511 if (Hoption.Scat) PaintScatterPlot(option);
9512 if (Hoption.Arrow) PaintArrows(option);
9513 if (Hoption.Box) PaintBoxes(option);
9514 if (Hoption.Color) {
9515 if (Hoption.Color == 3) PaintColorLevelsFast(option);
9516 else PaintColorLevels(option);
9517 }
9518 if (Hoption.Contour) PaintContour(option);
9519 if (Hoption.Text) PaintText(option);
9520 if (Hoption.Error >= 100) Paint2DErrors(option);
9521 if (Hoption.Candle) PaintCandlePlot(option);
9522 }
9523 if (Hoption.Lego) PaintLego(option);
9524 if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9525 if (Hoption.Tri) PaintTriangles(option);
9526 }
9527
9528 // Draw histogram title
9529 PaintTitle();
9530
9531 // Draw the axes
9532 if (!Hoption.Lego && !Hoption.Surf &&
9533 !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9534
9535 TF1 *fit = 0;
9536 TIter next(fFunctions);
9537 TObject *obj;
9538 while ((obj = next())) {
9539 if (obj->InheritsFrom(TF1::Class())) {
9540 fit = (TF1*)obj;
9541 break;
9542 }
9543 }
9544 if ((Hoption.Same%10) != 1) {
9545 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9546 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9547 //ALWAYS executed on non-iOS platform.
9548 //On iOS, depends on mode.
9550 }
9551 }
9552 }
9553}
9554
9555////////////////////////////////////////////////////////////////////////////////
9556/// Control function to draw a TH2Poly bins' contours.
9557///
9558/// - option = "F" draw the bins as filled areas.
9559/// - option = "L" draw the bins as line.
9560/// - option = "P" draw the bins as markers.
9561
9563{
9564
9565 //Do not highlight the histogram, if its part was picked.
9566 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9567
9568 TString opt = option;
9569 opt.ToLower();
9570 Bool_t line = kFALSE;
9571 Bool_t fill = kFALSE;
9572 Bool_t mark = kFALSE;
9573 if (opt.Contains("l")) line = kTRUE;
9574 if (opt.Contains("f")) fill = kTRUE;
9575 if (opt.Contains("p")) mark = kTRUE;
9576
9577 TH2PolyBin *b;
9578 Double_t z;
9579
9580 TIter next(((TH2Poly*)fH)->GetBins());
9581 TObject *obj, *poly;
9582
9583 while ((obj=next())) {
9584 b = (TH2PolyBin*)obj;
9585 z = b->GetContent();
9586 if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9587 poly = b->GetPolygon();
9588
9589 // Paint the TGraph bins.
9590 if (poly->IsA() == TGraph::Class()) {
9591 TGraph *g = (TGraph*)poly;
9592 g->TAttLine::Modify();
9593 g->TAttMarker::Modify();
9594 g->TAttFill::Modify();
9595 if (line) {
9596 Int_t fs = g->GetFillStyle();
9597 Int_t fc = g->GetFillColor();
9598 g->SetFillStyle(0);
9599 g->SetFillColor(g->GetLineColor());
9600 g->Paint("F");
9601 g->SetFillStyle(fs);
9602 g->SetFillColor(fc);
9603 }
9604 if (fill) g->Paint("F");
9605 if (mark) g->Paint("P");
9606 }
9607
9608 // Paint the TMultiGraph bins.
9609 if (poly->IsA() == TMultiGraph::Class()) {
9610 TMultiGraph *mg = (TMultiGraph*)poly;
9611 TList *gl = mg->GetListOfGraphs();
9612 if (!gl) return;
9613 TGraph *g;
9614 TIter nextg(gl);
9615 while ((g = (TGraph*) nextg())) {
9616 g->TAttLine::Modify();
9617 g->TAttMarker::Modify();
9618 g->TAttFill::Modify();
9619 if (line) {
9620 Int_t fs = g->GetFillStyle();
9621 Int_t fc = g->GetFillColor();
9622 g->SetFillStyle(0);
9623 g->SetFillColor(g->GetLineColor());
9624 g->Paint("F");
9625 g->SetFillStyle(fs);
9626 g->SetFillColor(fc);
9627 }
9628 if (fill) g->Paint("F");
9629 if (mark) g->Paint("P");
9630 }
9631 }
9632 }
9633}
9634
9635////////////////////////////////////////////////////////////////////////////////
9636/// [Control function to draw a TH2Poly as a color plot.](#HP20a)
9637
9639{
9640
9641 //Do not highlight the histogram, if its part was picked.
9642 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9643 return;
9644
9645 Int_t ncolors, color, theColor;
9646 Double_t z, zc;
9647 Double_t zmin = fH->GetMinimum();
9648 Double_t zmax = fH->GetMaximum();
9649 if (Hoption.Logz) {
9650 if (zmax > 0) {
9651 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9652 zmin = TMath::Log10(zmin);
9653 zmax = TMath::Log10(zmax);
9654 } else {
9655 return;
9656 }
9657 }
9658 Double_t dz = zmax - zmin;
9659
9660 // Initialize the levels on the Z axis
9661 ncolors = gStyle->GetNumberOfColors();
9662 Int_t ndiv = fH->GetContour();
9663 if (ndiv == 0 ) {
9664 ndiv = gStyle->GetNumberContours();
9665 fH->SetContour(ndiv);
9666 }
9667 Int_t ndivz = TMath::Abs(ndiv);
9668 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9669 Double_t scale = ndivz/dz;
9670
9671 TH2PolyBin *b;
9672
9673 TIter next(((TH2Poly*)fH)->GetBins());
9674 TObject *obj, *poly;
9675
9676 while ((obj=next())) {
9677 b = (TH2PolyBin*)obj;
9678 poly = b->GetPolygon();
9679
9680 z = b->GetContent();
9681 if (z==0 && Hoption.Zero) continue;
9682 if (Hoption.Logz) {
9683 if (z > 0) z = TMath::Log10(z);
9684 else z = zmin;
9685 }
9686 if (z < zmin) continue;
9687
9688 // Define the bin color.
9690 zc = fH->GetContourLevelPad(0);
9691 if (z < zc) continue;
9692 color = -1;
9693 for (Int_t k=0; k<ndiv; k++) {
9694 zc = fH->GetContourLevelPad(k);
9695 if (z < zc) {
9696 continue;
9697 } else {
9698 color++;
9699 }
9700 }
9701 } else {
9702 color = Int_t(0.01+(z-zmin)*scale);
9703 }
9704 theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9705 if (theColor > ncolors-1) theColor = ncolors-1;
9706
9707 // Paint the TGraph bins.
9708 if (poly->IsA() == TGraph::Class()) {
9709 TGraph *g = (TGraph*)poly;
9710 g->SetFillColor(gStyle->GetColorPalette(theColor));
9711 g->TAttFill::Modify();
9712 g->Paint("F");
9713 }
9714
9715 // Paint the TMultiGraph bins.
9716 if (poly->IsA() == TMultiGraph::Class()) {
9717 TMultiGraph *mg = (TMultiGraph*)poly;
9718 TList *gl = mg->GetListOfGraphs();
9719 if (!gl) return;
9720 TGraph *g;
9721 TIter nextg(gl);
9722 while ((g = (TGraph*) nextg())) {
9723 g->SetFillColor(gStyle->GetColorPalette(theColor));
9724 g->TAttFill::Modify();
9725 g->Paint("F");
9726 }
9727 }
9728 }
9730}
9731
9732////////////////////////////////////////////////////////////////////////////////
9733/// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
9734
9736{
9737
9738 //Do not highlight the histogram, if its part was selected.
9739 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9740 return;
9741
9742 Int_t k, loop, marker=0;
9743 Double_t z, xk,xstep, yk, ystep, xp, yp;
9744 Double_t scale = 1;
9745 Double_t zmin = fH->GetMinimum();
9746 Double_t zmax = fH->GetMaximum();
9747 if (Hoption.Logz) {
9748 if (zmax > 0) {
9749 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9750 zmin = TMath::Log10(zmin);
9751 zmax = TMath::Log10(zmax);
9752 } else {
9753 return;
9754 }
9755 }
9756 Double_t dz = zmax - zmin;
9757 scale = (kNMAX-1)/dz;
9758
9759
9760 // use an independent instance of a random generator
9761 // instead of gRandom to avoid conflicts and
9762 // to get same random numbers when drawing the same histogram
9763 TRandom2 random;
9764
9765 TH2PolyBin *b;
9766
9767 TIter next(((TH2Poly*)fH)->GetBins());
9768 TObject *obj, *poly;
9769
9770 Double_t maxarea = 0, a;
9771 while ((obj=next())) {
9772 b = (TH2PolyBin*)obj;
9773 a = b->GetArea();
9774 if (a>maxarea) maxarea = a;
9775 }
9776
9777 next.Reset();
9778
9779 while ((obj=next())) {
9780 b = (TH2PolyBin*)obj;
9781 poly = b->GetPolygon();
9782 z = b->GetContent();
9783 if (z < zmin) z = zmin;
9784 if (z > zmax) z = zmax;
9785 if (Hoption.Logz) {
9786 if (z > 0) z = TMath::Log10(z) - zmin;
9787 } else {
9788 z -= zmin;
9789 }
9790 k = Int_t((z*scale)*(b->GetArea()/maxarea));
9791 xk = b->GetXMin();
9792 yk = b->GetYMin();
9793 xstep = b->GetXMax()-xk;
9794 ystep = b->GetYMax()-yk;
9795
9796 // Paint the TGraph bins.
9797 if (poly->IsA() == TGraph::Class()) {
9798 TGraph *g = (TGraph*)poly;
9799 if (k <= 0 || z <= 0) continue;
9800 loop = 0;
9801 while (loop<k) {
9802 if (k+marker >= kNMAX) {
9803 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9804 marker=0;
9805 }
9806 xp = (random.Rndm()*xstep) + xk;
9807 yp = (random.Rndm()*ystep) + yk;
9808 if (g->IsInside(xp,yp)) {
9809 fXbuf[marker] = xp;
9810 fYbuf[marker] = yp;
9811 marker++;
9812 loop++;
9813 }
9814 }
9815 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9816 }
9817
9818 // Paint the TMultiGraph bins.
9819 if (poly->IsA() == TMultiGraph::Class()) {
9820 TMultiGraph *mg = (TMultiGraph*)poly;
9821 TList *gl = mg->GetListOfGraphs();
9822 if (!gl) return;
9823 if (k <= 0 || z <= 0) continue;
9824 loop = 0;
9825 while (loop<k) {
9826 if (k+marker >= kNMAX) {
9827 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9828 marker=0;
9829 }
9830 xp = (random.Rndm()*xstep) + xk;
9831 yp = (random.Rndm()*ystep) + yk;
9832 if (mg->IsInside(xp,yp)) {
9833 fXbuf[marker] = xp;
9834 fYbuf[marker] = yp;
9835 marker++;
9836 loop++;
9837 }
9838 }
9839 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9840 }
9841 }
9842 PaintTH2PolyBins("l");
9843}
9844
9845////////////////////////////////////////////////////////////////////////////////
9846/// [Control function to draw a TH2Poly as a text plot.](#HP20a)
9847
9849{
9850
9851 TLatex text;
9855
9856 Double_t x, y, z, e, angle = 0;
9857 TString tt, tf;
9858 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9859 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9860 Int_t opt = (Int_t)Hoption.Text/1000;
9861
9862 text.SetTextAlign(22);
9863 if (Hoption.Text == 1) angle = 0;
9864 text.SetTextAngle(angle);
9865 text.TAttText::Modify();
9866
9867 TH2PolyBin *b;
9868
9869 TIter next(((TH2Poly*)fH)->GetBins());
9870 TObject *obj, *p;
9871
9872 while ((obj=next())) {
9873 b = (TH2PolyBin*)obj;
9874 p = b->GetPolygon();
9875 x = (b->GetXMin()+b->GetXMax())/2;
9876 if (Hoption.Logx) {
9877 if (x > 0) x = TMath::Log10(x);
9878 else continue;
9879 }
9880 y = (b->GetYMin()+b->GetYMax())/2;
9881 if (Hoption.Logy) {
9882 if (y > 0) y = TMath::Log10(y);
9883 else continue;
9884 }
9885 z = b->GetContent();
9886 if (z < fH->GetMinimum() || (z == 0 && !Hoption.MinimumZero)) continue;
9887 if (opt==2) {
9888 e = fH->GetBinError(b->GetBinNumber());
9889 tf.Form("#splitline{%s%s}{#pm %s%s}",
9891 "%",gStyle->GetPaintTextFormat());
9892 tt.Form(tf.Data(),z,e);
9893 } else {
9894 tt.Form(tf.Data(),z);
9895 }
9896 if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
9897 else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),tt.Data());
9898 }
9899
9900 PaintTH2PolyBins("l");
9901}
9902
9903////////////////////////////////////////////////////////////////////////////////
9904/// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
9905
9907{
9908
9909 TLatex text;
9913
9914 Double_t x, y, z, e, angle = 0;
9915 TString tt, tf;
9916 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9917 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9918
9919 // 1D histograms
9920 if (fH->GetDimension() == 1) {
9921 Bool_t getentries = kFALSE;
9922 Double_t yt;
9923 TProfile *hp = (TProfile*)fH;
9924 if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
9925 Hoption.Text = Hoption.Text-2000;
9926 getentries = kTRUE;
9927 }
9928 if (Hoption.Text == 1) angle = 90;
9929 text.SetTextAlign(11);
9930 if (angle == 90) text.SetTextAlign(12);
9931 if (angle == 0) text.SetTextAlign(21);
9932 text.TAttText::Modify();
9933 Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9934 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9935 if (Hoption.Bar) {
9936 x = fH->GetXaxis()->GetBinLowEdge(i)+
9937 fH->GetXaxis()->GetBinWidth(i)*
9938 (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9939 } else {
9940 x = fH->GetXaxis()->GetBinCenter(i);
9941 }
9942 y = fH->GetBinContent(i);
9943 yt = y;
9944 if (Hoption.MinimumZero && y<0) y = 0;
9945 if (getentries) yt = hp->GetBinEntries(i);
9946 if (yt == 0.) continue;
9947 tt.Form(tf.Data(),yt);
9948 if (Hoption.Logx) {
9949 if (x > 0) x = TMath::Log10(x);
9950 else continue;
9951 }
9952 if (Hoption.Logy) {
9953 if (y > 0) y = TMath::Log10(y);
9954 else continue;
9955 }
9956 if (y >= gPad->GetY2()) continue;
9957 if (y <= gPad->GetY1()) continue;
9958 text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),tt.Data());
9959 }
9960
9961 // 2D histograms
9962 } else {
9963 text.SetTextAlign(22);
9964 if (Hoption.Text == 1) angle = 0;
9965 text.SetTextAngle(angle);
9966 text.TAttText::Modify();
9967 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9968 y = fYaxis->GetBinCenter(j);
9969 if (Hoption.Logy) {
9970 if (y > 0) y = TMath::Log10(y);
9971 else continue;
9972 }
9973 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9974 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9975 x = fXaxis->GetBinCenter(i);
9976 if (Hoption.Logx) {
9977 if (x > 0) x = TMath::Log10(x);
9978 else continue;
9979 }
9980 if (!IsInside(x,y)) continue;
9981 z = fH->GetBinContent(bin);
9982 if (z < Hparam.zmin || (z == 0 && !Hoption.MinimumZero)) continue;
9983 if (Hoption.Text>2000) {
9984 e = fH->GetBinError(bin);
9985 tf.Form("#splitline{%s%s}{#pm %s%s}",
9987 "%",gStyle->GetPaintTextFormat());
9988 tt.Form(tf.Data(),z,e);
9989 } else {
9990 tt.Form(tf.Data(),z);
9991 }
9992 text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9993 angle,0.02*fH->GetMarkerSize(),tt.Data());
9994 }
9995 }
9996 }
9997}
9998
9999////////////////////////////////////////////////////////////////////////////////
10000/// [Control function to draw a 3D implicit functions.](#HP27)
10001
10003{
10004
10005 Int_t irep;
10006
10007 TGaxis *axis = new TGaxis();
10008 TAxis *xaxis = fH->GetXaxis();
10009 TAxis *yaxis = fH->GetYaxis();
10010 TAxis *zaxis = fH->GetZaxis();
10011
10012 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
10013 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
10014 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
10015 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
10016 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
10017 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
10018
10020
10021 TView *view = gPad->GetView();
10022 if (!view) {
10023 Error("PaintTF3", "no TView in current pad");
10024 return;
10025 }
10026 Double_t thedeg = 90 - gPad->GetTheta();
10027 Double_t phideg = -90 - gPad->GetPhi();
10028 Double_t psideg = view->GetPsi();
10029 view->SetView(phideg, thedeg, psideg, irep);
10030
10031 fLego->InitMoveScreen(-1.1,1.1);
10032
10033 if (Hoption.BackBox) {
10036 fLego->BackBox(90);
10037 }
10038
10040
10042 fH->GetNbinsY(),
10043 fH->GetNbinsZ(), "BF");
10044
10045 if (Hoption.FrontBox) {
10046 fLego->InitMoveScreen(-1.1,1.1);
10048 fLego->FrontBox(90);
10049 }
10050 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
10051
10052 PaintTitle();
10053
10054 delete axis;
10055 delete fLego; fLego = 0;
10056}
10057
10058////////////////////////////////////////////////////////////////////////////////
10059/// Draw the histogram title
10060///
10061/// The title is drawn according to the title alignment returned by
10062/// `GetTitleAlign()`. It is a 2 digits integer): hv
10063///
10064/// where `h` is the horizontal alignment and `v` is the
10065/// vertical alignment.
10066///
10067/// - `h` can get the values 1 2 3 for left, center, and right
10068/// - `v` can get the values 1 2 3 for bottom, middle and top
10069///
10070/// for instance the default alignment is: 13 (left top)
10071
10073{
10074 // probably best place for calls PaintHighlightBin
10075 // calls after paint histo (1D or 2D) and before paint title and stats
10076 if (!gPad->GetView()) PaintHighlightBin();
10077
10078 if (Hoption.Same) return;
10079 if (fH->TestBit(TH1::kNoTitle)) return;
10080 Int_t nt = strlen(fH->GetTitle());
10081 TPaveText *title = 0;
10082 TObject *obj;
10083 TIter next(gPad->GetListOfPrimitives());
10084 while ((obj = next())) {
10085 if (!obj->InheritsFrom(TPaveText::Class())) continue;
10086 title = (TPaveText*)obj;
10087 if (strcmp(title->GetName(),"title")) {title = 0; continue;}
10088 break;
10089 }
10090 if (nt == 0 || gStyle->GetOptTitle() <= 0) {
10091 if (title) delete title;
10092 return;
10093 }
10094 Double_t ht = gStyle->GetTitleH();
10095 Double_t wt = gStyle->GetTitleW();
10096
10097 if (ht <= 0) {
10098 if (gStyle->GetTitleFont("")%10 == 3) {
10099 Double_t hw = TMath::Max((Double_t)gPad->XtoPixel(gPad->GetX2()),
10100 (Double_t)gPad->YtoPixel(gPad->GetY1()));
10101 ht = 1.1*(gStyle->GetTitleSize("")/hw);
10102 } else {
10103 ht = 1.1*gStyle->GetTitleFontSize();
10104 }
10105 }
10106 if (ht <= 0) ht = 0.05;
10107 if (wt <= 0) {
10108 TLatex l;
10109 l.SetTextSize(ht);
10110 l.SetTitle(fH->GetTitle());
10111 // adjustment in case the title has several lines (#splitline)
10112 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
10113 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
10114 wt = TMath::Min(0.7, 0.02+wndc);
10115 }
10116 if (title) {
10117 TText *t0 = (TText*)title->GetLine(0);
10118 if (t0) {
10119 if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
10120 t0->SetTitle(fH->GetTitle());
10121 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
10122 }
10123 return;
10124 }
10125
10126 Int_t talh = gStyle->GetTitleAlign()/10;
10127 if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
10128 Int_t talv = gStyle->GetTitleAlign()%10;
10129 if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
10130 Double_t xpos, ypos;
10131 xpos = gStyle->GetTitleX();
10132 ypos = gStyle->GetTitleY();
10133 if (talh == 2) xpos = xpos-wt/2.;
10134 if (talh == 3) xpos = xpos-wt;
10135 if (talv == 2) ypos = ypos+ht/2.;
10136 if (talv == 1) ypos = ypos+ht;
10137
10138 TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
10139
10140 // box with the histogram title
10142 ptitle->SetFillStyle(gStyle->GetTitleStyle());
10143 ptitle->SetName("title");
10146 ptitle->SetTextFont(gStyle->GetTitleFont(""));
10147 if (gStyle->GetTitleFont("")%10 > 2)
10149 ptitle->AddText(fH->GetTitle());
10150 ptitle->SetBit(kCanDelete);
10151 ptitle->Draw();
10152 ptitle->Paint();
10153
10154 if(!gPad->IsEditable()) delete ptitle;
10155}
10156
10157////////////////////////////////////////////////////////////////////////////////
10158/// Process message `mess`.
10159
10160void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
10161{
10162
10163 if (!strcmp(mess,"SetF3")) {
10165 } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
10167 } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
10168 TVectorD &v = (TVectorD&)(*obj);
10169 Double_t xclip = v(0);
10170 Double_t yclip = v(1);
10171 Double_t zclip = v(2);
10173 }
10174}
10175
10176////////////////////////////////////////////////////////////////////////////////
10177/// Static function.
10178///
10179/// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
10180/// This procedure can be used to create an all-sky map in Galactic
10181/// coordinates with an equal-area Aitoff projection. Output map
10182/// coordinates are zero longitude centered.
10183/// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
10184///
10185/// source: GMT
10186///
10187/// code from Ernst-Jan Buis
10188
10190{
10191
10192 Double_t x, y;
10193
10194 Double_t alpha2 = (l/2)*TMath::DegToRad();
10195 Double_t delta = b*TMath::DegToRad();
10196 Double_t r2 = TMath::Sqrt(2.);
10197 Double_t f = 2*r2/TMath::Pi();
10198 Double_t cdec = TMath::Cos(delta);
10199 Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
10200 x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
10201 y = TMath::Sin(delta)*r2/denom;
10202 x *= TMath::RadToDeg()/f;
10203 y *= TMath::RadToDeg()/f;
10204 // x *= -1.; // for a skymap swap left<->right
10205 Al = x;
10206 Ab = y;
10207
10208 return 0;
10209}
10210
10211////////////////////////////////////////////////////////////////////////////////
10212/// Static function
10213///
10214/// Probably the most famous of the various map projections, the Mercator projection
10215/// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
10216/// with no distortion along the equator.
10217/// The Mercator projection has been used extensively for world maps in which the distortion towards
10218/// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
10219/// Greenland is larger than South America. In reality, the latter is about eight times the size of
10220/// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
10221/// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
10222/// code from Ernst-Jan Buis
10223
10225{
10226
10227 Al = l;
10229 Ab = TMath::Log(aid);
10230 return 0;
10231}
10232
10233////////////////////////////////////////////////////////////////////////////////
10234/// Static function code from Ernst-Jan Buis
10235
10237{
10238
10239 Al = l*cos(b*TMath::DegToRad());
10240 Ab = b;
10241 return 0;
10242}
10243
10244////////////////////////////////////////////////////////////////////////////////
10245/// Static function code from Ernst-Jan Buis
10246
10248{
10249
10250 Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
10251 Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
10252 return 0;
10253}
10254
10255////////////////////////////////////////////////////////////////////////////////
10256/// Recompute the histogram range following graphics operations.
10257
10259{
10260
10261 if (Hoption.Same) return;
10262
10263 // Compute x,y range
10268
10269 Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
10270 if (Hoption.Proj ==1) {
10271 // TODO : check x range not lower than -180 and not higher than 180
10276
10277 if (xmin > xmin_aid) xmin = xmin_aid;
10278 if (ymin > ymin_aid) ymin = ymin_aid;
10279 if (xmax < xmax_aid) xmax = xmax_aid;
10280 if (ymax < ymax_aid) ymax = ymax_aid;
10281 if (Hparam.ymin<0 && Hparam.ymax>0) {
10282 // there is an 'equator', check its range in the plot..
10283 THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
10284 THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
10285 if (xmin >xmin_aid) xmin = xmin_aid;
10286 if (xmax <xmax_aid) xmax = xmax_aid;
10287 }
10288 if (Hparam.xmin<0 && Hparam.xmax>0) {
10289 THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10290 THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
10291 if (ymin >ymin_aid) ymin = ymin_aid;
10292 if (ymax <ymax_aid) ymax = ymax_aid;
10293 }
10294 } else if ( Hoption.Proj ==2) {
10295 if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
10296 Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
10297 Hoption.Proj = 0;
10298 } else {
10301 }
10302 } else if (Hoption.Proj == 3) {
10307
10308 if (xmin > xmin_aid) xmin = xmin_aid;
10309 if (ymin > ymin_aid) ymin = ymin_aid;
10310 if (xmax < xmax_aid) xmax = xmax_aid;
10311 if (ymax < ymax_aid) ymax = ymax_aid;
10312 if (Hparam.ymin<0 && Hparam.ymax>0) {
10313 THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10314 THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10315 if (xmin >xmin_aid) xmin = xmin_aid;
10316 if (xmax <xmax_aid) xmax = xmax_aid;
10317 }
10318 if (Hparam.xmin<0 && Hparam.xmax>0) {
10319 THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
10320 THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10321 if (ymin >ymin_aid) ymin = ymin_aid;
10322 if (ymax <ymax_aid) ymax = ymax_aid;
10323 }
10324 } else if (Hoption.Proj == 4) {
10329
10330 if (xmin > xmin_aid) xmin = xmin_aid;
10331 if (ymin > ymin_aid) ymin = ymin_aid;
10332 if (xmax < xmax_aid) xmax = xmax_aid;
10333 if (ymax < ymax_aid) ymax = ymax_aid;
10334 if (Hparam.ymin<0 && Hparam.ymax>0) {
10335 THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10336 THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10337 if (xmin >xmin_aid) xmin = xmin_aid;
10338 if (xmax <xmax_aid) xmax = xmax_aid;
10339 }
10340 if (Hparam.xmin<0 && Hparam.xmax>0) {
10341 THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10342 THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10343 if (ymin >ymin_aid) ymin = ymin_aid;
10344 if (ymax <ymax_aid) ymax = ymax_aid;
10345 }
10346 }
10347 Hparam.xmin= xmin;
10348 Hparam.xmax= xmax;
10349 Hparam.ymin= ymin;
10350 Hparam.ymax= ymax;
10351
10352 Double_t dx = xmax-xmin;
10353 Double_t dy = ymax-ymin;
10354 Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
10355 Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
10356
10357 // Range() could change the size of the pad pixmap and therefore should
10358 // be called before the other paint routines
10359 gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
10360 ymin - dyr*gPad->GetBottomMargin(),
10361 xmax + dxr*gPad->GetRightMargin(),
10362 ymax + dyr*gPad->GetTopMargin());
10363 gPad->RangeAxis(xmin, ymin, xmax, ymax);
10364}
10365
10366////////////////////////////////////////////////////////////////////////////////
10367/// Set current histogram to `h`
10368
10370{
10371
10372 if (h == 0) return;
10373 fH = h;
10374 fXaxis = h->GetXaxis();
10375 fYaxis = h->GetYaxis();
10376 fZaxis = h->GetZaxis();
10378}
10379
10380////////////////////////////////////////////////////////////////////////////////
10381/// Initialize various options to draw 2D histograms.
10382
10384{
10385
10386 static const char *where = "TableInit";
10387
10388 Int_t first, last;
10389 Double_t yMARGIN= gStyle->GetHistTopMargin();
10390 Double_t zmin, zmax;
10391 Int_t maximum = 0;
10392 Int_t minimum = 0;
10393 if (fH->GetMaximumStored() != -1111) maximum = 1;
10394 if (fH->GetMinimumStored() != -1111) minimum = 1;
10395
10396 // ----------------- Compute X axis parameters
10397 first = fXaxis->GetFirst();
10398 last = fXaxis->GetLast();
10399 Hparam.xlast = last;
10405
10406 // if log scale in X, replace xmin,max by the log
10407 if (Hoption.Logx) {
10408 // find the first edge of a bin that is > 0
10409 if (Hparam.xlowedge <=0 ) {
10412 }
10413 if (Hparam.xmin <=0 || Hparam.xmax <=0) {
10414 Error(where, "cannot set X axis to log scale");
10415 return 0;
10416 }
10420 if (Hparam.xlast > last) Hparam.xlast = last;
10423 }
10424
10425 // ----------------- Compute Y axis parameters
10426 first = fYaxis->GetFirst();
10427 last = fYaxis->GetLast();
10428 Hparam.ylast = last;
10432 if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10435
10436 // if log scale in Y, replace ymin,max by the log
10437 if (Hoption.Logy) {
10438 if (Hparam.ylowedge <=0 ) {
10441 }
10442 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10443 Error(where, "cannot set Y axis to log scale");
10444 return 0;
10445 }
10449 if (Hparam.ylast > last) Hparam.ylast = last;
10452 }
10453
10454
10455 // ----------------- Compute Z axis parameters
10456 Double_t bigp = TMath::Power(10,32);
10457 zmax = -bigp;
10458 zmin = bigp;
10459 Double_t c1, e1;
10460 Double_t allchan = 0;
10461 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10462 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10463 c1 = fH->GetBinContent(i,j);
10464 zmax = TMath::Max(zmax,c1);
10465 if (Hoption.Error) {
10466 e1 = fH->GetBinError(i,j);
10467 zmax = TMath::Max(zmax,c1+e1);
10468 }
10469 zmin = TMath::Min(zmin,c1);
10470 allchan += c1;
10471 }
10472 }
10473
10474 // Take into account maximum , minimum
10475
10476 if (maximum) zmax = fH->GetMaximumStored();
10477 if (minimum) zmin = fH->GetMinimumStored();
10478 if (Hoption.Logz && zmax < 0) {
10479 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10480 return 0;
10481 } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10482 zmin = 0.01;
10483 zmax = 10.;
10484 }
10485 if (zmin >= zmax) {
10486 if (Hoption.Logz) {
10487 if (zmax > 0) zmin = 0.001*zmax;
10488 else {
10489 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10490 return 0;
10491 }
10492 }
10493 }
10494
10495 // take into account normalization factor
10496 Hparam.allchan = allchan;
10497 Double_t factor = allchan;
10498 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10499 if (allchan) factor /= allchan;
10500 if (factor == 0) factor = 1;
10501 Hparam.factor = factor;
10502 zmax = factor*zmax;
10503 zmin = factor*zmin;
10504 c1 = zmax;
10505 if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10506
10507 // For log scales, histogram coordinates are log10(ymin) and
10508 // log10(ymax). Final adjustment (if not option "Same")
10509 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10510 // Maximum and Minimum are not defined.
10511 if (Hoption.Logz) {
10512 if (zmin <= 0) {
10513 zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10514 fH->SetMinimum(zmin);
10515 }
10516 zmin = TMath::Log10(zmin);
10517 if (!minimum) zmin += TMath::Log10(0.5);
10518 zmax = TMath::Log10(zmax);
10519 if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10520 goto LZMIN;
10521 }
10522
10523 // final adjustment of YMAXI for linear scale (if not option "Same"):
10524 // decrease histogram height to MAX% of allowed height if HMAXIM
10525 // has not been called.
10526 // MAX% is the value in percent which has been set in HPLSET
10527 // (default is 90%).
10528 if (!maximum) {
10529 zmax += yMARGIN*(zmax-zmin);
10530 }
10531
10532 // final adjustment of ymin for linear scale.
10533 // if minimum is not set , then ymin is set to zero if >0
10534 // or to ymin - yMARGIN if <0.
10535 if (!minimum) {
10536 if (Hoption.MinimumZero) {
10537 if (zmin >= 0) zmin = 0;
10538 else zmin -= yMARGIN*(zmax-zmin);
10539 } else {
10540 Double_t dzmin = yMARGIN*(zmax-zmin);
10541 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10542 else zmin -= dzmin;
10543 }
10544 }
10545
10546LZMIN:
10547 Hparam.zmin = zmin;
10548 Hparam.zmax = zmax;
10549
10550 // Set bar offset and width
10553
10554 return 1;
10555}
10556
10557////////////////////////////////////////////////////////////////////////////////
10558/// This function returns the best format to print the error value (e)
10559/// knowing the parameter value (v) and the format (f) used to print it.
10560
10562{
10563
10564 static TString ef;
10565 TString tf, tv;
10566
10567 // print v with the format f in tv.
10568 tf.Form("%s%s","%",f);
10569 tv.Form(tf.Data(),v);
10570
10571 // Analyse tv.
10572 int ie = tv.Index("e");
10573 int iE = tv.Index("E");
10574 int id = tv.Index(".");
10575
10576 // v has been printed with the exponent notation.
10577 // There is 2 cases, the exponent is positive or negative
10578 if (ie >= 0 || iE >= 0) {
10579 if (tv.Index("+") >= 0) {
10580 if (e < 1) {
10581 ef.Form("%s.1f","%");
10582 } else {
10583 if (ie >= 0) {
10584 ef.Form("%s.%de","%",ie-id-1);
10585 } else {
10586 ef.Form("%s.%dE","%",iE-id-1);
10587 }
10588 }
10589 } else {
10590 if (ie >= 0) {
10591 ef.Form("%s.%de","%",ie-id-1);
10592 } else {
10593 ef.Form("%s.%dE","%",iE-id-1);
10594 }
10595 }
10596
10597 // There is not '.' in tv. e will be printed with one decimal digit.
10598 } else if (id < 0) {
10599 ef.Form("%s.1f","%");
10600
10601 // There is a '.' in tv and no exponent notation. e's decimal part will
10602 // have the same number of digits as v's one.
10603 } else {
10604 ef.Form("%s.%df","%",tv.Length()-id-1);
10605 }
10606
10607 return ef.Data();
10608}
10609
10610////////////////////////////////////////////////////////////////////////////////
10611/// Set projection.
10612
10613void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10614{
10615
10616 if (fShowProjection) return;
10617 TString opt = option;
10618 opt.ToLower();
10619 Int_t projection = 0;
10620 if (opt.Contains("x")) projection = 1;
10621 if (opt.Contains("y")) projection = 2;
10622 if (opt.Contains("z")) projection = 3;
10623 if (opt.Contains("xy")) projection = 4;
10624 if (opt.Contains("yx")) projection = 5;
10625 if (opt.Contains("xz")) projection = 6;
10626 if (opt.Contains("zx")) projection = 7;
10627 if (opt.Contains("yz")) projection = 8;
10628 if (opt.Contains("zy")) projection = 9;
10629 if (projection < 4) fShowOption = option+1;
10630 else fShowOption = option+2;
10631 fShowProjection = projection+100*nbins;
10632 gROOT->MakeDefCanvas();
10633 gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
10634 gPad->SetGrid();
10635}
10636
10637////////////////////////////////////////////////////////////////////////////////
10638/// Show projection onto X.
10639
10641{
10642
10643 Int_t nbins = (Int_t)fShowProjection/100;
10644 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10645 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10646
10647 // Erase old position and draw a line at current position
10648 static int pyold1 = 0;
10649 static int pyold2 = 0;
10650 float uxmin = gPad->GetUxmin();
10651 float uxmax = gPad->GetUxmax();
10652 int pxmin = gPad->XtoAbsPixel(uxmin);
10653 int pxmax = gPad->XtoAbsPixel(uxmax);
10654 Float_t upy = gPad->AbsPixeltoY(py);
10655 Float_t y = gPad->PadtoY(upy);
10656 Int_t biny1 = fH->GetYaxis()->FindBin(y);
10657 Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10658 Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10659 Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10660
10661 if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10662 gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10663 pyold1 = py1;
10664 pyold2 = py2;
10665
10666 // Create or set the new canvas proj x
10667 TVirtualPad *padsav = gPad;
10668 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10670 if (c) {
10671 c->Clear();
10672 } else {
10673 fShowProjection = 0;
10674 pyold1 = 0;
10675 pyold2 = 0;
10676 return;
10677 }
10678 c->cd();
10679 c->SetLogy(padsav->GetLogz());
10680 c->SetLogx(padsav->GetLogx());
10681
10682 // Draw slice corresponding to mouse position
10683 TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10684 TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10685 if (hp) {
10686 hp->SetFillColor(38);
10687 // apply a patch from Oliver Freyermuth to set the title in the projection
10688 // using the range of the projected Y values
10689 if (biny1 == biny2) {
10690 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10691 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10692 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10693 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10694 if (fH->GetYaxis()->GetLabels() != NULL) {
10695 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10696 } else {
10697 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10698 }
10699 } else {
10700 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10701 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10702 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10703 // biny1 is used here to get equal precision no matter how large the binrange is,
10704 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10705 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10706 if (fH->GetYaxis()->GetLabels() != NULL) {
10707 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf] [%s..%s]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1), fH->GetYaxis()->GetBinLabel(biny2)));
10708 } else {
10709 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10710 }
10711 }
10712 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10713 hp->SetYTitle("Number of Entries");
10714 hp->Draw();
10715 c->Update();
10716 padsav->cd();
10717 }
10718}
10719
10720////////////////////////////////////////////////////////////////////////////////
10721/// Show projection onto Y.
10722
10724{
10725
10726 Int_t nbins = (Int_t)fShowProjection/100;
10727 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10728 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10729
10730 // Erase old position and draw a line at current position
10731 static int pxold1 = 0;
10732 static int pxold2 = 0;
10733 float uymin = gPad->GetUymin();
10734 float uymax = gPad->GetUymax();
10735 int pymin = gPad->YtoAbsPixel(uymin);
10736 int pymax = gPad->YtoAbsPixel(uymax);
10737 Float_t upx = gPad->AbsPixeltoX(px);
10738 Float_t x = gPad->PadtoX(upx);
10739 Int_t binx1 = fH->GetXaxis()->FindBin(x);
10740 Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10741 Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10742 Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10743
10744 if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10745 gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10746 pxold1 = px1;
10747 pxold2 = px2;
10748
10749 // Create or set the new canvas proj y
10750 TVirtualPad *padsav = gPad;
10751 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10753 if (c) {
10754 c->Clear();
10755 } else {
10756 fShowProjection = 0;
10757 pxold1 = 0;
10758 pxold2 = 0;
10759 return;
10760 }
10761 c->cd();
10762 c->SetLogy(padsav->GetLogz());
10763 c->SetLogx(padsav->GetLogy());
10764
10765 // Draw slice corresponding to mouse position
10766 TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10767 TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10768 if (hp) {
10769 hp->SetFillColor(38);
10770 // apply a patch from Oliver Freyermuth to set the title in the projection
10771 // using the range of the projected X values
10772 if (binx1 == binx2) {
10773 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10774 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10775 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10776 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10777 if (fH->GetXaxis()->GetLabels() != NULL) {
10778 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10779 } else {
10780 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10781 }
10782 } else {
10783 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10784 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10785 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10786 // binx1 is used here to get equal precision no matter how large the binrange is,
10787 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10788 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10789 if (fH->GetXaxis()->GetLabels() != NULL) {
10790 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf] [%s..%s]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1), fH->GetXaxis()->GetBinLabel(binx2)));
10791 } else {
10792 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10793 }
10794 }
10795 hp->SetXTitle(fH->GetYaxis()->GetTitle());
10796 hp->SetYTitle("Number of Entries");
10797 hp->Draw();
10798 c->Update();
10799 padsav->cd();
10800 }
10801}
10802
10803////////////////////////////////////////////////////////////////////////////////
10804/// Show projection (specified by `fShowProjection`) of a `TH3`.
10805/// The drawing option for the projection is in `fShowOption`.
10806///
10807/// First implementation; R.Brun
10808///
10809/// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10810
10812{
10813
10814 Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10815 if (fH->GetDimension() < 3) {
10816 if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10817 if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10818 }
10819
10820 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10821 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10822
10823 // Erase old position and draw a line at current position
10824 TView *view = gPad->GetView();
10825 if (!view) return;
10826 TH3 *h3 = (TH3*)fH;
10827 TAxis *xaxis = h3->GetXaxis();
10828 TAxis *yaxis = h3->GetYaxis();
10829 TAxis *zaxis = h3->GetZaxis();
10830 Double_t u[3],xx[3];
10831
10832 static TPoint line1[2];//store end points of a line, initialised 0 by default
10833 static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10834 static TPoint line3[2];
10835 static TPoint line4[2];
10836 static TPoint endface1[5];
10837 static TPoint endface2[5];
10838 static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10839 static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10840
10841 Double_t uxmin = gPad->GetUxmin();
10842 Double_t uxmax = gPad->GetUxmax();
10843 Double_t uymin = gPad->GetUymin();
10844 Double_t uymax = gPad->GetUymax();
10845
10846 int pxmin = gPad->XtoAbsPixel(uxmin);
10847 int pxmax = gPad->XtoAbsPixel(uxmax);
10848 if (pxmin==pxmax) return;
10849 int pymin = gPad->YtoAbsPixel(uymin);
10850 int pymax = gPad->YtoAbsPixel(uymax);
10851 if (pymin==pymax) return;
10852 Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10853 Double_t cy = (pymax-pymin)/(uymax-uymin);
10854 TVirtualPad *padsav = gPad;
10855 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10857 if (!c) {
10858 fShowProjection = 0;
10859 return;
10860 }
10861
10862 switch ((Int_t)fShowProjection%100) {
10863 case 1:
10864 // "x"
10865 {
10866 Int_t firstY = yaxis->GetFirst();
10867 Int_t lastY = yaxis->GetLast();
10868 Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10869 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10870 yaxis->SetRange(biny,biny2);
10871 Int_t firstZ = zaxis->GetFirst();
10872 Int_t lastZ = zaxis->GetLast();
10873 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10874 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10875 zaxis->SetRange(binz,binz2);
10876 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10877 if (nbins>1 && line1[0].GetX()) {
10878 gVirtualX->DrawPolyLine(2,line2);
10879 gVirtualX->DrawPolyLine(2,line3);
10880 gVirtualX->DrawPolyLine(2,line4);
10881 gVirtualX->DrawPolyLine(5,endface1);
10882 gVirtualX->DrawPolyLine(5,endface2);
10883 }
10884 xx[0] = xaxis->GetXmin();
10885 xx[2] = zaxis->GetBinCenter(binz);
10886 xx[1] = yaxis->GetBinCenter(biny);
10887 view->WCtoNDC(xx,u);
10888 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10889 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10890 xx[0] = xaxis->GetXmax();
10891 view->WCtoNDC(xx,u);
10892 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10893 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10894 gVirtualX->DrawPolyLine(2,line1);
10895 if (nbins>1) {
10896 xx[0] = xaxis->GetXmin();
10897 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10898 xx[1] = yaxis->GetBinCenter(biny);
10899 view->WCtoNDC(xx,u);
10900 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10901 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10902 xx[0] = xaxis->GetXmax();
10903 view->WCtoNDC(xx,u);
10904 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10905 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10906
10907 xx[0] = xaxis->GetXmin();
10908 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10909 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10910 view->WCtoNDC(xx,u);
10911 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10912 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10913 xx[0] = xaxis->GetXmax();
10914 view->WCtoNDC(xx,u);
10915 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10916 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10917
10918 xx[0] = xaxis->GetXmin();
10919 xx[2] = zaxis->GetBinCenter(binz);
10920 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10921 view->WCtoNDC(xx,u);
10922 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10923 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10924 xx[0] = xaxis->GetXmax();
10925 view->WCtoNDC(xx,u);
10926 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10927 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10928
10929 endface1[0].SetX(line1[0].GetX());
10930 endface1[0].SetY(line1[0].GetY());
10931 endface1[1].SetX(line2[0].GetX());
10932 endface1[1].SetY(line2[0].GetY());
10933 endface1[2].SetX(line3[0].GetX());
10934 endface1[2].SetY(line3[0].GetY());
10935 endface1[3].SetX(line4[0].GetX());
10936 endface1[3].SetY(line4[0].GetY());
10937 endface1[4].SetX(line1[0].GetX());
10938 endface1[4].SetY(line1[0].GetY());
10939
10940 endface2[0].SetX(line1[1].GetX());
10941 endface2[0].SetY(line1[1].GetY());
10942 endface2[1].SetX(line2[1].GetX());
10943 endface2[1].SetY(line2[1].GetY());
10944 endface2[2].SetX(line3[1].GetX());
10945 endface2[2].SetY(line3[1].GetY());
10946 endface2[3].SetX(line4[1].GetX());
10947 endface2[3].SetY(line4[1].GetY());
10948 endface2[4].SetX(line1[1].GetX());
10949 endface2[4].SetY(line1[1].GetY());
10950
10951 gVirtualX->DrawPolyLine(2,line2);
10952 gVirtualX->DrawPolyLine(2,line3);
10953 gVirtualX->DrawPolyLine(2,line4);
10954 gVirtualX->DrawPolyLine(5,endface1);
10955 gVirtualX->DrawPolyLine(5,endface2);
10956 }
10957 c->Clear();
10958 c->cd();
10959 TH1 *hp = h3->Project3D("x");
10960 yaxis->SetRange(firstY,lastY);
10961 zaxis->SetRange(firstZ,lastZ);
10962 if (hp) {
10963 hp->SetFillColor(38);
10964 if (nbins == 1)
10965 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10966 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10967 else {
10968 hp->SetTitle(TString::Format("ProjectionX, biny=[%d,%d] [y=%.1f..%.1f], binz=[%d,%d] [z=%.1f..%.1f]", biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2),
10969 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10970 }
10971 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10972 hp->SetYTitle("Number of Entries");
10973 hp->Draw(fShowOption.Data());
10974 }
10975 }
10976 break;
10977
10978 case 2:
10979 // "y"
10980 {
10981 Int_t firstX = xaxis->GetFirst();
10982 Int_t lastX = xaxis->GetLast();
10983 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10984 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10985 xaxis->SetRange(binx,binx2);
10986 Int_t firstZ = zaxis->GetFirst();
10987 Int_t lastZ = zaxis->GetLast();
10988 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10989 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10990 zaxis->SetRange(binz,binz2);
10991 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10992 if (nbins>1 && line1[0].GetX()) {
10993 gVirtualX->DrawPolyLine(2,line2);
10994 gVirtualX->DrawPolyLine(2,line3);
10995 gVirtualX->DrawPolyLine(2,line4);
10996 gVirtualX->DrawPolyLine(5,endface1);
10997 gVirtualX->DrawPolyLine(5,endface2);
10998 }
10999 xx[0]=xaxis->GetBinCenter(binx);
11000 xx[2] = zaxis->GetBinCenter(binz);
11001 xx[1] = yaxis->GetXmin();
11002 view->WCtoNDC(xx,u);
11003 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11004 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11005 xx[1] = yaxis->GetXmax();
11006 view->WCtoNDC(xx,u);
11007 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11008 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11009 gVirtualX->DrawPolyLine(2,line1);
11010 if (nbins>1) {
11011 xx[1] = yaxis->GetXmin();
11012 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11013 xx[0] = xaxis->GetBinCenter(binx);
11014 view->WCtoNDC(xx,u);
11015 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11016 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11017 xx[1] = yaxis->GetXmax();
11018 view->WCtoNDC(xx,u);
11019 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11020 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11021
11022 xx[1] = yaxis->GetXmin();
11023 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11024 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11025 view->WCtoNDC(xx,u);
11026 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11027 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11028 xx[1] = yaxis->GetXmax();
11029 view->WCtoNDC(xx,u);
11030 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11031 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11032
11033 xx[1] = yaxis->GetXmin();
11034 xx[2] = zaxis->GetBinCenter(binz);
11035 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11036 view->WCtoNDC(xx,u);
11037 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11038 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11039 xx[1] = yaxis->GetXmax();
11040 view->WCtoNDC(xx,u);
11041 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11042 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11043
11044 endface1[0].SetX(line1[0].GetX());
11045 endface1[0].SetY(line1[0].GetY());
11046 endface1[1].SetX(line2[0].GetX());
11047 endface1[1].SetY(line2[0].GetY());
11048 endface1[2].SetX(line3[0].GetX());
11049 endface1[2].SetY(line3[0].GetY());
11050 endface1[3].SetX(line4[0].GetX());
11051 endface1[3].SetY(line4[0].GetY());
11052 endface1[4].SetX(line1[0].GetX());
11053 endface1[4].SetY(line1[0].GetY());
11054
11055 endface2[0].SetX(line1[1].GetX());
11056 endface2[0].SetY(line1[1].GetY());
11057 endface2[1].SetX(line2[1].GetX());
11058 endface2[1].SetY(line2[1].GetY());
11059 endface2[2].SetX(line3[1].GetX());
11060 endface2[2].SetY(line3[1].GetY());
11061 endface2[3].SetX(line4[1].GetX());
11062 endface2[3].SetY(line4[1].GetY());
11063 endface2[4].SetX(line1[1].GetX());
11064 endface2[4].SetY(line1[1].GetY());
11065
11066 gVirtualX->DrawPolyLine(2,line2);
11067 gVirtualX->DrawPolyLine(2,line3);
11068 gVirtualX->DrawPolyLine(2,line4);
11069 gVirtualX->DrawPolyLine(5,endface1);
11070 gVirtualX->DrawPolyLine(5,endface2);
11071 }
11072 c->Clear();
11073 c->cd();
11074 TH1 *hp = h3->Project3D("y");
11075 xaxis->SetRange(firstX,lastX);
11076 zaxis->SetRange(firstZ,lastZ);
11077 if (hp) {
11078 hp->SetFillColor(38);
11079 if (nbins == 1)
11080 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11081 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
11082 else
11083 hp->SetTitle(TString::Format("ProjectionY, binx=[%d,%d] [x=%.1f..%.1f], binz=[%d,%d] [z=%.1f..%.1f]", binx, binx2, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx2),
11084 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
11085 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11086 hp->SetYTitle("Number of Entries");
11087 hp->Draw(fShowOption.Data());
11088 }
11089 }
11090 break;
11091
11092 case 3:
11093 // "z"
11094 {
11095 Int_t firstX = xaxis->GetFirst();
11096 Int_t lastX = xaxis->GetLast();
11097 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
11098 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11099 xaxis->SetRange(binx,binx2);
11100 Int_t firstY = yaxis->GetFirst();
11101 Int_t lastY = yaxis->GetLast();
11102 Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
11103 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11104 yaxis->SetRange(biny,biny2);
11105 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
11106 if (nbins>1 && line1[0].GetX()) {
11107 gVirtualX->DrawPolyLine(2,line2);
11108 gVirtualX->DrawPolyLine(2,line3);
11109 gVirtualX->DrawPolyLine(2,line4);
11110 gVirtualX->DrawPolyLine(5,endface1);
11111 gVirtualX->DrawPolyLine(5,endface2);
11112 }
11113 xx[0] = xaxis->GetBinCenter(binx);
11114 xx[1] = yaxis->GetBinCenter(biny);
11115 xx[2] = zaxis->GetXmin();
11116 view->WCtoNDC(xx,u);
11117 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11118 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11119 xx[2] = zaxis->GetXmax();
11120 view->WCtoNDC(xx,u);
11121 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11122 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11123 gVirtualX->DrawPolyLine(2,line1);
11124 if (nbins>1) {
11125 xx[2] = zaxis->GetXmin();
11126 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11127 xx[0] = xaxis->GetBinCenter(binx);
11128 view->WCtoNDC(xx,u);
11129 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11130 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11131 xx[2] = zaxis->GetXmax();
11132 view->WCtoNDC(xx,u);
11133 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11134 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11135
11136 xx[2] = zaxis->GetXmin();
11137 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11138 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11139 view->WCtoNDC(xx,u);
11140 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11141 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11142 xx[2] = zaxis->GetXmax();
11143 view->WCtoNDC(xx,u);
11144 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11145 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11146
11147 xx[2] = zaxis->GetXmin();
11148 xx[1] = yaxis->GetBinCenter(biny);
11149 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11150 view->WCtoNDC(xx,u);
11151 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11152 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11153 xx[2] = zaxis->GetXmax();
11154 view->WCtoNDC(xx,u);
11155 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11156 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11157
11158 endface1[0].SetX(line1[0].GetX());
11159 endface1[0].SetY(line1[0].GetY());
11160 endface1[1].SetX(line2[0].GetX());
11161 endface1[1].SetY(line2[0].GetY());
11162 endface1[2].SetX(line3[0].GetX());
11163 endface1[2].SetY(line3[0].GetY());
11164 endface1[3].SetX(line4[0].GetX());
11165 endface1[3].SetY(line4[0].GetY());
11166 endface1[4].SetX(line1[0].GetX());
11167 endface1[4].SetY(line1[0].GetY());
11168
11169 endface2[0].SetX(line1[1].GetX());
11170 endface2[0].SetY(line1[1].GetY());
11171 endface2[1].SetX(line2[1].GetX());
11172 endface2[1].SetY(line2[1].GetY());
11173 endface2[2].SetX(line3[1].GetX());
11174 endface2[2].SetY(line3[1].GetY());
11175 endface2[3].SetX(line4[1].GetX());
11176 endface2[3].SetY(line4[1].GetY());
11177 endface2[4].SetX(line1[1].GetX());
11178 endface2[4].SetY(line1[1].GetY());
11179
11180 gVirtualX->DrawPolyLine(2,line2);
11181 gVirtualX->DrawPolyLine(2,line3);
11182 gVirtualX->DrawPolyLine(2,line4);
11183 gVirtualX->DrawPolyLine(5,endface1);
11184 gVirtualX->DrawPolyLine(5,endface2);
11185 }
11186 c->Clear();
11187 c->cd();
11188 TH1 *hp = h3->Project3D("z");
11189 xaxis->SetRange(firstX,lastX);
11190 yaxis->SetRange(firstY,lastY);
11191 if (hp) {
11192 hp->SetFillColor(38);
11193 if (nbins == 1)
11194 hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11195 biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
11196 else
11197 hp->SetTitle(TString::Format("ProjectionZ, binx=[%d,%d] [x=%.1f..%.1f], biny=[%d,%d] [y=%.1f..%.1f]", binx, binx2, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx2),
11198 biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
11199 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11200 hp->SetYTitle("Number of Entries");
11201 hp->Draw(fShowOption.Data());
11202 }
11203 }
11204 break;
11205
11206 case 4:
11207 // "xy"
11208 {
11209 Int_t first = zaxis->GetFirst();
11210 Int_t last = zaxis->GetLast();
11211 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11212 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11213 zaxis->SetRange(binz,binz2);
11214 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11215 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11216 xx[0] = xaxis->GetXmin();
11217 xx[1] = yaxis->GetXmax();
11218 xx[2] = zaxis->GetBinCenter(binz);
11219 view->WCtoNDC(xx,u);
11220 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11221 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11222 rect1[4].SetX(rect1[0].GetX());
11223 rect1[4].SetY(rect1[0].GetY());
11224 xx[0] = xaxis->GetXmax();
11225 view->WCtoNDC(xx,u);
11226 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11227 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11228 xx[1] = yaxis->GetXmin();
11229 view->WCtoNDC(xx,u);
11230 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11231 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11232 xx[0] = xaxis->GetXmin();
11233 view->WCtoNDC(xx,u);
11234 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11235 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11236 gVirtualX->DrawPolyLine(5,rect1);
11237 if (nbins>1) {
11238 xx[0] = xaxis->GetXmin();
11239 xx[1] = yaxis->GetXmax();
11240 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11241 view->WCtoNDC(xx,u);
11242 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11243 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11244 rect2[4].SetX(rect2[0].GetX());
11245 rect2[4].SetY(rect2[0].GetY());
11246 xx[0] = xaxis->GetXmax();
11247 view->WCtoNDC(xx,u);
11248 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11249 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11250 xx[1] = yaxis->GetXmin();
11251 view->WCtoNDC(xx,u);
11252 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11253 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11254 xx[0] = xaxis->GetXmin();
11255 view->WCtoNDC(xx,u);
11256 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11257 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11258 gVirtualX->DrawPolyLine(5,rect2);
11259 }
11260
11261 c->Clear();
11262 c->cd();
11263 TH2 *hp = (TH2*)h3->Project3D("xy");
11264 zaxis->SetRange(first,last);
11265 if (hp) {
11266 hp->SetFillColor(38);
11267 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11268 else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11269 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11270 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11271 hp->SetZTitle("Number of Entries");
11272 hp->Draw(fShowOption.Data());
11273 }
11274 }
11275 break;
11276
11277 case 5:
11278 // "yx"
11279 {
11280 Int_t first = zaxis->GetFirst();
11281 Int_t last = zaxis->GetLast();
11282 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11283 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11284 zaxis->SetRange(binz,binz2);
11285 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11286 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11287 xx[0] = xaxis->GetXmin();
11288 xx[1] = yaxis->GetXmax();
11289 xx[2] = zaxis->GetBinCenter(binz);
11290 view->WCtoNDC(xx,u);
11291 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11292 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11293 rect1[4].SetX(rect1[0].GetX());
11294 rect1[4].SetY(rect1[0].GetY());
11295 xx[0] = xaxis->GetXmax();
11296 view->WCtoNDC(xx,u);
11297 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11298 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11299 xx[1] = yaxis->GetXmin();
11300 view->WCtoNDC(xx,u);
11301 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11302 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11303 xx[0] = xaxis->GetXmin();
11304 view->WCtoNDC(xx,u);
11305 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11306 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11307 gVirtualX->DrawPolyLine(5,rect1);
11308 if (nbins>1) {
11309 xx[0] = xaxis->GetXmin();
11310 xx[1] = yaxis->GetXmax();
11311 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11312 view->WCtoNDC(xx,u);
11313 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11314 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11315 rect2[4].SetX(rect2[0].GetX());
11316 rect2[4].SetY(rect2[0].GetY());
11317 xx[0] = xaxis->GetXmax();
11318 view->WCtoNDC(xx,u);
11319 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11320 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11321 xx[1] = yaxis->GetXmin();
11322 view->WCtoNDC(xx,u);
11323 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11324 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11325 xx[0] = xaxis->GetXmin();
11326 view->WCtoNDC(xx,u);
11327 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11328 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11329 gVirtualX->DrawPolyLine(5,rect2);
11330 }
11331 c->Clear();
11332 c->cd();
11333 TH2 *hp = (TH2*)h3->Project3D("yx");
11334 zaxis->SetRange(first,last);
11335 if (hp) {
11336 hp->SetFillColor(38);
11337 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11338 else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11339 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11340 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11341 hp->SetZTitle("Number of Entries");
11342 hp->Draw(fShowOption.Data());
11343 }
11344 }
11345 break;
11346
11347 case 6:
11348 // "xz"
11349 {
11350 Int_t first = yaxis->GetFirst();
11351 Int_t last = yaxis->GetLast();
11352 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11353 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11354 yaxis->SetRange(biny,biny2);
11355 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11356 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11357 xx[0] = xaxis->GetXmin();
11358 xx[2] = zaxis->GetXmax();
11359 xx[1] = yaxis->GetBinCenter(biny);
11360 view->WCtoNDC(xx,u);
11361 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11362 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11363 rect1[4].SetX(rect1[0].GetX());
11364 rect1[4].SetY(rect1[0].GetY());
11365 xx[0] = xaxis->GetXmax();
11366 view->WCtoNDC(xx,u);
11367 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11368 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11369 xx[2] = zaxis->GetXmin();
11370 view->WCtoNDC(xx,u);
11371 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11372 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11373 xx[0] = xaxis->GetXmin();
11374 view->WCtoNDC(xx,u);
11375 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11376 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11377 gVirtualX->DrawPolyLine(5,rect1);
11378 if (nbins>1) {
11379 xx[0] = xaxis->GetXmin();
11380 xx[2] = zaxis->GetXmax();
11381 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11382 view->WCtoNDC(xx,u);
11383 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11384 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11385 rect2[4].SetX(rect2[0].GetX());
11386 rect2[4].SetY(rect2[0].GetY());
11387 xx[0] = xaxis->GetXmax();
11388 view->WCtoNDC(xx,u);
11389 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11390 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11391 xx[2] = zaxis->GetXmin();
11392 view->WCtoNDC(xx,u);
11393 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11394 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11395 xx[0] = xaxis->GetXmin();
11396 view->WCtoNDC(xx,u);
11397 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11398 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11399 gVirtualX->DrawPolyLine(5,rect2);
11400 }
11401 c->Clear();
11402 c->cd();
11403 TH2 *hp = (TH2*)h3->Project3D("xz");
11404 yaxis->SetRange(first,last);
11405 if (hp) {
11406 hp->SetFillColor(38);
11407 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11408 else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11409 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11410 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11411 hp->SetZTitle("Number of Entries");
11412 hp->Draw(fShowOption.Data());
11413 }
11414 }
11415 break;
11416
11417 case 7:
11418 // "zx"
11419 {
11420 Int_t first = yaxis->GetFirst();
11421 Int_t last = yaxis->GetLast();
11422 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11423 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11424 yaxis->SetRange(biny,biny2);
11425 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11426 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11427 xx[0] = xaxis->GetXmin();
11428 xx[2] = zaxis->GetXmax();
11429 xx[1] = yaxis->GetBinCenter(biny);
11430 view->WCtoNDC(xx,u);
11431 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11432 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11433 rect1[4].SetX(rect1[0].GetX());
11434 rect1[4].SetY(rect1[0].GetY());
11435 xx[0] = xaxis->GetXmax();
11436 view->WCtoNDC(xx,u);
11437 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11438 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11439 xx[2] = zaxis->GetXmin();
11440 view->WCtoNDC(xx,u);
11441 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11442 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11443 xx[0] = xaxis->GetXmin();
11444 view->WCtoNDC(xx,u);
11445 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11446 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11447 gVirtualX->DrawPolyLine(5,rect1);
11448 if (nbins>1) {
11449 xx[0] = xaxis->GetXmin();
11450 xx[2] = zaxis->GetXmax();
11451 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11452 view->WCtoNDC(xx,u);
11453 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11454 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11455 rect2[4].SetX(rect2[0].GetX());
11456 rect2[4].SetY(rect2[0].GetY());
11457 xx[0] = xaxis->GetXmax();
11458 view->WCtoNDC(xx,u);
11459 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11460 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11461 xx[2] = zaxis->GetXmin();
11462 view->WCtoNDC(xx,u);
11463 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11464 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11465 xx[0] = xaxis->GetXmin();
11466 view->WCtoNDC(xx,u);
11467 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11468 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11469 gVirtualX->DrawPolyLine(5,rect2);
11470 }
11471 c->Clear();
11472 c->cd();
11473 TH2 *hp = (TH2*)h3->Project3D("zx");
11474 yaxis->SetRange(first,last);
11475 if (hp) {
11476 hp->SetFillColor(38);
11477 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11478 else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11479 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11480 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11481 hp->SetZTitle("Number of Entries");
11482 hp->Draw(fShowOption.Data());
11483 }
11484 }
11485 break;
11486
11487 case 8:
11488 // "yz"
11489 {
11490 Int_t first = xaxis->GetFirst();
11491 Int_t last = xaxis->GetLast();
11492 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11493 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11494 xaxis->SetRange(binx,binx2);
11495 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11496 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11497 xx[2] = zaxis->GetXmin();
11498 xx[1] = yaxis->GetXmax();
11499 xx[0] = xaxis->GetBinCenter(binx);
11500 view->WCtoNDC(xx,u);
11501 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11502 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11503 rect1[4].SetX(rect1[0].GetX());
11504 rect1[4].SetY(rect1[0].GetY());
11505 xx[2] = zaxis->GetXmax();
11506 view->WCtoNDC(xx,u);
11507 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11508 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11509 xx[1] = yaxis->GetXmin();
11510 view->WCtoNDC(xx,u);
11511 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11512 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11513 xx[2] = zaxis->GetXmin();
11514 view->WCtoNDC(xx,u);
11515 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11516 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11517 gVirtualX->DrawPolyLine(5,rect1);
11518 if (nbins>1) {
11519 xx[2] = zaxis->GetXmin();
11520 xx[1] = yaxis->GetXmax();
11521 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11522 view->WCtoNDC(xx,u);
11523 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11524 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11525 rect2[4].SetX(rect2[0].GetX());
11526 rect2[4].SetY(rect2[0].GetY());
11527 xx[2] = zaxis->GetXmax();
11528 view->WCtoNDC(xx,u);
11529 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11530 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11531 xx[1] = yaxis->GetXmin();
11532 view->WCtoNDC(xx,u);
11533 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11534 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11535 xx[2] = zaxis->GetXmin();
11536 view->WCtoNDC(xx,u);
11537 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11538 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11539 gVirtualX->DrawPolyLine(5,rect2);
11540 }
11541 c->Clear();
11542 c->cd();
11543 TH2 *hp = (TH2*)h3->Project3D("yz");
11544 xaxis->SetRange(first,last);
11545 if (hp) {
11546 hp->SetFillColor(38);
11547 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11548 else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11549 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11550 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11551 hp->SetZTitle("Number of Entries");
11552 hp->Draw(fShowOption.Data());
11553 }
11554 }
11555 break;
11556
11557 case 9:
11558 // "zy"
11559 {
11560 Int_t first = xaxis->GetFirst();
11561 Int_t last = xaxis->GetLast();
11562 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11563 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11564 xaxis->SetRange(binx,binx2);
11565 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11566 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11567 xx[2] = zaxis->GetXmin();
11568 xx[1] = yaxis->GetXmax();
11569 xx[0] = xaxis->GetBinCenter(binx);
11570 view->WCtoNDC(xx,u);
11571 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11572 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11573 rect1[4].SetX(rect1[0].GetX());
11574 rect1[4].SetY(rect1[0].GetY());
11575 xx[2] = zaxis->GetXmax();
11576 view->WCtoNDC(xx,u);
11577 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11578 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11579 xx[1] = yaxis->GetXmin();
11580 view->WCtoNDC(xx,u);
11581 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11582 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11583 xx[2] = zaxis->GetXmin();
11584 view->WCtoNDC(xx,u);
11585 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11586 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11587 gVirtualX->DrawPolyLine(5,rect1);
11588 if (nbins>1) {
11589 xx[2] = zaxis->GetXmin();
11590 xx[1] = yaxis->GetXmax();
11591 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11592 view->WCtoNDC(xx,u);
11593 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11594 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11595 rect2[4].SetX(rect2[0].GetX());
11596 rect2[4].SetY(rect2[0].GetY());
11597 xx[2] = zaxis->GetXmax();
11598 view->WCtoNDC(xx,u);
11599 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11600 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11601 xx[1] = yaxis->GetXmin();
11602 view->WCtoNDC(xx,u);
11603 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11604 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11605 xx[2] = zaxis->GetXmin();
11606 view->WCtoNDC(xx,u);
11607 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11608 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11609 gVirtualX->DrawPolyLine(5,rect2);
11610 }
11611 c->Clear();
11612 c->cd();
11613 TH2 *hp = (TH2*)h3->Project3D("zy");
11614 xaxis->SetRange(first,last);
11615 if (hp) {
11616 hp->SetFillColor(38);
11617 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11618 else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11619 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11620 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11621 hp->SetZTitle("Number of Entries");
11622 hp->Draw(fShowOption.Data());
11623 }
11624 }
11625 break;
11626 }
11627 c->Update();
11628 padsav->cd();
11629}
@ kMouseMotion
Definition: Buttons.h:23
@ kWheelUp
Definition: Buttons.h:18
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kWheelDown
Definition: Buttons.h:18
@ kButton1Down
Definition: Buttons.h:17
@ kButton1Locate
Definition: Buttons.h:22
void Class()
Definition: Class.C:29
Handle_t Window_t
Definition: GuiTypes.h:28
ROOT::R::TRInterface & r
Definition: Object.C:4
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
short Width_t
Definition: RtypesCore.h:78
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
double Double_t
Definition: RtypesCore.h:55
short Color_t
Definition: RtypesCore.h:79
short Style_t
Definition: RtypesCore.h:76
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define BIT(n)
Definition: Rtypes.h:83
#define ClassImp(name)
Definition: Rtypes.h:365
@ kBlack
Definition: Rtypes.h:63
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
XFontStruct * id
Definition: TGX11.cxx:108
float xmin
Definition: THbookFile.cxx:93
int ncx
Definition: THbookFile.cxx:91
float ymin
Definition: THbookFile.cxx:93
int ncy
Definition: THbookFile.cxx:91
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
static TBox * gYHighlightBox
static TString gStringStdDevZ
static TString gStringStdDevX
static TString gStringIntegralBinWidth
const UInt_t kCannotRotate
static TString gStringStdDev
const Int_t kNMAX
Hparam_t Hparam
const Int_t kMAXCONTOUR
static TBox * gXHighlightBox
static TString gStringOverflow
static TString gStringUnderflow
static TString gStringSkewnessY
static TString gStringMean
static TString gStringKurtosis
Hoption_t Hoption
static TString gStringMeanX
static TString gStringEntries
static TString gStringIntegral
static TString gStringKurtosisY
static TString gStringStdDevY
static TString gStringMeanY
static TString gStringSkewnessX
static TString gStringKurtosisX
static TString gStringSkewnessZ
TH1 * gCurrentHist
static TString gStringMeanZ
static TString gStringSkewness
static TString gStringKurtosisZ
const Int_t kMaxCuts
Definition: THistPainter.h:38
double cos(double)
const Int_t kCYLINDRICAL
const Int_t kSPHERICAL
const Int_t kRAPIDITY
#define gROOT
Definition: TROOT.h:415
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:407
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
const Int_t kCARTESIAN
Definition: TView3D.cxx:32
const Int_t kPOLAR
Definition: TView3D.cxx:33
#define gPad
Definition: TVirtualPad.h:286
#define gVirtualX
Definition: TVirtualX.h:345
@ kArrowVer
Definition: TVirtualX.h:46
@ kPointer
Definition: TVirtualX.h:47
polygon * polys
Definition: X3DBuffer.c:24
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3728
Int_t fN
Definition: TArray.h:38
Draw all kinds of Arrows.
Definition: TArrow.h:29
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:45
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:43
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual void SetImageQuality(EImageQuality lquality)
Definition: TAttImage.h:99
@ kImgBest
Definition: TAttImage.h:68
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
virtual Font_t GetTextFont() const
Return the text font.
Definition: TAttText.h:35
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:42
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
const TArrayD * GetXbins() const
Definition: TAxis.h:130
Double_t GetXmax() const
Definition: TAxis.h:134
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition: TAxis.cxx:426
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
const char * ChooseTimeFormat(Double_t axislength=0)
Choose a reasonable time format from the coordinates in the active pad and the number of divisions in...
Definition: TAxis.cxx:124
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:557
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void SetRangeUser(Double_t ufirst, Double_t ulast)
Set the viewing range for the axis from ufirst to ulast (in user coordinates).
Definition: TAxis.cxx:928
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:129
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:903
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
THashList * GetLabels() const
Definition: TAxis.h:117
Create a Box.
Definition: TBox.h:24
Double_t GetX1() const
Definition: TBox.h:52
virtual void SetY2(Double_t y2)
Definition: TBox.h:66
Double_t GetX2() const
Definition: TBox.h:53
Double_t GetY1() const
Definition: TBox.h:54
virtual void SetX1(Double_t x1)
Definition: TBox.h:63
Double_t GetY2() const
Definition: TBox.h:55
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition: TBox.cxx:194
virtual void SetX2(Double_t x2)
Definition: TBox.h:64
virtual void SetY1(Double_t y1)
Definition: TBox.h:65
virtual void Paint(Option_t *option="")
Paint this box with its current attributes.
Definition: TBox.cxx:668
The candle plot painter class.
Definition: TCandle.h:25
void SetLog(int x, int y, int z)
Definition: TCandle.h:122
CandleOption
Definition: TCandle.h:28
void SetHistoWidth(const Double_t width)
Definition: TCandle.h:126
virtual void Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition: TCandle.cxx:674
Bool_t IsViolinScaled()
Definition: TCandle.cxx:190
Bool_t IsHorizontal()
Definition: TCandle.h:116
int ParseOption(char *optin)
Parsing of the option-string.
Definition: TCandle.cxx:244
void SetOption(CandleOption opt)
Definition: TCandle.h:121
void SetHistogram(TH1D *proj)
Definition: TCandle.h:127
Bool_t IsCandleScaled()
Definition: TCandle.cxx:185
void SetCandleWidth(const Double_t width)
Definition: TCandle.h:125
void SetAxisPosition(const Double_t candlePos)
Definition: TCandle.h:123
static Bool_t SupportAlpha()
Static function returning "true" if transparency is supported.
Definition: TCanvas.cxx:2326
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2906
void SetName(const char *name)
Definition: TCollection.h:204
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
The color creation and management class.
Definition: TColor.h:19
virtual void SetRGB(Float_t r, Float_t g, Float_t b)
Initialize this color and its associated colors.
Definition: TColor.cxx:1702
static void RGBtoHLS(Float_t r, Float_t g, Float_t b, Float_t &h, Float_t &l, Float_t &s)
Definition: TColor.h:78
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:51
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition: TColor.cxx:1764
static Int_t GetColorBright(Int_t color)
Static function: Returns the bright color number corresponding to n If the TColor object does not exi...
Definition: TColor.cxx:1903
static Int_t GetColorDark(Int_t color)
Static function: Returns the dark color number corresponding to n If the TColor object does not exist...
Definition: TColor.cxx:1935
static void HLStoRGB(Float_t h, Float_t l, Float_t s, Float_t &r, Float_t &g, Float_t &b)
Definition: TColor.h:73
virtual void SetAlpha(Float_t a)
Definition: TColor.h:67
To draw a Crown.
Definition: TCrown.h:19
virtual void Paint(Option_t *option="")
Paint this crown with its current attributes.
Definition: TCrown.cxx:181
Graphical cut class.
Definition: TCutG.h:20
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
1-Dim function class
Definition: TF1.h:211
virtual Double_t GetXmax() const
Definition: TF1.h:550
virtual Int_t GetNDF() const
Return the number of degrees of freedom in the fit the fNDF parameter has been previously computed du...
Definition: TF1.cxx:1869
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1920
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1910
Double_t GetChisquare() const
Definition: TF1.h:438
virtual void SetMaximum(Double_t maximum=-1111)
Set the maximum value along Y for this function In case the function is already drawn,...
Definition: TF1.cxx:3393
virtual Double_t GetMaximumStored() const
Definition: TF1.h:467
virtual Int_t GetNpar() const
Definition: TF1.h:475
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1880
@ kNotDraw
Definition: TF1.h:321
virtual void SetMinimum(Double_t minimum=-1111)
Set the minimum value along Y for this function In case the function is already drawn,...
Definition: TF1.cxx:3406
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:523
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition: TF1.cxx:1429
virtual Double_t GetXmin() const
Definition: TF1.h:546
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:506
A 2-Dim function with parameters.
Definition: TF2.h:29
virtual void Paint(Option_t *option="")
Paint this 2-D function with its current attributes.
Definition: TF2.cxx:722
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:150
A 3-Dim function with parameters.
Definition: TF3.h:28
The axis painter class.
Definition: TGaxis.h:24
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2723
virtual void PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt="", Double_t gridlength=0, Bool_t drawGridOnly=kFALSE)
Control function to draw an axis.
Definition: TGaxis.cxx:956
void SetTitleOffset(Float_t titleoffset=1)
Definition: TGaxis.h:125
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition: TGaxis.cxx:2696
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:107
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition: TGaxis.cxx:906
void SetTickSize(Float_t ticksize)
Definition: TGaxis.h:119
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:108
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2688
The TGraphDelaunay painting class.
void Paint(Option_t *option)
Paint a TGraphDelaunay according to the value of "option":
TList * GetContourList(Double_t contour)
Returns the X and Y graphs building a contour.
TGraphDelaunay2D generates a Delaunay triangulation of a TGraph2D.
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
@ kClipFrame
clip to the frame boundary
Definition: TGraph.h:70
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6333
TAxis * GetZaxis()
Definition: TH1.h:318
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:268
virtual Float_t GetBarWidth() const
Definition: TH1.h:252
virtual Double_t GetMinimumStored() const
Definition: TH1.h:288
virtual Float_t GetBarOffset() const
Definition: TH1.h:251
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:7128
virtual Int_t GetNbinsY() const
Definition: TH1.h:293
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8507
virtual Int_t GetNbinsZ() const
Definition: TH1.h:294
virtual Double_t GetNormFactor() const
Definition: TH1.h:296
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:7074
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7180
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7892
virtual void SetXTitle(const char *title)
Definition: TH1.h:409
virtual Int_t GetDimension() const
Definition: TH1.h:278
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1226
@ kNoTitle
don't draw the histogram title
Definition: TH1.h:165
@ kUserContour
user specified contour levels
Definition: TH1.h:161
@ kNoStats
don't draw stats box
Definition: TH1.h:160
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition: TH1.cxx:4801
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7994
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
TAxis * GetYaxis()
Definition: TH1.h:317
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8523
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7935
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7438
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8666
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8596
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4294
virtual void SetZTitle(const char *title)
Definition: TH1.h:411
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:7105
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2998
virtual Double_t GetMaximumStored() const
Definition: TH1.h:284
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:8175
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:8024
@ kNormal
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4899
const Double_t * GetBuffer() const
Definition: TH1.h:234
virtual Bool_t IsHighlight() const
Definition: TH1.h:330
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8607
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8554
virtual void SetYTitle(const char *title)
Definition: TH1.h:410
virtual Int_t GetSumw2N() const
Definition: TH1.h:310
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7167
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:8079
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7414
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:706
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7863
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1347
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7250
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:292
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
TH1D * ProjectionY(const char *name="_py", Int_t firstxbin=0, Int_t lastxbin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along Y.
Definition: TH2.cxx:2301
TH1D * ProjectionX(const char *name="_px", Int_t firstybin=0, Int_t lastybin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along X.
Definition: TH2.cxx:2261
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH2.cxx:1149
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH2.h:88
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH3.cxx:1158
virtual TH1 * Project3D(Option_t *option="x") const
Project a 3-d histogram into 1 or 2-d histograms depending on the option parameter,...
Definition: TH3.cxx:2172
The histogram painter class.
Definition: THistPainter.h:47
static Int_t ProjectSinusoidal2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
virtual Bool_t IsInside(Int_t x, Int_t y)
Return kTRUE if the cell ix, iy is inside one of the graphical cuts.
TAxis * fYaxis
Definition: THistPainter.h:52
Double_t * fXbuf
Definition: THistPainter.h:58
Int_t fXHighlightBin
Definition: THistPainter.h:66
virtual void DrawPanel()
Display a panel with all histogram drawing options.
virtual void PaintErrors(Option_t *option)
Draw 1D histograms error bars.
virtual void SetHistogram(TH1 *h)
Set current histogram to h
virtual void PaintTF3()
Control function to draw a 3D implicit functions.
virtual void PaintStat(Int_t dostat, TF1 *fit)
Draw the statistics box for 1D and profile histograms.
virtual Int_t TableInit()
Initialize various options to draw 2D histograms.
virtual void PaintTH2PolyScatterPlot(Option_t *option)
Control function to draw a TH2Poly as a scatter plot.
static Int_t ProjectAitoff2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void PaintText(Option_t *option)
Control function to draw a 1D/2D histograms with the bin values.
virtual void PaintAxis(Bool_t drawGridOnly=kFALSE)
Draw axis (2D case) of an histogram.
virtual void PaintColorLevelsFast(Option_t *option)
[Rendering scheme for the COL2 and COLZ2 options] (#HP14)
virtual Int_t PaintInit()
Compute histogram parameters used by the drawing routines.
virtual void Paint2DErrors(Option_t *option)
Draw 2D histograms errors.
Int_t fYHighlightBin
Definition: THistPainter.h:67
virtual void PaintCandlePlot(Option_t *option)
Control function to draw a 2D histogram as a candle (box) plot or violin plot
virtual void PaintScatterPlot(Option_t *option)
Control function to draw a 2D histogram as a scatter plot.
virtual ~THistPainter()
Default destructor.
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Display the histogram info (bin number, contents, integral up to bin corresponding to cursor position...
virtual void PaintLego(Option_t *option)
Control function to draw a 2D histogram as a lego plot.
virtual void PaintH3(Option_t *option="")
Control function to draw a 3D histograms.
TString fShowOption
Definition: THistPainter.h:65
virtual void PaintHighlightBin(Option_t *option="")
Paint highlight bin as TBox object.
virtual void PaintTH2PolyBins(Option_t *option)
Control function to draw a TH2Poly bins' contours.
virtual Int_t PaintContourLine(Double_t elev1, Int_t icont1, Double_t x1, Double_t y1, Double_t elev2, Int_t icont2, Double_t x2, Double_t y2, Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
Fill the matrix xarr and yarr for Contour Plot.
Int_t fShowProjection
Definition: THistPainter.h:64
virtual void PaintLegoAxis(TGaxis *axis, Double_t ang)
Draw the axis for legos and surface plots.
virtual void PaintTriangles(Option_t *option)
Control function to draw a table using Delaunay triangles.
virtual void HighlightBin(Int_t px, Int_t py)
Check on highlight bin.
virtual void PaintH3Box(Int_t iopt)
Control function to draw a 3D histogram with boxes.
TList * fFunctions
Definition: THistPainter.h:54
static void PaintSpecialObjects(const TObject *obj, Option_t *option)
Static function to paint special objects like vectors and matrices.
virtual void PaintTitle()
Draw the histogram title.
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
virtual std::vector< THistRenderingRegion > ComputeRenderingRegions(TAxis *pAxis, Int_t nPixels, bool isLog)
Returns the rendering regions for an axis to use in the COL2 option.
virtual void ShowProjectionX(Int_t px, Int_t py)
Show projection onto X.
virtual void PaintPalette()
Paint the color palette on the right side of the pad.
virtual void ProcessMessage(const char *mess, const TObject *obj)
Process message mess.
Double_t * fYbuf
Definition: THistPainter.h:59
TAxis * fXaxis
Definition: THistPainter.h:51
virtual void PaintStat2(Int_t dostat, TF1 *fit)
Draw the statistics box for 2D histograms.
virtual void PaintArrows(Option_t *option)
Control function to draw a table as an arrow plot
virtual void RecalculateRange()
Recompute the histogram range following graphics operations.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance from the point px,py to a line.
static Int_t ProjectParabolic2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:55
virtual void PaintBarH(Option_t *option)
Draw a bar char in a rotated pad (X vertical, Y horizontal)
virtual void PaintStat3(Int_t dostat, TF1 *fit)
Draw the statistics box for 3D histograms.
virtual void PaintSurface(Option_t *option)
Control function to draw a 2D histogram as a surface plot.
TList * fStack
Definition: THistPainter.h:63
TGraph2DPainter * fGraph2DPainter
Definition: THistPainter.h:56
THistPainter()
Default constructor.
virtual void PaintTH2PolyText(Option_t *option)
Control function to draw a TH2Poly as a text plot.
virtual void ShowProjection3(Int_t px, Int_t py)
Show projection (specified by fShowProjection) of a TH3.
TAxis * fZaxis
Definition: THistPainter.h:53
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms
virtual void PaintFunction(Option_t *option)
[Paint functions associated to an histogram.](#HP28")
virtual void PaintBar(Option_t *option)
Draw a bar-chart in a normal pad.
static Int_t ProjectMercator2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void PaintBoxes(Option_t *option)
Control function to draw a 2D histogram as a box plot
virtual Int_t MakeChopt(Option_t *option)
Decode string choptin and fill Hoption structure.
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute the actions corresponding to event.
virtual void SetShowProjection(const char *option, Int_t nbins)
Set projection.
virtual void ShowProjectionY(Int_t px, Int_t py)
Show projection onto Y.
virtual void SetHighlight()
Set highlight (enable/disable) mode for fH.
static const char * GetBestFormat(Double_t v, Double_t e, const char *f)
This function returns the best format to print the error value (e) knowing the parameter value (v) an...
virtual void PaintContour(Option_t *option)
Control function to draw a 2D histogram as a contour plot.
TCutG * fCuts[kMaxCuts]
Definition: THistPainter.h:62
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
virtual TList * GetContourList(Double_t contour) const
Get a contour (as a list of TGraphs) using the Delaunay triangulation.
virtual Int_t PaintInitH()
Compute histogram parameters used by the drawing routines for a rotated pad.
virtual void PaintFrame()
Calculate range and clear pad (canvas).
Int_t fCutsOpt[kMaxCuts]
Definition: THistPainter.h:61
virtual void PaintH3Iso()
Control function to draw a 3D histogram with Iso Surfaces.
virtual void PaintH3BoxRaster()
Control function to draw a 3D histogram with boxes.
virtual void PaintHist(Option_t *option)
Control routine to draw 1D histograms
virtual Int_t MakeCuts(char *cutsopt)
Decode string choptin and fill Graphical cuts structure.
virtual void DefineColorLevels(Int_t ndivz)
Define the color levels used to paint legos, surfaces etc..
TString fObjectInfo
Definition: THistPainter.h:70
virtual void PaintColorLevels(Option_t *option)
Control function to draw a 2D histogram as a color plot.
A class to define a conversion from pixel values to pixel color.
Definition: TAttImage.h:33
static TImagePalette * CreateCOLPalette(Int_t nContours)
Factory method to creates an image palette for histogram plotting.
Definition: TAttImage.cxx:748
An abstract interface to image processing library.
Definition: TImage.h:29
virtual void SetImage(const Double_t *, UInt_t, UInt_t, TImagePalette *=0)
Definition: TImage.h:116
static TImage * Create()
Create an image.
Definition: TImage.cxx:36
virtual void PaintImage(Drawable_t, Int_t, Int_t, Int_t=0, Int_t=0, UInt_t=0, UInt_t=0, Option_t *="")
Definition: TImage.h:243
void Reset()
Definition: TCollection.h:252
To draw Mathematical Formula.
Definition: TLatex.h:18
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:97
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:656
Linear Algebra Package.
Definition: TMatrixTBase.h:85
TClass * Class()
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:35
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
void Add(TObject *obj)
Definition: TObjArray.h:74
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:341
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:169
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
@ kCannotPick
if object in a pad cannot be picked
Definition: TObject.h:63
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
The Legos and Surfaces painter class.
void DrawFaceMove3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 3rd variant for "MOVING SCREEN" algorithm (draw level lines only)
void SetDrawFace(DrawFaceFunc_t pointer)
Store pointer to current algorithm to draw faces.
void SetIsoSurfaceParameters(Double_t fmin, Double_t fmax, Int_t ncolor, Int_t ic1, Int_t ic2, Int_t ic3)
void IsoSurface(Int_t ns, Double_t *s, Int_t nx, Int_t ny, Int_t nz, Double_t *x, Double_t *y, Double_t *z, const char *chopt)
Draw set of iso-surfaces for a scalar function defined on a grid.
void DrawLevelLines(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw level lines without hidden line removal.
void ImplicitFunction(Double_t *rmin, Double_t *rmax, Int_t nx, Int_t ny, Int_t nz, const char *chopt)
Draw implicit function FUN(X,Y,Z) = 0 in cartesian coordinates using hidden surface removal algorithm...
void SetLegoFunction(LegoFunc_t pointer)
Store pointer to current lego function.
void SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in cylindrical coordinates.
void SurfaceFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Service function for Surfaces.
void LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in cylindrical coordinates.
void FillPolygonBorder(Int_t nn, Double_t *xy)
Fill a polygon including border ("RASTER SCREEN")
void LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots spheric coordinates.
void SurfaceCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw surface in cartesian coordinate system.
static void SetF3ClippingBoxOff()
Static function Set the implicit function clipping box "off".
void SurfaceProperty(Double_t qqa, Double_t qqd, Double_t qqs, Int_t nnqs, Int_t &irep)
Set surface property coefficients.
void InitMoveScreen(Double_t xmin, Double_t xmax)
Initialize "MOVING SCREEN" method.
void FindVisibleLine(Double_t *p1, Double_t *p2, Int_t ntmax, Int_t &nt, Double_t *t)
Find visible part of a line ("RASTER SCREEN")
void LegoCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw stack of lego-plots in cartesian coordinates.
void DrawFaceMode1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 1st variant (2 colors: 1st for external surface, 2nd for internal)
void LightSource(Int_t nl, Double_t yl, Double_t xscr, Double_t yscr, Double_t zscr, Int_t &irep)
Set light source.
void GouraudFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Find part of surface with luminosity in the corners.
void DrawFaceMove1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "MOVING SCREEN" algorithm (draw face with level lines)
void SetSurfaceFunction(SurfaceFunc_t pointer)
Store pointer to current surface function.
void SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in polar coordinates.
static void SetF3ClippingBoxOn(Double_t xclip, Double_t yclip, Double_t zclip)
Static function Set the implicit function clipping box "on" and define the clipping box.
void SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in spheric coordinates.
void BackBox(Double_t ang)
Draw back surfaces of surrounding box.
void ColorFunction(Int_t nl, Double_t *fl, Int_t *icl, Int_t &irep)
Set correspondence between function and color levels.
void DrawFaceRaster2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 2nd variant for "RASTER SCREEN" algorithm (draw face for stacked lego plot)
static void SetF3(TF3 *f3)
Static function Store pointer to current implicit function.
void LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in polar coordinates.
void SetEdgeAtt(Color_t color=1, Style_t style=1, Width_t width=1, Int_t n=0)
void SetMesh(Int_t mesh=1)
void InitRaster(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Int_t nx, Int_t ny)
Initialize hidden lines removal algorithm (RASTER SCREEN)
void DefineGridLevels(Int_t ndivz)
Define the grid levels drawn in the background of surface and lego plots.
void LegoFunction(Int_t ia, Int_t ib, Int_t &nv, Double_t *ab, Double_t *vv, Double_t *t)
Service function for Legos.
void DrawFaceMove2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 2nd variant for "MOVING SCREEN" algorithm (draw face for stacked lego plot)
void SetColorMain(Color_t color, Int_t n=0)
Store color for stack number n.
void Spectrum(Int_t nl, Double_t fmin, Double_t fmax, Int_t ic, Int_t idc, Int_t &irep)
Set Spectrum.
void DrawFaceRaster1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "RASTER SCREEN" algorithm (draw face with level lines)
void DrawFaceMode3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 3rd option (draw face for stacked lego plot)
void FrontBox(Double_t ang)
Draw front surfaces of surrounding box & axes.
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
void DrawFaceMode2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 2nd option (fill in correspondence with function levels)
The palette painting class.
Definition: TPaletteAxis.h:29
void SetHistogram(TH1 *h)
Definition: TPaletteAxis.h:57
virtual void Paint(Option_t *option="")
Paint the palette.
TH1 * GetHistogram()
Definition: TPaletteAxis.h:51
The histogram statistics painter class.
Definition: TPaveStats.h:18
Int_t GetOptStat() const
Return the stat option.
Definition: TPaveStats.cxx:265
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:311
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:302
virtual void SetParent(TObject *obj)
Definition: TPaveStats.h:52
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:35
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:285
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:256
virtual void Paint(Option_t *option="")
Paint the pave stat.
Definition: TPaveStats.cxx:319
void SetOptFit(Int_t fit=1)
Set the fit option.
Definition: TPaveStats.cxx:293
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:36
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:182
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:233
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:410
virtual TText * GetLine(Int_t number) const
Get Pointer to line number in this pavetext.
Definition: TPaveText.cxx:274
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:208
virtual void SetName(const char *name="")
Definition: TPave.h:75
Option_t * GetName() const
Returns name of object.
Definition: TPave.h:56
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:73
Double_t GetX1NDC() const
Definition: TPave.h:59
virtual void SetX2NDC(Double_t x2)
Definition: TPave.h:79
Draw a Pie Chart,.
Definition: TPie.h:23
virtual void Paint(Option_t *)
Paint a Pie chart in a canvas.
Definition: TPie.cxx:802
virtual void ExecuteEvent(Int_t, Int_t, Int_t)
Execute the mouse events.
Definition: TPie.cxx:393
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Evaluate the distance to the chart in gPad.
Definition: TPie.cxx:168
Definition: TPoint.h:31
void SetX(SCoord_t x)
Definition: TPoint.h:48
void SetY(SCoord_t y)
Definition: TPoint.h:49
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:23
Double_t * GetX() const
Definition: TPolyLine.h:54
virtual void SetPoint(Int_t point, Double_t x, Double_t y)
Set point number n to (x, y) If n is greater than the current size, the arrays are automatically exte...
Definition: TPolyLine.cxx:639
Double_t * GetY() const
Definition: TPolyLine.h:55
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X,...
Definition: TProfile2D.h:27
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:796
Profile Histogram.
Definition: TProfile.h:32
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition: TProfile.cxx:820
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:27
virtual Double_t Rndm()
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:56
Sequenceable collection abstract base class.
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetOptStat() const
Definition: TStyle.h:233
Color_t GetStatTextColor() const
Definition: TStyle.h:246
Float_t GetTitleX() const
Definition: TStyle.h:268
Int_t GetOptTitle() const
Definition: TStyle.h:234
Float_t GetStatFontSize() const
Definition: TStyle.h:249
Float_t GetBarOffset() const
Definition: TStyle.h:171
Float_t GetStatX() const
Definition: TStyle.h:252
Float_t GetTitleSize(Option_t *axis="X") const
Return title size.
Definition: TStyle.cxx:1051
Float_t GetTitleY() const
Definition: TStyle.h:269
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:1027
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:225
Float_t GetStatY() const
Definition: TStyle.h:253
Color_t GetTitleFillColor() const
Definition: TStyle.h:259
Style_t GetTitleStyle() const
Definition: TStyle.h:261
Color_t GetStatColor() const
Definition: TStyle.h:245
Float_t GetBarWidth() const
Definition: TStyle.h:172
Float_t GetStatH() const
Definition: TStyle.h:255
Width_t GetTitleBorderSize() const
Definition: TStyle.h:263
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:919
Float_t GetErrorX() const
Definition: TStyle.h:175
Double_t GetHistTopMargin() const
Definition: TStyle.h:226
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:314
Float_t GetEndErrorSize() const
Definition: TStyle.h:174
Width_t GetStatBorderSize() const
Definition: TStyle.h:247
Int_t GetTitleAlign()
Definition: TStyle.h:258
Color_t GetTitleTextColor() const
Definition: TStyle.h:260
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:315
Float_t GetTitleH() const
Definition: TStyle.h:271
Style_t GetStatStyle() const
Definition: TStyle.h:250
Float_t GetStatW() const
Definition: TStyle.h:254
const char * GetFitFormat() const
Definition: TStyle.h:188
const char * GetStatFormat() const
Definition: TStyle.h:251
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:985
Int_t GetOptFit() const
Definition: TStyle.h:232
Int_t GetNumberContours() const
Definition: TStyle.h:229
const char * GetPaintTextFormat() const
Definition: TStyle.h:238
Style_t GetStatFont() const
Definition: TStyle.h:248
Float_t GetTitleFontSize() const
Definition: TStyle.h:262
Float_t GetTitleW() const
Definition: TStyle.h:270
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1845
Base class for several text objects.
Definition: TText.h:23
TVectorT.
Definition: TVectorT.h:27
TClass * Class()
See TView3D.
Definition: TView.h:25
virtual Double_t GetPsi()=0
virtual Double_t * GetRmax()=0
virtual void SetAxisNDC(const Double_t *x1, const Double_t *x2, const Double_t *y1, const Double_t *y2, const Double_t *z1, const Double_t *z2)=0
virtual Double_t * GetRmin()=0
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)=0
virtual void SetOutlineToCube()=0
virtual Int_t GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)=0
virtual Double_t * GetTnorm()=0
virtual void ExecuteRotateView(Int_t event, Int_t px, Int_t py)=0
virtual TSeqCollection * GetOutline()=0
virtual void PadRange(Int_t rback)=0
virtual void FindNormal(Double_t x, Double_t y, Double_t z, Double_t &zn)=0
virtual void AxisVertex(Double_t ang, Double_t *av, Int_t &ix1, Int_t &ix2, Int_t &iy1, Int_t &iy2, Int_t &iz1, Int_t &iz2)=0
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)=0
Abstract base class used by ROOT graphics editor.
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
virtual void Show()
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:50
virtual Int_t GetLogz() const =0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Int_t GetLogy() const =0
virtual Int_t GetLogx() const =0
TText * text
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
double beta(double x, double y)
Calculates the beta function.
return c1
Definition: legend1.C:41
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
Double_t ey[n]
Definition: legend1.C:17
Double_t ex[n]
Definition: legend1.C:17
TH1F * h1
Definition: legend1.C:5
TF1 * f1
Definition: legend1.C:11
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
RooCmdArg Bins(Int_t nbin)
static constexpr double bar
static constexpr double rad
static constexpr double s
static constexpr double mg
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:703
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:621
Double_t ATan(Double_t)
Definition: TMath.h:665
constexpr Double_t PiOver2()
Definition: TMath.h:52
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Double_t Log(Double_t x)
Definition: TMath.h:750
constexpr Double_t DegToRad()
Conversion from degree to radian:
Definition: TMath.h:82
Double_t Sqrt(Double_t x)
Definition: TMath.h:681
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:725
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
Double_t Cos(Double_t)
Definition: TMath.h:631
constexpr Double_t Pi()
Definition: TMath.h:38
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:418
Double_t Sin(Double_t)
Definition: TMath.h:627
Double_t Tan(Double_t)
Definition: TMath.h:635
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMathBase.h:278
constexpr Double_t RadToDeg()
Conversion from radian to degree:
Definition: TMath.h:74
Double_t Log10(Double_t x)
Definition: TMath.h:754
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Definition: first.py:1
fill
Definition: fit1_py.py:6
Definition: graph.py:1
Histogram option structure.
Definition: Hoption.h:24
int Curve
"C" A smooth Curve is drawn.
Definition: Hoption.h:29
int Proj
1: Aitoff, 2: Mercator, 3: Sinusoidal, 4: Parabolic
Definition: Hoption.h:58
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition: Hoption.h:40
int Scat
"SCAT" Draw 2D plot a Scatter plot.
Definition: Hoption.h:47
int Text
"TEXT" Draw 2D plot with the content of each cell.
Definition: Hoption.h:49
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
int AxisPos
Axis position.
Definition: Hoption.h:59
int List
= 1 to generate the TObjArray "contours"
Definition: Hoption.h:57
int Logx
log scale in X. Also set by histogram option
Definition: Hoption.h:67
int Zscale
"Z" to display the Z scale (color palette)
Definition: Hoption.h:54
int MinimumZero
"MIN0" or gStyle->GetHistMinimumZero()
Definition: Hoption.h:62
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
int Off
"][" With H option, the first and last vertical lines are not drawn.
Definition: Hoption.h:32
int Func
"FUNC" Draw only the function (for example in case of fit).
Definition: Hoption.h:44
long Candle
"CANDLE" Draw a 2D histogram as candle/box plot or violin plot (also with "VIOLIN").
Definition: Hoption.h:52
int Spec
TSpectrum graphics.
Definition: Hoption.h:60
int FrontBox
= 0 to suppress the front box
Definition: Hoption.h:55
int Pie
"PIE" Draw 1D plot as a pie chart.
Definition: Hoption.h:51
int Char
"CHAR" Draw 2D plot with a character set.
Definition: Hoption.h:41
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
int Zero
if selected with any LEGO option the empty bins are not drawn.
Definition: Hoption.h:61
int Logz
log scale in Z. Also set by histogram option
Definition: Hoption.h:69
int Tri
"TRI" Draw 2D plot with Delaunay triangles.
Definition: Hoption.h:50
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:56
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
int Arrow
"ARR" Draw 2D plot with Arrows.
Definition: Hoption.h:39
int Line
"L" A simple polyline beetwen every point is drawn.
Definition: Hoption.h:34
int Same
"S" Histogram is plotted in the current PAD.
Definition: Hoption.h:36
int Lego
"LEGO" Draw as a Lego plot(LEGO,Lego=1, LEGO1,Lego1=11, LEGO2,Lego=12).
Definition: Hoption.h:46
int Bar
"B" A Bar chart is drawn at each point.
Definition: Hoption.h:28
int Fill
"F" A fill area is drawn ("CF" draw a smooth fill area).
Definition: Hoption.h:31
int Hist
"HIST" Draw only the histogram.
Definition: Hoption.h:45
int Surf
"SURF" Draw as a Surface (SURF,Surf=1, SURF1,Surf=11, SURF2,Surf=12)
Definition: Hoption.h:48
int Logy
log scale in Y. Also set by histogram option
Definition: Hoption.h:68
int System
type of coordinate system(1=car,2=pol,3=cyl,4=sph,5=psr)
Definition: Hoption.h:53
int Error
"E" Draw Errors with current marker type and size.
Definition: Hoption.h:30
Histogram parameters structure.
Definition: Hparam.h:26
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:41
Double_t ylowedge
low edge of axis
Definition: Hparam.h:32
Double_t xmin
minimum value along X
Definition: Hparam.h:29
Int_t ylast
last bin number along Y
Definition: Hparam.h:46
Int_t xfirst
first bin number along X
Definition: Hparam.h:43
Double_t zmin
minimum value along Z
Definition: Hparam.h:37
Double_t xbinsize
bin size in case of equidistant bins
Definition: Hparam.h:27
Double_t ymin
minimum value along y
Definition: Hparam.h:33
Double_t allchan
integrated sum of contents
Definition: Hparam.h:40
Double_t xlowedge
low edge of axis
Definition: Hparam.h:28
Double_t ymax
maximum value along y
Definition: Hparam.h:34
Double_t factor
multiplication factor (normalization)
Definition: Hparam.h:39
Int_t xlast
last bin number along X
Definition: Hparam.h:44
Double_t ybinsize
bin size in case of equidistant bins
Definition: Hparam.h:31
Double_t barwidth
width of bin for bars and legos [0,1]
Definition: Hparam.h:42
Double_t zmax
maximum value along Z
Definition: Hparam.h:38
Double_t xmax
maximum value along X
Definition: Hparam.h:30
Int_t yfirst
first bin number along Y
Definition: Hparam.h:45
auto * th2
Definition: textalign.C:17
auto * m
Definition: textangle.C:8
auto * tt
Definition: textangle.C:16
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
#define mark(osub)
Definition: triangle.c:1206