Logo ROOT   6.18/05
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| "CANDLE" | Draw a candle plot along X axis.|
283| "CANDLEX" | Same as "CANDLE".|
284| "CANDLEY" | Draw a candle plot along Y axis.|
285| "CANDLEXn"| Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
286| "CANDLEYn"| Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
287| "VIOLIN" | Draw a violin plot along X axis.|
288| "VIOLINX" | Same as "VIOLIN".|
289| "VIOLINY" | Draw a violin plot along Y axis.|
290| "VIOLINXn"| Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
291| "VIOLINYn"| Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
292| "CONT" | Draw a contour plot (same as CONT0).|
293| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
294| "CONT1" | Draw a contour plot using line styles to distinguish contours.|
295| "CONT2" | Draw a contour plot using the same line style for all contours.|
296| "CONT3" | Draw a contour plot using fill area colors.|
297| "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
298| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
299| "LIST" | Generate a list of TGraph objects for each contour.|
300| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
301| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
302| "SAME0" | Same as "SAME" but do not use the z-axis range of the first plot. |
303| "SAMES0" | Same as "SAMES" but do not use the z-axis range of the first plot. |
304| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
305| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
306| "SURF" | Draw a surface plot with hidden line removal.|
307| "SURF1" | Draw a surface plot with hidden surface removal.|
308| "SURF2" | Draw a surface plot using colors to show the cell contents.|
309| "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
310| "SURF4" | Draw a surface using Gouraud shading.|
311| "SURF5" | Same as SURF3 but only the colored contour is drawn. Used with option CYL, SPH or PSR it allows to draw colored contours on a sphere, a cylinder or a in pseudo rapidity space. In cartesian or polar coordinates, option SURF3 is used.|
312| "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
313| "FB" | With LEGO or SURFACE, suppress the Front-Box.|
314| "BB" | With LEGO or SURFACE, suppress the Back-Box.|
315| "A" | With LEGO or SURFACE, suppress the axis.|
316| "SCAT" | Draw a scatter-plot (default).|
317| "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
318
319
320#### <a name="HP01d"></a> Options supported for 3D histograms
321
322| Option | Description |
323|----------|-------------------------------------------------------------------|
324| " " | Default (scatter plot).|
325| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`.|
326| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
327| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
328| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
329| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
330| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
331| "LEGO" | Same as `BOX`.|
332
333
334#### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
335
336| Option | Description |
337|------------|-----------------------------------------------------------------|
338| " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
339| "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
340| "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
341| "PADS" | The current pad/canvas is subdivided into a number of pads equal to the number of histograms in the stack and each histogram is paint into a separate pad.|
342| "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
343| "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
344| "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
345
346
347
348### <a name="HP02"></a> Setting the Style
349
350
351Histograms use the current style (`gStyle`). When one changes the current
352style and would like to propagate the changes to the histogram,
353`TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
354each histogram is needed.
355
356To force all the histogram to use the current style use:
357
358 gROOT->ForceStyle();
359
360All the histograms read after this call will use the current style.
361
362
363### <a name="HP03"></a> Setting line, fill, marker, and text attributes
364
365
366The histogram classes inherit from the attribute classes:
367`TAttLine`, `TAttFill` and `TAttMarker`.
368See the description of these classes for the list of options.
369
370
371### <a name="HP04"></a> Setting Tick marks on the histogram axis
372
373
374The `TPad::SetTicks` method specifies the type of tick marks on the axis.
375If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
376
377 tx = 1; tick marks on top side are drawn (inside)
378 tx = 2; tick marks and labels on top side are drawn
379 ty = 1; tick marks on right side are drawn (inside)
380 ty = 2; tick marks and labels on right side are drawn
381
382By default only the left Y axis and X bottom axis are drawn
383(`tx = ty = 0`)
384
385`TPad::SetTicks(tx,ty)` allows to set these options.
386See also The `TAxis` functions to set specific axis attributes.
387
388In case multiple color filled histograms are drawn on the same pad, the fill
389area may hide the axis tick marks. One can force a redraw of the axis over all
390the histograms by calling:
391
392 gPad->RedrawAxis();
393
394
395### <a name="HP05"></a> Giving titles to the X, Y and Z axis
396
397
398 h->GetXaxis()->SetTitle("X axis title");
399 h->GetYaxis()->SetTitle("Y axis title");
400
401The histogram title and the axis titles can be any `TLatex` string.
402The titles are part of the persistent histogram.
403
404
405### <a name="HP060"></a> The option "SAME"
406
407
408By default, when an histogram is drawn, the current pad is cleared before
409drawing. In order to keep the previous drawing and draw on top of it the
410option `SAME` should be use. The histogram drawn with the option
411`SAME` uses the coordinates system available in the current pad.
412
413This option can be used alone or combined with any valid drawing option but
414some combinations must be use with care.
415
416#### <a name="HP060a"></a> Limitations
417
418- It does not work when combined with the `LEGO` and `SURF` options unless the
419 histogram plotted with the option `SAME` has exactly the same
420 ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
421 lego plots [histograms' stacks](#HP26) should be used.</li>
422
423
424### <a name="HP061"></a> Colors automatically picked in palette
425
426\since **ROOT version 6.09/01**
427
428When several histograms are painted in the same canvas thanks to the option "SAME"
429or via a `THStack` it might be useful to have an easy and automatic way to choose
430their color. The simplest way is to pick colors in the current active color
431palette. Palette coloring for histogram is activated thanks to the options `PFC`
432(Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
433When one of these options is given to `TH1::Draw` the histogram get its color
434from the current color palette defined by `gStyle->SetPalette(…)`. The color
435is determined according to the number of objects having palette coloring in
436the current pad.
437
438Begin_Macro(source)
439../../../tutorials/hist/histpalettecolor.C
440End_Macro
441
442Begin_Macro(source)
443../../../tutorials/hist/thstackpalettecolor.C
444End_Macro
445
446Begin_Macro(source)
447../../../tutorials/hist/thstack2palettecolor.C
448End_Macro
449
450### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
451
452
453The following example creates two histograms, the second histogram is the bins
454integral of the first one. It shows a procedure to draw the two histograms in
455the same pad and it draws the scale of the second histogram using a new vertical
456axis on the right side. See also the tutorial `transpad.C` for a variant
457of this example.
458
459Begin_Macro(source)
460{
461 auto c1 = new TCanvas("c1","c1",600,400);
462 // create/fill draw h1
463 gStyle->SetOptStat(kFALSE);
464 auto h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
465 Int_t i;
466 for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
467 h1->Draw();
468 c1->Update();
469
470 // create hint1 filled with the bins integral of h1
471 auto hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
472 Float_t sum = 0;
473 for (i=1;i<=100;i++) {
474 sum += h1->GetBinContent(i);
475 hint1->SetBinContent(i,sum);
476 }
477
478 // scale hint1 to the pad coordinates
479 Float_t rightmax = 1.1*hint1->GetMaximum();
480 Float_t scale = gPad->GetUymax()/rightmax;
481 hint1->SetLineColor(kRed);
482 hint1->Scale(scale);
483 hint1->Draw("same");
484
485 // draw an axis on the right side
486 auto axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
487 gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
488 axis->SetLineColor(kRed);
489 axis->SetTextColor(kRed);
490 axis->Draw();
491}
492End_Macro
493
494
495### <a name="HP07"></a> Statistics Display
496
497
498The type of information shown in the histogram statistics box can be selected
499with:
500
501 gStyle->SetOptStat(mode);
502
503The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
504
505 mode = ksiourmen (default = 000001111)
506 k = 1; kurtosis printed
507 k = 2; kurtosis and kurtosis error printed
508 s = 1; skewness printed
509 s = 2; skewness and skewness error printed
510 i = 1; integral of bins printed
511 i = 2; integral of bins with option "width" printed
512 o = 1; number of overflows printed
513 u = 1; number of underflows printed
514 r = 1; standard deviation printed
515 r = 2; standard deviation and standard deviation error printed
516 m = 1; mean value printed
517 m = 2; mean and mean error values printed
518 e = 1; number of entries printed
519 n = 1; name of histogram is printed
520
521For example:
522
523 gStyle->SetOptStat(11);
524
525displays only the name of histogram and the number of entries, whereas:
526
527 gStyle->SetOptStat(1101);
528
529displays the name of histogram, mean value and standard deviation.
530
531<b>WARNING 1:</b> never do:
532
533 gStyle->SetOptStat(0001111);
534
535but instead do:
536
537 gStyle->SetOptStat(1111);
538
539because `0001111` will be taken as an octal number!
540
541<b>WARNING 2:</b> for backward compatibility with older versions
542
543 gStyle->SetOptStat(1);
544
545is taken as:
546
547 gStyle->SetOptStat(1111)
548
549To print only the name of the histogram do:
550
551 gStyle->SetOptStat(1000000001);
552
553<b>NOTE</b> that in case of 2D histograms, when selecting only underflow
554(10000) or overflow (100000), the statistics box will show all combinations
555of underflow/overflows and not just one single number.
556
557The parameter mode can be any combination of the letters `kKsSiIourRmMen`
558
559 k : kurtosis printed
560 K : kurtosis and kurtosis error printed
561 s : skewness printed
562 S : skewness and skewness error printed
563 i : integral of bins printed
564 I : integral of bins with option "width" printed
565 o : number of overflows printed
566 u : number of underflows printed
567 r : standard deviation printed
568 R : standard deviation and standard deviation error printed
569 m : mean value printed
570 M : mean value mean error values printed
571 e : number of entries printed
572 n : name of histogram is printed
573
574For example, to print only name of histogram and number of entries do:
575
576 gStyle->SetOptStat("ne");
577
578To print only the name of the histogram do:
579
580 gStyle->SetOptStat("n");
581
582The default value is:
583
584 gStyle->SetOptStat("nemr");
585
586When a histogram is painted, a `TPaveStats` object is created and added
587to the list of functions of the histogram. If a `TPaveStats` object
588already exists in the histogram list of functions, the existing object is just
589updated with the current histogram parameters.
590
591Once a histogram is painted, the statistics box can be accessed using
592`h->FindObject("stats")`. In the command line it is enough to do:
593
594 Root > h->Draw()
595 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
596
597because after `h->Draw()` the histogram is automatically painted. But
598in a script file the painting should be forced using `gPad->Update()`
599in order to make sure the statistics box is created:
600
601 h->Draw();
602 gPad->Update();
603 TPaveStats *st = (TPaveStats*)h->FindObject("stats");
604
605Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
606
607When a histogram is drawn with the option `SAME`, the statistics box
608is not drawn. To force the statistics box drawing with the option
609`SAME`, the option `SAMES` must be used.
610If the new statistics box hides the previous statistics box, one can change
611its position with these lines (`h` being the pointer to the histogram):
612
613 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
614 Root > st->SetX1NDC(newx1); //new x start position
615 Root > st->SetX2NDC(newx2); //new x end position
616
617To change the type of information for an histogram with an existing
618`TPaveStats` one should do:
619
620 st->SetOptStat(mode);
621
622Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
623(see above).
624
625One can delete the statistics box for a histogram `TH1* h` with:
626
627 h->SetStats(0)
628
629and activate it again with:
630
631 h->SetStats(1).
632
633Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
634`$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
635
636
637### <a name="HP08"></a> Fit Statistics
638
639
640The type of information about fit parameters printed in the histogram statistics
641box can be selected via the parameter mode. The parameter mode can be
642`= pcev` (default `= 0111`)
643
644 p = 1; print Probability
645 c = 1; print Chisquare/Number of degrees of freedom
646 e = 1; print errors (if e=1, v must be 1)
647 v = 1; print name/values of parameters
648
649Example:
650
651 gStyle->SetOptFit(1011);
652
653print fit probability, parameter names/values and errors.
654
6551. When `v" = 1` is specified, only the non-fixed parameters are shown.
6562. When `v" = 2` all parameters are shown.
657
658Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
659to `gStyle->SetOptFit(111)`
660
661
662### <a name="HP09"></a> The error bars options
663
664
665| Option | Description |
666|----------|-------------------------------------------------------------------|
667| "E" | Default. Shows only the error bars, not a marker.|
668| "E1" | Small lines are drawn at the end of the error bars.|
669| "E2" | Error rectangles are drawn.|
670| "E3" | A filled area is drawn through the end points of the vertical error bars.|
671| "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
672| "E0" | Draw also bins with null contents.|
673
674Begin_Macro(source)
675{
676 auto c1 = new TCanvas("c1","c1",600,400);
677 auto he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
678 for (int i=0; i<10000; i++) he->Fill(gRandom->Gaus(0,1));
679 gStyle->SetEndErrorSize(3);
680 gStyle->SetErrorX(1.);
681 he->SetMarkerStyle(20);
682 he->Draw("E1");
683}
684End_Macro
685
686The options "E3" and "E4" draw an error band through the end points of the
687vertical error bars. With "E4" the error band is smoothed. Because of the
688smoothing algorithm used some artefacts may appear at the end of the band
689like in the following example. In such cases "E3" should be used instead
690of "E4".
691
692Begin_Macro(source)
693{
694 auto ce4 = new TCanvas("ce4","ce4",600,400);
695 ce4->Divide(2,1);
696 auto he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
697 Int_t i;
698 for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
699 he4->SetFillColor(kRed);
700 he4->GetXaxis()->SetRange(40,48);
701 ce4->cd(1);
702 he4->Draw("E4");
703 ce4->cd(2);
704 auto he3 = (TH1F*)he4->DrawClone("E3");
705 he3->SetTitle("Distribution drawn option E3");
706}
707End_Macro
708
7092D histograms can be drawn with error bars as shown is the following example:
710
711Begin_Macro(source)
712{
713 auto c2e = new TCanvas("c2e","c2e",600,400);
714 auto h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
715 Float_t px, py;
716 for (Int_t i = 0; i < 25000; i++) {
717 gRandom->Rannor(px,py);
718 h2e->Fill(px,5*py);
719 }
720 h2e->Draw("E");
721}
722End_Macro
723
724
725### <a name="HP100"></a> The bar chart option
726
727
728The option "B" allows to draw simple vertical bar charts.
729The bar width is controlled with `TH1::SetBarWidth()`,
730and the bar offset within the bin, with `TH1::SetBarOffset()`.
731These two settings are useful to draw several histograms on the
732same plot as shown in the following example:
733
734Begin_Macro(source)
735{
736 int i;
737 const Int_t nx = 8;
738 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
739 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
740 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
741
742 auto *cb = new TCanvas("cb","cb",600,400);
743 cb->SetGrid();
744
745 gStyle->SetHistMinimumZero();
746
747 auto h1b = new TH1F("h1b","Option B example",nx,0,nx);
748 h1b->SetFillColor(4);
749 h1b->SetBarWidth(0.4);
750 h1b->SetBarOffset(0.1);
751 h1b->SetStats(0);
752 h1b->SetMinimum(-5);
753 h1b->SetMaximum(5);
754
755 for (i=1; i<=nx; i++) {
756 h1b->SetBinContent(i, d_35_0[i-1]);
757 h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
758 }
759
760 h1b->Draw("b");
761
762 auto h2b = new TH1F("h2b","h2b",nx,0,nx);
763 h2b->SetFillColor(38);
764 h2b->SetBarWidth(0.4);
765 h2b->SetBarOffset(0.5);
766 h2b->SetStats(0);
767 for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
768
769 h2b->Draw("b same");
770}
771End_Macro
772
773
774### <a name="HP10"></a> The "BAR" and "HBAR" options
775
776
777When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
778bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
779An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
780`hbar2`, `hbar3`, `hbar4` (hbars.C).
781
782- The bar is filled with the histogram fill color.
783- The left side of the bar is drawn with a light fill color.
784- The right side of the bar is drawn with a dark fill color.
785- The percentage of the bar drawn with either the light or dark color is:
786 - 0% for option "(h)bar" or "(h)bar0"
787 - 10% for option "(h)bar1"
788 - 20% for option "(h)bar2"
789 - 30% for option "(h)bar3"
790 - 40% for option "(h)bar4"
791
792When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
793
794Begin_Macro(source)
795../../../tutorials/hist/hbars.C
796End_Macro
797
798To control the bar width (default is the bin width) `TH1::SetBarWidth()`
799should be used.
800
801To control the bar offset (default is 0) `TH1::SetBarOffset()` should
802be used.
803
804These two parameters are useful when several histograms are plotted using
805the option `SAME`. They allow to plot the histograms next to each other.
806
807
808### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
809
810
811For each cell (i,j) a number of points proportional to the cell content is
812drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
813`kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
814If option is of the form `scat=ff`, (eg `scat=1.8`,
815`scat=1e-3`), then `ff` is used as a scale factor to compute the
816number of dots. `scat=1` is the default.
817
818By default the scatter plot is painted with a "dot marker" which not scalable
819(see the `TAttMarker` documentation). To change the marker size, a scalable marker
820type should be used. For instance a circle (marker style 20).
821
822Begin_Macro(source)
823{
824 auto c1 = new TCanvas("c1","c1",600,400);
825 auto hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
826 Float_t px, py;
827 for (Int_t i = 0; i < 25000; i++) {
828 gRandom->Rannor(px,py);
829 hscat->Fill(px,5*py);
830 hscat->Fill(3+0.5*px,2*py-10.);
831 }
832 hscat->Draw("scat=0.5");
833}
834End_Macro
835
836
837### <a name="HP12"></a> The ARRow option
838
839
840Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
841The orientation of the arrow follows the cell gradient.
842
843Begin_Macro(source)
844{
845 auto c1 = new TCanvas("c1","c1",600,400);
846 auto harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
847 harr->SetLineColor(kRed);
848 Float_t px, py;
849 for (Int_t i = 0; i < 25000; i++) {
850 gRandom->Rannor(px,py);
851 harr->Fill(px,5*py);
852 harr->Fill(3+0.5*px,2*py-10.,0.1);
853 }
854 harr->Draw("ARR");
855}
856End_Macro
857
858\since **ROOT version 6.17/01**
859
860The option `ARR` can be combined with the option `COL` or `COLZ`.
861
862Begin_Macro(source)
863{
864 auto c1 = new TCanvas("c1","c1",600,400);
865 auto harr = new TH2F("harr","Option ARR + COLZ example",20,-4,4,20,-20,20);
866 harr->SetStats(0);
867 Float_t px, py;
868 for (Int_t i = 0; i < 25000; i++) {
869 gRandom->Rannor(px,py);
870 harr->Fill(px,5*py);
871 harr->Fill(3+0.5*px,2*py-10.,0.1);
872 }
873 harr->Draw("ARR COLZ");
874}
875End_Macro
876
877
878### <a name="HP13"></a> The BOX option
879
880
881For each cell (i,j) a box is drawn. The size (surface) of the box is
882proportional to the absolute value of the cell content.
883The cells with a negative content are drawn with a `X` on top of the box.
884
885Begin_Macro(source)
886{
887 auto c1 = new TCanvas("c1","c1",600,400);
888 auto hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
889 hbox->SetFillColor(42);
890 hbox->Fill(0.5, 0.5, 1.);
891 hbox->Fill(0.5, 1.5, 4.);
892 hbox->Fill(0.5, 2.5, 3.);
893 hbox->Fill(1.5, 0.5, 2.);
894 hbox->Fill(1.5, 1.5, 12.);
895 hbox->Fill(1.5, 2.5, -6.);
896 hbox->Fill(2.5, 0.5, -4.);
897 hbox->Fill(2.5, 1.5, 6.);
898 hbox->Fill(2.5, 2.5, 0.5);
899 hbox->Draw("BOX");
900}
901End_Macro
902
903With option `BOX1` a button is drawn for each cell with surface
904proportional to content's absolute value. A sunken button is drawn for
905negative values a raised one for positive.
906
907Begin_Macro(source)
908{
909 auto c1 = new TCanvas("c1","c1",600,400);
910 auto hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
911 hbox1->SetFillColor(42);
912 hbox1->Fill(0.5, 0.5, 1.);
913 hbox1->Fill(0.5, 1.5, 4.);
914 hbox1->Fill(0.5, 2.5, 3.);
915 hbox1->Fill(1.5, 0.5, 2.);
916 hbox1->Fill(1.5, 1.5, 12.);
917 hbox1->Fill(1.5, 2.5, -6.);
918 hbox1->Fill(2.5, 0.5, -4.);
919 hbox1->Fill(2.5, 1.5, 6.);
920 hbox1->Fill(2.5, 2.5, 0.5);
921 hbox1->Draw("BOX1");
922}
923End_Macro
924
925When the option `SAME` (or "SAMES") is used with the option `BOX`,
926the boxes' sizes are computing taking the previous plots into account. The range
927along the Z axis is imposed by the first plot (the one without option
928`SAME`); therefore the order in which the plots are done is relevant.
929
930Begin_Macro(source)
931{
932 auto c1 = new TCanvas("c1","c1",600,400);
933 auto hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
934 auto hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
935 auto hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
936 auto hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
937 for (Int_t i=0;i<1000;i++) {
938 double x,y;
939 gRandom->Rannor(x,y);
940 if (x>0 && y>0) hb1->Fill(x,y,4);
941 if (x<0 && y<0) hb2->Fill(x,y,3);
942 if (x>0 && y<0) hb3->Fill(x,y,2);
943 if (x<0 && y>0) hb4->Fill(x,y,1);
944 }
945 hb1->SetFillColor(1);
946 hb2->SetFillColor(2);
947 hb3->SetFillColor(3);
948 hb4->SetFillColor(4);
949 hb1->Draw("box");
950 hb2->Draw("box same");
951 hb3->Draw("box same");
952 hb4->Draw("box same");
953}
954End_Macro
955
956\since **ROOT version 6.17/01:**
957
958Sometimes the change of the range of the Z axis is unwanted, in which case, one
959can use `SAME0` (or `SAMES0`) option to opt out of this change.
960
961Begin_Macro(source)
962{
963 auto h2 = new TH2F("h2"," ",10,0,10,10,20,30);
964 auto hf = (TH2F*)h2->Clone("hf");
965 h2->SetBit(TH1::kNoStats);
966 hf->SetBit(TH1::kNoStats);
967 h2->Fill(5,22);
968 h2->Fill(5,23);
969 h2->Fill(6,22);
970 h2->Fill(6,23);
971 hf->Fill(6,23);
972 hf->Fill(6,23);
973 hf->Fill(6,23);
974 hf->Fill(6,23);
975 hf->Fill(5,23);
976
977 auto hf_copy1 = hf->Clone("hf_copy1");
978 auto* lt = new TLatex();
979
980 auto* cx = new TCanvas(); cx->Divide(2,1);
981
982 cx->cd(1);
983 h2->Draw("box");
984 hf->Draw("text colz same");
985 lt->DrawLatexNDC(0.3,0.5,"SAME");
986
987 cx->cd(2);
988 h2->Draw("box");
989 hf_copy1->Draw("text colz same0");
990 lt->DrawLatexNDC(0.3,0.5,"SAME0");
991}
992End_Macro
993
994
995### <a name="HP14"></a> The COLor option
996
997
998For each cell (i,j) a box is drawn with a color proportional to the cell
999content.
1000
1001The color table used is defined in the current style.
1002
1003If the histogram's minimum and maximum are the same (flat histogram), the
1004mapping on colors is not possible, therefore nothing is painted. To paint a
1005flat histogram it is enough to set the histogram minimum
1006(`TH1::SetMinimum()`) different from the bins' content.
1007
1008The default number of color levels used to paint the cells is 20.
1009It can be changed with `TH1::SetContour()` or
1010`TStyle::SetNumberContours()`. The higher this number is, the smoother
1011is the color change between cells.
1012
1013The color palette in TStyle can be modified via `gStyle->SetPalette()`.
1014
1015All the non-empty bins are painted. Empty bins are not painted unless
1016some bins have a negative content because in that case the null bins
1017might be not empty.
1018
1019`TProfile2D` histograms are handled differently because, for this type of 2D
1020histograms, it is possible to know if an empty bin has been filled or not. So even
1021if all the bins' contents are positive some empty bins might be painted. And vice versa,
1022if some bins have a negative content some empty bins might be not painted.
1023
1024Combined with the option `COL`, the option `Z` allows to
1025display the color palette defined by `gStyle->SetPalette()`.
1026
1027In the following example, the histogram has only positive bins; the empty
1028bins (containing 0) are not drawn.
1029
1030Begin_Macro(source)
1031{
1032 auto c1 = new TCanvas("c1","c1",600,400);
1033 auto hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
1034 Float_t px, py;
1035 for (Int_t i = 0; i < 25000; i++) {
1036 gRandom->Rannor(px,py);
1037 hcol1->Fill(px,5*py);
1038 }
1039 hcol1->Draw("COLZ");
1040}
1041End_Macro
1042
1043In the first plot of following example, the histogram has some negative bins;
1044the empty bins (containing 0) are drawn. In some cases one wants to not draw
1045empty bins (containing 0) of histograms having a negative minimum. The option
1046`1`, used to produce the second plot in the following picture, allows to do that.
1047
1048Begin_Macro(source)
1049{
1050 auto c1 = new TCanvas("c1","c1",600,600);
1051 c1->Divide(1,2);
1052 auto hcol23 = new TH2F("hcol23","Option COLZ example ",40,-4,4,40,-20,20);
1053 auto hcol24 = new TH2F("hcol24","Option COLZ1 example ",40,-4,4,40,-20,20);
1054 Float_t px, py;
1055 for (Int_t i = 0; i < 25000; i++) {
1056 gRandom->Rannor(px,py);
1057 hcol23->Fill(px,5*py);
1058 hcol24->Fill(px,5*py);
1059 }
1060 hcol23->Fill(0.,0.,-200.);
1061 hcol24->Fill(0.,0.,-200.);
1062 c1->cd(1); hcol23->Draw("COLZ");
1063 c1->cd(2); hcol24->Draw("COLZ1");
1064}
1065End_Macro
1066
1067When the maximum of the histogram is set to a smaller value than the real maximum,
1068 the bins having a content between the new maximum and the real maximum are
1069painted with the color corresponding to the new maximum.
1070
1071When the minimum of the histogram is set to a greater value than the real minimum,
1072 the bins having a value between the real minimum and the new minimum are not drawn
1073 unless the option `0` is set.
1074
1075The following example illustrates the option `0` combined with the option `COL`.
1076
1077Begin_Macro(source)
1078{
1079 auto c1 = new TCanvas("c1","c1",600,600);
1080 c1->Divide(1,2);
1081 auto hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1082 auto hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1083 Float_t px, py;
1084 for (Int_t i = 0; i < 25000; i++) {
1085 gRandom->Rannor(px,py);
1086 hcol21->Fill(px,5*py);
1087 hcol22->Fill(px,5*py);
1088 }
1089 hcol21->SetBit(TH1::kNoStats);
1090 hcol22->SetBit(TH1::kNoStats);
1091 c1->cd(1); hcol21->Draw("COLZ");
1092 c1->cd(2); hcol22->Draw("COLZ0");
1093 hcol22->SetMaximum(100);
1094 hcol22->SetMinimum(40);
1095}
1096End_Macro
1097
1098\since **ROOT version 6.09/01:**
1099
1100When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1101are computing taking the previous plots into account. The range along the Z axis
1102is imposed by the first plot (the one without option SAME); therefore the order
1103in which the plots are done is relevant. Same as [in the `BOX` option](#HP13), one can use
1104`SAME0` (or `SAMES0`) to opt out of this imposition.
1105
1106Begin_Macro(source)
1107{
1108 auto c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1109 auto h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1110 auto h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1111 auto h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1112 auto h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1113 h1->SetBit(TH1::kNoStats);
1114 for (Int_t i=0;i<5000;i++) {
1115 double x,y;
1116 gRandom->Rannor(x,y);
1117 if(x>0 && y>0) h1->Fill(x,y,4);
1118 if(x<0 && y<0) h2->Fill(x,y,3);
1119 if(x>0 && y<0) h3->Fill(x,y,2);
1120 if(x<0 && y>0) h4->Fill(x,y,1);
1121 }
1122 h1->Draw("colz");
1123 h2->Draw("col same");
1124 h3->Draw("col same");
1125 h4->Draw("col same");
1126}
1127End_Macro
1128
1129The option `COL` can be combined with the option `POL`:
1130
1131Begin_Macro(source)
1132{
1133 auto c1 = new TCanvas("c1","c1",600,400);
1134 auto hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1135 Float_t px, py;
1136 for (Int_t i = 0; i < 25000; i++) {
1137 gRandom->Rannor(px,py);
1138 hcol1->Fill(px,py);
1139 }
1140 hcol1->Draw("COLZPOL");
1141}
1142End_Macro
1143
1144\since **ROOT version 6.07/03:**
1145
1146A second rendering technique is also available with the COL2 and COLZ2 options.
1147
1148These options provide potential performance improvements compared to the standard
1149COL option. The performance comparison of the COL2 to the COL option depends on
1150the histogram and the size of the rendering region in the current pad. In general,
1151a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1152faster with the COL option.
1153
1154However, for larger histograms (approx. more than 100 bins per axis)
1155that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1156For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1157faster with the COL2 option.
1158
1159The COL2 option will also scale its performance based on the size of the
1160pixmap the histogram image is being rendered into. It also is much better optimized for
1161sessions where the user is forwarding X11 windows through an `ssh` connection.
1162
1163For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1164and COLZ options. There is one major difference and that concerns the treatment of
1165bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1166
1167COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1168graphics file format like PostScript or PDF (an empty image will be generated). It can
1169be saved only in bitmap files like PNG format for instance.
1170
1171
1172### <a name="HP140"></a> The CANDLE and VIOLIN options
1173
1174The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1175implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1176the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1177vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1178(1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1179
1180Instead of using the predefined representations, the candle and violin parameters can be
1181changed individually. In that case the option have the following form:
1182
1183 CANDLEX(<option-string>)
1184 CANDLEY(<option-string>)
1185 VIOLINX(<option-string>)
1186 VIOLINY(<option-string>).
1187
1188All zeros at the beginning of `option-string` can be omitted.
1189
1190`option-string` consists eight values, defined as follow:
1191
1192 "CANDLEX(zhpawMmb)"
1193
1194Where:
1195
1196 - `b = 0`; no box drawn
1197 - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1198 makes sense in the very most cases to always draw the box
1199 - `b = 2`; draw a filled box with border
1200
1201 - `m = 0`; no median drawn
1202 - `m = 1`; median is drawn as a line
1203 - `m = 2`; median is drawn with errors (notches)
1204 - `m = 3`; median is drawn as a circle
1205
1206 - `M = 0`; no mean drawn
1207 - `M = 1`; mean is drawn as a dashed line
1208 - `M = 3`; mean is drawn as a circle
1209
1210 - `w = 0`; no whisker drawn
1211 - `w = 1`; whisker is drawn to end of distribution.
1212 - `w = 2`; whisker is drawn to max 1.5*iqr
1213
1214 - `a = 0`; no anchor drawn
1215 - `a = 1`; the anchors are drawn
1216
1217 - `p = 0`; no points drawn
1218 - `p = 1`; only outliers are drawn
1219 - `p = 2`; all datapoints are drawn
1220 - `p = 3`: all datapoints are drawn scattered
1221
1222 - `h = 0`; no histogram is drawn
1223 - `h = 1`; histogram at the left or bottom side is drawn
1224 - `h = 2`; histogram at the right or top side is drawn
1225 - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1226
1227 - `z = 0`; no zero indicator line is drawn
1228 - `z = 1`; zero indicator line is drawn.
1229
1230As one can see all individual options for both candle and violin plots can be accessed by this
1231mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1232meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1233vice versa, if you wish.
1234
1235Using a logarithmic x- or y-axis is possible for candle and violin charts.
1236
1237\since **ROOT version 6.11/01**
1238
1239a logarithmic z-axis is possible, too but will only affect violin charts of course.
1240
1241#### <a name="HP140a"></a> The CANDLE option
1242
1243<a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1244a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1245way to describe graphically a data distribution (D) with only five numbers:
1246
1247 1. The minimum value of the distribution D (bottom or left whisker).
1248 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1249 3. The median (M): 50% of the data points in D are less than M.
1250 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1251 5. The maximum value of the distribution D (top or right whisker).
1252
1253In this implementation a TH2 is considered as a collection of TH1 along
1254X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1255Each TH1 is represented as one candle.
1256
1257Begin_Macro(source)
1258../../../tutorials/hist/candleplotwhiskers.C
1259End_Macro
1260
1261The candle reduces the information coming from a whole distribution into few values.
1262Independently from the number of entries or the significance of the underlying distribution
1263a candle will always look like a candle. So candle plots should be used carefully in
1264particular with unknown distributions. The definition of a candle is based on
1265__unbinned data__. Here, candles are created from binned data. Because of this, the
1266deviation is connected to the bin width used. The calculation of the quantiles
1267normally done on unbinned data also. Because data are binned, this will
1268only work the best possible way within the resolution of one bin
1269
1270Because of all these facts one should take care that:
1271
1272 - there are enough points per candle
1273 - the bin width is small enough (more bins will increase the maximum
1274 available resolution of the quantiles although there will be some
1275 bins with no entries)
1276 - never make a candle-plot if the underlying distribution is double-distributed
1277 - only create candles of distributions that are more-or-less gaussian (the
1278 MPV should be not too far away from the mean).
1279
1280#### What a candle is made of
1281
1282\since **ROOT version 6.07/05**
1283
1284##### The box
1285The box displays the position of the inter-quantile-range of the underlying
1286distribution. The box contains 25% of the distribution below the median
1287and 25% of the distribution above the median. If the underlying distribution is large
1288enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1289(Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1290the position of the box can be modified by SetBarWidth() and SetBarOffset().
1291The +-25% quantiles are calculated by the GetQuantiles() methods.
1292
1293\since **ROOT version 6.11/01**
1294
1295Using the static function TCandle::SetBoxRange(double) the box definition will be
1296overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1297to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1298The static function will affect all candle-charts in the running program.
1299Default is 0.5.
1300
1301Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1302whole candle) can be influenced. Deactivated, the width is constant (to be set by
1303SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1304amount of data in the corresponding candle, the maximum width can be influenced by
1305SetBarWidth(). The static function will affect all candle-charts in the running program.
1306Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1307supported, yet
1308
1309##### The Median
1310For a sorted list of numbers, the median is the value in the middle of the list.
1311E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1312because it is in the middle of the list. If the number of entries is even the
1313average of the two values in the middle will be used. As histograms are binned
1314data, the situation is a bit more complex. The following example shows this:
1315
1316~~~ {.cpp}
1317void quantiles() {
1318 TH1I *h = new TH1I("h","h",10,0,10);
1319 //h->Fill(3);
1320 //h->Fill(3);
1321 h->Fill(4);
1322 h->Draw();
1323 Double_t *p = new Double_t[1];
1324 p[0] = 0.5;
1325 Double_t *q = new Double_t[1];
1326 q[0] = 0;
1327 h->GetQuantiles(1,q,p);
1328
1329 cout << "Median is: " << q[0] << std::endl;
1330}
1331~~~
1332
1333Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1334the example will return a calculated median of 4.5, because that's the bin center
1335of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1336commented out, it will return 3.75, because the algorithm tries to evenly distribute
1337the individual values of a bin with bin content > 0. It means the sorted list
1338would be "3.25, 3.75, 4.5".
1339
1340The consequence is a median of 3.75. This shows how important it is to use a
1341small enough bin-width when using candle-plots on binned data.
1342If the distribution is large enough and gaussian shaped the median will be exactly
1343equal to the mean.
1344The median can be shown as a line or as a circle or not shown at all.
1345
1346In order to show the significance of the median notched candle plots apply a "notch" or
1347narrowing of the box around the median. The significance is defined by
1348\f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1349(where iqr is the size of the box and N is the number of entries of the whole
1350distribution). Candle plots like these are usually called "notched candle plots".
1351
1352In case the significance of the median is greater that the size of the box, the
1353box will have an unnatural shape. Usually it means the chart has not enough data,
1354or that representing this uncertainty is not useful
1355
1356##### The Mean
1357The mean can be drawn as a dashed line or as a circle or not drawn at all.
1358The mean is the arithmetic average of the values in the distribution.
1359It is calculated using GetMean(). Because histograms are
1360binned data, the mean value can differ from a calculation on the raw-data.
1361If the distribution is large enough and gaussian shaped the mean will be
1362exactly the median.
1363
1364##### The Whiskers
1365The whiskers represent the part of the distribution not covered by the box.
1366The upper 25% and the lower 25% of the distribution are located within the whiskers.
1367Two representations are available.
1368
1369 - A simple one (using w=1) defining the lower whisker from the lowest data value
1370 to the bottom of the box, and the upper whisker from the top of the box to the
1371 highest data value. In this representation the whisker-lines are dashed.
1372 - A more complex one having a further restriction. The whiskers are still connected
1373 to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1374 be that the outermost part of the underlying distribution will not be covered
1375 by the whiskers. Usually these missing parts will be represented by the outliers
1376 (see points). Of course the upper and the lower whisker may differ in length.
1377 In this representation the whiskers are drawn as solid lines.
1378
1379\since **ROOT version 6.11/01**
1380
1381Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1382will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1383the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1384that candle. The static function will affect all candle-charts in the running program.
1385Default is 1.
1386
1387If the distribution is large enough and gaussian shaped, the maximum length of
1388the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
13891.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1390(see picture above). In that case 99.3% of the total distribution will be covered
1391by the box and the whiskers, whereas 0.7% are represented by the outliers.
1392
1393##### The Anchors
1394The anchors have no special meaning in terms of statistical calculation. They mark
1395the end of the whiskers and they have the width of the box. Both representation
1396with and without anchors are common.
1397
1398##### The Points
1399Depending on the configuration the points can have different meanings:
1400 - If p=1 the points represent the outliers. If they are shown, it means
1401 some parts of the underlying distribution are not covered by the whiskers.
1402 This can only occur when the whiskers are set to option w=2. Here the whiskers
1403 can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1404 whiskers will be drawn as outliers. The outliers will be represented by crosses.
1405 - If p=2 all points in the distribution will be painted as crosses. This is
1406 useful for small datasets only (up to 10 or 20 points per candle).
1407 The outliers are shown along the candle. Because the underlying distribution
1408 is binned, is frequently occurs that a bin contains more than one value.
1409 Because of this the points will be randomly scattered within their bin along
1410 the candle axis. If the bin content for a bin is exactly 1 (usually
1411 this happens for the outliers) if will be drawn in the middle of the bin along
1412 the candle axis. As the maximum number of points per candle is limited by kNMax/2
1413 on very large datasets scaling will be performed automatically. In that case one
1414 would loose all outliers because they have usually a bin content of 1 (and a
1415 bin content between 0 and 1 after the scaling). Because of this all bin contents
1416 between 0 and 1 - after the scaling - will be forced to be 1.
1417 - As the drawing of all values on large datasets can lead to big amounts of crosses,
1418 one can show all values as a scatter plot instead by choosing p=3. The points will be
1419 drawn as dots and will be scattered within the width of the candle. The color
1420 of the points will be the color of the candle-chart.
1421
1422##### Other Options
1423Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1424with a histogram.
1425
1426#### How to use the candle-plots drawing option
1427
1428There are six predefined candle-plot representations:
1429
1430 - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1431 - "CANDLEX2": Standard candle with better whisker definition + outliers.
1432 It is a good compromise
1433 - "CANDLEX3": Like candle2 but with a mean as a circle.
1434 It is easier to distinguish mean and median
1435 - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1436 (notched candle plots).
1437 For bigger datasets per candle
1438 - "CANDLEX5": Like candle2 but showing all data points.
1439 For very small datasets
1440 - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1441 For huge datasets
1442
1443
1444The following picture shows how the six predefined representations look.
1445
1446Begin_Macro
1447{
1448 auto c1 = new TCanvas("c1","c1",700,800);
1449 c1->Divide(2,3);
1450 gStyle->SetOptStat(kFALSE);
1451
1452 auto hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1453 Float_t px, py;
1454 for (Int_t i = 0; i < 15000; i++) {
1455 gRandom->Rannor(px,py);
1456 hcandle->Fill(px,5*py);
1457 }
1458 hcandle->SetMarkerSize(0.5);
1459
1460 TH2F *h2;
1461 for (Int_t i=1; i<7; i++) {
1462 c1->cd(i);
1463 h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1464 h2->SetTitle(Form("CANDLE%d",i));
1465 }
1466}
1467End_Macro
1468
1469
1470#### Example 1
1471Box and improved whisker, no mean, no median, no anchor no outliers
1472
1473 h1->Draw("CANDLEX(2001)");
1474
1475#### Example 2
1476A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1477
1478 h1->Draw("CANDLEX(112111)");
1479
1480#### Example 3
1481The following example shows how several candle plots can be super-imposed using
1482the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1483Also the color, the line width, the size of the points and so on can be changed by the
1484standard attribute setting methods such as SetLineColor() SetLineWidth().
1485
1486Begin_Macro(source)
1487../../../tutorials/hist/candleplot.C
1488End_Macro
1489
1490#### <a name="HP140b"></a> The VIOLIN option
1491
1492<a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1493that also encodes the pdf information at each point.
1494
1495
1496Quartiles and mean are also represented at each point, with a marker
1497and two lines.
1498
1499In this implementation a TH2 is considered as a collection of TH1 along
1500X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1501
1502#### What a violin is made of
1503
1504\since **ROOT version 6.09/02**
1505
1506##### The histogram
1507The histogram is typically drawn to both directions with respect to the middle-line of the
1508corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1509one side (h=1, or h=2).
1510The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1511histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1512be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1513A solid fill style is recommended.
1514
1515\since **ROOT version 6.11/01**
1516
1517Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1518violin can be influenced. Activated, the height of the bins of the individual violins will be
1519scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1520Deactivated, the height of the bin with the maximum content of each individual violin is
1521set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1522in the running program. Default is true. Scaling between multiple violin-charts
1523(using "same" or THStack) is not supported, yet.
1524
1525##### The zero indicator line
1526Typical for violin charts is a line in the background over the whole histogram indicating
1527the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1528will always be the same as the fill-color of the histogram.
1529
1530##### The Mean
1531The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1532
1533##### Whiskers
1534The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1535difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1536the whiskers will be forced to be solid (usually hashed)
1537
1538##### Points
1539The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1540better whisker definition (w=2) and outliers (p=1).
1541
1542##### Other options
1543It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1544including a box-plot.
1545
1546#### How to use the violin-plots drawing option
1547
1548There are two predefined violin-plot representations:
1549 - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1550 zero indicator line)
1551 - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1552
1553A solid fill style is recommended for this plot (as opposed to a hollow or
1554hashed style).
1555
1556Begin_Macro(source)
1557{
1558 auto c1 = new TCanvas("c1","c1",600,400);
1559 Int_t nx(6), ny(40);
1560 Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1561 auto hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1562 TF1 f1("f1", "gaus", +0,0 +4.0);
1563 Double_t x,y;
1564 for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1565 Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1566 f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1567 for(Int_t i=0; i<10000; ++i){
1568 x = xc;
1569 y = f1.GetRandom();
1570 hviolin->Fill(x, y);
1571 }
1572 }
1573 hviolin->SetFillColor(kGray);
1574 hviolin->SetMarkerStyle(20);
1575 hviolin->SetMarkerSize(0.5);
1576 hviolin->Draw("VIOLIN");
1577 c1->Update();
1578}
1579End_Macro
1580
1581The next example illustrates a time development of a certain value:
1582
1583Begin_Macro(source)
1584../../../tutorials/hist/candledecay.C
1585End_Macro
1586
1587
1588### <a name="HP15"></a> The TEXT and TEXTnn Option
1589
1590
1591For each bin the content is printed. The text attributes are:
1592
1593- text font = current TStyle font (`gStyle->SetTextFont()`).
1594- text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1595 with the option `TEXT` the marker size can be changed with
1596 `h->SetMarkerSize(markersize)`).
1597- text color = marker color.
1598
1599By default the format `g` is used. This format can be redefined
1600by calling `gStyle->SetPaintTextFormat()`.
1601
1602It is also possible to use `TEXTnn` in order to draw the text with
1603the angle `nn` (`0 < nn < 90`).
1604
1605For 2D histograms the text is plotted in the center of each non empty cells.
1606It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`
1607or providing MIN0 draw option. For 1D histogram the text is plotted at a y
1608position equal to the bin content.
1609
1610For 2D histograms when the option "E" (errors) is combined with the option
1611text ("TEXTE"), the error for each bin is also printed.
1612
1613Begin_Macro(source)
1614{
1615 auto c01 = new TCanvas("c01","c01",700,400);
1616 c01->Divide(2,1);
1617 auto htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1618 auto htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1619 Float_t px, py;
1620 for (Int_t i = 0; i < 25000; i++) {
1621 gRandom->Rannor(px,py);
1622 htext1->Fill(px,0.1);
1623 htext2->Fill(px,5*py,0.1);
1624 }
1625 gStyle->SetPaintTextFormat("4.1f m");
1626 htext2->SetMarkerSize(1.8);
1627 c01->cd(1);
1628 htext2->Draw("TEXT45");
1629 c01->cd(2);
1630 htext1->Draw();
1631 htext1->Draw("HIST TEXT0 SAME");
1632}
1633End_Macro
1634
1635\since **ROOT version 6.07/07:**
1636
1637In case several histograms are drawn on top ot each other (using option `SAME`),
1638the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1639text position in each cell, in percentage of the bin width.
1640
1641Begin_Macro(source)
1642{
1643 auto c03 = new TCanvas("c03","c03",700,400);
1644 gStyle->SetOptStat(0);
1645 auto htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1646 auto htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1647 auto htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1648 Float_t px, py;
1649 for (Int_t i = 0; i < 25000; i++) {
1650 gRandom->Rannor(px,py);
1651 htext3->Fill(4*px,20*py,0.1);
1652 htext4->Fill(4*px,20*py,0.5);
1653 htext5->Fill(4*px,20*py,1.0);
1654 }
1655 htext4->SetMarkerSize(1.8);
1656 htext5->SetMarkerSize(1.8);
1657 htext5->SetMarkerColor(kRed);
1658 htext3->Draw("COL");
1659 htext4->SetBarOffset(0.2);
1660 htext4->Draw("TEXT SAME");
1661 htext5->SetBarOffset(-0.2);
1662 htext5->Draw("TEXT SAME");
1663}
1664End_Macro
1665
1666In the case of profile histograms it is possible to print the number
1667of entries instead of the bin content. It is enough to combine the
1668option "E" (for entries) with the option "TEXT".
1669
1670Begin_Macro(source)
1671{
1672 auto c02 = new TCanvas("c02","c02",700,400);
1673 c02->Divide(2,1);
1674 gStyle->SetPaintTextFormat("g");
1675
1676 auto profile = new TProfile("profile","profile",10,0,10);
1677 profile->SetMarkerSize(2.2);
1678 profile->Fill(0.5,1);
1679 profile->Fill(1.5,2);
1680 profile->Fill(2.5,3);
1681 profile->Fill(3.5,4);
1682 profile->Fill(4.5,5);
1683 profile->Fill(5.5,5);
1684 profile->Fill(6.5,4);
1685 profile->Fill(7.5,3);
1686 profile->Fill(8.5,2);
1687 profile->Fill(9.5,1);
1688 c02->cd(1); profile->Draw("HIST TEXT0");
1689 c02->cd(2); profile->Draw("HIST TEXT0E");
1690}
1691End_Macro
1692
1693### <a name="HP16"></a> The CONTour options
1694
1695
1696The following contour options are supported:
1697
1698| Option | Description |
1699|----------|-------------------------------------------------------------------|
1700| "CONT" | Draw a contour plot (same as CONT0).|
1701| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1702| "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1703| "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1704| "CONT3" | Draw a contour plot solid lines for all contours.|
1705| "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1706| "CONT5" | Draw a contour plot using Delaunay triangles.|
1707
1708
1709
1710The following example shows a 2D histogram plotted with the option
1711`CONTZ`. The option `CONT` draws a contour plot using surface
1712colors to distinguish contours. Combined with the option `CONT` (or
1713`CONT0`), the option `Z` allows to display the color palette
1714defined by `gStyle->SetPalette()`.
1715
1716Begin_Macro(source)
1717{
1718 auto c1 = new TCanvas("c1","c1",600,400);
1719 auto hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1720 Float_t px, py;
1721 for (Int_t i = 0; i < 25000; i++) {
1722 gRandom->Rannor(px,py);
1723 hcontz->Fill(px-1,5*py);
1724 hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1725 }
1726 hcontz->Draw("CONTZ");
1727}
1728End_Macro
1729
1730The following example shows a 2D histogram plotted with the option
1731`CONT1Z`. The option `CONT1` draws a contour plot using the
1732line colors to distinguish contours. Combined with the option `CONT1`,
1733the option `Z` allows to display the color palette defined by
1734`gStyle->SetPalette()`.
1735
1736Begin_Macro(source)
1737{
1738 auto c1 = new TCanvas("c1","c1",600,400);
1739 auto hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1740 Float_t px, py;
1741 for (Int_t i = 0; i < 25000; i++) {
1742 gRandom->Rannor(px,py);
1743 hcont1->Fill(px-1,5*py);
1744 hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1745 }
1746 hcont1->Draw("CONT1Z");
1747}
1748End_Macro
1749
1750The following example shows a 2D histogram plotted with the option
1751`CONT2`. The option `CONT2` draws a contour plot using the
1752line styles to distinguish contours.
1753
1754Begin_Macro(source)
1755{
1756 auto c1 = new TCanvas("c1","c1",600,400);
1757 auto hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1758 Float_t px, py;
1759 for (Int_t i = 0; i < 25000; i++) {
1760 gRandom->Rannor(px,py);
1761 hcont2->Fill(px-1,5*py);
1762 hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1763 }
1764 hcont2->Draw("CONT2");
1765}
1766End_Macro
1767
1768The following example shows a 2D histogram plotted with the option
1769`CONT3`. The option `CONT3` draws contour plot solid lines for
1770all contours.
1771
1772Begin_Macro(source)
1773{
1774 auto c1 = new TCanvas("c1","c1",600,400);
1775 auto hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1776 Float_t px, py;
1777 for (Int_t i = 0; i < 25000; i++) {
1778 gRandom->Rannor(px,py);
1779 hcont3->Fill(px-1,5*py);
1780 hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1781 }
1782 hcont3->Draw("CONT3");
1783}
1784End_Macro
1785
1786The following example shows a 2D histogram plotted with the option
1787`CONT4`. The option `CONT4` draws a contour plot using surface
1788colors to distinguish contours (`SURF` option at theta = 0). Combined
1789with the option `CONT` (or `CONT0`), the option `Z`
1790allows to display the color palette defined by `gStyle->SetPalette()`.
1791
1792Begin_Macro(source)
1793{
1794 auto c1 = new TCanvas("c1","c1",600,400);
1795 auto hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1796 Float_t px, py;
1797 for (Int_t i = 0; i < 25000; i++) {
1798 gRandom->Rannor(px,py);
1799 hcont4->Fill(px-1,5*py);
1800 hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1801 }
1802 hcont4->Draw("CONT4Z");
1803}
1804End_Macro
1805
1806The default number of contour levels is 20 equidistant levels and can be changed
1807with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1808
1809#### <a name="HP16a"></a> The LIST option
1810
1811When option `LIST` is specified together with option
1812`CONT`, the points used to draw the contours are saved in
1813`TGraph` objects:
1814
1815 h->Draw("CONT LIST");
1816 gPad->Update();
1817
1818The contour are saved in `TGraph` objects once the pad is painted.
1819Therefore to use this functionality in a macro, `gPad->Update()`
1820should be performed after the histogram drawing. Once the list is
1821built, the contours are accessible in the following way:
1822
1823 TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1824 Int_t ncontours = contours->GetSize();
1825 TList *list = (TList*)contours->At(i);
1826
1827Where `i` is a contour number, and list contains a list of
1828`TGraph` objects.
1829For one given contour, more than one disjoint polyline may be generated.
1830The number of TGraphs per contour is given by:
1831
1832 list->GetSize();
1833
1834To access the first graph in the list one should do:
1835
1836 TGraph *gr1 = (TGraph*)list->First();
1837
1838
1839The following example (ContourList.C) shows how to use this functionality.
1840
1841Begin_Macro(source)
1842../../../tutorials/hist/ContourList.C
1843End_Macro
1844
1845#### <a name="HP16b"></a> The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options
1846
1847The following options select the `CONT4` option and are useful for
1848sky maps or exposure maps (earth.C).
1849
1850| Option | Description |
1851|--------------|---------------------------------------------------------------|
1852| "AITOFF" | Draw a contour via an AITOFF projection.|
1853| "MERCATOR" | Draw a contour via an Mercator projection.|
1854| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1855| "PARABOLIC" | Draw a contour via an Parabolic projection.|
1856
1857Begin_Macro(source)
1858../../../tutorials/graphics/earth.C
1859End_Macro
1860
1861
1862### <a name="HP17"></a> The LEGO options
1863
1864
1865In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1866is proportional to the cell content. The lego aspect is control with the
1867following options:
1868
1869| Option | Description |
1870|----------|-------------------------------------------------------------------|
1871| "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1872| "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1873| "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1874| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1875| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1876| "0" | When used with any LEGO option, the empty bins are not drawn.|
1877
1878
1879See the limitations with [the option "SAME"](#HP060a).
1880
1881Line attributes can be used in lego plots to change the edges' style.
1882
1883The following example shows a 2D histogram plotted with the option
1884`LEGO`. The option `LEGO` draws a lego plot using the hidden
1885lines removal technique.
1886
1887Begin_Macro(source)
1888{
1889 auto c2 = new TCanvas("c2","c2",600,400);
1890 auto hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1891 Float_t px, py;
1892 for (Int_t i = 0; i < 25000; i++) {
1893 gRandom->Rannor(px,py);
1894 hlego->Fill(px-1,5*py);
1895 hlego->Fill(2+0.5*px,2*py-10.,0.1);
1896 }
1897 hlego->Draw("LEGO");
1898}
1899End_Macro
1900
1901The following example shows a 2D histogram plotted with the option
1902`LEGO1`. The option `LEGO1` draws a lego plot using the
1903hidden surface removal technique. Combined with any `LEGOn` option, the
1904option `0` allows to not drawn the empty bins.
1905
1906Begin_Macro(source)
1907{
1908 auto c2 = new TCanvas("c2","c2",600,400);
1909 auto hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1910 Float_t px, py;
1911 for (Int_t i = 0; i < 25000; i++) {
1912 gRandom->Rannor(px,py);
1913 hlego1->Fill(px-1,5*py);
1914 hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1915 }
1916 hlego1->SetFillColor(kYellow);
1917 hlego1->Draw("LEGO1 0");
1918}
1919End_Macro
1920
1921The following example shows a 2D histogram plotted with the option
1922`LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1923draws a lego plot using the hidden surface removal technique but doesn't draw
1924the border lines of each individual lego-bar. This is very useful for histograms
1925having many bins. With such histograms the option `LEGO1` gives a black
1926image because of the border lines. This option also works with stacked legos.
1927
1928Begin_Macro(source)
1929{
1930 auto c2 = new TCanvas("c2","c2",600,400);
1931 auto hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1932 Float_t px, py;
1933 for (Int_t i = 0; i < 25000; i++) {
1934 gRandom->Rannor(px,py);
1935 hlego3->Fill(px-1,5*py);
1936 hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1937 }
1938 hlego3->SetFillColor(kRed);
1939 hlego3->Draw("LEGO3");
1940}
1941End_Macro
1942
1943The following example shows a 2D histogram plotted with the option
1944`LEGO2`. The option `LEGO2` draws a lego plot using colors to
1945show the cell contents. Combined with the option `LEGO2`, the option
1946`Z` allows to display the color palette defined by
1947`gStyle->SetPalette()`.
1948
1949Begin_Macro(source)
1950{
1951 auto c2 = new TCanvas("c2","c2",600,400);
1952 auto hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1953 Float_t px, py;
1954 for (Int_t i = 0; i < 25000; i++) {
1955 gRandom->Rannor(px,py);
1956 hlego2->Fill(px-1,5*py);
1957 hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1958 }
1959 hlego2->Draw("LEGO2Z");
1960}
1961End_Macro
1962
1963
1964
1965### <a name="HP18"></a> The "SURFace" options
1966
1967
1968In a surface plot, cell contents are represented as a mesh.
1969The height of the mesh is proportional to the cell content.
1970
1971| Option | Description |
1972|----------|-------------------------------------------------------------------|
1973| "SURF" | Draw a surface plot using the hidden line removal technique.|
1974| "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1975| "SURF2" | Draw a surface plot using colors to show the cell contents.|
1976| "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1977| "SURF4" | Draw a surface using the Gouraud shading technique.|
1978| "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1979| "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.|
1980| "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1981
1982
1983
1984See the limitations with [the option "SAME"](#HP060a).
1985
1986The following example shows a 2D histogram plotted with the option
1987`SURF`. The option `SURF` draws a lego plot using the hidden
1988lines removal technique.
1989
1990Begin_Macro(source)
1991{
1992 auto c2 = new TCanvas("c2","c2",600,400);
1993 auto hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1994 Float_t px, py;
1995 for (Int_t i = 0; i < 25000; i++) {
1996 gRandom->Rannor(px,py);
1997 hsurf->Fill(px-1,5*py);
1998 hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1999 }
2000 hsurf->Draw("SURF");
2001}
2002End_Macro
2003
2004The following example shows a 2D histogram plotted with the option
2005`SURF1`. The option `SURF1` draws a surface plot using the
2006hidden surface removal technique. Combined with the option `SURF1`,
2007the option `Z` allows to display the color palette defined by
2008`gStyle->SetPalette()`.
2009
2010Begin_Macro(source)
2011{
2012 auto c2 = new TCanvas("c2","c2",600,400);
2013 auto hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
2014 Float_t px, py;
2015 for (Int_t i = 0; i < 25000; i++) {
2016 gRandom->Rannor(px,py);
2017 hsurf1->Fill(px-1,5*py);
2018 hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
2019 }
2020 hsurf1->Draw("SURF1");
2021}
2022End_Macro
2023
2024The following example shows a 2D histogram plotted with the option
2025`SURF2`. The option `SURF2` draws a surface plot using colors
2026to show the cell contents. Combined with the option `SURF2`, the option
2027`Z` allows to display the color palette defined by
2028`gStyle->SetPalette()`.
2029
2030Begin_Macro(source)
2031{
2032 auto c2 = new TCanvas("c2","c2",600,400);
2033 auto hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
2034 Float_t px, py;
2035 for (Int_t i = 0; i < 25000; i++) {
2036 gRandom->Rannor(px,py);
2037 hsurf2->Fill(px-1,5*py);
2038 hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2039 }
2040 hsurf2->Draw("SURF2");
2041}
2042End_Macro
2043
2044The following example shows a 2D histogram plotted with the option
2045`SURF3`. The option `SURF3` draws a surface plot using the
2046hidden line removal technique with, in addition, a filled contour view drawn on the
2047top. Combined with the option `SURF3`, the option `Z` allows
2048to display the color palette defined by `gStyle->SetPalette()`.
2049
2050Begin_Macro(source)
2051{
2052 auto c2 = new TCanvas("c2","c2",600,400);
2053 auto hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2054 Float_t px, py;
2055 for (Int_t i = 0; i < 25000; i++) {
2056 gRandom->Rannor(px,py);
2057 hsurf3->Fill(px-1,5*py);
2058 hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2059 }
2060 hsurf3->Draw("SURF3");
2061}
2062End_Macro
2063
2064The following example shows a 2D histogram plotted with the option
2065`SURF4`. The option `SURF4` draws a surface using the Gouraud
2066shading technique.
2067
2068Begin_Macro(source)
2069{
2070 auto c2 = new TCanvas("c2","c2",600,400);
2071 auto hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2072 Float_t px, py;
2073 for (Int_t i = 0; i < 25000; i++) {
2074 gRandom->Rannor(px,py);
2075 hsurf4->Fill(px-1,5*py);
2076 hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2077 }
2078 hsurf4->SetFillColor(kOrange);
2079 hsurf4->Draw("SURF4");
2080}
2081End_Macro
2082
2083The following example shows a 2D histogram plotted with the option
2084`SURF5 CYL`. Combined with the option `SURF5`, the option
2085`Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2086
2087Begin_Macro(source)
2088{
2089 auto c2 = new TCanvas("c2","c2",600,400);
2090 auto hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2091 Float_t px, py;
2092 for (Int_t i = 0; i < 25000; i++) {
2093 gRandom->Rannor(px,py);
2094 hsurf5->Fill(px-1,5*py);
2095 hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2096 }
2097 hsurf5->Draw("SURF5 CYL");
2098}
2099End_Macro
2100
2101The following example shows a 2D histogram plotted with the option
2102`SURF7`. The option `SURF7` draws a surface plot using the
2103hidden surfaces removal technique with, in addition, a line contour view drawn on the
2104top. Combined with the option `SURF7`, the option `Z` allows
2105to display the color palette defined by `gStyle->SetPalette()`.
2106
2107Begin_Macro(source)
2108{
2109 auto c2 = new TCanvas("c2","c2",600,400);
2110 auto hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2111 Float_t px, py;
2112 for (Int_t i = 0; i < 25000; i++) {
2113 gRandom->Rannor(px,py);
2114 hsurf7->Fill(px-1,5*py);
2115 hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2116 }
2117 hsurf7->Draw("SURF7");
2118}
2119End_Macro
2120
2121As shown in the following example, when a contour plot is painted on top of a
2122surface plot using the option `SAME`, the contours appear in 3D on the
2123surface.
2124
2125Begin_Macro(source)
2126{
2127 auto c20=new TCanvas("c20","c20",600,400);
2128 int NBins = 50;
2129 double d = 2;
2130 auto hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2131 for (int bx = 1; bx <= NBins; ++bx) {
2132 for (int by = 1; by <= NBins; ++by) {
2133 double x = hsc->GetXaxis()->GetBinCenter(bx);
2134 double y = hsc->GetYaxis()->GetBinCenter(by);
2135 hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2136 }
2137 }
2138 hsc->Draw("surf2");
2139 hsc->Draw("CONT1 SAME");
2140}
2141End_Macro
2142
2143
2144### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2145
2146
2147Legos and surfaces plots are represented by default in Cartesian coordinates.
2148Combined with any `LEGOn` or `SURFn` options the following
2149options allow to draw a lego or a surface in other coordinates systems.
2150
2151| Option | Description |
2152|----------|-------------------------------------------------------------------|
2153| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2154| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2155| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2156| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2157
2158
2159
2160<b>WARNING:</b> Axis are not drawn with these options.
2161
2162The following example shows the same histogram as a lego plot is the four
2163different coordinates systems.
2164
2165Begin_Macro(source)
2166{
2167 auto c3 = new TCanvas("c3","c3",600,400);
2168 c3->Divide(2,2);
2169 auto hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2170 Float_t px, py;
2171 for (Int_t i = 0; i < 25000; i++) {
2172 gRandom->Rannor(px,py);
2173 hlcc->Fill(px-1,5*py);
2174 hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2175 }
2176 hlcc->SetFillColor(kYellow);
2177 c3->cd(1); hlcc->Draw("LEGO1 CYL");
2178 c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2179 hlpc->SetTitle("Polar coordinates");
2180 c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2181 hlsc->SetTitle("Spherical coordinates");
2182 c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2183 hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2184}
2185End_Macro
2186
2187The following example shows the same histogram as a surface plot is the four different coordinates systems.
2188
2189Begin_Macro(source)
2190{
2191 auto c4 = new TCanvas("c4","c4",600,400);
2192 c4->Divide(2,2);
2193 auto hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2194 Float_t px, py;
2195 for (Int_t i = 0; i < 25000; i++) {
2196 gRandom->Rannor(px,py);
2197 hscc->Fill(px-1,5*py);
2198 hscc->Fill(2+0.5*px,2*py-10.,0.1);
2199 }
2200 c4->cd(1); hscc->Draw("SURF1 CYL");
2201 c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2202 hspc->SetTitle("Polar coordinates");
2203 c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2204 hssc->SetTitle("Spherical coordinates");
2205 c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2206 hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2207}
2208End_Macro
2209
2210
2211### <a name="HP20"></a> Base line for bar-charts and lego plots
2212
2213
2214By default the base line used to draw the boxes for bar-charts and lego plots is
2215the histogram minimum. It is possible to force this base line to be 0, using MIN0 draw
2216option or with the command:
2217
2218 gStyle->SetHistMinimumZero();
2219
2220Begin_Macro(source)
2221{
2222 auto c5 = new TCanvas("c5","c5",700,400);
2223 c5->Divide(2,1);
2224 auto hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2225 auto hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2226 Int_t i;
2227 Double_t x,y;
2228 hz1->SetFillColor(kBlue);
2229 hz2->SetFillColor(kBlue);
2230 for (i=0;i<10000;i++) {
2231 x = gRandom->Gaus(0,1);
2232 y = gRandom->Gaus(0,1);
2233 if (x>0) {
2234 hz1->Fill(x,1);
2235 hz2->Fill(x,y,1);
2236 } else {
2237 hz1->Fill(x,-1);
2238 hz2->Fill(x,y,-2);
2239 }
2240 }
2241 c5->cd(1); hz1->Draw("bar2 min0");
2242 c5->cd(2); hz2->Draw("lego1 min0");
2243}
2244End_Macro
2245
2246This option also works for horizontal plots. The example given in the section
2247["The bar chart option"](#HP100) appears as follow:
2248
2249Begin_Macro(source)
2250{
2251 int i;
2252 const Int_t nx = 8;
2253 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2254 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2255 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2256
2257 auto cbh = new TCanvas("cbh","cbh",400,600);
2258 cbh->SetGrid();
2259
2260 auto h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2261 h1bh->SetFillColor(4);
2262 h1bh->SetBarWidth(0.4);
2263 h1bh->SetBarOffset(0.1);
2264 h1bh->SetStats(0);
2265 h1bh->SetMinimum(-5);
2266 h1bh->SetMaximum(5);
2267
2268 for (i=1; i<=nx; i++) {
2269 h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2270 h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2271 }
2272
2273 h1bh->Draw("hbar min0");
2274
2275 auto h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2276 h2bh->SetFillColor(38);
2277 h2bh->SetBarWidth(0.4);
2278 h2bh->SetBarOffset(0.5);
2279 h2bh->SetStats(0);
2280 for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2281
2282 h2bh->Draw("hbar min0 same");
2283}
2284End_Macro
2285
2286
2287### <a name="HP20a"></a> TH2Poly Drawing
2288
2289
2290The following options are supported:
2291
2292| Option | Description |
2293|----------|-------------------------------------------------------------------|
2294| "SCAT" | Draw a scatter plot (default).|
2295| "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2296| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2297| "0" | When used with any COL options, the empty bins are not drawn.|
2298| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2299| "TEXTN" | Draw bin names as text.|
2300| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2301| "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2302| "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2303| "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2304
2305
2306
2307`TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2308shapes. The bins are defined as graphs. The following macro is a very simple
2309example showing how to book a TH2Poly and draw it.
2310
2311Begin_Macro(source)
2312{
2313 auto ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2314 auto h2p = new TH2Poly();
2315 h2p->SetName("h2poly_name");
2316 h2p->SetTitle("h2poly_title");
2317 Double_t px1[] = {0, 5, 6};
2318 Double_t py1[] = {0, 0, 5};
2319 Double_t px2[] = {0, -1, -1, 0};
2320 Double_t py2[] = {0, 0, -1, 3};
2321 Double_t px3[] = {4, 3, 0, 1, 2.4};
2322 Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
2323 h2p->AddBin(3, px1, py1);
2324 h2p->AddBin(4, px2, py2);
2325 h2p->AddBin(5, px3, py3);
2326 h2p->Fill(0.1, 0.01, 3);
2327 h2p->Fill(-0.5, -0.5, 7);
2328 h2p->Fill(-0.7, -0.5, 1);
2329 h2p->Fill(1, 3, 1.5);
2330 Double_t fx[] = {0.1, -0.5, -0.7, 1};
2331 Double_t fy[] = {0.01, -0.5, -0.5, 3};
2332 Double_t fw[] = {3, 1, 1, 1.5};
2333 h2p->FillN(4, fx, fy, fw);
2334 h2p->Draw("col");
2335}
2336End_Macro
2337
2338Rectangular bins are a frequent case. The special version of
2339the `AddBin` method allows to define them more easily like
2340shown in the following example (th2polyBoxes.C).
2341
2342Begin_Macro(source)
2343../../../tutorials/hist/th2polyBoxes.C
2344End_Macro
2345
2346One `TH2Poly` bin can be a list of polygons. Such bins are defined
2347by calling `AddBin` with a `TMultiGraph`. The following example
2348shows a such case:
2349
2350Begin_Macro(source)
2351{
2352 auto ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2353
2354 Int_t i, bin;
2355 const Int_t nx = 48;
2356 const char *states [nx] = {
2357 "alabama", "arizona", "arkansas", "california",
2358 "colorado", "connecticut", "delaware", "florida",
2359 "georgia", "idaho", "illinois", "indiana",
2360 "iowa", "kansas", "kentucky", "louisiana",
2361 "maine", "maryland", "massachusetts", "michigan",
2362 "minnesota", "mississippi", "missouri", "montana",
2363 "nebraska", "nevada", "new_hampshire", "new_jersey",
2364 "new_mexico", "new_york", "north_carolina", "north_dakota",
2365 "ohio", "oklahoma", "oregon", "pennsylvania",
2366 "rhode_island", "south_carolina", "south_dakota", "tennessee",
2367 "texas", "utah", "vermont", "virginia",
2368 "washington", "west_virginia", "wisconsin", "wyoming"
2369 };
2370 Double_t pop[nx] = {
2371 4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2372 9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2373 1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2374 1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2375 11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2376 24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2377 };
2378
2379 Double_t lon1 = -130;
2380 Double_t lon2 = -65;
2381 Double_t lat1 = 24;
2382 Double_t lat2 = 50;
2383 auto p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2384
2385 TFile::SetCacheFileDir(".");
2386 TFile *f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2387
2388 TMultiGraph *mg;
2389 TKey *key;
2390 TIter nextkey(gDirectory->GetListOfKeys());
2391 while ((key = (TKey*)nextkey())) {
2392 TObject *obj = key->ReadObj();
2393 if (obj->InheritsFrom("TMultiGraph")) {
2394 mg = (TMultiGraph*)obj;
2395 bin = p->AddBin(mg);
2396 }
2397 }
2398
2399 for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2400
2401 gStyle->SetOptStat(11);
2402 p->Draw("COLZ L");
2403}
2404End_Macro
2405
2406`TH2Poly` histograms can also be plotted using the GL interface using
2407the option "GLLEGO".
2408
2409\since **ROOT version 6.09/01**
2410
2411In some cases it can be useful to not draw the empty bins. the option "0"
2412combined with the option "COL" et COLZ allows to do that.
2413
2414Begin_Macro(source)
2415{
2416 auto chc = new TCanvas("chc","chc",600,400);
2417
2418 auto hc = new TH2Poly();
2419 hc->Honeycomb(0,0,.1,25,25);
2420 hc->SetName("hc");
2421 hc->SetTitle("Option COLZ 0");
2422 TRandom ran;
2423 for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2424 hc->Draw("colz 0");
2425}
2426End_Macro
2427
2428### <a name="HP21"></a> The SPEC option
2429
2430
2431This option allows to use the `TSpectrum2Painter` tools. See the full
2432documentation in `TSpectrum2Painter::PaintSpectrum`.
2433
2434
2435### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2436
2437
2438When this option is specified, a color palette with an axis indicating the value
2439of the corresponding color is drawn on the right side of the picture. In case,
2440not enough space is left, one can increase the size of the right margin by
2441calling `TPad::SetRightMargin()`. The attributes used to display the
2442palette axis values are taken from the Z axis of the object. For example, to
2443set the labels size on the palette axis do:
2444
2445 hist->GetZaxis()->SetLabelSize().
2446
2447<b>WARNING:</b> The palette axis is always drawn vertically.
2448
2449
2450### <a name="HP23"></a> Setting the color palette
2451
2452
2453To change the color palette `TStyle::SetPalette` should be used, eg:
2454
2455 gStyle->SetPalette(ncolors,colors);
2456
2457For example the option `COL` draws a 2D histogram with cells
2458represented by a box filled with a color index which is a function
2459of the cell content.
2460If the cell content is N, the color index used will be the color number
2461in `colors[N]`, etc. If the maximum cell content is greater than
2462`ncolors`, all cell contents are scaled to `ncolors`.
2463
2464If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2465defined. This palette is recommended for pads, labels ...
2466
2467`if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2468Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2469palette.
2470
2471Other pre-defined palettes with 255 colors are available when `colors == 0`.
2472The following value of `ncolors` give access to:
2473
2474
2475 if ncolors = 51 and colors=0, a Deep Sea palette is used.
2476 if ncolors = 52 and colors=0, a Grey Scale palette is used.
2477 if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2478 if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2479 if ncolors = 55 and colors=0, a Rain Bow palette is used.
2480 if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2481
2482
2483If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2484
2485The default palette defines:
2486
2487- index 0 to 9 : shades of grey
2488- index 10 to 19 : shades of brown
2489- index 20 to 29 : shades of blue
2490- index 30 to 39 : shades of red
2491- index 40 to 49 : basic colors
2492
2493The color numbers specified in the palette can be viewed by selecting
2494the item `colors` in the `VIEW` menu of the canvas tool bar.
2495The red, green, and blue components of a color can be changed thanks to
2496`TColor::SetRGB()`.
2497
2498
2499### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2500
2501
2502Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2503histogram. One must create a graphical cut (mouse or C++) and specify the name
2504of the cut between `[]` in the `Draw()` option.
2505For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2506
2507 myhist->Draw("surf1 [cutg]");
2508
2509To invert the cut, it is enough to put a `-` in front of its name:
2510
2511 myhist->Draw("surf1 [-cutg]");
2512
2513It is possible to apply several cuts (`,` means logical AND):
2514
2515 myhist->Draw("surf1 [cutg1,cutg2]");
2516
2517Begin_Macro(source)
2518../../../tutorials/fit/fit2a.C
2519End_Macro
2520
2521### <a name="HP25"></a> Drawing options for 3D histograms
2522
2523
2524| Option | Description |
2525|----------|-------------------------------------------------------------------|
2526| "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)`|
2527| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2528| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2529| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2530| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2531| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2532
2533Note that instead of `BOX` one can also use `LEGO`.
2534
2535By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2536
2537The following example shows a 3D histogram plotted as a scatter plot.
2538
2539Begin_Macro(source)
2540{
2541 auto c06 = new TCanvas("c06","c06",600,400);
2542 gStyle->SetOptStat(kFALSE);
2543 auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2544 Double_t x, y, z;
2545 for (Int_t i=0;i<10000;i++) {
2546 gRandom->Rannor(x, y);
2547 z = x*x + y*y;
2548 h3scat->Fill(x,y,z);
2549 }
2550 h3scat->Draw();
2551}
2552End_Macro
2553
2554The following example shows a 3D histogram plotted with the option `BOX`.
2555
2556Begin_Macro(source)
2557{
2558 auto c16 = new TCanvas("c16","c16",600,400);
2559 gStyle->SetOptStat(kFALSE);
2560 auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2561 Double_t x, y, z;
2562 for (Int_t i=0;i<10000;i++) {
2563 gRandom->Rannor(x, y);
2564 z = x*x + y*y;
2565 h3box->Fill(x,y,z);
2566 }
2567 h3box->Draw("BOX");
2568}
2569End_Macro
2570
2571The following example shows a 3D histogram plotted with the option `BOX1`.
2572
2573Begin_Macro(source)
2574{
2575 auto c36 = new TCanvas("c36","c36",600,400);
2576 gStyle->SetOptStat(kFALSE);
2577 auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2578 Double_t x, y, z;
2579 for (Int_t i=0;i<10000;i++) {
2580 gRandom->Rannor(x, y);
2581 z = abs(sin(x)/x + cos(y)*y);
2582 h3box->Fill(x,y,z);
2583 }
2584 h3box->SetFillColor(9);
2585 h3box->Draw("BOX1");
2586}
2587End_Macro
2588
2589The following example shows a 3D histogram plotted with the option `BOX2`.
2590
2591Begin_Macro(source)
2592{
2593 auto c56 = new TCanvas("c56","c56",600,400);
2594 gStyle->SetOptStat(kFALSE);
2595 auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2596 Double_t x, y, z;
2597 for (Int_t i=0;i<10000;i++) {
2598 gRandom->Rannor(x, y);
2599 z = abs(sin(x)/x + cos(y)*y);
2600 h3box->Fill(x,y,z);
2601 }
2602 h3box->Draw("BOX2 Z");
2603}
2604End_Macro
2605
2606The following example shows a 3D histogram plotted with the option `BOX3`.
2607
2608Begin_Macro(source)
2609{
2610 auto c46 = new TCanvas("c46","c46",600,400);
2611 c46->SetFillColor(38);
2612 gStyle->SetOptStat(kFALSE);
2613 auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2614 Double_t x, y, z;
2615 for (Int_t i=0;i<10000;i++) {
2616 gRandom->Rannor(x, y);
2617 z = x*x + y*y;
2618 h3box->Fill(x,y,z);
2619 }
2620 h3box->Draw("BOX3");
2621}
2622End_Macro
2623
2624For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2625to the absolute value of the bin content. The bins with a negative content are
2626drawn with a X on each face of the box as shown in the following example:
2627
2628Begin_Macro(source)
2629{
2630 auto c = new TCanvas("c","c",600,400);
2631 gStyle->SetOptStat(kFALSE);
2632 auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2633 h3box->Fill(0., 2., 2., 10.);
2634 h3box->Fill(2., 2., 2., 5.);
2635 h3box->Fill(2., 2., .5, 2.);
2636 h3box->Fill(2., 2., 3., -1.);
2637 h3box->Fill(3., 2., 2., -10.);
2638 h3box->SetFillColor(8);
2639 h3box->Draw("box1");
2640}
2641End_Macro
2642
2643The following example shows a 3D histogram plotted with the option `ISO`.
2644
2645Begin_Macro(source)
2646{
2647 auto c26 = new TCanvas("c26","c26",600,400);
2648 gStyle->SetOptStat(kFALSE);
2649 auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2650 Double_t x, y, z;
2651 for (Int_t i=0;i<10000;i++) {
2652 gRandom->Rannor(x, y);
2653 z = x*x + y*y;
2654 h3iso->Fill(x,y,z);
2655 }
2656 h3iso->SetFillColor(kCyan);
2657 h3iso->Draw("ISO");
2658}
2659End_Macro
2660
2661
2662### <a name="HP26"></a> Drawing option for histograms' stacks
2663
2664
2665Stacks of histograms are managed with the `THStack`. A `THStack`
2666is a collection of `TH1` (or derived) objects. For painting only the
2667`THStack` containing `TH1` only or
2668`THStack` containing `TH2` only will be considered.
2669
2670By default, histograms are shown stacked:
2671
26721. The first histogram is paint.
26732. The the sum of the first and second, etc...
2674
2675If the option `NOSTACK` is specified, the histograms are all paint in
2676the same pad as if the option `SAME` had been specified. This allows to
2677compute X and Y scales common to all the histograms, like
2678`TMultiGraph` does for graphs.
2679
2680If the option `PADS` is specified, the current pad/canvas is
2681subdivided into a number of pads equal to the number of histograms and each
2682histogram is paint into a separate pad.
2683
2684The following example shows various types of stacks (hstack.C).
2685
2686Begin_Macro(source)
2687../../../tutorials/hist/hstack.C
2688End_Macro
2689
2690The option `nostackb` allows to draw the histograms next to each
2691other as bar charts:
2692
2693Begin_Macro(source)
2694{
2695 auto cst0 = new TCanvas("cst0","cst0",600,400);
2696 THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2697
2698 TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2699 h1->FillRandom("gaus",20000);
2700 h1->SetFillColor(kRed);
2701 hs->Add(h1);
2702
2703 auto h2 = new TH1F("h2","h2",10,-4,4);
2704 h2->FillRandom("gaus",15000);
2705 h2->SetFillColor(kBlue);
2706 hs->Add(h2);
2707
2708 auto h3 = new TH1F("h3","h3",10,-4,4);
2709 h3->FillRandom("gaus",10000);
2710 h3->SetFillColor(kGreen);
2711 hs->Add(h3);
2712
2713 hs->Draw("nostackb");
2714 hs->GetXaxis()->SetNdivisions(-10);
2715 cst0->SetGridx();
2716}
2717End_Macro
2718
2719If at least one of the histograms in the stack has errors, the whole stack is
2720visualized by default with error bars. To visualize it without errors the
2721option `HIST` should be used.
2722
2723Begin_Macro(source)
2724{
2725 auto cst1 = new TCanvas("cst1","cst1",700,400);
2726 cst1->Divide(2,1);
2727
2728 auto hst11 = new TH1F("hst11", "", 20, -10, 10);
2729 hst11->Sumw2();
2730 hst11->FillRandom("gaus", 1000);
2731 hst11->SetFillColor(kViolet);
2732 hst11->SetLineColor(kViolet);
2733
2734 auto hst12 = new TH1F("hst12", "", 20, -10, 10);
2735 hst12->FillRandom("gaus", 500);
2736 hst12->SetFillColor(kBlue);
2737 hst12->SetLineColor(kBlue);
2738
2739 THStack st1("st1", "st1");
2740 st1.Add(hst11);
2741 st1.Add(hst12);
2742
2743 cst1->cd(1); st1.Draw();
2744 cst1->cd(2); st1.Draw("hist");
2745}
2746End_Macro
2747
2748### <a name="HP27"></a> Drawing of 3D implicit functions
2749
2750
27513D implicit functions (`TF3`) can be drawn as iso-surfaces.
2752The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2753In the following example the options "FB" and "BB" suppress the
2754"Front Box" and "Back Box" around the plot.
2755
2756Begin_Macro(source)
2757{
2758 auto c2 = new TCanvas("c2","c2",600,400);
2759 auto f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2760 f3->SetClippingBoxOn(0,0,0);
2761 f3->SetFillColor(30);
2762 f3->SetLineColor(15);
2763 f3->Draw("FBBB");
2764}
2765End_Macro
2766
2767
2768### <a name="HP28"></a> Associated functions drawing
2769
2770
2771An associated function is created by `TH1::Fit`. More than on fitted
2772function can be associated with one histogram (see `TH1::Fit`).
2773
2774A `TF1` object `f1` can be added to the list of associated
2775functions of an histogram `h` without calling `TH1::Fit`
2776simply doing:
2777
2778 h->GetListOfFunctions()->Add(f1);
2779
2780or
2781
2782 h->GetListOfFunctions()->Add(f1,someoption);
2783
2784To retrieve a function by name from this list, do:
2785
2786 TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2787
2788or
2789
2790 TF1 *f1 = h->GetFunction(name);
2791
2792Associated functions are automatically painted when an histogram is drawn.
2793To avoid the painting of the associated functions the option `HIST`
2794should be added to the list of the options used to paint the histogram.
2795
2796
2797### <a name="HP29"></a> Drawing using OpenGL
2798
2799
2800The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2801graphics library. The plotting options start with `GL` keyword.
2802In addition, in order to inform canvases that OpenGL should be used to render
28033D representations, the following option should be set:
2804
2805 gStyle->SetCanvasPreferGL(true);
2806
2807
2808#### <a name="HP29a"></a> General information: plot types and supported options
2809
2810The following types of plots are provided:
2811
2812For lego plots the supported options are:
2813
2814| Option | Description |
2815|----------|-------------------------------------------------------------------|
2816| "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2817| "GLLEGO2"| Bins with color levels.|
2818| "GLLEGO3"| Cylindrical bars.|
2819
2820
2821
2822Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2823In polar only Z axis can be logarithmic, in cylindrical only Y.
2824
2825For surface plots (`TF2` and `TH2`) the supported options are:
2826
2827| Option | Description |
2828|-----------|------------------------------------------------------------------|
2829| "GLSURF" | Draw a surface.|
2830| "GLSURF1" | Surface with color levels|
2831| "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2832| "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2833| "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2834
2835
2836
2837The surface painting in cartesian coordinates supports logarithmic scales along
2838X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2839in cylindrical coordinates only the Y axis.
2840
2841Additional options to SURF and LEGO - Coordinate systems:
2842
2843| Option | Description |
2844|----------|-------------------------------------------------------------------|
2845| " " | Default, cartesian coordinates system.|
2846| "POL" | Polar coordinates system.|
2847| "CYL" | Cylindrical coordinates system.|
2848| "SPH" | Spherical coordinates system.|
2849
2850
2851
2852#### <a name="HP290"></a> TH3 as color boxes
2853
2854The supported option is:
2855
2856| Option | Description |
2857|----------|-------------------------------------------------------------------|
2858| "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2859
2860
2861
2862#### <a name="HP29b"></a> TH3 as boxes (spheres)
2863
2864The supported options are:
2865
2866| Option | Description |
2867|----------|-------------------------------------------------------------------|
2868| "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2869| "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2870
2871
2872
2873#### <a name="HP29c"></a> TH3 as iso-surface(s)
2874
2875The supported option is:
2876
2877| Option | Description |
2878|----------|-------------------------------------------------------------------|
2879| "GLISO" | TH3 is drawn using iso-surfaces.|
2880
2881
2882
2883#### <a name="HP29d"></a> TF3 (implicit function)
2884
2885The supported option is:
2886
2887| Option | Description |
2888|----------|-------------------------------------------------------------------|
2889| "GLTF3" | Draw a TF3.|
2890
2891
2892
2893#### <a name="HP29e"></a> Parametric surfaces
2894
2895`$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2896equations and visualize the surface.
2897
2898#### <a name="HP29f"></a> Interaction with the plots
2899
2900All the interactions are implemented via standard methods
2901`DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2902interactions with the OpenGL plots are possible only when the mouse cursor is
2903in the plot's area (the plot's area is the part of a the pad occupied by
2904gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2905pad interaction is performed.
2906
2907#### <a name="HP29g"></a> Selectable parts
2908
2909Different parts of the plot can be selected:
2910
2911- xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2912 if the dynamic slicing by this plane is supported, and it's highlighted in red,
2913 if the dynamic slicing is not supported.
2914- The plot itself:
2915 On surfaces, the selected surface is outlined in red. (TF3 and
2916 ISO are not outlined). On lego plots, the selected bin is
2917 highlighted. The bin number and content are displayed in pad's
2918 status bar. In box plots, the box or sphere is highlighted and
2919 the bin info is displayed in pad's status bar.
2920
2921
2922#### <a name="HP29h"></a> Rotation and zooming
2923
2924
2925- Rotation:
2926 When the plot is selected, it can be rotated by pressing and
2927 holding the left mouse button and move the cursor.
2928- Zoom/Unzoom:
2929 Mouse wheel or 'j', 'J', 'k', 'K' keys.
2930
2931
2932#### <a name="HP29i"></a> Panning
2933
2934The selected plot can be moved in a pad's area by pressing and
2935holding the left mouse button and the shift key.
2936
2937#### <a name="HP29j"></a> Box cut
2938
2939Surface, iso, box, TF3 and parametric painters support box cut by
2940pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2941area. That will display a transparent box, cutting away part of the
2942surface (or boxes) in order to show internal part of plot. This box
2943can be moved inside the plot's area (the full size of the box is
2944equal to the plot's surrounding box) by selecting one of the box
2945cut axes and pressing the left mouse button to move it.
2946
2947#### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2948
2949Currently, all gl-plots support some form of slicing. When back plane
2950is selected (and if it's highlighted in green) you can press and hold
2951left mouse button and shift key and move this back plane inside
2952plot's area, creating the slice. During this "slicing" plot becomes
2953semi-transparent. To remove all slices (and projected curves for
2954surfaces) double click with left mouse button in a plot's area.
2955
2956#### <a name="HP29l"></a> Surface with option "GLSURF"
2957
2958The surface profile is displayed on the slicing plane.
2959The profile projection is drawn on the back plane
2960by pressing `'p'` or `'P'` key.
2961
2962#### <a name="HP29m"></a> TF3
2963
2964The contour plot is drawn on the slicing plane. For TF3 the color
2965scheme can be changed by pressing 's' or 'S'.
2966
2967#### <a name="HP29n"></a> Box
2968
2969The contour plot corresponding to slice plane position is drawn in real time.
2970
2971#### <a name="HP29o"></a> Iso
2972
2973Slicing is similar to "GLBOX" option.
2974
2975#### <a name="HP29p"></a> Parametric plot
2976
2977No slicing. Additional keys: 's' or 'S' to change color scheme -
2978about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2979increase number of polygons ('l' for "level" of details), 'w' or 'W'
2980to show outlines ('w' for "wireframe").
2981
2982#### <a name="HP30"></a> Highlight mode for histogram
2983
2984\since **ROOT version 6.15/01**
2985
2986\image html hlHisto3_top.gif "Highlight mode"
2987
2988Highlight mode is implemented for `TH1` (and for `TGraph`) class. When
2989highlight mode is on, mouse movement over the bin will be represented
2990graphically. Bin will be highlighted as "bin box" (presented by box
2991object). Moreover, any highlight (change of bin) emits signal
2992`TCanvas::Highlighted()` which allows the user to react and call their own
2993function. For a better understanding see also the tutorials
2994`$ROOTSYS/tutorials/hist/hlHisto*.C` files.
2995
2996Highlight mode is switched on/off by `TH1::SetHighlight()` function
2997or interactively from `TH1` context menu. `TH1::IsHighlight()` to verify
2998whether the highlight mode enabled or disabled, default it is disabled.
2999
3000~~~ {.cpp}
3001 root [0] .x $ROOTSYS/tutorials/hsimple.C
3002 root [1] hpx->SetHighlight(kTRUE) // or interactively from TH1 context menu
3003 root [2] hpx->IsHighlight()
3004 (bool) true
3005~~~
3006
3007\image html hlsimple_nofun.gif "Highlight mode for histogram"
3008
3009#### <a name="HP30a"></a> Highlight mode and user function
3010
3011The user can use (connect) `TCanvas::Highlighted()` signal, which is always
3012emitted if there is a highlight bin and call user function via signal
3013and slot communication mechanism. `TCanvas::Highlighted()` is similar
3014`TCanvas::Picked()`
3015
3016- when selected object (histogram as a whole) is different from previous
3017then emit `Picked()` signal
3018- when selected (highlighted) bin from histogram is different from previous
3019then emit `Highlighted()` signal
3020
3021Any user function (or functions) has to be defined
3022`UserFunction(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)`.
3023In example (see below) has name `PrintInfo()`. All parameters of user
3024function are taken from
3025
3026 void TCanvas::Highlighted(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3027
3028- `pad` is pointer to pad with highlighted histogram
3029- `obj` is pointer to highlighted histogram
3030- `x` is highlighted x bin for 1D histogram
3031- `y` is highlighted y bin for 2D histogram (for 1D histogram not in use)
3032
3033Example how to create a connection from any `TCanvas` object to a user
3034`UserFunction()` slot (see also `TQObject::Connect()` for additional info)
3035
3036 TQObject::Connect("TCanvas", "Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
3037 0, 0, "UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3038
3039or use non-static "simplified" function
3040`TCanvas::HighlightConnect(const char *slot)`
3041
3042 c1->HighlightConnect("UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3043
3044NOTE the signal and slot string must have a form
3045"(TVirtualPad*,TObject*,Int_t,Int_t)"
3046
3047 root [0] .x $ROOTSYS/tutorials/hsimple.C
3048 root [1] hpx->SetHighlight(kTRUE)
3049 root [2] .x hlprint.C
3050
3051file `hlprint.C`
3052~~~ {.cpp}
3053void PrintInfo(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3054{
3055 TH1F *h = (TH1F *)obj;
3056 if (!h->IsHighlight()) // after highlight disabled
3057 h->SetTitle("highlight disable");
3058 else
3059 h->SetTitle(TString::Format("bin[%03d] (%5.2f) content %g", x,
3060 h->GetBinCenter(x), h->GetBinContent(x)));
3061 pad->Update();
3062}
3063
3064void hlprint()
3065{
3066 if (!gPad) return;
3067 gPad->GetCanvas()->HighlightConnect("PrintInfo(TVirtualPad*,TObject*,Int_t,Int_t)");
3068}
3069~~~
3070
3071\image html hlsimple.gif "Highlight mode and simple user function"
3072
3073For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperature.C` file.
3074
3075*/
3076
3078
3081
3082const Int_t kNMAX = 2000;
3083
3084const Int_t kMAXCONTOUR = 104;
3086
3087static TBox *gXHighlightBox = 0; // highlight X box
3088static TBox *gYHighlightBox = 0; // highlight Y box
3089
3111
3113
3114////////////////////////////////////////////////////////////////////////////////
3115/// Default constructor.
3116
3118{
3119
3120 fH = 0;
3121 fXaxis = 0;
3122 fYaxis = 0;
3123 fZaxis = 0;
3124 fFunctions = 0;
3125 fXbuf = 0;
3126 fYbuf = 0;
3127 fNcuts = 0;
3128 fStack = 0;
3129 fLego = 0;
3130 fPie = 0;
3131 fGraph2DPainter = 0;
3132 fShowProjection = 0;
3133 fShowOption = "";
3134 for (int i=0; i<kMaxCuts; i++) {
3135 fCuts[i] = 0;
3136 fCutsOpt[i] = 0;
3137 }
3138 fXHighlightBin = -1;
3139 fYHighlightBin = -1;
3140
3141 gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
3142 gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
3143 gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
3144 gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
3145 gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3146 gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3147 gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3148 gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3149 gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3150 gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3151 gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3152 gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3153 gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3154 gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3155 gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3156 gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3157 gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3158 gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3159 gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3160 gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3161 gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3162}
3163
3164////////////////////////////////////////////////////////////////////////////////
3165/// Default destructor.
3166
3168{
3169}
3170
3171////////////////////////////////////////////////////////////////////////////////
3172/// Compute the distance from the point px,py to a line.
3173///
3174/// Compute the closest distance of approach from point px,py to elements of
3175/// an histogram. The distance is computed in pixels units.
3176///
3177/// Algorithm: Currently, this simple model computes the distance from the mouse
3178/// to the histogram contour only.
3179
3181{
3182
3183 Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3184
3185 const Int_t big = 9999;
3186 const Int_t kMaxDiff = 7;
3187
3188 if (fPie) return fPie->DistancetoPrimitive(px, py);
3189
3190 Double_t x = gPad->AbsPixeltoX(px);
3191 Double_t x1 = gPad->AbsPixeltoX(px+1);
3192
3193 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3194 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3195 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3196 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3197 Int_t curdist = big;
3198 Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3199 Bool_t dsame;
3200 TObject *PadPointer = gPad->GetPadPointer();
3201 if (!PadPointer) return 0;
3202 TString doption = PadPointer->GetDrawOption();
3203 Double_t factor = 1;
3204 if (fH->GetNormFactor() != 0) {
3205 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3206 }
3207 // return if point is not in the histogram area
3208
3209 // If a 3D view exists, check distance to axis
3210 TView *view = gPad->GetView();
3211 Int_t d1,d2,d3;
3212 if (view && Hoption.Contour != 14) {
3213 Double_t ratio;
3214 d3 = view->GetDistancetoAxis(3, px, py, ratio);
3215 if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3216 d1 = view->GetDistancetoAxis(1, px, py, ratio);
3217 if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3218 d2 = view->GetDistancetoAxis(2, px, py, ratio);
3219 if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3220 if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3221 goto FUNCTIONS;
3222 }
3223 // check if point is close to an axis
3224 doption.ToLower();
3225 dsame = kFALSE;
3226 if (doption.Contains("same")) dsame = kTRUE;
3227
3228 dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3229 if (doption.Contains("y+")) {
3230 xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3231 if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3232 if (!dsame) {
3233 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3234 else gPad->SetSelected(fXaxis);
3235 return 0;
3236 }
3237 }
3238 } else {
3239 xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3240 if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3241 if (!dsame) {
3242 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3243 else gPad->SetSelected(fXaxis);
3244 return 0;
3245 }
3246 }
3247 }
3248
3249 dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3250 if (doption.Contains("x+")) {
3251 yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3252 if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3253 if (!dsame) {
3254 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3255 else gPad->SetSelected(fYaxis);
3256 return 0;
3257 }
3258 }
3259 } else {
3260 yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3261 if (yxaxis < puymin) yxaxis = puymin;
3262 if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3263 if (!dsame) {
3264 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3265 else gPad->SetSelected(fYaxis);
3266 return 0;
3267 }
3268 }
3269 }
3270
3271 if (fH->IsHighlight()) { // only if highlight is enable
3272 if ((px > puxmin) && (py < puymin) && (px < puxmax) && (py > puymax))
3273 HighlightBin(px, py);
3274 }
3275
3276 // if object is 2D or 3D return this object
3277 if (fH->GetDimension() == 2) {
3278 if (fH->InheritsFrom(TH2Poly::Class())) {
3279 TH2Poly *th2 = (TH2Poly*)fH;
3281 gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3282 Double_t pxu = gPad->AbsPixeltoX(px);
3283 Double_t pyu = gPad->AbsPixeltoY(py);
3284 if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3285 curdist = big;
3286 goto FUNCTIONS;
3287 } else {
3288 Int_t bin = th2->FindBin(pxu, pyu);
3289 if (bin>0) curdist = 1;
3290 else curdist = big;
3291 goto FUNCTIONS;
3292 }
3293 }
3294 Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3295 if ( px > puxmin + delta2
3296 && px < puxmax - delta2
3297 && py > puymax + delta2
3298 && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3299 }
3300
3301 // point is inside histogram area. Find channel number
3302 if (gPad->IsVertical()) {
3303 Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3304 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3305 Double_t binval = factor*fH->GetBinContent(bin);
3306 Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3307 if (binval == 0 && pybin < puymin) pybin = 10000;
3308 // special case if more than one bin for the pixel
3309 if (binsup-bin>1) {
3310 Double_t binvalmin, binvalmax;
3311 binvalmin=binval;
3312 binvalmax=binval;
3313 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3314 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3315 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3316 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3317 }
3318 Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3319 Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3320 if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3321 }
3322 if (bin != binsup) { // Mouse on bin border
3323 Double_t binsupval = factor*fH->GetBinContent(binsup);
3324 Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3325 if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3326 }
3327 if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3328 } else {
3329 Double_t y = gPad->AbsPixeltoY(py);
3330 Double_t y1 = gPad->AbsPixeltoY(py+1);
3331 Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3332 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3333 Double_t binval = factor*fH->GetBinContent(bin);
3334 Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3335 if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3336 // special case if more than one bin for the pixel
3337 if (binsup-bin>1) {
3338 Double_t binvalmin, binvalmax;
3339 binvalmin=binval;
3340 binvalmax=binval;
3341 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3342 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3343 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3344 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3345 }
3346 Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3347 Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3348 if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3349 }
3350 if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3351 }
3352 // Loop on the list of associated functions and user objects
3353FUNCTIONS:
3354 TObject *f;
3355 TIter next(fFunctions);
3356 while ((f = (TObject*) next())) {
3357 Int_t dist;
3358 if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3359 else dist = f->DistancetoPrimitive(px,py);
3360 if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3361 }
3362 return curdist;
3363}
3364
3365////////////////////////////////////////////////////////////////////////////////
3366/// Display a panel with all histogram drawing options.
3367
3369{
3370
3371 gCurrentHist = fH;
3372 if (!gPad) {
3373 Error("DrawPanel", "need to draw histogram first");
3374 return;
3375 }
3377 editor->Show();
3378 gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3379 (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3380}
3381
3382////////////////////////////////////////////////////////////////////////////////
3383/// Execute the actions corresponding to `event`.
3384///
3385/// This function is called when a histogram is clicked with the locator at
3386/// the pixel position px,py.
3387
3389{
3390
3391 if (!gPad) return;
3392
3393 static Int_t bin, px1, py1, px2, py2, pyold;
3394 static TBox *zoombox;
3395 Double_t zbx1,zbx2,zby1,zby2;
3396
3397 Int_t bin1, bin2;
3398 Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3399 Bool_t opaque = gPad->OpaqueMoving();
3400
3401 if (!gPad->IsEditable()) return;
3402
3403 if (fPie) {
3404 fPie->ExecuteEvent(event, px, py);
3405 return;
3406 }
3407 // come here if we have a lego/surface in the pad
3408 TView *view = gPad->GetView();
3409
3410 if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3411 view->ExecuteRotateView(event, px, py);
3412 return;
3413 }
3414
3415 TAxis *xaxis = fH->GetXaxis();
3416 TAxis *yaxis = fH->GetYaxis();
3417 Int_t dimension = fH->GetDimension();
3418
3419 // In case of option SAME the axis must be the ones of the first drawn histogram
3420 TString IsSame = fH->GetDrawOption();
3421 IsSame.ToLower();
3422 if (IsSame.Index("same")>=0) {
3423 TH1 *h1;
3424 TIter next(gPad->GetListOfPrimitives());
3425 while ((h1 = (TH1 *)next())) {
3426 if (!h1->InheritsFrom(TH1::Class())) continue;
3427 xaxis = h1->GetXaxis();
3428 yaxis = h1->GetYaxis();
3429 break;
3430 }
3431 }
3432
3433 Double_t factor = 1;
3434 if (fH->GetNormFactor() != 0) {
3435 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3436 }
3437
3438 switch (event) {
3439
3440 case kButton1Down:
3441
3442 if (!opaque) gVirtualX->SetLineColor(-1);
3443 fH->TAttLine::Modify();
3444
3445 if (opaque && dimension ==2) {
3446 zbx1 = gPad->AbsPixeltoX(px);
3447 zbx2 = gPad->AbsPixeltoX(px);
3448 zby1 = gPad->AbsPixeltoY(py);
3449 zby2 = gPad->AbsPixeltoY(py);
3450 px1 = px;
3451 py1 = py;
3452 if (gPad->GetLogx()) {
3453 zbx1 = TMath::Power(10,zbx1);
3454 zbx2 = TMath::Power(10,zbx2);
3455 }
3456 if (gPad->GetLogy()) {
3457 zby1 = TMath::Power(10,zby1);
3458 zby2 = TMath::Power(10,zby2);
3459 }
3460 zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3461 Int_t ci = TColor::GetColor("#7d7dff");
3462 TColor *zoomcolor = gROOT->GetColor(ci);
3463 if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3464 else zoomcolor->SetAlpha(0.5);
3465 zoombox->SetFillColor(ci);
3466 zoombox->Draw();
3467 gPad->Modified();
3468 gPad->Update();
3469 }
3470 // No break !!!
3471
3472 case kMouseMotion:
3473
3474 if (fShowProjection) {ShowProjection3(px,py); break;}
3475
3476 gPad->SetCursor(kPointer);
3477 if (dimension ==1) {
3478 if (Hoption.Bar) {
3479 baroffset = fH->GetBarOffset();
3480 barwidth = fH->GetBarWidth();
3481 } else {
3482 baroffset = 0;
3483 barwidth = 1;
3484 }
3485 x = gPad->AbsPixeltoX(px);
3486 bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3487 binwidth = fXaxis->GetBinWidth(bin);
3488 xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3489 xup = gPad->XtoPad(xlow + barwidth*binwidth);
3490 ylow = gPad->GetUymin();
3491 px1 = gPad->XtoAbsPixel(xlow);
3492 px2 = gPad->XtoAbsPixel(xup);
3493 py1 = gPad->YtoAbsPixel(ylow);
3494 py2 = py;
3495 pyold = py;
3496 if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3497 }
3498
3499 break;
3500
3501 case kButton1Motion:
3502
3503 if (dimension ==1) {
3504 if (gROOT->GetEditHistograms()) {
3505 if (!opaque) {
3506 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3507 py2 += py - pyold;
3508 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3509 pyold = py;
3510 } else {
3511 py2 += py - pyold;
3512 pyold = py;
3513 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3514 fH->SetBinContent(bin,binval);
3515 gPad->Modified(kTRUE);
3516 }
3517 }
3518 }
3519
3520 if (opaque && dimension ==2) {
3521 if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3522 zbx2 = gPad->AbsPixeltoX(px);
3523 zby2 = gPad->AbsPixeltoY(py);
3524 if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3525 if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3526 zoombox->SetX2(zbx2);
3527 zoombox->SetY2(zby2);
3528 gPad->Modified();
3529 gPad->Update();
3530 }
3531 }
3532
3533 break;
3534
3535 case kWheelUp:
3536
3537 if (dimension ==2) {
3538 bin1 = xaxis->GetFirst()+1;
3539 bin2 = xaxis->GetLast()-1;
3540 bin1 = TMath::Max(bin1, 1);
3541 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3542 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3543 bin1 = yaxis->GetFirst()+1;
3544 bin2 = yaxis->GetLast()-1;
3545 bin1 = TMath::Max(bin1, 1);
3546 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3547 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3548 }
3549 gPad->Modified();
3550 gPad->Update();
3551
3552 break;
3553
3554 case kWheelDown:
3555
3556 if (dimension == 2) {
3557 bin1 = xaxis->GetFirst()-1;
3558 bin2 = xaxis->GetLast()+1;
3559 bin1 = TMath::Max(bin1, 1);
3560 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3561 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3562 bin1 = yaxis->GetFirst()-1;
3563 bin2 = yaxis->GetLast()+1;
3564 bin1 = TMath::Max(bin1, 1);
3565 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3566 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3567 }
3568 gPad->Modified();
3569 gPad->Update();
3570
3571 break;
3572
3573 case kButton1Up:
3574 if (dimension ==1) {
3575 if (gROOT->GetEditHistograms()) {
3576 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3577 fH->SetBinContent(bin,binval);
3578 PaintInit(); // recalculate Hparam structure and recalculate range
3579 }
3580
3581 // might resize pad pixmap so should be called before any paint routine
3583 }
3584 if (opaque && dimension ==2) {
3585 if (zoombox) {
3586 Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3587 Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3588 Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3589 Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3590 x1 = TMath::Max(x1,xaxis->GetXmin());
3591 x2 = TMath::Min(x2,xaxis->GetXmax());
3592 y1 = TMath::Max(y1,yaxis->GetXmin());
3593 y2 = TMath::Min(y2,yaxis->GetXmax());
3594 if (x1<x2 && y1<y2) {
3595 xaxis->SetRangeUser(x1, x2);
3596 yaxis->SetRangeUser(y1, y2);
3597 }
3598 zoombox->Delete();
3599 zoombox = 0;
3600 }
3601 }
3602 gPad->Modified(kTRUE);
3603 if (opaque) gVirtualX->SetLineColor(-1);
3604
3605 break;
3606
3607 case kButton1Locate:
3608
3609 ExecuteEvent(kButton1Down, px, py);
3610
3611 while (1) {
3612 px = py = 0;
3613 event = gVirtualX->RequestLocator(1, 1, px, py);
3614
3616
3617 if (event != -1) { // button is released
3618 ExecuteEvent(kButton1Up, px, py);
3619 return;
3620 }
3621 }
3622 }
3623}
3624
3625////////////////////////////////////////////////////////////////////////////////
3626/// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3627
3629{
3630
3631
3632
3633 // Check if fH contains a TGraphDelaunay2D
3634 TList *hl = fH->GetListOfFunctions();
3635 TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3636 // try with the old painter
3637 TGraphDelaunay *dtOld = nullptr;
3638 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3639
3640 if (!dt && !dtOld) return nullptr;
3641
3642 gCurrentHist = fH;
3643
3644 if (!fGraph2DPainter) {
3645 if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3646 else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3647 }
3648
3649 return fGraph2DPainter->GetContourList(contour);
3650}
3651
3652////////////////////////////////////////////////////////////////////////////////
3653/// Display the histogram info (bin number, contents, integral up to bin
3654/// corresponding to cursor position px,py.
3655
3657{
3658
3659 if (!gPad) return (char*)"";
3660
3661 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3662 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3663 Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3664 TString drawOption = fH->GetDrawOption();
3665 drawOption.ToLower();
3666 Double_t xmin, xmax, uxmin,uxmax;
3667 Double_t ymin, ymax, uymin,uymax;
3668 if (fH->GetDimension() == 2) {
3669 if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3670 uxmin=gPad->GetUxmin();
3671 uxmax=gPad->GetUxmax();
3674 x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3675 uymin=gPad->GetUymin();
3676 uymax=gPad->GetUymax();
3679 y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3680 }
3681 }
3682 Int_t binx,biny,binmin=0,binx1;
3683 if (gPad->IsVertical()) {
3684 binx = fXaxis->FindFixBin(x);
3685 if (drawOption.Index("same") >= 0) {
3686 TH1 *h1;
3687 TIter next(gPad->GetListOfPrimitives());
3688 while ((h1 = (TH1 *)next())) {
3689 if (!h1->InheritsFrom(TH1::Class())) continue;
3690 binmin = h1->GetXaxis()->GetFirst();
3691 break;
3692 }
3693 } else {
3694 binmin = fXaxis->GetFirst();
3695 }
3696 binx1 = fXaxis->FindFixBin(x1);
3697 // special case if more than 1 bin in x per pixel
3698 if (binx1-binx>1 && fH->GetDimension() == 1) {
3699 Double_t binval=fH->GetBinContent(binx);
3700 Int_t binnear=binx;
3701 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3702 Double_t binvaltmp = fH->GetBinContent(ibin);
3703 if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3704 binval=binvaltmp;
3705 binnear=ibin;
3706 }
3707 }
3708 binx = binnear;
3709 }
3710 } else {
3711 x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3712 binx = fXaxis->FindFixBin(y);
3713 if (drawOption.Index("same") >= 0) {
3714 TH1 *h1;
3715 TIter next(gPad->GetListOfPrimitives());
3716 while ((h1 = (TH1 *)next())) {
3717 if (!h1->InheritsFrom(TH1::Class())) continue;
3718 binmin = h1->GetXaxis()->GetFirst();
3719 break;
3720 }
3721 } else {
3722 binmin = fXaxis->GetFirst();
3723 }
3724 binx1 = fXaxis->FindFixBin(x1);
3725 // special case if more than 1 bin in x per pixel
3726 if (binx1-binx>1 && fH->GetDimension() == 1) {
3727 Double_t binval=fH->GetBinContent(binx);
3728 Int_t binnear=binx;
3729 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3730 Double_t binvaltmp = fH->GetBinContent(ibin);
3731 if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3732 binval=binvaltmp;
3733 binnear=ibin;
3734 }
3735 }
3736 binx = binnear;
3737 }
3738 }
3739 if (fH->GetDimension() == 1) {
3741 TProfile *tp = (TProfile*)fH;
3742 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3743 x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3744 (Int_t) tp->GetBinEntries(binx));
3745 }
3746 else {
3747 Double_t integ = 0;
3748 for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3749 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3750 x,y,binx,fH->GetBinContent(binx),integ);
3751 }
3752 } else if (fH->GetDimension() == 2) {
3753 if (fH->InheritsFrom(TH2Poly::Class())) {
3754 TH2Poly *th2 = (TH2Poly*)fH;
3755 biny = th2->FindBin(x,y);
3756 fObjectInfo.Form("%s (x=%g, y=%g, bin=%d, binc=%g)",
3757 th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3758 }
3759 else if (fH->InheritsFrom(TProfile2D::Class())) {
3760 TProfile2D *tp = (TProfile2D*)fH;
3761 biny = fYaxis->FindFixBin(y);
3762 Int_t bin = fH->GetBin(binx,biny);
3763 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3764 x, y, binx, biny, fH->GetBinContent(bin),
3765 fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3766 } else {
3767 biny = fYaxis->FindFixBin(y);
3768 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3769 x,y,binx,biny,fH->GetBinContent(binx,biny),
3770 fH->GetBinError(binx,biny));
3771 }
3772 } else {
3773 // 3d case: retrieving the x,y,z bin is not yet implemented
3774 // print just the x,y info
3775 fObjectInfo.Form("(x=%g, y=%g)",x,y);
3776 }
3777
3778 return (char *)fObjectInfo.Data();
3779}
3780
3781////////////////////////////////////////////////////////////////////////////////
3782/// Set highlight (enable/disable) mode for fH
3783
3785{
3786 if (fH->IsHighlight()) return;
3787
3788 fXHighlightBin = -1;
3789 fYHighlightBin = -1;
3790 // delete previous highlight box
3793 // emit Highlighted() signal (user can check on disabled)
3794 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3795}
3796
3797////////////////////////////////////////////////////////////////////////////////
3798/// Check on highlight bin
3799
3801{
3802 // call from DistancetoPrimitive (only if highlight is enable)
3803
3804 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3805 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3806 Int_t binx = fXaxis->FindFixBin(x);
3807 Int_t biny = fYaxis->FindFixBin(y);
3808 if (!gPad->IsVertical()) binx = fXaxis->FindFixBin(y);
3809
3810 Bool_t changedBin = kFALSE;
3811 if (binx != fXHighlightBin) {
3812 fXHighlightBin = binx;
3813 changedBin = kTRUE;
3814 } else if (fH->GetDimension() == 1) return;
3815 if (biny != fYHighlightBin) {
3816 fYHighlightBin = biny;
3817 changedBin = kTRUE;
3818 }
3819 if (!changedBin) return;
3820
3821 // Info("HighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3822 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3823
3824 // paint highlight bin as box (recursive calls PaintHighlightBin)
3825 gPad->Modified(kTRUE);
3826 gPad->Update();
3827
3828 // emit Highlighted() signal
3829 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3830}
3831
3832////////////////////////////////////////////////////////////////////////////////
3833/// Paint highlight bin as TBox object
3834
3836{
3837 // call from PaintTitle
3838
3839 if (!fH->IsHighlight()) return;
3840
3841 Double_t uxmin = gPad->GetUxmin();
3842 Double_t uxmax = gPad->GetUxmax();
3843 Double_t uymin = gPad->GetUymin();
3844 Double_t uymax = gPad->GetUymax();
3845 if (gPad->GetLogx()) {
3846 uxmin = TMath::Power(10.0, uxmin);
3847 uxmax = TMath::Power(10.0, uxmax);
3848 }
3849 if (gPad->GetLogy()) {
3850 uymin = TMath::Power(10.0, uymin);
3851 uymax = TMath::Power(10.0, uymax);
3852 }
3853
3854 // testing specific possibility (after zoom, draw with "same", log, etc.)
3855 Double_t hcenter;
3856 if (gPad->IsVertical()) {
3858 if ((hcenter < uxmin) || (hcenter > uxmax)) return;
3859 } else {
3861 if ((hcenter < uymin) || (hcenter > uymax)) return;
3862 }
3863 if (fH->GetDimension() == 2) {
3865 if ((hcenter < uymin) || (hcenter > uymax)) return;
3866 }
3867
3868 // paint X highlight bin (for 1D or 2D)
3869 Double_t hbx1, hbx2, hby1, hby2;
3870 if (gPad->IsVertical()) {
3873 hby1 = uymin;
3874 hby2 = uymax;
3875 } else {
3876 hbx1 = uxmin;
3877 hbx2 = uxmax;
3880 }
3881
3882 if (!gXHighlightBox) {
3883 gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3887 else gROOT->GetColor(gXHighlightBox->GetFillColor())->SetAlpha(0.5);
3888 }
3889 gXHighlightBox->SetX1(hbx1);
3890 gXHighlightBox->SetX2(hbx2);
3891 gXHighlightBox->SetY1(hby1);
3892 gXHighlightBox->SetY2(hby2);
3894
3895 // Info("PaintHighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3896 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3897
3898 // paint Y highlight bin (only for 2D)
3899 if (fH->GetDimension() != 2) return;
3900 hbx1 = uxmin;
3901 hbx2 = uxmax;
3904
3905 if (!gYHighlightBox) {
3906 gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3910 }
3911 gYHighlightBox->SetX1(hbx1);
3912 gYHighlightBox->SetX2(hbx2);
3913 gYHighlightBox->SetY1(hby1);
3914 gYHighlightBox->SetY2(hby2);
3916}
3917
3918////////////////////////////////////////////////////////////////////////////////
3919/// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3920
3922{
3923
3924 for (Int_t i=0;i<fNcuts;i++) {
3927 if (fCutsOpt[i] > 0) {
3928 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3929 } else {
3930 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3931 }
3932 }
3933 return kTRUE;
3934}
3935
3936////////////////////////////////////////////////////////////////////////////////
3937/// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3938
3940{
3941
3942 for (Int_t i=0;i<fNcuts;i++) {
3943 if (fCutsOpt[i] > 0) {
3944 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3945 } else {
3946 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3947 }
3948 }
3949 return kTRUE;
3950}
3951
3952////////////////////////////////////////////////////////////////////////////////
3953/// Decode string `choptin` and fill Hoption structure.
3954
3956{
3957
3958 char *l;
3959 char chopt[128];
3960 Int_t nch = strlen(choptin);
3961 strlcpy(chopt,choptin,128);
3962 Int_t hdim = fH->GetDimension();
3963
3972
3973 // special 2D options
3974 Hoption.List = 0;
3975 Hoption.Zscale = 0;
3976 Hoption.FrontBox = 1;
3977 Hoption.BackBox = 1;
3979
3980 Hoption.Zero = 0;
3981
3983
3984 //check for graphical cuts
3985 MakeCuts(chopt);
3986
3987 for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3988 if (hdim > 1) Hoption.Scat = 1;
3989 if (!nch) Hoption.Hist = 1;
3990 if (fFunctions->First()) Hoption.Func = 1;
3991 if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3992
3993 char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
3994 char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
3995 char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
3996 if (l1 || l2 || l3) {
3997 Int_t i = gPad->NextPaletteColor();
3998 if (l1) {memcpy(l1," ",3); fH->SetFillColor(i);}
3999 if (l2) {memcpy(l2," ",3); fH->SetLineColor(i);}
4000 if (l3) {memcpy(l3," ",3); fH->SetMarkerColor(i);}
4001 Hoption.Hist = 1; // Make sure something is drawn in case there is no drawing option specified.
4002 }
4003
4004 l = strstr(chopt,"MIN0");
4005 if (l) {
4006 Hoption.MinimumZero = 1;
4007 memcpy(l," ",4);
4008 }
4009
4010 l = strstr(chopt,"SPEC");
4011 if (l) {
4012 Hoption.Scat = 0;
4013 memcpy(l," ",4);
4014 Int_t bs=0;
4015 l = strstr(chopt,"BF(");
4016 if (l) {
4017 if (sscanf(&l[3],"%d",&bs) > 0) {
4018 Int_t i=0;
4019 while (l[i]!=')') {
4020 l[i] = ' ';
4021 i++;
4022 }
4023 l[i] = ' ';
4024 }
4025 }
4026 Hoption.Spec = TMath::Max(1600,bs);
4027 return 1;
4028 }
4029
4030 l = strstr(chopt,"GL");
4031 if (l) {
4032 memcpy(l," ",2);
4033 }
4034 l = strstr(chopt,"X+");
4035 if (l) {
4036 Hoption.AxisPos = 10;
4037 memcpy(l," ",2);
4038 }
4039 l = strstr(chopt,"Y+");
4040 if (l) {
4041 Hoption.AxisPos += 1;
4042 memcpy(l," ",2);
4043 }
4044 if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
4045 if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
4046
4047 l = strstr(chopt,"SAMES");
4048 if (l) {
4049 if (nch == 5) Hoption.Hist = 1;
4050 Hoption.Same = 2;
4051 memcpy(l," ",5);
4052 if (l[5] == '0') { Hoption.Same += 10; l[5] = ' '; }
4053 }
4054 l = strstr(chopt,"SAME");
4055 if (l) {
4056 if (nch == 4) Hoption.Hist = 1;
4057 Hoption.Same = 1;
4058 memcpy(l," ",4);
4059 if (l[4] == '0') { Hoption.Same += 10; l[4] = ' '; }
4060 }
4061
4062 l = strstr(chopt,"PIE");
4063 if (l) {
4064 Hoption.Pie = 1;
4065 memcpy(l," ",3);
4066 }
4067
4068
4069 l = strstr(chopt,"CANDLE");
4070 if (l) {
4071 TCandle candle;
4072 Hoption.Candle = candle.ParseOption(l);
4073 Hoption.Scat = 0;
4074 }
4075
4076 l = strstr(chopt,"VIOLIN");
4077 if (l) {
4078 TCandle candle;
4079 Hoption.Candle = candle.ParseOption(l);
4080 Hoption.Scat = 0;
4081 }
4082
4083 l = strstr(chopt,"LEGO");
4084 if (l) {
4085 Hoption.Scat = 0;
4086 Hoption.Lego = 1; memcpy(l," ",4);
4087 if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
4088 if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
4089 if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
4090 if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
4091 if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
4092 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4093 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4094 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4095 }
4096
4097 l = strstr(chopt,"SURF");
4098 if (l) {
4099 Hoption.Scat = 0;
4100 Hoption.Surf = 1; memcpy(l," ",4);
4101 if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
4102 if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
4103 if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
4104 if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
4105 if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
4106 if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
4107 if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
4108 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4109 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4110 }
4111
4112 l = strstr(chopt,"TF3");
4113 if (l) {
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,"ISO");
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,"LIST"); if (l) { Hoption.List = 1; memcpy(l," ",4);}
4125
4126 l = strstr(chopt,"CONT");
4127 if (l) {
4128 memcpy(l," ",4);
4129 if (hdim>1) {
4130 Hoption.Scat = 0;
4131 Hoption.Contour = 1;
4132 if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
4133 if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
4134 if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
4135 if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
4136 if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
4137 } else {
4138 Hoption.Hist = 1;
4139 }
4140 }
4141 l = strstr(chopt,"HBAR");
4142 if (l) {
4143 Hoption.Hist = 0;
4144 Hoption.Bar = 20; memcpy(l," ",4);
4145 if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
4146 if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
4147 if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
4148 if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
4149 }
4150 l = strstr(chopt,"BAR");
4151 if (l) {
4152 Hoption.Hist = 0;
4153 Hoption.Bar = 10; memcpy(l," ",3);
4154 if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
4155 if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
4156 if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
4157 if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
4158 }
4159
4160 l = strstr(chopt,"ARR" );
4161 if (l) {
4162 memcpy(l," ", 3);
4163 if (hdim>1) {
4164 Hoption.Arrow = 1;
4165 Hoption.Scat = 0;
4166 l = strstr(chopt,"COL"); if (l) { Hoption.Arrow = 2; memcpy(l," ",3); }
4167 l = strstr(chopt,"Z"); if (l) { Hoption.Zscale = 1; memcpy(l," ",1); }
4168 } else {
4169 Hoption.Hist = 1;
4170 }
4171 }
4172 l = strstr(chopt,"BOX" );
4173 if (l) {
4174 memcpy(l," ", 3);
4175 if (hdim>1) {
4176 Hoption.Scat = 0;
4177 Hoption.Box = 1;
4178 if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
4179 if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
4180 if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
4181 } else {
4182 Hoption.Hist = 1;
4183 }
4184 }
4185 l = strstr(chopt,"COLZ");
4186 if (l) {
4187 memcpy(l," ",4);
4188 if (hdim>1) {
4189 Hoption.Color = 1;
4190 Hoption.Scat = 0;
4191 Hoption.Zscale = 1;
4192 if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
4193 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4194 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4195 } else {
4196 Hoption.Hist = 1;
4197 }
4198 }
4199 l = strstr(chopt,"COL" );
4200 if (l) {
4201 memcpy(l," ", 3);
4202 if (hdim>1) {
4203 Hoption.Color = 1;
4204 Hoption.Scat = 0;
4205 if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
4206 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4207 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4208 } else {
4209 Hoption.Hist = 1;
4210 }
4211 }
4212 l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; memcpy(l," ",4); Hoption.Scat = 0; }
4213 l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; memcpy(l," ",4); Hoption.Hist = 0; }
4214 l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; memcpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
4215 l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; memcpy(l," ",4); }
4216 l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; memcpy(l," ",4); }
4217 l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; memcpy(l," ",4); }
4218 l = strstr(chopt,"TEXT");
4219 if (l) {
4220 Int_t angle;
4221 if (sscanf(&l[4],"%d",&angle) > 0) {
4222 if (angle < 0) angle=0;
4223 if (angle > 90) angle=90;
4224 Hoption.Text = 1000+angle;
4225 } else {
4226 Hoption.Text = 1;
4227 }
4228 memcpy(l," ", 4);
4229 l = strstr(chopt,"N");
4230 if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
4231 Hoption.Scat = 0;
4232 }
4233 l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; memcpy(l," ",3); }
4234 l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; memcpy(l," ",3); }
4235 l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; memcpy(l," ",3); }
4236 l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; memcpy(l," ",3); }
4237
4238 l = strstr(chopt,"TRI");
4239 if (l) {
4240 Hoption.Scat = 0;
4241 Hoption.Color = 0;
4242 Hoption.Tri = 1; memcpy(l," ",3);
4243 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4244 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4245 l = strstr(chopt,"ERR"); if (l) memcpy(l," ",3);
4246 }
4247
4248 l = strstr(chopt,"AITOFF");
4249 if (l) {
4250 Hoption.Proj = 1; memcpy(l," ",6); //Aitoff projection
4251 }
4252 l = strstr(chopt,"MERCATOR");
4253 if (l) {
4254 Hoption.Proj = 2; memcpy(l," ",8); //Mercator projection
4255 }
4256 l = strstr(chopt,"SINUSOIDAL");
4257 if (l) {
4258 Hoption.Proj = 3; memcpy(l," ",10); //Sinusoidal projection
4259 }
4260 l = strstr(chopt,"PARABOLIC");
4261 if (l) {
4262 Hoption.Proj = 4; memcpy(l," ",9); //Parabolic projection
4263 }
4264 if (Hoption.Proj > 0) {
4265 Hoption.Scat = 0;
4266 Hoption.Contour = 14;
4267 }
4268
4269 if (strstr(chopt,"A")) Hoption.Axis = -1;
4270 if (strstr(chopt,"B")) Hoption.Bar = 1;
4271 if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
4272 if (strstr(chopt,"F")) Hoption.Fill =1;
4273 if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
4274 if (strstr(chopt,"F2")) Hoption.Fill =2;
4275 if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
4276 if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
4277 if (strstr(chopt,"Z")) Hoption.Zscale =1;
4278 if (strstr(chopt,"*")) Hoption.Star =1;
4279 if (strstr(chopt,"H")) Hoption.Hist =2;
4280 if (strstr(chopt,"P0")) Hoption.Mark =10;
4281
4282 if (fH->InheritsFrom(TH2Poly::Class())) {
4284 }
4285
4286 if (strstr(chopt,"E")) {
4287 if (hdim == 1) {
4288 Hoption.Error = 1;
4289 if (strstr(chopt,"E0")) Hoption.Error = 10;
4290 if (strstr(chopt,"E1")) Hoption.Error = 11;
4291 if (strstr(chopt,"E2")) Hoption.Error = 12;
4292 if (strstr(chopt,"E3")) Hoption.Error = 13;
4293 if (strstr(chopt,"E4")) Hoption.Error = 14;
4294 if (strstr(chopt,"E5")) Hoption.Error = 15;
4295 if (strstr(chopt,"E6")) Hoption.Error = 16;
4296 if (strstr(chopt,"X0")) {
4297 if (Hoption.Error == 1) Hoption.Error += 20;
4298 Hoption.Error += 10;
4299 }
4301 Hoption.Text += 2000;
4302 Hoption.Error = 0;
4303 }
4304 } else {
4305 if (Hoption.Error == 0) {
4306 Hoption.Error = 100;
4307 Hoption.Scat = 0;
4308 }
4309 if (Hoption.Text) {
4310 Hoption.Text += 2000;
4311 Hoption.Error = 0;
4312 }
4313 }
4314 }
4315
4316 if (Hoption.Surf == 15) {
4318 Hoption.Surf = 13;
4319 Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4320 }
4321 }
4322
4323 // Copy options from current style
4324 Hoption.Logx = gPad->GetLogx();
4325 Hoption.Logy = gPad->GetLogy();
4326 Hoption.Logz = gPad->GetLogz();
4327
4328 // Check options incompatibilities
4329 if (Hoption.Bar == 1) Hoption.Hist = -1;
4330 return 1;
4331}
4332
4333////////////////////////////////////////////////////////////////////////////////
4334/// Decode string `choptin` and fill Graphical cuts structure.
4335
4337{
4338
4339 fNcuts = 0;
4340 char *left = (char*)strchr(choptin,'[');
4341 if (!left) return 0;
4342 char *right = (char*)strchr(choptin,']');
4343 if (!right) return 0;
4344 Int_t nch = right-left;
4345 if (nch < 2) return 0;
4346 char *cuts = left+1;
4347 *right = 0;
4348 char *comma, *minus;
4349 Int_t i;
4350 while (1) {
4351 comma = strchr(cuts,',');
4352 if (comma) *comma = 0;
4353 minus = strchr(cuts,'-');
4354 if (minus) cuts = minus+1;
4355 while (*cuts == ' ') cuts++;
4356 Int_t nc = strlen(cuts);
4357 while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4358 TIter next(gROOT->GetListOfSpecials());
4359 TCutG *cut=0;
4360 TObject *obj;
4361 while ((obj = next())) {
4362 if (!obj->InheritsFrom(TCutG::Class())) continue;
4363 if (strcmp(obj->GetName(),cuts)) continue;
4364 cut = (TCutG*)obj;
4365 break;
4366 }
4367 if (cut) {
4368 fCuts[fNcuts] = cut;
4369 fCutsOpt[fNcuts] = 1;
4370 if (minus) fCutsOpt[fNcuts] = -1;
4371 fNcuts++;
4372 }
4373 if (!comma) break;
4374 cuts = comma+1;
4375 }
4376 for (i=0;i<=nch;i++) left[i] = ' ';
4377 return fNcuts;
4378}
4379
4380////////////////////////////////////////////////////////////////////////////////
4381/// [Control routine to paint any kind of histograms](#HP00)
4382
4384{
4385
4386 if (fH->GetBuffer()) fH->BufferEmpty(-1);
4387
4388 //For iOS: put the histogram on the top of stack of pickable objects.
4389 const TPickerStackGuard topPush(fH);
4390
4391 gPad->SetVertical(kTRUE);
4392
4393 TH1 *oldhist = gCurrentHist;
4394 gCurrentHist = fH;
4395 TH1 *hsave = fH;
4396 Double_t minsav = fH->GetMinimumStored();
4397
4398 if (!MakeChopt(option)) return; //check options and fill Hoption structure
4399
4400 // Paint using TSpectrum2Painter
4401 if (Hoption.Spec) {
4402 if (!TableInit()) return;
4403 if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4404 gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
4405 (ULong_t)fH, option, Hoption.Spec));
4406 return;
4407 }
4408
4409 if (Hoption.Pie) {
4410 if (fH->GetDimension() == 1) {
4411 if (!fPie) fPie = new TPie(fH);
4412 fPie->Paint(option);
4413 } else {
4414 Error("Paint", "Option PIE is for 1D histograms only");
4415 }
4416 return;
4417 } else {
4418 if (fPie) delete fPie;
4419 fPie = 0;
4420 }
4421
4422 fXbuf = new Double_t[kNMAX];
4423 fYbuf = new Double_t[kNMAX];
4424 if (fH->GetDimension() > 2) {
4425 PaintH3(option);
4426 fH->SetMinimum(minsav);
4427 if (Hoption.Func) {
4428 Hoption_t hoptsave = Hoption;
4429 Hparam_t hparsave = Hparam;
4430 PaintFunction(option);
4431 SetHistogram(hsave);
4432 Hoption = hoptsave;
4433 Hparam = hparsave;
4434 }
4435 gCurrentHist = oldhist;
4436 delete [] fXbuf; delete [] fYbuf;
4437 return;
4438 }
4439 TView *view = gPad->GetView();
4440 if (view) {
4441 if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4442 delete view;
4443 gPad->SetView(0);
4444 }
4445 }
4446 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4447 // In case of 1D histogram, Z axis becomes Y axis.
4448 Int_t logysav=0, logzsav=0;
4449 if (fH->GetDimension() == 1) {
4450 logysav = Hoption.Logy;
4451 logzsav = Hoption.Logz;
4452 Hoption.Logz = 0;
4453 if (Hoption.Logy) {
4454 Hoption.Logz = 1;
4455 Hoption.Logy = 0;
4456 }
4457 }
4458 PaintTable(option);
4459 if (Hoption.Func) {
4460 Hoption_t hoptsave = Hoption;
4461 Hparam_t hparsave = Hparam;
4462 PaintFunction(option);
4463 SetHistogram(hsave);
4464 Hoption = hoptsave;
4465 Hparam = hparsave;
4466 }
4467 fH->SetMinimum(minsav);
4468 gCurrentHist = oldhist;
4469 delete [] fXbuf; delete [] fYbuf;
4470 if (fH->GetDimension() == 1) {
4471 Hoption.Logy = logysav;
4472 Hoption.Logz = logzsav;
4473 }
4474 return;
4475 }
4476
4477 if (Hoption.Bar >= 20) {
4478 PaintBarH(option);
4479 delete [] fXbuf; delete [] fYbuf;
4480 return;
4481 }
4482
4483 // fill Hparam structure with histo parameters
4484 if (!PaintInit()) {
4485 delete [] fXbuf; delete [] fYbuf;
4486 return;
4487 }
4488
4489 // Picture surround (if new page) and page number (if requested).
4490 // Histogram surround (if not option "Same").
4491 PaintFrame();
4492
4493 // Paint histogram axis only
4494 Bool_t gridx = gPad->GetGridx();
4495 Bool_t gridy = gPad->GetGridy();
4496 if (Hoption.Axis > 0) {
4497 if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4498 else {
4499 if (gridx) gPad->SetGridx(0);
4500 if (gridy) gPad->SetGridy(0);
4502 if (gridx) gPad->SetGridx(1);
4503 if (gridy) gPad->SetGridy(1);
4504 }
4505 if ((Hoption.Same%10) ==1) Hoption.Same += 1;
4506 goto paintstat;
4507 }
4508 if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4509
4510 // test for options BAR or HBAR
4511 if (Hoption.Bar >= 10) {
4512 PaintBar(option);
4513 }
4514
4515 // do not draw histogram if error bars required
4516 if (!Hoption.Error) {
4517 if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4518 }
4519
4520 // test for error bars or option E
4521 if (Hoption.Error) {
4522 PaintErrors(option);
4523 if (Hoption.Hist == 2) PaintHist(option);
4524 }
4525
4526 if (Hoption.Text) PaintText(option);
4527
4528 // test for associated function
4529 if (Hoption.Func) {
4530 Hoption_t hoptsave = Hoption;
4531 Hparam_t hparsave = Hparam;
4532 PaintFunction(option);
4533 SetHistogram(hsave);
4534 Hoption = hoptsave;
4535 Hparam = hparsave;
4536 }
4537
4538 if (gridx) gPad->SetGridx(0);
4539 if (gridy) gPad->SetGridy(0);
4541 if (gridx) gPad->SetGridx(1);
4542 if (gridy) gPad->SetGridy(1);
4543
4544 PaintTitle(); // Draw histogram title
4545
4546 // Draw box with histogram statistics and/or fit parameters
4547paintstat:
4548 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4549 TIter next(fFunctions);
4550 TObject *obj = 0;
4551 while ((obj = next())) {
4552 if (obj->InheritsFrom(TF1::Class())) break;
4553 obj = 0;
4554 }
4555
4556 //Stat is painted twice (first, it will be in canvas' list of primitives),
4557 //second, it will be here, this is not required on iOS.
4558 //Condition is ALWAYS true on a platform different from iOS.
4559 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4560 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4561 }
4562 fH->SetMinimum(minsav);
4563 gCurrentHist = oldhist;
4564 delete [] fXbuf; fXbuf = 0;
4565 delete [] fYbuf; fYbuf = 0;
4566
4567}
4568
4569////////////////////////////////////////////////////////////////////////////////
4570/// [Control function to draw a table as an arrow plot](#HP12)
4571
4573{
4574 Double_t xk, xstep, yk, ystep;
4575 Double_t dx, dy, x1, x2, y1, y2, xc, yc, dxn, dyn;
4578 Double_t xrg = gPad->GetUxmin();
4579 Double_t yrg = gPad->GetUymin();
4580 Double_t xln = gPad->GetUxmax() - xrg;
4581 Double_t yln = gPad->GetUymax() - yrg;
4582 Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4583 Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4584 Double_t dn = 1.E-30;
4585
4586 auto arrow = new TArrow();
4587 arrow->SetAngle(30);
4588 arrow->SetFillStyle(1001);
4589 arrow->SetFillColor(fH->GetLineColor());
4590 arrow->SetLineColor(fH->GetLineColor());
4591 arrow->SetLineWidth(fH->GetLineWidth());
4592
4593 // Initialize the levels on the Z axis
4594 Int_t ncolors=0, ndivz=0;
4595 Double_t scale=0.;
4596 if (Hoption.Arrow>1) {
4597 ncolors = gStyle->GetNumberOfColors();
4598 Int_t ndiv = fH->GetContour();
4599 if (ndiv == 0 ) {
4600 ndiv = gStyle->GetNumberContours();
4601 fH->SetContour(ndiv);
4602 }
4603 ndivz = TMath::Abs(ndiv);
4604 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4605 scale = ndivz/(fH->GetMaximum()-fH->GetMinimum());
4606 }
4607
4608 for (Int_t id=1;id<=2;id++) {
4609 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4610 yk = fYaxis->GetBinLowEdge(j);
4611 ystep = fYaxis->GetBinWidth(j);
4612 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4613 xk = fXaxis->GetBinLowEdge(i);
4614 xstep = fXaxis->GetBinWidth(i);
4615 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4616 if (i == Hparam.xfirst) {
4617 dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4618 } else if (i == Hparam.xlast) {
4619 dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4620 } else {
4621 dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4622 }
4623 if (j == Hparam.yfirst) {
4624 dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4625 } else if (j == Hparam.ylast) {
4626 dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4627 } else {
4628 dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4629 }
4630 if (id == 1) {
4631 dn = TMath::Max(dn, TMath::Abs(dx));
4632 dn = TMath::Max(dn, TMath::Abs(dy));
4633 } else if (id == 2) {
4634 xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4635 dxn = cx*dx/dn;
4636 x1 = xc - dxn;
4637 x2 = xc + dxn;
4638 yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4639 dyn = cy*dy/dn;
4640 y1 = yc - dyn;
4641 y2 = yc + dyn;
4642 if (Hoption.Arrow>1) {
4643 int color = Int_t(0.01+(fH->GetBinContent(i, j)-fH->GetMinimum())*scale);
4644 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4645 if (theColor > ncolors-1) theColor = ncolors-1;
4646 arrow->SetFillColor(gStyle->GetColorPalette(theColor));
4647 arrow->SetLineColor(gStyle->GetColorPalette(theColor));
4648 }
4649 if (TMath::Abs(x2-x1) > 0. || TMath::Abs(y2-y1) > 0.) {
4650 arrow->PaintArrow(x1, y1, x2, y2, 0.015, "|>");
4651 } else {
4652 arrow->PaintArrow(x1, y1, x2, y2, 0.005, "|>");
4653 }
4654 }
4655 }
4656 }
4657 }
4658
4660}
4661
4662////////////////////////////////////////////////////////////////////////////////
4663/// Draw axis (2D case) of an histogram.
4664///
4665/// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4666/// to draw the grid and the axis separately. In `THistPainter::Paint` this
4667/// feature is used to make sure that the grid is drawn in the background and
4668/// the axis tick marks in the foreground of the pad.
4669
4671{
4672
4673 //On iOS, grid should not be pickable and can not be highlighted.
4674 //Condition is never true on a platform different from iOS.
4675 if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4676 return;
4677
4678 if (Hoption.Axis == -1) return;
4679 if (Hoption.Same && Hoption.Axis <= 0) return;
4680
4681 // Repainting alphanumeric labels axis on a plot done with
4682 // the option HBAR (horizontal) needs some adjustments.
4683 TAxis *xaxis = 0;
4684 TAxis *yaxis = 0;
4685 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4686 if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4687 TIter next(gPad->GetListOfPrimitives());
4688 TObject *obj;
4689 // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4690 while ((obj = next())) {
4691 if (!obj->InheritsFrom(TH1::Class()) &&
4692 !obj->InheritsFrom(THStack::Class())) continue;
4693 TString opt = obj->GetDrawOption();
4694 opt.ToLower();
4695 // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4696 if (strstr(opt,"hbar")) {
4697 gPad->SetVertical(kFALSE);
4698 xaxis = fXaxis;
4699 yaxis = fYaxis;
4700 if (!strcmp(xaxis->GetName(),"xaxis")) {
4701 fXaxis = yaxis;
4702 fYaxis = xaxis;
4703 }
4704 }
4705 break;
4706 }
4707 }
4708 }
4709
4710 static char chopt[10] = "";
4711 Double_t gridl = 0;
4712 Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4713 Int_t useHparam = 0;
4714 Double_t umin, umax, uminsave, umaxsave;
4715 Short_t xAxisPos = Hoption.AxisPos/10;
4716 Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4717
4718 Double_t axmin = gPad->GetUxmin();
4719 Double_t axmax = gPad->GetUxmax();
4720 Double_t aymin = gPad->GetUymin();
4721 Double_t aymax = gPad->GetUymax();
4722 char *cw = 0;
4723 TGaxis axis;
4724
4725 // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4726 // Hparam must be use for the axis limits.
4727 if (Hoption.Contour == 14) useHparam = 1;
4728 if (Hoption.Same) {
4729 TObject *obj;
4730 TIter next(gPad->GetListOfPrimitives());
4731 while ((obj=next())) {
4732 if (strstr(obj->GetDrawOption(),"cont4")) {
4733 useHparam = 1;
4734 break;
4735 }
4736 }
4737 }
4738
4739 // Paint X axis
4740
4741 //To make X-axis selectable on iOS device.
4742 if (gPad->PadInSelectionMode())
4743 gPad->PushSelectableObject(fXaxis);
4744
4745 //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4746 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4747 ndivx = fXaxis->GetNdivisions();
4748 if (ndivx > 1000) {
4749 nx2 = ndivx/100;
4750 nx1 = TMath::Max(1, ndivx%100);
4751 ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4752 }
4753 axis.SetTextAngle(0);
4755
4756 chopt[0] = 0;
4757 strlcat(chopt, "SDH",10);
4758 if (ndivx < 0) strlcat(chopt, "N",10);
4759 if (gPad->GetGridx()) {
4760 gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4761 strlcat(chopt, "W",10);
4762 }
4763
4764 // Define X-Axis limits
4765 if (Hoption.Logx) {
4766 strlcat(chopt, "G",10);
4767 ndiv = TMath::Abs(ndivx);
4768 if (useHparam) {
4769 umin = TMath::Power(10,Hparam.xmin);
4770 umax = TMath::Power(10,Hparam.xmax);
4771 } else {
4772 umin = TMath::Power(10,axmin);
4773 umax = TMath::Power(10,axmax);
4774 }
4775 } else {
4776 ndiv = TMath::Abs(ndivx);
4777 if (useHparam) {
4778 umin = Hparam.xmin;
4779 umax = Hparam.xmax;
4780 } else {
4781 umin = axmin;
4782 umax = axmax;
4783 }
4784 }
4785
4786 // Display axis as time
4787 if (fXaxis->GetTimeDisplay()) {
4788 strlcat(chopt,"t",10);
4789 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4791 }
4792 }
4793
4794 // The main X axis can be on the bottom or on the top of the pad
4795 Double_t xAxisYPos1, xAxisYPos2;
4796 if (xAxisPos == 1) {
4797 // Main X axis top
4798 xAxisYPos1 = aymax;
4799 xAxisYPos2 = aymin;
4800 } else {
4801 // Main X axis bottom
4802 xAxisYPos1 = aymin;
4803 xAxisYPos2 = aymax;
4804 }
4805
4806 // Paint the main X axis (always)
4807 uminsave = umin;
4808 umaxsave = umax;
4809 ndivsave = ndiv;
4810 axis.SetOption(chopt);
4811 if (xAxisPos) {
4812 strlcat(chopt, "-",10);
4813 gridl = -gridl;
4814 }
4815 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4816 axis.SetLabelSize(0.);
4817 axis.SetTitle("");
4818 }
4819 axis.PaintAxis(axmin, xAxisYPos1,
4820 axmax, xAxisYPos1,
4821 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4822
4823 // Paint additional X axis (if needed)
4824 // On iOS, this additional X axis is neither pickable, nor highlighted.
4825 // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4826 if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4827 if (xAxisPos) {
4828 cw=strstr(chopt,"-");
4829 *cw='z';
4830 } else {
4831 strlcat(chopt, "-",10);
4832 }
4833 if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4834 if ((cw=strstr(chopt,"W"))) *cw='z';
4835 axis.SetTitle("");
4836 axis.PaintAxis(axmin, xAxisYPos2,
4837 axmax, xAxisYPos2,
4838 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4839 }
4840 }//End of "if pad in selection mode etc".
4841
4842 // Paint Y axis
4843 //On iOS, Y axis must pushed into the stack of selectable objects.
4844 if (gPad->PadInSelectionMode())
4845 gPad->PushSelectableObject(fYaxis);
4846
4847 //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4848 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4849 ndivy = fYaxis->GetNdivisions();
4851
4852 chopt[0] = 0;
4853 strlcat(chopt, "SDH",10);
4854 if (ndivy < 0) strlcat(chopt, "N",10);
4855 if (gPad->GetGridy()) {
4856 gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4857 strlcat(chopt, "W",10);
4858 }
4859
4860 // Define Y-Axis limits
4861 if (Hoption.Logy) {
4862 strlcat(chopt, "G",10);
4863 ndiv = TMath::Abs(ndivy);
4864 if (useHparam) {
4865 umin = TMath::Power(10,Hparam.ymin);
4866 umax = TMath::Power(10,Hparam.ymax);
4867 } else {
4868 umin = TMath::Power(10,aymin);
4869 umax = TMath::Power(10,aymax);
4870 }
4871 } else {
4872 ndiv = TMath::Abs(ndivy);
4873 if (useHparam) {
4874 umin = Hparam.ymin;
4875 umax = Hparam.ymax;
4876 } else {
4877 umin = aymin;
4878 umax = aymax;
4879 }
4880 }
4881
4882 // Display axis as time
4883 if (fYaxis->GetTimeDisplay()) {
4884 strlcat(chopt,"t",10);
4885 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4887 }
4888 }
4889
4890 // The main Y axis can be on the left or on the right of the pad
4891 Double_t yAxisXPos1, yAxisXPos2;
4892 if (yAxisPos == 1) {
4893 // Main Y axis left
4894 yAxisXPos1 = axmax;
4895 yAxisXPos2 = axmin;
4896 } else {
4897 // Main Y axis right
4898 yAxisXPos1 = axmin;
4899 yAxisXPos2 = axmax;
4900 }
4901
4902 // Paint the main Y axis (always)
4903 uminsave = umin;
4904 umaxsave = umax;
4905 ndivsave = ndiv;
4906 axis.SetOption(chopt);
4907 if (yAxisPos) {
4908 strlcat(chopt, "+L",10);
4909 gridl = -gridl;
4910 }
4911 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4912 axis.SetLabelSize(0.);
4913 axis.SetTitle("");
4914 }
4915 axis.PaintAxis(yAxisXPos1, aymin,
4916 yAxisXPos1, aymax,
4917 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4918
4919 // Paint the additional Y axis (if needed)
4920 // Additional checks for pad mode are required on iOS: this "second" axis is
4921 // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4922 if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4923 if (gPad->GetTicky() < 2) {
4924 strlcat(chopt, "U",10);
4926 } else {
4927 strlcat(chopt, "+L",10);
4928 }
4929 if ((cw=strstr(chopt,"W"))) *cw='z';
4930 axis.SetTitle("");
4931 axis.PaintAxis(yAxisXPos2, aymin,
4932 yAxisXPos2, aymax,
4933 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4934 }
4935 }//End of "if pad is in selection mode etc."
4936
4937 // Reset the axis if they have been inverted in case of option HBAR
4938 if (xaxis) {
4939 fXaxis = xaxis;
4940 fYaxis = yaxis;
4941 }
4942}
4943
4944////////////////////////////////////////////////////////////////////////////////
4945/// [Draw a bar-chart in a normal pad.](#HP10)
4946
4948{
4949
4950 Int_t bar = Hoption.Bar - 10;
4951 Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4952 Double_t offset = fH->GetBarOffset();
4954 TBox box;
4955 Int_t hcolor = fH->GetFillColor();
4956 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4957 Int_t hstyle = fH->GetFillStyle();
4958 box.SetFillColor(hcolor);
4959 box.SetFillStyle(hstyle);
4960 box.SetLineStyle(fH->GetLineStyle());
4961 box.SetLineColor(fH->GetLineColor());
4962 box.SetLineWidth(fH->GetLineWidth());
4963 for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4964 y = fH->GetBinContent(bin);
4965 xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4966 xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4967 ymin = gPad->GetUymin();
4968 ymax = gPad->YtoPad(y);
4969 if (ymax < gPad->GetUymin()) continue;
4970 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4971 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4972 if (Hoption.MinimumZero && ymin < 0)
4973 ymin=TMath::Min(0.,gPad->GetUymax());
4974 w = (xmax-xmin)*width;
4975 xmin += offset*(xmax-xmin);
4976 xmax = xmin + w;
4977 if (bar < 1) {
4978 box.PaintBox(xmin,ymin,xmax,ymax);
4979 } else {
4980 umin = xmin + bar*(xmax-xmin)/10.;
4981 umax = xmax - bar*(xmax-xmin)/10.;
4982 //box.SetFillColor(hcolor+150); //bright
4983 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4984 box.PaintBox(xmin,ymin,umin,ymax);
4985 box.SetFillColor(hcolor);
4986 box.PaintBox(umin,ymin,umax,ymax);
4987 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4988 box.PaintBox(umax,ymin,xmax,ymax);
4989 }
4990 }
4991}
4992
4993////////////////////////////////////////////////////////////////////////////////
4994/// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4995
4997{
4998
4999 gPad->SetVertical(kFALSE);
5000
5001 PaintInitH();
5002
5003 TAxis *xaxis = fXaxis;
5004 TAxis *yaxis = fYaxis;
5005 if (!strcmp(xaxis->GetName(),"xaxis")) {
5006 fXaxis = yaxis;
5007 fYaxis = xaxis;
5008 }
5009
5010 PaintFrame();
5012
5013 Int_t bar = Hoption.Bar - 20;
5014 Double_t xmin,xmax,ymin,ymax,umin,umax,w;
5015 Double_t offset = fH->GetBarOffset();
5017 TBox box;
5018 Int_t hcolor = fH->GetFillColor();
5019 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5020 Int_t hstyle = fH->GetFillStyle();
5021 box.SetFillColor(hcolor);
5022 box.SetFillStyle(hstyle);
5023 box.SetLineStyle(fH->GetLineStyle());
5024 box.SetLineColor(fH->GetLineColor());
5025 box.SetLineWidth(fH->GetLineWidth());
5026 for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
5027 ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
5028 ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
5029 xmin = gPad->GetUxmin();
5030 xmax = gPad->XtoPad(fH->GetBinContent(bin));
5031 if (xmax < gPad->GetUxmin()) continue;
5032 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
5033 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
5034 if (Hoption.MinimumZero && xmin < 0)
5035 xmin=TMath::Min(0.,gPad->GetUxmax());
5036 w = (ymax-ymin)*width;
5037 ymin += offset*(ymax-ymin);
5038 ymax = ymin + w;
5039 if (bar < 1) {
5040 box.PaintBox(xmin,ymin,xmax,ymax);
5041 } else {
5042 umin = ymin + bar*(ymax-ymin)/10.;
5043 umax = ymax - bar*(ymax-ymin)/10.;
5044 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5045 box.PaintBox(xmin,ymin,xmax,umin);
5046 box.SetFillColor(hcolor);
5047 box.PaintBox(xmin,umin,xmax,umax);
5048 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5049 box.PaintBox(xmin,umax,xmax,ymax);
5050 }
5051 }
5052
5053 PaintTitle();
5054
5055 // Draw box with histogram statistics and/or fit parameters
5056 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5057 TIter next(fFunctions);
5058 TObject *obj = 0;
5059 while ((obj = next())) {
5060 if (obj->InheritsFrom(TF1::Class())) break;
5061 obj = 0;
5062 }
5063 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
5064 }
5065
5066 fXaxis = xaxis;
5067 fYaxis = yaxis;
5068}
5069
5070////////////////////////////////////////////////////////////////////////////////
5071/// [Control function to draw a 2D histogram as a box plot](#HP13)
5072
5074{
5075
5076 Style_t fillsav = fH->GetFillStyle();
5077 Style_t colsav = fH->GetFillColor();
5078 if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
5079 if (Hoption.Box == 11) fH->SetFillStyle(1001);
5080 fH->TAttLine::Modify();
5081 fH->TAttFill::Modify();
5082
5083 Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
5084 Double_t ux1 = gPad->PixeltoX(1);
5085 Double_t ux0 = gPad->PixeltoX(0);
5086 Double_t uy1 = gPad->PixeltoY(1);
5087 Double_t uy0 = gPad->PixeltoY(0);
5088 Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
5089 Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
5090
5091 Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
5094 Double_t zminlin = zmin, zmaxlin = zmax;
5095
5096 // In case of option SAME, zmin and zmax values are taken from the
5097 // first plotted 2D histogram.
5098 if (Hoption.Same > 0 && Hoption.Same < 10) {
5099 TH2 *h2;
5100 TIter next(gPad->GetListOfPrimitives());
5101 while ((h2 = (TH2 *)next())) {
5102 if (!h2->InheritsFrom(TH2::Class())) continue;
5103 zmin = TMath::Max(h2->GetMinimum(), 0.);
5104 zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
5105 TMath::Abs(h2->GetMinimum()));
5106 zminlin = zmin;
5107 zmaxlin = zmax;
5108 if (Hoption.Logz) {
5109 if (zmin <= 0) {
5110 zmin = TMath::Log10(zmax*0.001);
5111 } else {
5112 zmin = TMath::Log10(zmin);
5113 }
5114 zmax = TMath::Log10(zmax);
5115 }
5116 break;
5117 }
5118 } else {
5119 if (Hoption.Logz) {
5120 if (zmin > 0) {
5121 zmin = TMath::Log10(zmin);
5122 zmax = TMath::Log10(zmax);
5123 } else {
5124 return;
5125 }
5126 }
5127 }
5128
5129 Double_t zratio, dz = zmax - zmin;
5130 Bool_t kZminNeg = kFALSE;
5131 if (fH->GetMinimum()<0) kZminNeg = kTRUE;
5132 Bool_t kZNeg = kFALSE;
5133
5134 // Define the dark and light colors the "button style" boxes.
5135 Color_t color = fH->GetFillColor();
5136 Color_t light=0, dark=0;
5137 if (Hoption.Box == 11) {
5138 light = TColor::GetColorBright(color);
5139 dark = TColor::GetColorDark(color);
5140 }
5141
5142 // Loop over all the bins and draw the boxes
5143 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5144 yk = fYaxis->GetBinLowEdge(j);
5145 ystep = fYaxis->GetBinWidth(j);
5146 ycent = 0.5*ystep;
5147 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5148 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5149 xk = fXaxis->GetBinLowEdge(i);
5150 xstep = fXaxis->GetBinWidth(i);
5151 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5152 xcent = 0.5*xstep;
5153 z = Hparam.factor*fH->GetBinContent(bin);
5154 kZNeg = kFALSE;
5155
5156 if (TMath::Abs(z) < zminlin) continue; // Can be the case with ...
5157 if (TMath::Abs(z) > zmaxlin) z = zmaxlin; // ... option Same
5158 if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with netgative bins.
5159
5160 if (z < 0) {
5161 if (Hoption.Logz) continue;
5162 z = -z;
5163 kZNeg = kTRUE;
5164 }
5165 if (Hoption.Logz) {
5166 if (z != 0) z = TMath::Log10(z);
5167 else z = zmin;
5168 }
5169
5170 if (dz == 0) continue;
5171 zratio = TMath::Sqrt((z-zmin)/dz);
5172 if (zratio == 0) continue;
5173
5174 xup = xcent*zratio + xk + xcent;
5175 xlow = 2*(xk + xcent) - xup;
5176 if (xup-xlow < dxmin) xup = xlow+dxmin;
5177 if (Hoption.Logx) {
5178 if (xup > 0) xup = TMath::Log10(xup);
5179 else continue;
5180 if (xlow > 0) xlow = TMath::Log10(xlow);
5181 else continue;
5182 }
5183
5184 yup = ycent*zratio + yk + ycent;
5185 ylow = 2*(yk + ycent) - yup;
5186 if (yup-ylow < dymin) yup = ylow+dymin;
5187 if (Hoption.Logy) {
5188 if (yup > 0) yup = TMath::Log10(yup);
5189 else continue;
5190 if (ylow > 0) ylow = TMath::Log10(ylow);
5191 else continue;
5192 }
5193
5194 xlow = TMath::Max(xlow, gPad->GetUxmin());
5195 ylow = TMath::Max(ylow, gPad->GetUymin());
5196 xup = TMath::Min(xup , gPad->GetUxmax());
5197 yup = TMath::Min(yup , gPad->GetUymax());
5198
5199 if (xlow >= xup) continue;
5200 if (ylow >= yup) continue;
5201
5202 if (Hoption.Box == 1) {
5203 fH->SetFillColor(color);
5204 fH->TAttFill::Modify();
5205 gPad->PaintBox(xlow, ylow, xup, yup);
5206 if (kZNeg) {
5207 gPad->PaintLine(xlow, ylow, xup, yup);
5208 gPad->PaintLine(xlow, yup, xup, ylow);
5209 }
5210 } else if (Hoption.Box == 11) {
5211 // Draw the center of the box
5212 fH->SetFillColor(color);
5213 fH->TAttFill::Modify();
5214 gPad->PaintBox(xlow, ylow, xup, yup);
5215
5216 // Draw top&left part of the box
5217 Double_t x[7], y[7];
5218 Double_t bwidth = 0.1;
5219 x[0] = xlow; y[0] = ylow;
5220 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5221 x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
5222 x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
5223 x[4] = xup; y[4] = yup;
5224 x[5] = xlow; y[5] = yup;
5225 x[6] = xlow; y[6] = ylow;
5226 if (kZNeg) fH->SetFillColor(dark);
5227 else fH->SetFillColor(light);
5228 fH->TAttFill::Modify();
5229 gPad->PaintFillArea(7, x, y);
5230
5231 // Draw bottom&right part of the box
5232 x[0] = xlow; y[0] = ylow;
5233 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5234 x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
5235 x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
5236 x[4] = xup; y[4] = yup;
5237 x[5] = xup; y[5] = ylow;
5238 x[6] = xlow; y[6] = ylow;
5239 if (kZNeg) fH->SetFillColor(light);
5240 else fH->SetFillColor(dark);
5241 fH->TAttFill::Modify();
5242 gPad->PaintFillArea(7, x, y);
5243 }
5244 }
5245 }
5246
5248 fH->SetFillStyle(fillsav);
5249 fH->SetFillColor(colsav);
5250 fH->TAttFill::Modify();
5251}
5252
5253
5254
5255////////////////////////////////////////////////////////////////////////////////
5256/// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](#HP14)
5257
5259{
5260 TH1D *hproj;
5261 TH2D *h2 = (TH2D*)fH;
5262
5263 TCandle myCandle;
5265 myCandle.SetMarkerColor(fH->GetLineColor());
5266 myCandle.SetLineColor(fH->GetLineColor());
5267 myCandle.SetLineWidth(fH->GetLineWidth());
5268 myCandle.SetFillColor(fH->GetFillColor());
5269 myCandle.SetFillStyle(fH->GetFillStyle());
5270 myCandle.SetMarkerSize(fH->GetMarkerSize());
5271 myCandle.SetMarkerStyle(fH->GetMarkerStyle());
5273
5274 Bool_t swapXY = myCandle.IsHorizontal();
5275 const Double_t standardCandleWidth = 0.66;
5276 const Double_t standardHistoWidth = 0.8;
5277
5278 double allMaxContent = h2->GetBinContent(h2->GetMaximumBin());
5279 double allMaxIntegral = 0;
5280
5281 if (!swapXY) { // Vertical candle
5282 //Determining the slice with the maximum content
5283 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5284 hproj = h2->ProjectionY("_px", i, i);
5285 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5286 }
5287 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5288 Double_t binPosX = fXaxis->GetBinLowEdge(i);
5289 Double_t binWidth = fXaxis->GetBinWidth(i);
5290 hproj = h2->ProjectionY("_px", i, i);
5291 if (hproj->GetEntries() !=0) {
5292 Double_t candleWidth = fH->GetBarWidth();
5293 Double_t offset = fH->GetBarOffset()*binWidth;
5294 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5295 double myIntegral = hproj->Integral();
5296 Double_t histoWidth = candleWidth;
5297 if (candleWidth > 0.999 && candleWidth < 1.001) {
5298 candleWidth = standardCandleWidth;
5299 histoWidth = standardHistoWidth;
5300 }
5301 if (Hoption.Logz && myMaxContent > 0) {
5302 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5303 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5304 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5305 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5306
5307 myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
5308 myCandle.SetCandleWidth(candleWidth*binWidth);
5309 myCandle.SetHistoWidth(histoWidth*binWidth);
5310 myCandle.SetHistogram(hproj);
5311 myCandle.Paint();
5312 }
5313 }
5314 } else { // Horizontal candle
5315 //Determining the slice with the maximum content
5316 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5317 hproj = h2->ProjectionX("_py", i, i);
5318 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5319 }
5320 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5321 Double_t binPosY = fYaxis->GetBinLowEdge(i);
5322 Double_t binWidth = fYaxis->GetBinWidth(i);
5323 hproj = h2->ProjectionX("_py", i, i);
5324 if (hproj->GetEntries() !=0) {
5325 Double_t candleWidth = fH->GetBarWidth();
5326 Double_t offset = fH->GetBarOffset()*binWidth;
5327 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5328 double myIntegral = hproj->Integral();
5329 Double_t histoWidth = candleWidth;
5330 if (candleWidth > 0.999 && candleWidth < 1.001) {
5331 candleWidth = standardCandleWidth;
5332 histoWidth = standardHistoWidth;
5333 }
5334 if (Hoption.Logz && myMaxContent > 0) {
5335 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5336 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5337 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5338 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5339
5340 myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
5341 myCandle.SetCandleWidth(candleWidth*binWidth);
5342 myCandle.SetHistoWidth(histoWidth*binWidth);
5343 myCandle.SetHistogram(hproj);
5344 myCandle.Paint();
5345 }
5346 }
5347 }
5348}
5349
5350
5351
5352////////////////////////////////////////////////////////////////////////////////
5353/// Returns the rendering regions for an axis to use in the COL2 option
5354///
5355/// The algorithm analyses the size of the axis compared to the size of
5356/// the rendering region. It figures out the boundaries to use for each color
5357/// of the rendering region. Only one axis is computed here.
5358///
5359/// This allows for a single computation of the boundaries before iterating
5360/// through all of the bins.
5361///
5362/// \param pAxis the axis to consider
5363/// \param nPixels the number of pixels to render axis into
5364/// \param isLog whether the axis is log scale
5365
5366std::vector<THistRenderingRegion>
5368{
5369 std::vector<THistRenderingRegion> regions;
5370
5371 enum STRATEGY { Bins, Pixels } strategy;
5372
5373 Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
5374
5375 if (nBins >= nPixels) {
5376 // more bins than pixels... we should loop over pixels and sample
5377 strategy = Pixels;
5378 } else {
5379 // fewer bins than pixels... we should loop over bins
5380 strategy = Bins;
5381 }
5382
5383 if (isLog) {
5384
5385 Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5386 Int_t binOffset=0;
5387 while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5388 binOffset++;
5389 xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5390 }
5391 if (xMin <= 0) {
5392 // this should cause an error if we have
5393 return regions;
5394 }
5395 Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5396
5397 if (strategy == Bins) {
5398 // logarithmic plot. we find the pixel for the bin
5399 // pixel = eta * log10(V) - alpha
5400 // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5401 // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5402 // and V is axis value
5403 Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5404 Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5405
5406 for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5407
5408 // linear plot. we simply need to find the appropriate bin
5409 // for the
5410 Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5411 Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5412 Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5413 Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5414 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5415 std::make_pair(bin, bin+1)};
5416 regions.push_back(region);
5417 }
5418
5419 } else {
5420
5421 // loop over pixels
5422
5423 Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5424
5425 for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5426 // linear plot
5427 Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5428 Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5429 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5430 std::make_pair(binLow, binHigh)};
5431 regions.push_back(region);
5432 }
5433 }
5434 } else {
5435 // standard linear plot
5436
5437 if (strategy == Bins) {
5438 // loop over bins
5439 for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5440
5441 // linear plot. we simply need to find the appropriate bin
5442 // for the
5443 Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5444 Int_t xPx1 = xPx0 + nPixels/nBins;
5445
5446 // make sure we don't compute beyond our bounds
5447 if (xPx1>= nPixels) xPx1 = nPixels-1;
5448
5449 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5450 std::make_pair(bin, bin+1)};
5451 regions.push_back(region);
5452 }
5453 } else {
5454 // loop over pixels
5455 for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5456 // linear plot
5457 Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5458 Int_t binHigh = binLow + nBins/nPixels;
5459 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5460 std::make_pair(binLow, binHigh)};
5461 regions.push_back(region);
5462 }
5463 }
5464 }
5465
5466 return regions;
5467}
5468
5469////////////////////////////////////////////////////////////////////////////////
5470/// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
5471
5473{
5474
5475 if (Hoption.System != kCARTESIAN) {
5476 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5477 "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5478 PaintColorLevels(nullptr);
5479 return;
5480 }
5481
5482 Double_t z;
5483
5484 // Use existing max or min values. If either is already set
5485 // the appropriate value to use.
5486 Double_t zmin = fH->GetMinimumStored();
5487 Double_t zmax = fH->GetMaximumStored();
5488 Double_t originalZMin = zmin;
5489 Double_t originalZMax = zmax;
5490 if ((zmin == -1111) && (zmax == -1111)) {
5491 fH->GetMinimumAndMaximum(zmin, zmax);
5492 fH->SetMinimum(zmin);
5493 fH->SetMaximum(zmax);
5494 } else if (zmin == -1111) {
5495 zmin = fH->GetMinimum();
5496 fH->SetMinimum(zmin);
5497 } else if (zmax == -1111) {
5498 zmax = fH->GetMaximum();
5499 fH->SetMaximum(zmax);
5500 }
5501
5502 Double_t dz = zmax - zmin;
5503 if (dz <= 0) { // Histogram filled with a constant value
5504 zmax += 0.1*TMath::Abs(zmax);
5505 zmin -= 0.1*TMath::Abs(zmin);
5506 dz = zmax - zmin;
5507 }
5508
5509 if (Hoption.Logz) {
5510 if (zmin > 0) {
5511 zmin = TMath::Log10(zmin);
5512 zmax = TMath::Log10(zmax);
5513 dz = zmax - zmin;
5514 } else {
5515 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5516 "Cannot plot logz because bin content is less than 0.");
5517 return;
5518 }
5519 }
5520
5521 // Initialize the levels on the Z axis
5522 Int_t ndiv = fH->GetContour();
5523 if (ndiv == 0 ) {
5524 ndiv = gStyle->GetNumberContours();
5525 fH->SetContour(ndiv);
5526 }
5527 std::vector<Double_t> colorBounds(ndiv);
5528 std::vector<Double_t> contours(ndiv, 0);
5529 if (fH->TestBit(TH1::kUserContour) == 0) {
5530 fH->SetContour(ndiv);
5531 } else {
5532 fH->GetContour(contours.data());
5533 }
5534
5535 Double_t step = 1.0/ndiv;
5536 for (Int_t i=0; i<ndiv; ++i) {
5537 colorBounds[i] = step*i;
5538 }
5539
5540 auto pFrame = gPad->GetFrame();
5541 Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5542 Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5543 Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5544 Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5545 Int_t nXPixels = px1-px0;
5546 Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5547
5548 std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5549
5550 auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5551 auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5552 if (xRegions.size() == 0 || yRegions.size() == 0) {
5553 Error("THistPainter::PaintColorLevelFast(Option_t*)",
5554 "Encountered error while computing rendering regions.");
5555 return;
5556 }
5557
5558 Bool_t minExists = kFALSE;
5559 Bool_t maxExists = kFALSE;
5560 Double_t minValue = 1.;
5561 Double_t maxValue = 0.;
5562 for (auto& yRegion : yRegions) {
5563 for (auto& xRegion : xRegions ) {
5564
5565 const auto& xBinRange = xRegion.fBinRange;
5566 const auto& yBinRange = yRegion.fBinRange;
5567
5568 // sample the range
5569 z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5570
5571 if (Hoption.Logz) {
5572 if (z > 0) z = TMath::Log10(z);
5573 else z = zmin;
5574 }
5575
5576 // obey the user's max and min values if they were set
5577 if (z > zmax) z = zmax;
5578 if (z < zmin) z = zmin;
5579
5580 if (fH->TestBit(TH1::kUserContour) == 1) {
5581 // contours are absolute values
5582 auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5583 z = colorBounds[index];
5584 } else {
5585 Int_t index = 0;
5586 if (dz != 0) {
5587 index = 0.001 + ((z - zmin)/dz)*ndiv;
5588 }
5589
5590 if (index == static_cast<Int_t>(colorBounds.size())) {
5591 index--;
5592 }
5593
5594 // Do a little bookkeeping to use later for getting libAfterImage to produce
5595 // the correct colors
5596 if (index == 0) {
5597 minExists = kTRUE;
5598 } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5599 maxExists = kTRUE;
5600 }
5601
5602 z = colorBounds[index];
5603
5604 if (z < minValue) {
5605 minValue = z;
5606 }
5607 if (z > maxValue) {
5608 maxValue = z;
5609 }
5610 }
5611
5612 // fill in the actual pixels
5613 const auto& xPixelRange = xRegion.fPixelRange;
5614 const auto& yPixelRange = yRegion.fPixelRange;
5615 for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5616 for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5617 Int_t pixel = yPx*nXPixels + xPx;
5618 buffer[pixel] = z;
5619 }
5620 }
5621 } // end px loop
5622 } // end py loop
5623
5624 // This is a bit of a hack to ensure that we span the entire color range and
5625 // don't screw up the colors for a sparse histogram. No one will notice that I set a
5626 // single pixel on the edge of the image to a different color. This is even more
5627 // true because the chosen pixels will be covered by the axis.
5628 if (minValue != maxValue) {
5629 if ( !minExists) {
5630 buffer.front() = 0;
5631 }
5632
5633 if ( !maxExists) {
5634 buffer[buffer.size()-nXPixels] = 0.95;
5635 }
5636 }
5637
5638 // Generate the TImage
5640 TImage* pImage = TImage::Create();
5642 pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5643 delete pPalette;
5644
5645 Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5646 pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5647 delete pImage;
5648
5650
5651 // Reset the maximum and minimum values to their original values
5652 // when this function was called. If we don't do this, an initial
5653 // value of -1111 will be replaced with the true max or min values.
5654 fH->SetMinimum(originalZMin);
5655 fH->SetMaximum(originalZMax);
5656}
5657
5658////////////////////////////////////////////////////////////////////////////////
5659/// [Control function to draw a 2D histogram as a color plot.](#HP14)
5660
5662{
5663 Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5664
5665 Double_t zmin = fH->GetMinimum();
5666 Double_t zmax = fH->GetMaximum();
5667
5668 Double_t dz = zmax - zmin;
5669 if (dz <= 0) { // Histogram filled with a constant value
5670 zmax += 0.1*TMath::Abs(zmax);
5671 zmin -= 0.1*TMath::Abs(zmin);
5672 dz = zmax - zmin;
5673 }
5674
5675 // In case of option SAME, zmin and zmax values are taken from the
5676 // first plotted 2D histogram.
5677 if (Hoption.Same > 0 && Hoption.Same < 10) {
5678 TH2 *h2;
5679 TIter next(gPad->GetListOfPrimitives());
5680 while ((h2 = (TH2 *)next())) {
5681 if (!h2->InheritsFrom(TH2::Class())) continue;
5682 zmin = h2->GetMinimum();
5683 zmax = h2->GetMaximum();
5684 fH->SetMinimum(zmin);
5685 fH->SetMaximum(zmax);
5686 if (Hoption.Logz) {
5687 if (zmin <= 0) {
5688 zmin = TMath::Log10(zmax*0.001);
5689 } else {
5690 zmin = TMath::Log10(zmin);
5691 }
5692 zmax = TMath::Log10(zmax);
5693 }
5694 dz = zmax - zmin;
5695 break;
5696 }
5697 } else {
5698 if (Hoption.Logz) {
5699 if (zmin > 0) {
5700 zmin = TMath::Log10(zmin);
5701 zmax = TMath::Log10(zmax);
5702 dz = zmax - zmin;
5703 } else {
5704 return;
5705 }
5706 }
5707 }
5708
5709 Style_t fillsav = fH->GetFillStyle();
5710 Style_t colsav = fH->GetFillColor();
5711 fH->SetFillStyle(1001);
5712 fH->TAttFill::Modify();
5713
5714 // Initialize the levels on the Z axis
5715 Int_t ncolors = gStyle->GetNumberOfColors();
5716 Int_t ndiv = fH->GetContour();
5717 if (ndiv == 0 ) {
5718 ndiv = gStyle->GetNumberContours();
5719 fH->SetContour(ndiv);
5720 }
5721 Int_t ndivz = TMath::Abs(ndiv);
5722 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5723 Double_t scale = (dz ? ndivz / dz : 1.0);
5724
5725 Int_t color;
5726 TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5727 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5728 yk = fYaxis->GetBinLowEdge(j);
5729 ystep = fYaxis->GetBinWidth(j);
5730 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5731 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5732 xk = fXaxis->GetBinLowEdge(i);
5733 xstep = fXaxis->GetBinWidth(i);
5734 if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5735 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5736 z = fH->GetBinContent(bin);
5737 // if fH is a profile histogram do not draw empty bins
5738 if (prof2d) {
5739 const Double_t binEntries = prof2d->GetBinEntries(bin);
5740 if (binEntries == 0)
5741 continue;
5742 } else {
5743 // don't draw the empty bins for non-profile histograms
5744 // with positive content
5745 if (z == 0) {
5746 if (zmin >= 0 || Hoption.Logz) continue;
5747 if (Hoption.Color == 2) continue;
5748 }
5749 }
5750
5751 if (Hoption.Logz) {
5752 if (z > 0) z = TMath::Log10(z);
5753 else z = zmin;
5754 }
5755 if (z < zmin && !Hoption.Zero) continue;
5756 xup = xk + xstep;
5757 xlow = xk;
5758 if (Hoption.Logx) {
5759 if (xup > 0) xup = TMath::Log10(xup);
5760 else continue;
5761 if (xlow > 0) xlow = TMath::Log10(xlow);
5762 else continue;
5763 }
5764 yup = yk + ystep;
5765 ylow = yk;
5766 if (Hoption.System != kPOLAR) {
5767 if (Hoption.Logy) {
5768 if (yup > 0) yup = TMath::Log10(yup);
5769 else continue;
5770 if (ylow > 0) ylow = TMath::Log10(ylow);
5771 else continue;
5772 }
5773 if (xup < gPad->GetUxmin()) continue;
5774 if (yup < gPad->GetUymin()) continue;
5775 if (xlow > gPad->GetUxmax()) continue;
5776 if (ylow > gPad->GetUymax()) continue;
5777 if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5778 if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5779 if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5780 if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5781 }
5782
5784 zc = fH->GetContourLevelPad(0);
5785 if (z < zc) continue;
5786 color = -1;
5787 for (Int_t k=0; k<ndiv; k++) {
5788 zc = fH->GetContourLevelPad(k);
5789 if (z < zc) {
5790 continue;
5791 } else {
5792 color++;
5793 }
5794 }
5795 } else {
5796 color = Int_t(0.01+(z-zmin)*scale);
5797 }
5798
5799 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5800 if (theColor > ncolors-1) theColor = ncolors-1;
5802 fH->TAttFill::Modify();
5803 if (Hoption.System != kPOLAR) {
5804 gPad->PaintBox(xlow, ylow, xup, yup);
5805 } else {
5806 TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5807 crown.SetFillColor(gStyle->GetColorPalette(theColor));
5808 crown.Paint();
5809 }
5810 }
5811 }
5812
5814
5815 fH->SetFillStyle(fillsav);
5816 fH->SetFillColor(colsav);
5817 fH->TAttFill::Modify();
5818
5819}
5820
5821////////////////////////////////////////////////////////////////////////////////
5822/// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5823
5825{
5826
5827 Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5828 Int_t itars, mode, ir[4];
5829 Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5830
5831 if (Hoption.Contour == 14) {
5832 Hoption.Surf = 12;
5833 Hoption.Axis = 1;
5834 thesave = gPad->GetTheta();
5835 phisave = gPad->GetPhi();
5836 gPad->SetPhi(0.);
5837 gPad->SetTheta(90.);
5838 PaintSurface(option);
5839 gPad->SetPhi(phisave);
5840 gPad->SetTheta(thesave);
5841 TView *view = gPad->GetView();
5842 if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5843 PaintAxis();
5844 return;
5845 }
5846
5847 if (Hoption.Same) {
5848 // If the contour is painted on a 3d plot, the contour lines are
5849 // paint in 3d too.
5850 TObject *obj;
5851 TIter next(gPad->GetListOfPrimitives());
5852 while ((obj=next())) {
5853 if (strstr(obj->GetDrawOption(),"surf") ||
5854 strstr(obj->GetDrawOption(),"lego") ||
5855 strstr(obj->GetDrawOption(),"tri")) {
5856 Hoption.Surf = 16;
5857 PaintSurface(option);
5858 return;
5859 }
5860 }
5861 }
5862
5863 if (Hoption.Contour == 15) {
5864 TGraphDelaunay2D *dt = nullptr;
5865 TGraphDelaunay *dtOld = nullptr;
5866 TList *hl = fH->GetListOfFunctions();
5867 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5868 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5869 if (!dt && !dtOld) return;
5870 if (!fGraph2DPainter) {
5871 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5872 else fGraph2DPainter = new TGraph2DPainter(dtOld);
5873 }
5874 fGraph2DPainter->Paint(option);
5875 return;
5876 }
5877
5878 gPad->SetBit(TGraph::kClipFrame);
5879
5880 Double_t *levels = new Double_t[2*kMAXCONTOUR];
5881 Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5882 Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5883 Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5884
5885 Int_t npmax = 0;
5886 for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5887
5888 ncontour = fH->GetContour();
5889 if (ncontour == 0) {
5890 ncontour = gStyle->GetNumberContours();
5891 fH->SetContour(ncontour);
5892 }
5893 if (ncontour > kMAXCONTOUR) {
5894 Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5895 kMAXCONTOUR, ncontour);
5896 ncontour = kMAXCONTOUR-1;
5897 }
5898 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5899
5900 for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5901 Int_t linesav = fH->GetLineStyle();
5902 Int_t colorsav = fH->GetLineColor();
5903 Int_t fillsav = fH->GetFillColor();
5904 if (Hoption.Contour == 13) {
5905 fH->TAttLine::Modify();
5906 }
5907
5908 TPolyLine **polys = 0;
5909 TPolyLine *poly=0;
5910 TObjArray *contours = 0;
5911 TList *list = 0;
5912 TGraph *graph = 0;
5913 Int_t *np = 0;
5914 if (Hoption.Contour == 1) {
5915 np = new Int_t[ncontour];
5916 for (i=0;i<ncontour;i++) np[i] = 0;
5917 polys = new TPolyLine*[ncontour];
5918 for (i=0;i<ncontour;i++) {
5919 polys[i] = new TPolyLine(100);
5920 }
5921 if (Hoption.List == 1) {
5922 contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5923 if (contours) {
5924 gROOT->GetListOfSpecials()->Remove(contours);
5925 count = contours->GetSize();
5926 for (i=0;i<count;i++) {
5927 list = (TList*)contours->At(i);
5928 if (list) list->Delete();
5929 }
5930 }
5931 contours = new TObjArray(ncontour);
5932 contours->SetName("contours");
5933 gROOT->GetListOfSpecials()->Add(contours);
5934 for (i=0;i<ncontour;i++) {
5935 list = new TList();
5936 contours->Add(list);
5937 }
5938 }
5939 }
5940 Int_t theColor;
5941 Int_t ncolors = gStyle->GetNumberOfColors();
5942 Int_t ndivz = TMath::Abs(ncontour);
5943
5944 Int_t k,ipoly;
5945 for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5946 y[0] = fYaxis->GetBinCenter(j);
5947 y[1] = y[0];
5948 y[2] = fYaxis->GetBinCenter(j+1);
5949 y[3] = y[2];
5950 for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5951 zc[0] = fH->GetBinContent(i, j);
5952 zc[1] = fH->GetBinContent(i+1, j);
5953 zc[2] = fH->GetBinContent(i+1, j+1);
5954 zc[3] = fH->GetBinContent(i, j+1);
5955 if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5956 if (Hoption.Logz) {
5957 if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5958 else zc[0] = Hparam.zmin;
5959 if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5960 else zc[1] = Hparam.zmin;
5961 if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5962 else zc[2] = Hparam.zmin;
5963 if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5964 else zc[3] = Hparam.zmin;
5965 }
5966 for (k=0;k<4;k++) {
5967 ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5968 }
5969 if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5970 x[0] = fXaxis->GetBinCenter(i);
5971 x[3] = x[0];
5972 x[1] = fXaxis->GetBinCenter(i+1);
5973 x[2] = x[1];
5974 if (zc[0] <= zc[1]) n = 0; else n = 1;
5975 if (zc[2] <= zc[3]) m = 2; else m = 3;
5976 if (zc[n] > zc[m]) n = m;
5977 n++;
5978 lj=1;
5979 for (ix=1;ix<=4;ix++) {
5980 m = n%4 + 1;
5981 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5982 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5983 lj += 2*ljfill;
5984 n = m;
5985 }
5986
5987 if (zc[0] <= zc[1]) n = 0; else n = 1;
5988 if (zc[2] <= zc[3]) m = 2; else m = 3;
5989 if (zc[n] > zc[m]) n = m;
5990 n++;
5991 lj=2;
5992 for (ix=1;ix<=4;ix++) {
5993 if (n == 1) m = 4;
5994 else m = n-1;
5995 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5996 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5997 lj += 2*ljfill;
5998 n = m;
5999 }
6000
6001 // Re-order endpoints
6002
6003 count = 0;
6004 for (ix=1; ix<=lj-5; ix +=2) {
6005 //count = 0;
6006 while (itarr[ix-1] != itarr[ix]) {
6007 xsave = xarr[ix];
6008 ysave = yarr[ix];
6009 itars = itarr[ix];
6010 for (jx=ix; jx<=lj-5; jx +=2) {
6011 xarr[jx] = xarr[jx+2];
6012 yarr[jx] = yarr[jx+2];
6013 itarr[jx] = itarr[jx+2];
6014 }
6015 xarr[lj-3] = xsave;
6016 yarr[lj-3] = ysave;
6017 itarr[lj-3] = itars;
6018 if (count > 100) break;
6019 count++;
6020 }
6021 }
6022
6023 if (count > 100) continue;
6024 for (ix=1; ix<=lj-2; ix +=2) {
6025 theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
6026 icol = gStyle->GetColorPalette(theColor);
6027 if (Hoption.Contour == 11) {
6028 fH->SetLineColor(icol);
6029 }
6030 if (Hoption.Contour == 12) {
6031 mode = icol%5;
6032 if (mode == 0) mode = 5;
6033 fH->SetLineStyle(mode);
6034 }
6035 if (Hoption.Contour != 1) {
6036 fH->TAttLine::Modify();
6037 gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
6038 continue;
6039 }
6040
6041 ipoly = itarr[ix-1];
6042 if (ipoly >=0 && ipoly <ncontour) {
6043 poly = polys[ipoly];
6044 poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
6045 poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
6046 np[ipoly] += 2;
6047 if (npmax < np[ipoly]) npmax = np[ipoly];
6048 }
6049 }
6050 } // end of if (ir[0]
6051 } //end of for (i
6052 } //end of for (j
6053
6055 Double_t *xp, *yp;
6056 Int_t nadd,iminus,iplus;
6057 Double_t *xx, *yy;
6058 Int_t istart;
6059 Int_t first = ncontour;
6060 Int_t *polysort = 0;
6061 Int_t contListNb;
6062 if (Hoption.Contour != 1) goto theEND;
6063
6064 //The 2 points line generated above are now sorted/merged to generate
6065 //a list of consecutive points.
6066 // If the option "List" has been specified, the list of points is saved
6067 // in the form of TGraph objects in the ROOT list of special objects.
6068 xmin = gPad->GetUxmin();
6069 ymin = gPad->GetUymin();
6070 xp = new Double_t[2*npmax];
6071 yp = new Double_t[2*npmax];
6072 polysort = new Int_t[ncontour];
6073 //find first positive contour
6074 for (ipoly=0;ipoly<ncontour;ipoly++) {
6075 if (levels[ipoly] >= 0) {first = ipoly; break;}
6076 }
6077 //store negative contours from 0 to minimum, then all positive contours
6078 k = 0;
6079 for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
6080 for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
6081 // we can now draw sorted contours
6082 contListNb = 0;
6083 fH->SetFillStyle(1001);
6084 for (k=0;k<ncontour;k++) {
6085 ipoly = polysort[k];
6086 if (np[ipoly] == 0) continue;
6087 if (Hoption.List) list = (TList*)contours->At(contListNb);
6088 contListNb++;
6089 poly = polys[ipoly];
6090 xx = poly->GetX();
6091 yy = poly->GetY();
6092 istart = 0;
6093 while (1) {
6094 iminus = npmax;
6095 iplus = iminus+1;
6096 xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
6097 xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
6098 xx[istart] = xmin; yy[istart] = ymin;
6099 xx[istart+1] = xmin; yy[istart+1] = ymin;
6100 while (1) {
6101 nadd = 0;
6102 for (i=2;i<np[ipoly];i+=2) {
6103 if ((iplus < 2*npmax-1) && (xx[i] == xp[iplus]) && (yy[i] == yp[iplus])) {
6104 iplus++;
6105 xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
6106 xx[i] = xmin; yy[i] = ymin;
6107 xx[i+1] = xmin; yy[i+1] = ymin;
6108 nadd++;
6109 }
6110 if ((iminus > 0) && (xx[i+1] == xp[iminus]) && (yy[i+1] == yp[iminus])) {
6111 iminus--;
6112 xp[iminus] = xx[i]; yp[iminus] = yy[i];
6113 xx[i] = xmin; yy[i] = ymin;
6114 xx[i+1] = xmin; yy[i+1] = ymin;
6115 nadd++;
6116 }
6117 }
6118 if (nadd == 0) break;
6119 }
6120 theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
6121 icol = gStyle->GetColorPalette(theColor);
6122 if (ndivz > 1) fH->SetFillColor(icol);
6123 fH->TAttFill::Modify();
6124 gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6125 if (Hoption.List) {
6126 graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6127 graph->SetFillColor(icol);
6128 graph->SetLineWidth(fH->GetLineWidth());
6129 list->Add(graph);
6130 }
6131 //check if more points are left
6132 istart = 0;
6133 for (i=2;i<np[ipoly];i+=2) {
6134 if (xx[i] != xmin && yy[i] != ymin) {
6135 istart = i;
6136 break;
6137 }
6138 }
6139 if (istart == 0) break;
6140 }
6141 }
6142
6143 for (i=0;i<ncontour;i++) delete polys[i];
6144 delete [] polys;
6145 delete [] xp;
6146 delete [] yp;
6147 delete [] polysort;
6148
6149theEND:
6150 gPad->ResetBit(TGraph::kClipFrame);
6152 fH->SetLineStyle(linesav);
6153 fH->SetLineColor(colorsav);
6154 fH->SetFillColor(fillsav);
6155 if (np) delete [] np;
6156 delete [] xarr;
6157 delete [] yarr;
6158 delete [] itarr;
6159 delete [] levels;
6160}
6161
6162////////////////////////////////////////////////////////////////////////////////
6163/// Fill the matrix `xarr` and `yarr` for Contour Plot.
6164
6166 Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
6167 Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
6168{
6169
6170 Bool_t vert;
6171 Double_t tlen, tdif, elev, diff, pdif, xlen;
6172 Int_t n, i, icount;
6173
6174 if (x1 == x2) {
6175 vert = kTRUE;
6176 tlen = y2 - y1;
6177 } else {
6178 vert = kFALSE;
6179 tlen = x2 - x1;
6180 }
6181
6182 n = icont1 +1;
6183 tdif = elev2 - elev1;
6184 i = 0;
6185 icount = 0;
6186 while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
6187 //elev = fH->GetContourLevel(n);
6188 elev = levels[n];
6189 diff = elev - elev1;
6190 pdif = diff/tdif;
6191 xlen = tlen*pdif;
6192 if (vert) {
6193 if (Hoption.Logx)
6194 xarr[i] = TMath::Log10(x1);
6195 else
6196 xarr[i] = x1;
6197 if (Hoption.Logy)
6198 yarr[i] = TMath::Log10(y1 + xlen);
6199 else
6200 yarr[i] = y1 + xlen;
6201 } else {
6202 if (Hoption.Logx)
6203 xarr[i] = TMath::Log10(x1 + xlen);
6204 else
6205 xarr[i] = x1 + xlen;
6206 if (Hoption.Logy)
6207 yarr[i] = TMath::Log10(y1);
6208 else
6209 yarr[i] = y1;
6210 }
6211 itarr[i] = n;
6212 icount++;
6213 i +=2;
6214 n++;
6215 }
6216 return icount;
6217}
6218
6219////////////////////////////////////////////////////////////////////////////////
6220/// [Draw 1D histograms error bars.](#HP09)
6221
6223{
6224
6225 // On iOS, we do not highlight histogram, if it's not picked at the moment
6226 // (but part of histogram (axis or pavestat) was picked, that's why this code
6227 // is called at all. This conditional statement never executes on non-iOS platform.
6228 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
6229
6230 const Int_t kBASEMARKER=8;
6231 Double_t xp, yp, ex1, ex2, ey1, ey2;
6232 Double_t delta;
6233 Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
6234 Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
6236 Double_t logxmin = 0;
6237 Double_t logymin = 0;
6238 Int_t i, k, npoints, first, last, fixbin;
6239 Int_t if1 = 0;
6240 Int_t if2 = 0;
6241 Int_t drawmarker, errormarker;
6242 Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
6243
6244 Double_t *xline = 0;
6245 Double_t *yline = 0;
6246 option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
6247 if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
6248 if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
6249 if (Hoption.Error == 10) option0 = 1;
6250 if (Hoption.Error == 11) option1 = 1;
6251 if (Hoption.Error == 12) option2 = 1;
6252 if (Hoption.Error == 13) option3 = 1;
6253 if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
6254 if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
6255 if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
6256 if (option2+option3 == 0) optionE = 1;
6257 if (Hoption.Error == 0) optionE = 0;
6258 if (fXaxis->GetXbins()->fN) fixbin = 0;
6259 else fixbin = 1;
6260
6261 errormarker = fH->GetMarkerStyle();
6262 if (optionEX0) {
6263 xerror = 0;
6264 } else {
6265 xerror = gStyle->GetErrorX();
6266 }
6267 symbolsize = fH->GetMarkerSize();
6268 if (errormarker == 1) symbolsize = 0.01;
6269 sbase = symbolsize*kBASEMARKER;
6270 // set the graphics attributes
6271
6272 fH->TAttLine::Modify();
6273 fH->TAttFill::Modify();
6274 fH->TAttMarker::Modify();
6275
6276 // set the first and last bin
6277
6278 Double_t factor = Hparam.factor;
6280 last = Hparam.xlast;
6281 npoints = last - first +1;
6282 xmin = gPad->GetUxmin();
6283 xmax = gPad->GetUxmax();
6284 ymin = gPad->GetUymin();
6285 ymax = gPad->GetUymax();
6286
6287
6288 if (option3) {
6289 xline = new Double_t[2*npoints];
6290 yline = new Double_t[2*npoints];
6291 if (!xline || !yline) {
6292 Error("PaintErrors", "too many points, out of memory");
6293 return;
6294 }
6295 if1 = 1;
6296 if2 = 2*npoints;
6297 }
6298
6299 // compute the offset of the error bars due to the symbol size
6300 s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
6301 s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
6302
6303 // compute size of the lines at the end of the error bars
6304 Int_t dxend = Int_t(gStyle->GetEndErrorSize());
6305 bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
6306 bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
6307
6308
6309 if (fixbin) {
6310 if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
6311 else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
6312 } else {
6313 delta = fH->GetBinWidth(first);
6314 xp = fH->GetBinLowEdge(first) + 0.5*delta;
6315 }
6316
6317 // if errormarker = 0 or symbolsize = 0. no symbol is drawn
6318 if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
6319 if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
6320
6321 // ---------------------- Loop over the points---------------------
6322 for (k=first; k<=last; k++) {
6323
6324 // get the data
6325 // xp = X position of the current point
6326 // yp = Y position of the current point
6327 // ex1 = Low X error
6328 // ex2 = Up X error
6329 // ey1 = Low Y error
6330 // ey2 = Up Y error
6331 // (xi,yi) = Error bars coordinates
6332
6333 if (Hoption.Logx) {
6334 if (xp <= 0) goto L30;
6335 if (xp < logxmin) goto L30;
6336 if (xp > TMath::Power(10,xmax)) break;
6337 } else {
6338 if (xp < xmin) goto L30;
6339 if (xp > xmax) break;
6340 }
6341 yp = factor*fH->GetBinContent(k);
6342 if (optionI0 && yp==0) goto L30;
6343 if (fixbin) {
6344 ex1 = xerror*Hparam.xbinsize;
6345 } else {
6346 delta = fH->GetBinWidth(k);
6347 ex1 = xerror*delta;
6348 }
6349 if (fH->GetBinErrorOption() == TH1::kNormal) {
6350 ey1 = factor*fH->GetBinError(k);
6351 ey2 = ey1;
6352 } else {
6353 ey1 = factor*fH->GetBinErrorLow(k);
6354 ey2 = factor*fH->GetBinErrorUp(k);
6355 }
6356 ex2 = ex1;
6357
6358 xi4 = xp;
6359 xi3 = xp;
6360 xi2 = xp + ex2;
6361 xi1 = xp - ex1;
6362
6363 yi1 = yp;
6364 yi2 = yp;
6365 yi3 = yp - ey1;
6366 yi4 = yp + ey2;
6367
6368 // take the LOG if necessary
6369 if (Hoption.Logx) {
6370 xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
6371 xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
6372 xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
6373 xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
6374 }
6375 if (Hoption.Logy) {
6376 yi1 = TMath::Log10(TMath::Max(yi1,logymin));
6377 yi2 = TMath::Log10(TMath::Max(yi2,logymin));
6378 yi3 = TMath::Log10(TMath::Max(yi3,logymin));
6379 yi4 = TMath::Log10(TMath::Max(yi4,logymin));
6380 }
6381
6382 // test if error bars are not outside the limits
6383 // otherwise they are truncated
6384
6385 xi1 = TMath::Max(xi1,xmin);
6386 xi2 = TMath::Min(xi2,xmax);
6387 yi3 = TMath::Max(yi3,ymin);
6388 yi4 = TMath::Min(yi4,ymax);
6389
6390 // test if the marker is on the frame limits. If "Yes", the
6391 // marker will not be drawn and the error bars will be readjusted.
6392
6393 drawmarker = kTRUE;
6394 if (!option0 && !option3) {
6395 if (Hoption.Logy && yp < logymin) goto L30;
6396 if (yi1 < ymin || yi1 > ymax) goto L30;
6397 if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6398 }
6399 if (!symbolsize || !errormarker) drawmarker = kFALSE;
6400
6401 // draw the error rectangles
6402 if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
6403
6404 // keep points for fill area drawing
6405 if (option3) {
6406 xline[if1-1] = xi3;
6407 xline[if2-1] = xi3;
6408 yline[if1-1] = yi4;
6409 yline[if2-1] = yi3;
6410 if1++;
6411 if2--;
6412 }
6413
6414 // draw the error bars
6415 if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6416 if (optionE && drawmarker) {
6417 if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6418 if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6419 // don't duplicate the horizontal line
6420 if (Hoption.Hist != 2) {
6421 if (yi1<ymax && yi1>ymin) {
6422 if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6423 if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6424 }
6425 }
6426 }
6427 if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6428 if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6429 if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6430 // don't duplicate the horizontal line
6431 if (Hoption.Hist != 2) {
6432 if (yi1<ymax && yi1>ymin) {
6433 if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6434 if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6435 }
6436 }
6437 }
6438
6439 // draw line at the end of the error bars
6440
6441 if (option1 && drawmarker) {
6442 if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
6443 if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
6444 if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
6445 if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
6446 }
6447
6448 // draw the marker
6449
6450 if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6451
6452L30:
6453 if (fixbin) xp += Hparam.xbinsize;
6454 else {
6455 if (k < last) {
6456 delta = fH->GetBinWidth(k+1);
6457 xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6458 }
6459 }
6460 } //end of for loop
6461
6462 // draw the filled area
6463
6464 if (option3) {
6465 TGraph graph;
6466 graph.SetLineStyle(fH->GetLineStyle());
6467 graph.SetLineColor(fH->GetLineColor());
6468 graph.SetLineWidth(fH->GetLineWidth());
6469 graph.SetFillStyle(fH->GetFillStyle());
6470 graph.SetFillColor(fH->GetFillColor());
6471 Int_t logx = gPad->GetLogx();
6472 Int_t logy = gPad->GetLogy();
6473 gPad->SetLogx(0);
6474 gPad->SetLogy(0);
6475
6476 // In some cases the number of points in the fill area is smaller than
6477 // 2*npoints. In such cases the array xline and yline must be arranged
6478 // before being plotted. The next loop does that.
6479 if (if2 > npoints) {
6480 for (i=1; i<if1; i++) {
6481 xline[if1-2+i] = xline[if2-1+i];
6482 yline[if1-2+i] = yline[if2-1+i];
6483 }
6484 npoints = if1-1;
6485 }
6486 if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6487 else graph.PaintGraph(2*npoints,xline,yline,"F");
6488 gPad->SetLogx(logx);
6489 gPad->SetLogy(logy);
6490 delete [] xline;
6491 delete [] yline;
6492 }
6493}
6494
6495////////////////////////////////////////////////////////////////////////////////
6496/// Draw 2D histograms errors.
6497
6499{
6500
6501 fH->TAttMarker::Modify();
6502 fH->TAttLine::Modify();
6503
6504 // Define the 3D view
6505 fXbuf[0] = Hparam.xmin;
6506 fYbuf[0] = Hparam.xmax;
6507 fXbuf[1] = Hparam.ymin;
6508 fYbuf[1] = Hparam.ymax;
6509 fXbuf[2] = Hparam.zmin;
6510 fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6512 TView *view = gPad->GetView();
6513 if (!view) {
6514 Error("Paint2DErrors", "no TView in current pad");
6515 return;
6516 }
6517 Double_t thedeg = 90 - gPad->GetTheta();
6518 Double_t phideg = -90 - gPad->GetPhi();
6519 Double_t psideg = view->GetPsi();
6520 Int_t irep;
6521 view->SetView(phideg, thedeg, psideg, irep);
6522
6523 // Set color/style for back box
6524 fLego->SetFillStyle(gPad->GetFrameFillStyle());
6525 fLego->SetFillColor(gPad->GetFrameFillColor());
6526 fLego->TAttFill::Modify();
6527 Int_t backcolor = gPad->GetFrameFillColor();
6528 if (Hoption.System != kCARTESIAN) backcolor = 0;
6529 view->PadRange(backcolor);
6532 fLego->TAttFill::Modify();
6533
6534 // Paint the Back Box if needed
6535 if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6536 fLego->InitMoveScreen(-1.1,1.1);
6539 fLego->BackBox(90);
6540 }
6541
6542 // Paint the Errors
6543 Double_t x, ex, x1, x2;
6544 Double_t y, ey, y1, y2;
6545 Double_t z, ez1, ez2, z1, z2;
6546 Double_t temp1[3],temp2[3];
6547 Double_t xyerror;
6548 if (Hoption.Error == 110) {
6549 xyerror = 0;
6550 } else {
6551 xyerror = gStyle->GetErrorX();
6552 }
6553
6554 Double_t xk, xstep, yk, ystep;
6555 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6556 y = fYaxis->GetBinCenter(j);
6557 ey = fYaxis->GetBinWidth(j)*xyerror;
6558 y1 = y-ey;
6559 y2 = y+ey;
6560 if (Hoption.Logy) {
6561 if (y > 0) y = TMath::Log10(y);
6562 else continue;
6563 if (y1 > 0) y1 = TMath::Log10(y1);
6564 else y1 = Hparam.ymin;
6565 if (y2 > 0) y2 = TMath::Log10(y2);
6566 else y2 = Hparam.ymin;
6567 }
6568 yk = fYaxis->GetBinLowEdge(j);
6569 ystep = fYaxis->GetBinWidth(j);
6570 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6571 xk = fXaxis->GetBinLowEdge(i);
6572 xstep = fXaxis->GetBinWidth(i);
6573 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6574 Int_t bin = fH->GetBin(i,j);
6575 x = fXaxis->GetBinCenter(i);
6576 ex = fXaxis->GetBinWidth(i)*xyerror;
6577 x1 = x-ex;
6578 x2 = x+ex;
6579 if (Hoption.Logx) {
6580 if (x > 0) x = TMath::Log10(x);
6581 else continue;
6582 if (x1 > 0) x1 = TMath::Log10(x1);
6583 else x1 = Hparam.xmin;
6584 if (x2 > 0) x2 = TMath::Log10(x2);
6585 else x2 = Hparam.xmin;
6586 }
6587 z = fH->GetBinContent(bin);
6588 if (fH->GetBinErrorOption() == TH1::kNormal) {
6589 ez1 = fH->GetBinError(bin);
6590 ez2 = ez1;
6591 }
6592 else {
6593 ez1 = fH->GetBinErrorLow(bin);
6594 ez2 = fH->GetBinErrorUp(bin);
6595 }
6596 z1 = z - ez1;
6597 z2 = z + ez2;
6598 if (Hoption.Logz) {
6599 if (z > 0) z = TMath::Log10(z);
6600 else z = Hparam.zmin;
6601 if (z1 > 0) z1 = TMath::Log10(z1);
6602 else z1 = Hparam.zmin;
6603 if (z2 > 0) z2 = TMath::Log10(z2);
6604 else z2 = Hparam.zmin;
6605
6606 }
6607 if (z <= Hparam.zmin) continue;
6608 if (z > Hparam.zmax) z = Hparam.zmax;
6609
6610 temp1[0] = x1;
6611 temp1[1] = y;
6612 temp1[2] = z;
6613 temp2[0] = x2;
6614 temp2[1] = y;
6615 temp2[2] = z;
6616 gPad->PaintLine3D(temp1, temp2);
6617 temp1[0] = x;
6618 temp1[1] = y1;
6619 temp1[2] = z;
6620 temp2[0] = x;
6621 temp2[1] = y2;
6622 temp2[2] = z;
6623 gPad->PaintLine3D(temp1, temp2);
6624 temp1[0] = x;
6625 temp1[1] = y;
6626 temp1[2] = z1;
6627 temp2[0] = x;
6628 temp2[1] = y;
6629 temp2[2] = z2;
6630 gPad->PaintLine3D(temp1, temp2);
6631 temp1[0] = x;
6632 temp1[1] = y;
6633 temp1[2] = z;
6634 view->WCtoNDC(temp1, &temp2[0]);
6635 gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6636 }
6637 }
6638
6639 // Paint the Front Box if needed
6640 if (Hoption.FrontBox) {
6641 fLego->InitMoveScreen(-1.1,1.1);
6643 fLego->FrontBox(90);
6644 }
6645
6646 // Paint the Axis if needed
6647 if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6648 TGaxis *axis = new TGaxis();
6649 PaintLegoAxis(axis, 90);
6650 delete axis;
6651 }
6652
6653 delete fLego; fLego = 0;
6654}
6655
6656////////////////////////////////////////////////////////////////////////////////
6657/// Calculate range and clear pad (canvas).
6658
6660{
6661
6662 if (Hoption.Same) return;
6663
6665
6666 if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6667 Hoption.Contour == 14 || Hoption.Error >= 100) {
6668 TObject *frame = gPad->FindObject("TFrame");
6669 if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6670 return;
6671 }
6672
6673 //The next statement is always executed on non-iOS platform,
6674 //on iOS depends on pad mode.
6675 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6676 gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6677}
6678
6679////////////////////////////////////////////////////////////////////////////////
6680/// [Paint functions associated to an histogram.](#HP28")
6681
6683{
6684
6686 TObject *obj;
6687
6688 while (lnk) {
6689 obj = lnk->GetObject();
6690 TVirtualPad *padsave = gPad;
6691 if (obj->InheritsFrom(TF2::Class())) {
6692 if (obj->TestBit(TF2::kNotDraw) == 0) {
6693 if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) {
6694 TF2 *f2 = (TF2*)obj;
6695 f2->SetMinimum(fH->GetMinimum());
6696 f2->SetMaximum(fH->GetMaximum());
6697 f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6698 f2->Paint("surf same");
6699 } else {
6700 obj->Paint("cont3 same");
6701 }
6702 }
6703 } else if (obj->InheritsFrom(TF1::Class())) {
6704 if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6705 } else {
6706 //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6707 gPad->PushSelectableObject(obj);
6708
6709 //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6710 //and picked object.
6711 if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6712 obj->Paint(lnk->GetOption());
6713 }
6714 lnk = (TObjOptLink*)lnk->Next();
6715 padsave->cd();
6716 }
6717}
6718
6719////////////////////////////////////////////////////////////////////////////////
6720/// [Control routine to draw 1D histograms](#HP01b)
6721
6723{
6724
6725 //On iOS: do not highlight hist, if part of it was selected.
6726 //Never executes on non-iOS platform.
6727 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6728 return;
6729
6730 static char chopth[17];
6731
6732 Int_t htype, oldhtype;
6733 Int_t i, j, first, last, nbins, fixbin;
6734 Double_t c1, yb;
6735 yb = 0;
6736
6737 strlcpy(chopth, " ",17);
6738
6741 Double_t baroffset = fH->GetBarOffset();
6742 Double_t barwidth = fH->GetBarWidth();
6743 Double_t baroffsetsave = gStyle->GetBarOffset();
6744 Double_t barwidthsave = gStyle->GetBarWidth();
6745 gStyle->SetBarOffset(baroffset);
6746 gStyle->SetBarWidth(barwidth);
6747
6748 // Create "LIFE" structure to keep current histogram status
6749
6751 last = Hparam.xlast;
6752 nbins = last - first + 1;
6753
6754 Double_t *keepx = 0;
6755 Double_t *keepy = 0;
6756 if (fXaxis->GetXbins()->fN) fixbin = 0;
6757 else fixbin = 1;
6758 if (fixbin) keepx = new Double_t[2];
6759 else keepx = new Double_t[nbins+1];
6760 keepy = new Double_t[nbins];
6761 Double_t logymin = 0;
6762 if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6763
6764 // Loop on histogram bins
6765
6766 for (j=first; j<=last;j++) {
6768 if (TMath::Abs(ymax-ymin) > 0) {
6769 if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6770 else yb = c1;
6771 }
6772 if (!Hoption.Line) {
6773 yb = TMath::Max(yb, ymin);
6774 yb = TMath::Min(yb, ymax);
6775 }
6776 keepy[j-first] = yb;
6777 }
6778
6779 // Draw histogram according to value of FillStyle and FillColor
6780
6781 if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6782 else {
6783 for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6784 keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6785 }
6786
6787 // Prepare Fill area (systematic with option "Bar").
6788
6789 oldhtype = fH->GetFillStyle();
6790 htype = oldhtype;
6791 if (Hoption.Bar) {
6792 if (htype == 0 || htype == 1000) htype = 1001;
6793 }
6794
6795 Width_t lw = (Width_t)fH->GetLineWidth();
6796
6797 // Code option for GrapHist
6798
6799 if (Hoption.Line) chopth[0] = 'L';
6800 if (Hoption.Star) chopth[1] = '*';
6801 if (Hoption.Mark) chopth[2] = 'P';
6802 if (Hoption.Mark == 10) chopth[3] = '0';
6804 if (Hoption.Curve) chopth[3] = 'C';
6805 if (Hoption.Hist > 0) chopth[4] = 'H';
6806 else if (Hoption.Bar) chopth[5] = 'B';
6807 if (fH->GetFillColor() && htype) {
6808 if (Hoption.Logy) {
6809 chopth[6] = '1';
6810 }
6811 if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6812 chopth[7] = 'F';
6813 }
6814 }
6815 }
6816 if (!fixbin && strlen(chopth)) {
6817 chopth[8] = 'N';
6818 }
6819
6820 if (Hoption.Fill == 2) chopth[13] = '2';
6821
6822 // Option LOGX
6823
6824 if (Hoption.Logx) {
6825 chopth[9] = 'G';
6826 chopth[10] = 'X';
6827 if (fixbin) {
6828 keepx[0] = TMath::Power(10,keepx[0]);
6829 keepx[1] = TMath::Power(10,keepx[1]);
6830 }
6831 }
6832
6833 if (Hoption.Off) {
6834 chopth[11] = ']';
6835 chopth[12] = '[';
6836 }
6837
6838 // Draw the histogram
6839
6840 TGraph graph;
6841 graph.SetLineWidth(lw);
6842 graph.SetLineStyle(fH->GetLineStyle());
6843 graph.SetLineColor(fH->GetLineColor());
6844 graph.SetFillStyle(htype);
6845 graph.SetFillColor(fH->GetFillColor());
6846 graph.SetMarkerStyle(fH->GetMarkerStyle());
6847 graph.SetMarkerSize(fH->GetMarkerSize());
6848 graph.SetMarkerColor(fH->GetMarkerColor());
6849 if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6850
6851 graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6852
6853 delete [] keepx;
6854 delete [] keepy;
6855 gStyle->SetBarOffset(baroffsetsave);
6856 gStyle->SetBarWidth(barwidthsave);
6857
6858 htype=oldhtype;
6859}
6860
6861////////////////////////////////////////////////////////////////////////////////
6862/// [Control function to draw a 3D histograms.](#HP01d)
6863
6865{
6866
6867 char *cmd;
6868 TString opt = option;
6869 opt.ToLower();
6870 Int_t irep;
6871
6872 if (Hoption.Box || Hoption.Lego) {
6873 if (Hoption.Box == 11 || Hoption.Lego == 11) {
6874 PaintH3Box(1);
6875 } else if (Hoption.Box == 12 || Hoption.Lego == 12) {
6876 PaintH3Box(2);
6877 } else if (Hoption.Box == 13 || Hoption.Lego == 13) {
6878 PaintH3Box(3);
6879 } else {
6881 }
6882 return;
6883 } else if (strstr(opt,"iso")) {
6884 PaintH3Iso();
6885 return;
6886 } else if (strstr(opt,"tf3")) {
6887 PaintTF3();
6888 return;
6889 } else {
6890 cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6891 }
6892
6893 if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6894 if (strstr(opt,"bb")) Hoption.BackBox = 0;
6895
6896 TView *view = gPad->GetView();
6897 if (!view) return;
6898 Double_t thedeg = 90 - gPad->GetTheta();
6899 Double_t phideg = -90 - gPad->GetPhi();
6900 Double_t psideg = view->GetPsi();
6901 view->SetView(phideg, thedeg, psideg, irep);
6902
6903 // Paint the data
6904 gROOT->ProcessLine(cmd);
6905
6906 if (Hoption.Same) return;
6907
6908 // Draw axis
6909 view->SetOutlineToCube();
6910 TSeqCollection *ol = view->GetOutline();
6911 if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6913 TGaxis *axis = new TGaxis();
6914 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6915 delete axis;
6916
6917 // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6918 // be painted with the option colz.
6919 if (fH->GetDrawOption() && strstr(opt,"colz")) {
6920 Int_t ndiv = fH->GetContour();
6921 if (ndiv == 0 ) {
6922 ndiv = gStyle->GetNumberContours();
6923 fH->SetContour(ndiv);
6924 }
6925 PaintPalette();
6926 }
6927
6928 // Draw title
6929 PaintTitle();
6930
6931 //Draw stats and fit results
6932 TF1 *fit = 0;
6933 TIter next(fFunctions);
6934 TObject *obj;
6935 while ((obj = next())) {
6936 if (obj->InheritsFrom(TF1::Class())) {
6937 fit = (TF1*)obj;
6938 break;
6939 }
6940 }
6941 if ((Hoption.Same%10) != 1) {
6942 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6944 }
6945 }
6946
6947}
6948
6949////////////////////////////////////////////////////////////////////////////////
6950/// Compute histogram parameters used by the drawing routines.
6951
6953{
6954
6955 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6956
6957 Int_t i;
6958 static const char *where = "PaintInit";
6959 Double_t yMARGIN = gStyle->GetHistTopMargin();
6960 Int_t maximum = 0;
6961 Int_t minimum = 0;
6962 if (fH->GetMaximumStored() != -1111) maximum = 1;
6963 if (fH->GetMinimumStored() != -1111) minimum = 1;
6964
6965 // Compute X axis parameters
6966
6967 Int_t last = fXaxis->GetLast();
6971 Hparam.xlast = last;
6975
6976 // if log scale in X, replace xmin,max by the log
6977 if (Hoption.Logx) {
6978 if (Hparam.xmax<=0) {
6979 Error(where, "cannot set X axis to log scale");
6980 return 0;
6981 }
6982 if (Hparam.xlowedge <=0 ) {
6983 if (Hoption.Same) {
6984 Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
6985 } else {
6986 for (i=first; i<=last; i++) {
6987 Double_t binLow = fXaxis->GetBinLowEdge(i);
6988 if (binLow>0) {
6989 Hparam.xlowedge = binLow;
6990 break;
6991 }
6992 if (binLow == 0 && fH->GetBinContent(i) !=0) {
6993 Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
6994 break;
6995 }
6996 }
6997 if (Hparam.xlowedge<=0) {
6998 Error(where, "cannot set X axis to log scale");
6999 return 0;
7000 }
7001 }
7003 }
7008 if (Hparam.xlast > last) Hparam.xlast = last;
7010 }
7011
7012 // Compute Y axis parameters
7013 Double_t bigp = TMath::Power(10,32);
7014 Double_t ymax = -bigp;
7015 Double_t ymin = bigp;
7016 Double_t c1, e1;
7017 Double_t xv[1];
7018 Double_t fval;
7019 TObject *f;
7020 TF1 *f1;
7021 Double_t allchan = 0;
7022 Int_t nonNullErrors = 0;
7023 TIter next(fFunctions);
7024 for (i=first; i<=last;i++) {
7025 c1 = fH->GetBinContent(i);
7027 if (Hoption.Logy) {
7028 if (c1 > 0) ymin = TMath::Min(ymin,c1);
7029 } else {
7031 }
7032 if (Hoption.Error) {
7034 e1 = fH->GetBinError(i);
7035 else
7036 e1 = fH->GetBinErrorUp(i);
7037 if (e1 > 0) nonNullErrors++;
7038 ymax = TMath::Max(ymax,c1+e1);
7040 e1 = fH->GetBinErrorLow(i);
7041
7042 if (Hoption.Logy) {
7043 if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
7044 } else {
7045 ymin = TMath::Min(ymin,c1-e1);
7046 }
7047 }
7048 if (Hoption.Func) {
7049 xv[0] = fXaxis->GetBinCenter(i);
7050 while ((f = (TObject*) next())) {
7051 if (f->IsA() == TF1::Class()) {
7052 f1 = (TF1*)f;
7053 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7054 fval = f1->Eval(xv[0],0,0);
7055 if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
7056 ymax = TMath::Max(ymax,fval);
7057 if (Hoption.Logy) {
7058 if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
7059 }
7060 }
7061 }
7062 next.Reset();
7063 }
7064 allchan += c1;
7065 }
7066 if (!nonNullErrors) {
7067 if (Hoption.Error) {
7068 if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
7069 Hoption.Error=0;
7070 }
7071 }
7072
7073
7074 // Take into account maximum , minimum
7075
7076 if (Hoption.Logy && ymin <= 0) {
7077 if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
7078 else ymin = 0.001*ymax;
7079 }
7080
7081 Double_t xm = ymin;
7082 if (maximum) ymax = fH->GetMaximumStored();
7083 if (minimum) xm = fH->GetMinimumStored();
7084 if (Hoption.Logy && xm < 0) {
7085 Error(where, "log scale requested with a negative argument (%f)", xm);
7086 return 0;
7087 } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
7088 ymin = 0.01;
7089 ymax = 10.;
7090 } else {
7091 ymin = xm;
7092 }
7093
7094 if (ymin >= ymax) {
7095 if (Hoption.Logy) {
7096 if (ymax > 0) ymin = 0.001*ymax;
7097 else {
7098 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
7099 return 0;
7100 }
7101 }
7102 else {
7103 if (ymin > 0) {
7104 ymin = 0;
7105 ymax *= 2;
7106 } else if (ymin < 0) {
7107 ymax = 0;
7108 ymin *= 2;
7109 } else {
7110 ymin = 0;
7111 ymax = 1;
7112 }
7113 }
7114 }
7115
7116 // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
7117 if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
7118 ymin = ymin*(1-1E-14);
7119 ymax = ymax*(1+1E-14);
7120 }
7121
7122 // take into account normalization factor
7123 Hparam.allchan = allchan;
7124 Double_t factor = allchan;
7125 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7126 if (allchan) factor /= allchan;
7127 if (factor == 0) factor = 1;
7128 Hparam.factor = factor;
7129 ymax = factor*ymax;
7130 ymin = factor*ymin;
7131 //just in case the norm factor is negative
7132 // this may happen with a positive norm factor and a negative integral !
7133 if (ymax < ymin) {
7134 Double_t temp = ymax;
7135 ymax = ymin;
7136 ymin = temp;
7137 }
7138
7139 // For log scales, histogram coordinates are LOG10(ymin) and
7140 // LOG10(ymax). Final adjustment (if not option "Same"
7141 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7142 // Maximum and Minimum are not defined.
7143 if (Hoption.Logy) {
7144 if (ymin <=0 || ymax <=0) {
7145 Error(where, "Cannot set Y axis to log scale");
7146 return 0;
7147 }
7149 if (!minimum) ymin += TMath::Log10(0.5);
7151 if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
7152 if (!Hoption.Same) {
7153 Hparam.ymin = ymin;
7154 Hparam.ymax = ymax;
7155 }
7156 return 1;
7157 }
7158
7159 // final adjustment of ymin for linear scale.
7160 // if minimum is not set , then ymin is set to zero if >0
7161 // or to ymin - margin if <0.
7162 if (!minimum) {
7163 if (Hoption.MinimumZero) {
7164 if (ymin >= 0) ymin = 0;
7165 else ymin -= yMARGIN*(ymax-ymin);
7166 } else {
7167 Double_t dymin = yMARGIN*(ymax-ymin);
7168 if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
7169 else ymin -= dymin;
7170 }
7171 }
7172
7173 // final adjustment of YMAXI for linear scale (if not option "Same"):
7174 // decrease histogram height to MAX% of allowed height if HMAXIM
7175 // has not been called.
7176 if (!maximum) {
7177 ymax += yMARGIN*(ymax-ymin);
7178 }
7179
7180 Hparam.ymin = ymin;
7181 Hparam.ymax = ymax;
7182 return 1;
7183}
7184
7185////////////////////////////////////////////////////////////////////////////////
7186/// Compute histogram parameters used by the drawing routines for a rotated pad.
7187
7189{
7190
7191 static const char *where = "PaintInitH";
7192 Double_t yMARGIN = gStyle->GetHistTopMargin();
7193 Int_t maximum = 0;
7194 Int_t minimum = 0;
7195 if (fH->GetMaximumStored() != -1111) maximum = 1;
7196 if (fH->GetMinimumStored() != -1111) minimum = 1;
7197
7198 // Compute X axis parameters
7199
7200 Int_t last = fXaxis->GetLast();
7204 Hparam.xlast = last;
7208
7209 // if log scale in Y, replace ymin,max by the log
7210 if (Hoption.Logy) {
7211 if (Hparam.xlowedge <=0 ) {
7214 }
7215 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
7216 Error(where, "cannot set Y axis to log scale");
7217 return 0;
7218 }
7223 if (Hparam.xlast > last) Hparam.xlast = last;
7224 }
7225
7226 // Compute Y axis parameters
7227 Double_t bigp = TMath::Power(10,32);
7228 Double_t xmax = -bigp;
7229 Double_t xmin = bigp;
7230 Double_t c1, e1;
7231 Double_t xv[1];
7232 Double_t fval;
7233 Int_t i;
7234 TObject *f;
7235 TF1 *f1;
7236 Double_t allchan = 0;
7237 TIter next(fFunctions);
7238 for (i=first; i<=last;i++) {
7239 c1 = fH->GetBinContent(i);
7242 if (Hoption.Error) {
7243 e1 = fH->GetBinError(i);
7244 xmax = TMath::Max(xmax,c1+e1);
7245 xmin = TMath::Min(xmin,c1-e1);
7246 }
7247 if (Hoption.Func) {
7248 xv[0] = fXaxis->GetBinCenter(i);
7249 while ((f = (TObject*) next())) {
7250 if (f->IsA() == TF1::Class()) {
7251 f1 = (TF1*)f;
7252 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7253 fval = f1->Eval(xv[0],0,0);
7254 xmax = TMath::Max(xmax,fval);
7255 if (Hoption.Logy) {
7256 if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
7257 }
7258 }
7259 }
7260 next.Reset();
7261 }
7262 allchan += c1;
7263 }
7264
7265 // Take into account maximum , minimum
7266
7267 if (Hoption.Logx && xmin <= 0) {
7268 if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
7269 else xmin = 0.001*xmax;
7270 }
7271 Double_t xm = xmin;
7272 if (maximum) xmax = fH->GetMaximumStored();
7273 if (minimum) xm = fH->GetMinimumStored();
7274 if (Hoption.Logx && xm <= 0) {
7275 Error(where, "log scale requested with zero or negative argument (%f)", xm);
7276 return 0;
7277 }
7278 else xmin = xm;
7279 if (xmin >= xmax) {
7280 if (Hoption.Logx) {
7281 if (xmax > 0) xmin = 0.001*xmax;
7282 else {
7283 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
7284 return 0;
7285 }
7286 }
7287 else {
7288 if (xmin > 0) {
7289 xmin = 0;
7290 xmax *= 2;
7291 } else if (xmin < 0) {
7292 xmax = 0;
7293 xmin *= 2;
7294 } else {
7295 xmin = -1;
7296 xmax = 1;
7297 }
7298 }
7299 }
7300
7301 // take into account normalization factor
7302 Hparam.allchan = allchan;
7303 Double_t factor = allchan;
7304 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7305 if (allchan) factor /= allchan;
7306 if (factor == 0) factor = 1;
7307 Hparam.factor = factor;
7308 xmax = factor*xmax;
7309 xmin = factor*xmin;
7310
7311 // For log scales, histogram coordinates are LOG10(ymin) and
7312 // LOG10(ymax). Final adjustment (if not option "Same"
7313 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7314 // Maximum and Minimum are not defined.
7315 if (Hoption.Logx) {
7316 if (xmin <=0 || xmax <=0) {
7317 Error(where, "Cannot set Y axis to log scale");
7318 return 0;
7319 }
7321 if (!minimum) xmin += TMath::Log10(0.5);
7323 if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
7324 if (!Hoption.Same) {
7325 Hparam.xmin = xmin;
7326 Hparam.xmax = xmax;
7327 }
7328 return 1;
7329 }
7330
7331 // final adjustment of ymin for linear scale.
7332 // if minimum is not set , then ymin is set to zero if >0
7333 // or to ymin - margin if <0.
7334 if (!minimum) {
7335 if (xmin >= 0) xmin = 0;
7336 else xmin -= yMARGIN*(xmax-xmin);
7337 }
7338
7339 // final adjustment of YMAXI for linear scale (if not option "Same"):
7340 // decrease histogram height to MAX% of allowed height if HMAXIM
7341 // has not been called.
7342 if (!maximum) {
7343 xmax += yMARGIN*(xmax-xmin);
7344 }
7345 Hparam.xmin = xmin;
7346 Hparam.xmax = xmax;
7347 return 1;
7348}
7349
7350////////////////////////////////////////////////////////////////////////////////
7351/// [Control function to draw a 3D histogram with boxes.](#HP25)
7352
7354{
7355 // Predefined box structure
7356 Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
7357 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
7358 Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
7359 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
7360
7361 // Define dimensions of world space
7362 TGaxis *axis = new TGaxis();
7363 TAxis *xaxis = fH->GetXaxis();
7364 TAxis *yaxis = fH->GetYaxis();
7365 TAxis *zaxis = fH->GetZaxis();
7366
7367 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7368 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7369 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7370 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7371 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7372 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7373
7375
7376 // Set view
7377 TView *view = gPad->GetView();
7378 if (!view) {
7379 Error("PaintH3", "no TView in current pad");
7380 return;
7381 }
7382 Double_t thedeg = 90 - gPad->GetTheta();
7383 Double_t phideg = -90 - gPad->GetPhi();
7384 Double_t psideg = view->GetPsi();
7385 Int_t irep;
7386 view->SetView(phideg, thedeg, psideg, irep);
7387
7388 Int_t backcolor = gPad->GetFrameFillColor();
7389 view->PadRange(backcolor);
7390
7391 // Draw back surfaces of frame box
7392 fLego->InitMoveScreen(-1.1,1.1);
7393 if (Hoption.BackBox) {
7396 fLego->BackBox(90);
7397 }
7398
7400
7401 // Define order of drawing
7402 Double_t *tnorm = view->GetTnorm();
7403 if (!tnorm) return;
7404 Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7405 Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7406 Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7407 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7408 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7409 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7410 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7411 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7412 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7413
7414 // Set graphic attributes (colour, style, etc.)
7415 Style_t fillsav = fH->GetFillStyle();
7416 Style_t colsav = fH->GetFillColor();
7417 Style_t coldark = TColor::GetColorDark(colsav);
7418 Style_t colbright = TColor::GetColorBright(colsav);
7419
7420 fH->SetFillStyle(1001);
7421 fH->TAttFill::Modify();
7422 fH->TAttLine::Modify();
7423 Int_t ncolors = gStyle->GetNumberOfColors();
7424 Int_t theColor;
7425
7426 // Create bin boxes and draw
7427 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7430
7431 Double_t pmin[3], pmax[3], sxyz[8][3];
7432 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7433 pmin[0] = xaxis->GetBinLowEdge(ix);
7434 pmax[0] = xaxis->GetBinUpEdge(ix);
7435 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7436 pmin[1] = yaxis->GetBinLowEdge(iy);
7437 pmax[1] = yaxis->GetBinUpEdge(iy);
7438 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7439 pmin[2] = zaxis->GetBinLowEdge(iz);
7440 pmax[2] = zaxis->GetBinUpEdge(iz);
7441 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7442 Bool_t neg = kFALSE;
7443 Int_t n = 5;
7444 if (w<0) {
7445 w = -w;
7446 neg = kTRUE;
7447 }
7448 if (w < wmin) continue;
7449 if (w > wmax) w = wmax;
7450 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7451 if (scale == 0) continue;
7452 for (Int_t i=0; i<3; ++i) {
7453 Double_t c = (pmax[i] + pmin[i])*0.5;
7454 Double_t d = (pmax[i] - pmin[i])*scale;
7455 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7456 sxyz[k][i] = wxyz[k][i]*d + c;
7457 }
7458 }
7459 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7460 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7461 }
7462 Double_t x[8], y[8]; // draw bin box faces
7463 for (Int_t k=0; k<6; ++k) {
7464 for (Int_t i=0; i<4; ++i) {
7465 Int_t iv = iface[k][i];
7466 x[i] = sxyz[iv][0];
7467 y[i] = sxyz[iv][1];
7468 }
7469 x[4] = x[0] ; y[4] = y[0];
7470 if (neg) {
7471 x[5] = x[2] ; y[5] = y[2];
7472 x[6] = x[3] ; y[6] = y[3];
7473 x[7] = x[1] ; y[7] = y[1];
7474 n = 8;
7475 } else {
7476 n = 5;
7477 }
7478 Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7479 if (z <= 0.) continue;
7480 if (iopt == 2) {
7481 theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7483 } else {
7484 if (k == 3 || k == 5) {
7485 fH->SetFillColor(coldark);
7486 } else if (k == 0 || k == 1) {
7487 fH->SetFillColor(colbright);
7488 } else {
7489 fH->SetFillColor(colsav);
7490 }
7491 }
7492 fH->TAttFill::Modify();
7493 gPad->PaintFillArea(4, x, y);
7494 if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7495 }
7496 }
7497 }
7498 }
7499
7500 // Draw front surfaces of frame box
7501 if (Hoption.FrontBox) fLego->FrontBox(90);
7502
7503 // Draw axis and title
7504 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7505 PaintTitle();
7506
7507 // Draw palette. if needed.
7508 if (Hoption.Zscale) {
7509 Int_t ndiv = fH->GetContour();
7510 if (ndiv == 0 ) {
7511 ndiv = gStyle->GetNumberContours();
7512 fH->SetContour(ndiv);
7513 }
7514 PaintPalette();
7515 }
7516
7517 delete axis;
7518 delete fLego; fLego = 0;
7519
7520 fH->SetFillStyle(fillsav);
7521 fH->SetFillColor(colsav);
7522 fH->TAttFill::Modify();
7523}
7524
7525////////////////////////////////////////////////////////////////////////////////
7526/// [Control function to draw a 3D histogram with boxes.](#HP25)
7527
7529{
7530 // Predefined box structure
7531 Double_t wxyz[8][3] = {
7532 {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7533 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7534 };
7535 Int_t iface[6][4] = {
7536 {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7537 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7538 };
7539 Double_t normal[6][3] = {
7540 {0,0,-1}, {0,0,1}, // Z-, Z+
7541 {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7542 };
7543
7544 // Define dimensions of world space
7545 TGaxis *axis = new TGaxis();
7546 TAxis *xaxis = fH->GetXaxis();
7547 TAxis *yaxis = fH->GetYaxis();
7548 TAxis *zaxis = fH->GetZaxis();
7549
7550 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7551 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7552 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7553 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7554 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7555 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7556
7558
7559 // Set view
7560 TView *view = gPad->GetView();
7561 if (!view) {
7562 Error("PaintH3", "no TView in current pad");
7563 return;
7564 }
7565 Double_t thedeg = 90 - gPad->GetTheta();
7566 Double_t phideg = -90 - gPad->GetPhi();
7567 Double_t psideg = view->GetPsi();
7568 Int_t irep;
7569 view->SetView(phideg, thedeg, psideg, irep);
7570
7571 Int_t backcolor = gPad->GetFrameFillColor();
7572 view->PadRange(backcolor);
7573
7574 // Draw front surfaces of frame box
7575 if (Hoption.FrontBox) {
7576 fLego->InitMoveScreen(-1.1,1.1);
7578 }
7579
7580 // Initialize hidden line removal algorithm "raster screen"
7581 fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7582
7583 // Define order of drawing
7584 Double_t *tnorm = view->GetTnorm();
7585 if (!tnorm) return;
7586 Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7587 Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7588 Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7589 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7590 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7591 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7592 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7593 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7594 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7595
7596 // Set line attributes (colour, style, etc.)
7597 fH->TAttLine::Modify();
7598
7599 // Create bin boxes and draw
7600 const Int_t NTMAX = 100;
7601 Double_t tt[NTMAX][2];
7602 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7605 Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7606 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7607 pmin[0] = xaxis->GetBinLowEdge(ix);
7608 pmax[0] = xaxis->GetBinUpEdge(ix);
7609 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7610 pmin[1] = yaxis->GetBinLowEdge(iy);
7611 pmax[1] = yaxis->GetBinUpEdge(iy);
7612 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7613 pmin[2] = zaxis->GetBinLowEdge(iz);
7614 pmax[2] = zaxis->GetBinUpEdge(iz);
7615 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7616 Bool_t neg = kFALSE;
7617 if (w<0) {
7618 w = -w;
7619 neg = kTRUE;
7620 }
7621 if (w < wmin) continue;
7622 if (w > wmax) w = wmax;
7623 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7624 if (scale == 0) continue;
7625 for (Int_t i=0; i<3; ++i) {
7626 Double_t c = (pmax[i] + pmin[i])*0.5;
7627 Double_t d = (pmax[i] - pmin[i])*scale;
7628 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7629 sxyz[k][i] = wxyz[k][i]*d + c;
7630 }
7631 }
7632 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7633 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7634 }
7635 for (Int_t k=0; k<6; ++k) { // draw box faces
7636 Double_t zn;
7637 view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7638 if (zn <= 0) continue;
7639 for (Int_t i=0; i<4; ++i) {
7640 Int_t ip = iface[k][i];
7641 pp[i][0] = sxyz[ip][0];
7642 pp[i][1] = sxyz[ip][1];
7643 }
7644 for (Int_t i=0; i<4; ++i) {
7645 Int_t i1 = i;
7646 Int_t i2 = (i == 3) ? 0 : i + 1;
7647 Int_t nt;
7648 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7649 Double_t xdel = pp[i2][0] - pp[i1][0];
7650 Double_t ydel = pp[i2][1] - pp[i1][1];
7651 Double_t x[2], y[2];
7652 for (Int_t it = 0; it < nt; ++it) {
7653 x[0] = pp[i1][0] + xdel*tt[it][0];
7654 y[0] = pp[i1][1] + ydel*tt[it][0];
7655 x[1] = pp[i1][0] + xdel*tt[it][1];
7656 y[1] = pp[i1][1] + ydel*tt[it][1];
7657 gPad->PaintPolyLine(2, x, y);
7658 }
7659 }
7660 if (neg) {
7661 Int_t i1 = 0;
7662 Int_t i2 = 2;
7663 Int_t nt;
7664 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7665 Double_t xdel = pp[i2][0] - pp[i1][0];
7666 Double_t ydel = pp[i2][1] - pp[i1][1];
7667 Double_t x[2], y[2];
7668 for (Int_t it = 0; it < nt; ++it) {
7669 x[0] = pp[i1][0] + xdel*tt[it][0];
7670 y[0] = pp[i1][1] + ydel*tt[it][0];
7671 x[1] = pp[i1][0] + xdel*tt[it][1];
7672 y[1] = pp[i1][1] + ydel*tt[it][1];
7673 gPad->PaintPolyLine(2, x, y);
7674 }
7675 i1 = 1;
7676 i2 = 3;
7677 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7678 xdel = pp[i2][0] - pp[i1][0];
7679 ydel = pp[i2][1] - pp[i1][1];
7680 for (Int_t it = 0; it < nt; ++it) {
7681 x[0] = pp[i1][0] + xdel*tt[it][0];
7682 y[0] = pp[i1][1] + ydel*tt[it][0];
7683 x[1] = pp[i1][0] + xdel*tt[it][1];
7684 y[1] = pp[i1][1] + ydel*tt[it][1];
7685 gPad->PaintPolyLine(2, x, y);
7686 }
7687 }
7688 fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7689 }
7690 }
7691 }
7692 }
7693
7694 // Draw frame box
7695 if (Hoption.BackBox) {
7698 fLego->BackBox(90);
7699 }
7700
7701 if (Hoption.FrontBox) fLego->FrontBox(90);
7702
7703 // Draw axis and title
7704 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7705 PaintTitle();
7706
7707 delete axis;
7708 delete fLego; fLego = 0;
7709}
7710
7711////////////////////////////////////////////////////////////////////////////////
7712/// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
7713
7715{
7716
7717 const Double_t ydiff = 1;
7718 const Double_t yligh1 = 10;
7719 const Double_t qa = 0.15;
7720 const Double_t qd = 0.15;
7721 const Double_t qs = 0.8;
7722 Double_t fmin, fmax;
7723 Int_t i, irep;
7724 Int_t nbcol = 28;
7725 Int_t icol1 = 201;
7726 Int_t ic1 = icol1;
7727 Int_t ic2 = ic1+nbcol;
7728 Int_t ic3 = ic2+nbcol;
7729
7730 TGaxis *axis = new TGaxis();
7731 TAxis *xaxis = fH->GetXaxis();
7732 TAxis *yaxis = fH->GetYaxis();
7733 TAxis *zaxis = fH->GetZaxis();
7734
7735 Int_t nx = fH->GetNbinsX();
7736 Int_t ny = fH->GetNbinsY();
7737 Int_t nz = fH->GetNbinsZ();
7738
7739 Double_t *x = new Double_t[nx];
7740 Double_t *y = new Double_t[ny];
7741 Double_t *z = new Double_t[nz];
7742
7743 for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7744 for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7745 for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7746
7747 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7748 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7749 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7750 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7751 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7752 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7753
7754 Double_t s[3];
7755 s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7756 s[1] = 0.5*s[0];
7757 s[2] = 1.5*s[0];
7758
7760
7761 TView *view = gPad->GetView();
7762 if (!view) {
7763 Error("PaintH3Iso", "no TView in current pad");
7764 delete [] x;
7765 delete [] y;
7766 delete [] z;
7767 return;
7768 }
7769 Double_t thedeg = 90 - gPad->GetTheta();
7770 Double_t phideg = -90 - gPad->GetPhi();
7771 Double_t psideg = view->GetPsi();
7772 view->SetView(phideg, thedeg, psideg, irep);
7773
7774 Int_t backcolor = gPad->GetFrameFillColor();
7775 if (Hoption.System != kCARTESIAN) backcolor = 0;
7776 view->PadRange(backcolor);
7777
7778 Double_t dcol = 0.5/Double_t(nbcol);
7779 TColor *colref = gROOT->GetColor(fH->GetFillColor());
7780 if (!colref) {
7781 delete [] x;
7782 delete [] y;
7783 delete [] z;
7784 return;
7785 }
7786 Float_t r, g, b, hue, light, satur;
7787 colref->GetRGB(r,g,b);
7788 TColor::RGBtoHLS(r,g,b,hue,light,satur);
7789 TColor *acol;
7790 for (Int_t col=0;col<nbcol;col++) {
7791 acol = gROOT->GetColor(col+icol1);
7792 TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7793 if (acol) acol->SetRGB(r, g, b);
7794 }
7795
7796 fLego->InitMoveScreen(-1.1,1.1);
7797
7798 if (Hoption.BackBox) {
7801 fLego->BackBox(90);
7802 }
7803
7804 fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7805 fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7806 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7807 fmin = ydiff*qa;
7808 fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7809 fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7810
7811 fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7812
7813 if (Hoption.FrontBox) {
7814 fLego->InitMoveScreen(-1.1,1.1);
7816 fLego->FrontBox(90);
7817 }
7818 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7819
7820 PaintTitle();
7821
7822 delete axis;
7823 delete fLego; fLego = 0;
7824 delete [] x;
7825 delete [] y;
7826 delete [] z;
7827}
7828
7829////////////////////////////////////////////////////////////////////////////////
7830/// [Control function to draw a 2D histogram as a lego plot.](#HP17)
7831
7833{
7834
7835 Int_t raster = 1;
7836 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7837 Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7838 Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7839 Double_t zmin = Hparam.zmin;
7840 Double_t zmax = Hparam.zmax;
7841 Double_t xlab1 = Hparam.xmin;
7842 Double_t xlab2 = Hparam.xmax;
7843 Double_t ylab1 = Hparam.ymin;
7844 Double_t ylab2 = Hparam.ymax;
7845 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7846 Double_t deltaz = TMath::Abs(zmin);
7847 if (deltaz == 0) deltaz = 1;
7848 if (zmin >= zmax) {
7849 zmin -= 0.5*deltaz;
7850 zmax += 0.5*deltaz;
7851 }
7852 Double_t z1c = zmin;
7853 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7854
7855 // Compute the lego limits and instantiate a lego object
7856 fXbuf[0] = -1;
7857 fYbuf[0] = 1;
7858 fXbuf[1] = -1;
7859 fYbuf[1] = 1;
7860 if (Hoption.System == kPOLAR) {
7861 fXbuf[2] = z1c;
7862 fYbuf[2] = z2c;
7863 } else if (Hoption.System == kCYLINDRICAL) {
7864 if (Hoption.Logy) {
7865 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7866 else fXbuf[2] = 0;
7867 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7868 else fYbuf[2] = 0;
7869 } else {
7870 fXbuf[2] = ylab1;
7871 fYbuf[2] = ylab2;
7872 }
7873 z1c = 0; z2c = 1;
7874 } else if (Hoption.System == kSPHERICAL) {
7875 fXbuf[2] = -1;
7876 fYbuf[2] = 1;
7877 z1c = 0; z2c = 1;
7878 } else if (Hoption.System == kRAPIDITY) {
7879 fXbuf[2] = -1/TMath::Tan(dangle);
7880 fYbuf[2] = 1/TMath::Tan(dangle);
7881 } else {
7882 fXbuf[0] = xlab1;
7883 fYbuf[0] = xlab2;
7884 fXbuf[1] = ylab1;
7885 fYbuf[1] = ylab2;
7886 fXbuf[2] = z1c;
7887 fYbuf[2] = z2c;
7888 raster = 0;
7889 }
7890
7892
7893 Int_t nids = -1;
7894 TH1 * hid = NULL;
7895 Color_t colormain = -1, colordark = -1;
7896 Bool_t drawShadowsInLego1 = kTRUE;
7897
7898 // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7899 if (Hoption.Lego == 13) {
7900 Hoption.Lego = 11;
7901 fLego->SetMesh(0);
7902 }
7903 // LEGO4 is like LEGO1 except no shadows are drawn.
7904 if (Hoption.Lego == 14) {
7905 Hoption.Lego = 11;
7906 drawShadowsInLego1 = kFALSE;
7907 }
7908
7909 // Create axis object
7910
7911 TGaxis *axis = new TGaxis();
7912
7913 // Initialize the levels on the Z axis
7914 Int_t ndiv = fH->GetContour();
7915 if (ndiv == 0 ) {
7916 ndiv = gStyle->GetNumberContours();
7917 fH->SetContour(ndiv);
7918 }
7919 Int_t ndivz = TMath::Abs(ndiv);
7920 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7921
7922 // Initialize colors
7923 if (!fStack) {
7925 } else {
7926 for (Int_t id=0;id<=fStack->GetSize();id++) {
7927 hid = (TH1*)fStack->At((id==0)?id:id-1);
7929 }
7930 }
7931
7932 if (Hoption.Lego == 11) {
7933 nids = 1;
7934 if (fStack) nids = fStack->GetSize();
7935 hid = fH;
7936 for (Int_t id=0;id<=nids;id++) {
7937 if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7938 colormain = hid->GetFillColor();
7939 if (colormain == 1) colormain = 17; //avoid drawing with black
7940 if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7941 else colordark = colormain;
7942 fLego->SetColorMain(colormain,id);
7943 fLego->SetColorDark(colordark,id);
7944 if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7945 if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7946 }
7947 }
7948
7949 // Now ready to draw the lego plot
7950 Int_t irep = 0;
7951
7952 TView *view = gPad->GetView();
7953 if (!view) {
7954 Error("PaintLego", "no TView in current pad");
7955 return;
7956 }
7957
7958 Double_t thedeg = 90 - gPad->GetTheta();
7959 Double_t phideg = -90 - gPad->GetPhi();
7960 Double_t psideg = view->GetPsi();
7961 view->SetView(phideg, thedeg, psideg, irep);
7962
7963 fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7965
7966 // Set color/style for back box
7967 fLego->SetFillStyle(gPad->GetFrameFillStyle());
7968 fLego->SetFillColor(gPad->GetFrameFillColor());
7969 fLego->TAttFill::Modify();
7970
7971 Int_t backcolor = gPad->GetFrameFillColor();
7972 if (Hoption.System != kCARTESIAN) backcolor = 0;
7973 view->PadRange(backcolor);
7974
7977 fLego->TAttFill::Modify();
7978
7980
7981 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7982 else fLego->InitMoveScreen(-1.1,1.1);
7983
7984 if (Hoption.Lego == 19) {
7986 if (Hoption.BackBox) fLego->BackBox(90);
7987 if (Hoption.FrontBox) fLego->FrontBox(90);
7988 if (!Hoption.Axis) PaintLegoAxis(axis, 90);
7989 return;
7990 }
7991
7992 if (Hoption.Lego == 11 || Hoption.Lego == 12) {
7995 fLego->BackBox(90);
7996 }
7997 }
7998
7999 if (Hoption.Lego == 12) DefineColorLevels(ndivz);
8000
8005 if (Hoption.System == kPOLAR) {
8006 if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
8007 if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
8008 if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
8009 } else if (Hoption.System == kCYLINDRICAL) {
8010 if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
8011 if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
8012 if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
8013 } else if (Hoption.System == kSPHERICAL) {
8014 if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
8015 if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
8016 if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
8017 } else if (Hoption.System == kRAPIDITY) {
8018 if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
8019 if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
8020 if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
8021 } else {
8022 if (Hoption.Lego == 1) {
8024 fLego->LegoCartesian(90,nx,ny,"FB");}
8025 if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
8026 if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
8027 }
8028
8029 if (Hoption.Lego == 1 || Hoption.Lego == 11) {
8032 fLego->BackBox(90);
8033 }
8034 }
8035 if (Hoption.System == kCARTESIAN) {
8036 fLego->InitMoveScreen(-1.1,1.1);
8038 if (Hoption.FrontBox) fLego->FrontBox(90);
8039 }
8040 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8042 delete axis;
8043 delete fLego; fLego = 0;
8044}
8045
8046////////////////////////////////////////////////////////////////////////////////
8047/// Draw the axis for legos and surface plots.
8048
8050{
8051
8052 static Double_t epsil = 0.001;
8053
8054 Double_t cosa, sina;
8055 Double_t bmin, bmax;
8056 Double_t r[24] /* was [3][8] */;
8057 Int_t ndivx, ndivy, ndivz, i;
8058 Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
8059 static char chopax[8], chopay[8], chopaz[8];
8060 Int_t ix1, ix2, iy1, iy2, iz1, iz2;
8061 Double_t rad;
8062
8063 TView *view = gPad->GetView();
8064 if (!view) {
8065 Error("PaintLegoAxis", "no TView in current pad");
8066 return;
8067 }
8068
8069 // In polar coordinates, draw a short line going from the external circle
8070 // corresponding to r = 1 up to r = 1.1
8071 if (Hoption.System == kPOLAR) {
8072 r[0] = 1;
8073 r[1] = 0;
8074 r[2] = 0;
8075 view->WCtoNDC(r, x1);
8076 r[0] = 1.1;
8077 r[1] = 0;
8078 r[2] = 0;
8079 view->WCtoNDC(r, x2);
8080 gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
8081 return;
8082 }
8083
8084 if (Hoption.System != kCARTESIAN) return;
8085
8086 rad = TMath::ATan(1.) * 4. /180.;
8087 cosa = TMath::Cos(ang*rad);
8088 sina = TMath::Sin(ang*rad);
8089
8090 view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
8091 for (i = 1; i <= 8; ++i) {
8092 r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
8093 r[i*3 - 2] = av[i*3 - 2]*sina;
8094 r[i*3 - 1] = av[i*3 - 1];
8095 }
8096
8097 view->WCtoNDC(&r[ix1*3 - 3], x1);
8098 view->WCtoNDC(&r[ix2*3 - 3], x2);
8099 view->WCtoNDC(&r[iy1*3 - 3], y1);
8100 view->WCtoNDC(&r[iy2*3 - 3], y2);
8101 view->WCtoNDC(&r[iz1*3 - 3], z1);
8102 view->WCtoNDC(&r[iz2*3 - 3], z2);
8103
8104 view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
8105
8106 Double_t *rmin = view->GetRmin();
8107 Double_t *rmax = view->GetRmax();
8108 if (!rmin || !rmax) return;
8109
8110 // Initialize the axis options
8111 if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
8112 else strlcpy(chopax, "SDH=-",8);
8113 if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
8114 else strlcpy(chopay, "SDH=-",8);
8115 if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
8116 else strlcpy(chopaz, "SDH=-",8);
8117
8118 // Option LOG is required ?
8119 if (Hoption.Logx) strlcat(chopax,"G",8);
8120 if (Hoption.Logy) strlcat(chopay,"G",8);
8121 if (Hoption.Logz) strlcat(chopaz,"G",8);
8122
8123 // Initialize the number of divisions. If the
8124 // number of divisions is negative, option 'N' is required.
8125 ndivx = fXaxis->GetNdivisions();
8126 ndivy = fYaxis->GetNdivisions();
8127 ndivz = fZaxis->GetNdivisions();
8128 if (ndivx < 0) {
8129 ndivx = TMath::Abs(ndivx);
8130 strlcat(chopax, "N",8);
8131 }
8132 if (ndivy < 0) {
8133 ndivy = TMath::Abs(ndivy);
8134 strlcat(chopay, "N",8);
8135 }
8136 if (ndivz < 0) {
8137 ndivz = TMath::Abs(ndivz);
8138 strlcat(chopaz, "N",8);
8139 }
8140
8141 // Set Axis attributes.
8142 // The variable SCALE rescales the VSIZ
8143 // in order to have the same label size for all angles.
8144
8145 axis->SetLineWidth(1);
8146
8147 // X axis drawing
8148 if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
8151 if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
8152 bmin = TMath::Power(10, rmin[0]);
8153 bmax = TMath::Power(10, rmax[0]);
8154 } else {
8155 bmin = rmin[0];
8156 bmax = rmax[0];
8157 }
8158 // Option time display is required ?
8159 if (fXaxis->GetTimeDisplay()) {
8160 strlcat(chopax,"t",8);
8161 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
8162 axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
8163 } else {
8165 }
8166 }
8167 axis->SetOption(chopax);
8168 axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
8169 }
8170
8171 // Y axis drawing
8172 if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
8175 if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
8176
8177 if (fH->GetDimension() < 2) {
8178 strlcpy(chopay, "V=+UN",8);
8179 ndivy = 0;
8180 }
8181 if (TMath::Abs(y1[0] - y2[0]) < epsil) {
8182 y2[0] = y1[0];
8183 }
8184 if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
8185 bmin = TMath::Power(10, rmin[1]);
8186 bmax = TMath::Power(10, rmax[1]);
8187 } else {
8188 bmin = rmin[1];
8189 bmax = rmax[1];
8190 }
8191 // Option time display is required ?
8192 if (fYaxis->GetTimeDisplay()) {
8193 strlcat(chopay,"t",8);
8194 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
8195 axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
8196 } else {
8198 }
8199 }
8200 axis->SetOption(chopay);
8201 axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
8202 }
8203
8204 // Z axis drawing
8205 if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
8207 if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
8208 bmin = TMath::Power(10, rmin[2]);
8209 bmax = TMath::Power(10, rmax[2]);
8210 } else {
8211 bmin = rmin[2];
8212 bmax = rmax[2];
8213 }
8214 // Option time display is required ?
8215 if (fZaxis->GetTimeDisplay()) {
8216 strlcat(chopaz,"t",8);
8217 if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
8218 axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
8219 } else {
8221 }
8222 }
8223 axis->SetOption(chopaz);
8224 axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
8225 }
8226
8227 //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
8228}
8229
8230////////////////////////////////////////////////////////////////////////////////
8231/// [Paint the color palette on the right side of the pad.](#HP22)
8232
8234{
8235
8236 TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
8237 TView *view = gPad->GetView();
8238 if (palette) {
8239 if (view) {
8240 if (!palette->TestBit(TPaletteAxis::kHasView)) {
8241 fFunctions->Remove(palette);
8242 delete palette; palette = 0;
8243 }
8244 } else {
8245 if (palette->TestBit(TPaletteAxis::kHasView)) {
8246 fFunctions->Remove(palette);
8247 delete palette; palette = 0;
8248 }
8249 }
8250 // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
8251 if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
8252 }
8253
8254 if (!palette) {
8255 Double_t xup = gPad->GetUxmax();
8256 Double_t x2 = gPad->PadtoX(gPad->GetX2());
8257 Double_t ymin = gPad->PadtoY(gPad->GetUymin());
8258 Double_t ymax = gPad->PadtoY(gPad->GetUymax());
8259 Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
8260 Double_t xmin = gPad->PadtoX(xup +0.1*xr);
8261 Double_t xmax = gPad->PadtoX(xup + xr);
8262 if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
8263 palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
8264 fFunctions->AddFirst(palette);
8265 palette->Paint();
8266 }
8267}
8268
8269////////////////////////////////////////////////////////////////////////////////
8270/// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
8271
8273{
8274
8275 fH->TAttMarker::Modify();
8276
8277 Int_t k, marker;
8278 Double_t dz, z, xk,xstep, yk, ystep;
8279 Double_t scale = 1;
8280 Bool_t ltest = kFALSE;
8281 Double_t zmax = fH->GetMaximum();
8282 Double_t zmin = fH->GetMinimum();
8283 if (zmin == 0 && zmax == 0) return;
8284 if (zmin == zmax) {
8285 zmax += 0.1*TMath::Abs(zmax);
8286 zmin -= 0.1*TMath::Abs(zmin);
8287 }
8289 if (Hoption.Logz) {
8290 if (zmin > 0) zmin = TMath::Log10(zmin);
8291 else zmin = 0;
8292 if (zmax > 0) zmax = TMath::Log10(zmax);
8293 else zmax = 0;
8294 if (zmin == 0 && zmax == 0) return;
8295 dz = zmax - zmin;
8296 scale = 100/dz;
8297 if (ncells > 10000) scale /= 5;
8298 ltest = kTRUE;
8299 } else {
8300 dz = zmax - zmin;
8301 if (dz >= kNMAX || zmax < 1) {
8302 scale = (kNMAX-1)/dz;
8303 if (ncells > 10000) scale /= 5;
8304 ltest = kTRUE;
8305 }
8306 }
8307 if (fH->GetMinimumStored() == -1111) {
8308 Double_t yMARGIN = gStyle->GetHistTopMargin();
8309 if (Hoption.MinimumZero) {
8310 if (zmin >= 0) zmin = 0;
8311 else zmin -= yMARGIN*(zmax-zmin);
8312 } else {
8313 Double_t dzmin = yMARGIN*(zmax-zmin);
8314 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
8315 else zmin -= dzmin;
8316 }
8317 }
8318
8319 TString opt = option;
8320 opt.ToLower();
8321 if (opt.Contains("scat=")) {
8322 char optscat[100];
8323 strlcpy(optscat,opt.Data(),100);
8324 char *oscat = strstr(optscat,"scat=");
8325 char *blank = strstr(oscat," "); if (blank) *blank = 0;
8326 sscanf(oscat+5,"%lg",&scale);
8327 }
8328 // use an independent instance of a random generator
8329 // instead of gRandom to avoid conflicts and
8330 // to get same random numbers when drawing the same histogram
8331 TRandom2 random;
8332 marker=0;
8333 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8334 yk = fYaxis->GetBinLowEdge(j);
8335 ystep = fYaxis->GetBinWidth(j);
8336 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8337 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8338 xk = fXaxis->GetBinLowEdge(i);
8339 xstep = fXaxis->GetBinWidth(i);
8340 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
8341 z = fH->GetBinContent(bin);
8342 if (z < zmin) z = zmin;
8343 if (z > zmax) z = zmax;
8344 if (Hoption.Logz) {
8345 if (z > 0) z = TMath::Log10(z) - zmin;
8346 } else {
8347 z -= zmin;
8348 }
8349 if (z <= 0) continue;
8350 k = Int_t(z*scale);
8351 if (ltest) k++;
8352 if (k > 0) {
8353 for (Int_t loop=0; loop<k; loop++) {
8354 if (k+marker >= kNMAX) {
8355 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8356 marker=0;
8357 }
8358 fXbuf[marker] = (random.Rndm()*xstep) + xk;
8359 fYbuf[marker] = (random.Rndm()*ystep) + yk;
8360 if (Hoption.Logx) {
8361 if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
8362 else break;
8363 }
8364 if (Hoption.Logy) {
8365 if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
8366 else break;
8367 }
8368 if (fXbuf[marker] < gPad->GetUxmin()) break;
8369 if (fYbuf[marker] < gPad->GetUymin()) break;
8370 if (fXbuf[marker] > gPad->GetUxmax()) break;
8371 if (fYbuf[marker] > gPad->GetUymax()) break;
8372 marker++;
8373 }
8374 }
8375 }
8376 }
8377 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8378
8380}
8381
8382////////////////////////////////////////////////////////////////////////////////
8383/// Static function to paint special objects like vectors and matrices.
8384/// This function is called via `gROOT->ProcessLine` to paint these objects
8385/// without having a direct dependency of the graphics or histogramming
8386/// system.
8387
8389{
8390
8391 if (!obj) return;
8394
8395 if (obj->InheritsFrom(TMatrixFBase::Class())) {
8396 // case TMatrixF
8397 TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
8398 R__TMatrixFBase->SetBit(kCanDelete);
8399 R__TMatrixFBase->Draw(option);
8400
8401 } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
8402 // case TMatrixD
8403 TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8404 R__TMatrixDBase->SetBit(kCanDelete);
8405 R__TMatrixDBase->Draw(option);
8406
8407 } else if (obj->InheritsFrom(TVectorF::Class())) {
8408 //case TVectorF
8409 TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8410 R__TVectorF->SetBit(kCanDelete);
8411 R__TVectorF->Draw(option);
8412
8413 } else if (obj->InheritsFrom(TVectorD::Class())) {
8414 //case TVectorD
8415 TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8416 R__TVectorD->SetBit(kCanDelete);
8417 R__TVectorD->Draw(option);
8418 }
8419
8420 TH1::AddDirectory(status);
8421}
8422
8423////////////////////////////////////////////////////////////////////////////////
8424/// [Draw the statistics box for 1D and profile histograms.](#HP07)
8425
8427{
8428
8429 TString tt, tf;
8430 Int_t dofit;
8431 TPaveStats *stats = 0;
8432 TIter next(fFunctions);
8433 TObject *obj;
8434 while ((obj = next())) {
8435 if (obj->InheritsFrom(TPaveStats::Class())) {
8436 stats = (TPaveStats*)obj;
8437 break;
8438 }
8439 }
8440
8441 if (stats && dostat) {
8442 dofit = stats->GetOptFit();
8443 dostat = stats->GetOptStat();
8444 } else {
8445 dofit = gStyle->GetOptFit();
8446 }
8447 if (!dofit) fit = 0;
8448 if (dofit == 1) dofit = 111;
8449 if (dostat == 1) dostat = 1111;
8450 Int_t print_name = dostat%10;
8451 Int_t print_entries = (dostat/10)%10;
8452 Int_t print_mean = (dostat/100)%10;
8453 Int_t print_stddev = (dostat/1000)%10;
8454 Int_t print_under = (dostat/10000)%10;
8455 Int_t print_over = (dostat/100000)%10;
8456 Int_t print_integral= (dostat/1000000)%10;
8457 Int_t print_skew = (dostat/10000000)%10;
8458 Int_t print_kurt = (dostat/100000000)%10;
8459 Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8460 print_under + print_over + print_integral +
8461 print_skew + print_kurt;
8462 Int_t print_fval = dofit%10;
8463 Int_t print_ferrors = (dofit/10)%10;
8464 Int_t print_fchi2 = (dofit/100)%10;
8465 Int_t print_fprob = (dofit/1000)%10;
8466 Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8467 if (fit) {
8468 if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8469 else nlinesf += fit->GetNpar();
8470 }
8471 if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8472
8473 // Pavetext with statistics
8474 Bool_t done = kFALSE;
8475 if (!dostat && !fit) {
8476 if (stats) { fFunctions->Remove(stats); delete stats;}
8477 return;
8478 }
8479 Double_t statw = gStyle->GetStatW();
8480 if (fit) statw = 1.8*gStyle->GetStatW();
8481 Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8482 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8483 stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8484 }
8485 if (stats) {
8486 stats->Clear();
8487 done = kTRUE;
8488 } else {
8489 stats = new TPaveStats(
8490 gStyle->GetStatX()-statw,
8491 gStyle->GetStatY()-stath,
8492 gStyle->GetStatX(),
8493 gStyle->GetStatY(),"brNDC");
8494
8495 stats->SetParent(fH);
8496 stats->SetOptFit(dofit);
8497 stats->SetOptStat(dostat);
8498 stats->SetFillColor(gStyle->GetStatColor());
8499 stats->SetFillStyle(gStyle->GetStatStyle());
8501 stats->SetTextFont(gStyle->GetStatFont());
8502 if (gStyle->GetStatFont()%10 > 2)
8504 stats->SetFitFormat(gStyle->GetFitFormat());
8506 stats->SetName("stats");
8507
8509 stats->SetTextAlign(12);
8510 stats->SetBit(kCanDelete);
8511 stats->SetBit(kMustCleanup);
8512 }
8513 if (print_name) stats->AddText(fH->GetName());
8514 if (print_entries) {
8515 if (fH->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8516 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8517 stats->AddText(tt.Data());
8518 }
8519 if (print_mean) {
8520 if (print_mean == 1) {
8521 tf.Form("%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8522 tt.Form(tf.Data(),fH->GetMean(1));
8523 } else {
8524 tf.Form("%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8525 ,"%",stats->GetStatFormat());
8526 tt.Form(tf.Data(),fH->GetMean(1),fH->GetMeanError(1));
8527 }
8528 stats->AddText(tt.Data());
8530 if (print_mean == 1) {
8531 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8532 tt.Form(tf.Data(),fH->GetMean(2));
8533 } else {
8534 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8535 ,"%",stats->GetStatFormat());
8536 tt.Form(tf.Data(),fH->GetMean(2),fH->GetMeanError(2));
8537 }
8538 stats->AddText(tt.Data());
8539 }
8540 }
8541 if (print_stddev) {
8542 if (print_stddev == 1) {
8543 tf.Form("%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8544 tt.Form(tf.Data(),fH->GetStdDev(1));
8545 } else {
8546 tf.Form("%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8547 ,"%",stats->GetStatFormat());
8548 tt.Form(tf.Data(),fH->GetStdDev(1),fH->GetStdDevError(1));
8549 }
8550 stats->AddText(tt.Data());
8552 if (print_stddev == 1) {
8553 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8554 tt.Form(tf.Data(),fH->GetStdDev(2));
8555 } else {
8556 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8557 ,"%",stats->GetStatFormat());
8558 tt.Form(tf.Data(),fH->GetStdDev(2),fH->GetStdDevError(2));
8559 }
8560 stats->AddText(tt.Data());
8561 }
8562 }
8563 if (print_under) {
8564 tf.Form("%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8565 tt.Form(tf.Data(),fH->GetBinContent(0));
8566 stats->AddText(tt.Data());
8567 }
8568 if (print_over) {
8569 tf.Form("%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8570 tt.Form(tf.Data(),fH->GetBinContent(fXaxis->GetNbins()+1));
8571 stats->AddText(tt.Data());
8572 }
8573 if (print_integral) {
8574 if (print_integral == 1) {
8575 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8576 tt.Form(tf.Data(),fH->Integral());
8577 } else {
8578 tf.Form("%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8579 tt.Form(tf.Data(),fH->Integral("width"));
8580 }
8581 stats->AddText(tt.Data());
8582 }
8583 if (print_skew) {
8584 if (print_skew == 1) {
8585 tf.Form("%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8586 tt.Form(tf.Data(),fH->GetSkewness(1));
8587 } else {
8588 tf.Form("%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8589 ,"%",stats->GetStatFormat());
8590 tt.Form(tf.Data(),fH->GetSkewness(1),fH->GetSkewness(11));
8591 }
8592 stats->AddText(tt.Data());
8593 }
8594 if (print_kurt) {
8595 if (print_kurt == 1) {
8596 tf.Form("%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8597 tt.Form(tf.Data(),fH->GetKurtosis(1));
8598 } else {
8599 tf.Form("%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8600 ,"%",stats->GetStatFormat());
8601 tt.Form(tf.Data(),fH->GetKurtosis(1),fH->GetKurtosis(11));
8602 }
8603 stats->AddText(tt.Data());
8604 }
8605
8606 // Draw Fit parameters
8607 if (fit) {
8608 Int_t ndf = fit->GetNDF();
8609 tf.Form("#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8610 tt.Form(tf.Data(),(Float_t)fit->GetChisquare());
8611 if (print_fchi2) stats->AddText(tt.Data());
8612 if (print_fprob) {
8613 tf.Form("Prob = %s%s","%",stats->GetFitFormat());
8614 tt.Form(tf.Data(),(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8615 stats->AddText(tt.Data());
8616 }
8617 if (print_fval || print_ferrors) {
8618 Double_t parmin,parmax;
8619 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8620 fit->GetParLimits(ipar,parmin,parmax);
8621 if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8622 if (print_ferrors) {
8623 tf.Form("%-8s = %s%s #pm %s ", fit->GetParName(ipar), "%",stats->GetFitFormat(),
8624 GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8625 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar)
8626 ,(Float_t)fit->GetParError(ipar));
8627 } else {
8628 tf.Form("%-8s = %s%s ",fit->GetParName(ipar), "%",stats->GetFitFormat());
8629 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar));
8630 }
8631 stats->AddText(tt.Data());
8632 }
8633 }
8634 }
8635
8636 if (!done) fFunctions->Add(stats);
8637 stats->Paint();
8638}
8639
8640////////////////////////////////////////////////////////////////////////////////
8641/// [Draw the statistics box for 2D histograms.](#HP07)
8642
8644{
8645
8646 if (fH->GetDimension() != 2) return;
8647 TH2 *h2 = (TH2*)fH;
8648
8649 TString tt, tf;
8650 Int_t dofit;
8651 TPaveStats *stats = 0;
8652 TIter next(fFunctions);
8653 TObject *obj;
8654 while ((obj = next())) {
8655 if (obj->InheritsFrom(TPaveStats::Class())) {
8656 stats = (TPaveStats*)obj;
8657 break;
8658 }
8659 }
8660 if (stats && dostat) {
8661 dofit = stats->GetOptFit();
8662 dostat = stats->GetOptStat();
8663 } else {
8664 dofit = gStyle->GetOptFit();
8665 }
8666 if (dostat == 1) dostat = 1111;
8667 Int_t print_name = dostat%10;
8668 Int_t print_entries = (dostat/10)%10;
8669 Int_t print_mean = (dostat/100)%10;
8670 Int_t print_stddev = (dostat/1000)%10;
8671 Int_t print_under = (dostat/10000)%10;
8672 Int_t print_over = (dostat/100000)%10;
8673 Int_t print_integral= (dostat/1000000)%10;
8674 Int_t print_skew = (dostat/10000000)%10;
8675 Int_t print_kurt = (dostat/100000000)%10;
8676 Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8677 if (print_under || print_over) nlines += 3;
8678
8679 // Pavetext with statistics
8680 if (!gStyle->GetOptFit()) fit = 0;
8681 Bool_t done = kFALSE;
8682 if (!dostat && !fit) {
8683 if (stats) { fFunctions->Remove(stats); delete stats;}
8684 return;
8685 }
8686 Double_t statw = gStyle->GetStatW();
8687 if (fit) statw = 1.8*gStyle->GetStatW();
8688 Double_t stath = nlines*gStyle->GetStatFontSize();
8689 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8690 stath = 0.25*nlines*gStyle->GetStatH();
8691 }
8692 if (fit) stath += gStyle->GetStatH();
8693 if (stats) {
8694 stats->Clear();
8695 done = kTRUE;
8696 } else {
8697 stats = new TPaveStats(
8698 gStyle->GetStatX()-statw,
8699 gStyle->GetStatY()-stath,
8700 gStyle->GetStatX(),
8701 gStyle->GetStatY(),"brNDC");
8702
8703 stats->SetParent(fH);
8704 stats->SetOptFit(dofit);
8705 stats->SetOptStat(dostat);
8706 stats->SetFillColor(gStyle->GetStatColor());
8707 stats->SetFillStyle(gStyle->GetStatStyle());
8709 stats->SetName("stats");
8710
8712 stats->SetTextAlign(12);
8713 stats->SetTextFont(gStyle->GetStatFont());
8714 if (gStyle->GetStatFont()%10 > 2)
8716 stats->SetFitFormat(gStyle->GetFitFormat());
8718 stats->SetBit(kCanDelete);
8719 stats->SetBit(kMustCleanup);
8720 }
8721 if (print_name) stats->AddText(h2->GetName());
8722 if (print_entries) {
8723 if (h2->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8724 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8725 stats->AddText(tt.Data());
8726 }
8727 if (print_mean) {
8728 if (print_mean == 1) {
8729 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8730 tt.Form(tf.Data(),h2->GetMean(1));
8731 stats->AddText(tt.Data());
8732 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8733 tt.Form(tf.Data(),h2->GetMean(2));
8734 stats->AddText(tt.Data());
8735 } else {
8736 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8737 ,"%",stats->GetStatFormat());
8738 tt.Form(tf.Data(),h2->GetMean(1),h2->GetMeanError(1));
8739 stats->AddText(tt.Data());
8740 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8741 ,"%",stats->GetStatFormat());
8742 tt.Form(tf.Data(),h2->GetMean(2),h2->GetMeanError(2));
8743 stats->AddText(tt.Data());
8744 }
8745 }
8746 if (print_stddev) {
8747 if (print_stddev == 1) {
8748 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8749 tt.Form(tf.Data(),h2->GetStdDev(1));
8750 stats->AddText(tt.Data());
8751 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8752 tt.Form(tf.Data(),h2->GetStdDev(2));
8753 stats->AddText(tt.Data());
8754 } else {
8755 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8756 ,"%",stats->GetStatFormat());
8757 tt.Form(tf.Data(),h2->GetStdDev(1),h2->GetStdDevError(1));
8758 stats->AddText(tt.Data());
8759 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8760 ,"%",stats->GetStatFormat());
8761 tt.Form(tf.Data(),h2->GetStdDev(2),h2->GetStdDevError(2));
8762 stats->AddText(tt.Data());
8763 }
8764 }
8765 if (print_integral) {
8766 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8767 tt.Form(tf.Data(),fH->Integral());
8768 stats->AddText(tt.Data());
8769 }
8770 if (print_skew) {
8771 if (print_skew == 1) {
8772 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8773 tt.Form(tf.Data(),h2->GetSkewness(1));
8774 stats->AddText(tt.Data());
8775 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8776 tt.Form(tf.Data(),h2->GetSkewness(2));
8777 stats->AddText(tt.Data());
8778 } else {
8779 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8780 ,"%",stats->GetStatFormat());
8781 tt.Form(tf.Data(),h2->GetSkewness(1),h2->GetSkewness(11));
8782 stats->AddText(tt.Data());
8783 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8784 ,"%",stats->GetStatFormat());
8785 tt.Form(tf.Data(),h2->GetSkewness(2),h2->GetSkewness(12));
8786 stats->AddText(tt.Data());
8787 }
8788 }
8789 if (print_kurt) {
8790 if (print_kurt == 1) {
8791 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8792 tt.Form(tf.Data(),h2->GetKurtosis(1));
8793 stats->AddText(tt.Data());
8794 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8795 tt.Form(tf.Data(),h2->GetKurtosis(2));
8796 stats->AddText(tt.Data());
8797 } else {
8798 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8799 ,"%",stats->GetStatFormat());
8800 tt.Form(tf.Data(),h2->GetKurtosis(1),h2->GetKurtosis(11));
8801 stats->AddText(tt.Data());
8802 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8803 ,"%",stats->GetStatFormat());
8804 tt.Form(tf.Data(),h2->GetKurtosis(2),h2->GetKurtosis(12));
8805 stats->AddText(tt.Data());
8806 }
8807 }
8808 if (print_under || print_over) {
8809 //get 3*3 under/overflows for 2d hist
8810 Double_t unov[9];
8811
8812 Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8813 Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8814 Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8815 Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8816 Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8817 Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8818
8819 unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8820 unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8821 unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8822 unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8823 unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8824 unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8825 unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8826 unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8827 unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8828
8829 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8830 stats->AddText(tt.Data());
8831 if (TMath::Abs(unov[4]) < 1.e7)
8832 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8833 else
8834 tt.Form(" %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8835 stats->AddText(tt.Data());
8836 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8837 stats->AddText(tt.Data());
8838 }
8839
8840 // Draw Fit parameters
8841 if (fit) {
8842 Int_t ndf = fit->GetNDF();
8843 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8844 stats->AddText(tt.Data());
8845 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8846 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8847 ,(Float_t)fit->GetParameter(ipar)
8848 ,(Float_t)fit->GetParError(ipar));
8849 stats->AddText(tt.Data());
8850 }
8851 }
8852
8853 if (!done) fFunctions->Add(stats);
8854 stats->Paint();
8855}
8856
8857////////////////////////////////////////////////////////////////////////////////
8858/// [Draw the statistics box for 3D histograms.](#HP07)
8859
8861{
8862
8863 if (fH->GetDimension() != 3) return;
8864 TH3 *h3 = (TH3*)fH;
8865
8866 TString tt, tf;
8867 Int_t dofit;
8868 TPaveStats *stats = 0;
8869 TIter next(fFunctions);
8870 TObject *obj;
8871 while ((obj = next())) {
8872 if (obj->InheritsFrom(TPaveStats::Class())) {
8873 stats = (TPaveStats*)obj;
8874 break;
8875 }
8876 }
8877 if (stats && dostat) {
8878 dofit = stats->GetOptFit();
8879 dostat = stats->GetOptStat();
8880 } else {
8881 dofit = gStyle->GetOptFit();
8882 }
8883 if (dostat == 1) dostat = 1111;
8884 Int_t print_name = dostat%10;
8885 Int_t print_entries = (dostat/10)%10;
8886 Int_t print_mean = (dostat/100)%10;
8887 Int_t print_stddev = (dostat/1000)%10;
8888 Int_t print_under = (dostat/10000)%10;
8889 Int_t print_over = (dostat/100000)%10;
8890 Int_t print_integral= (dostat/1000000)%10;
8891 Int_t print_skew = (dostat/10000000)%10;
8892 Int_t print_kurt = (dostat/100000000)%10;
8893 Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
8894 if (print_under || print_over) nlines += 3;
8895
8896 // Pavetext with statistics
8897 if (!gStyle->GetOptFit()) fit = 0;
8898 Bool_t done = kFALSE;
8899 if (!dostat && !fit) {
8900 if (stats) { fFunctions->Remove(stats); delete stats;}
8901 return;
8902 }
8903 Double_t statw = gStyle->GetStatW();
8904 if (fit) statw = 1.8*gStyle->GetStatW();
8905 Double_t stath = nlines*gStyle->GetStatFontSize();
8906 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8907 stath = 0.25*nlines*gStyle->GetStatH();
8908 }
8909 if (fit) stath += gStyle->GetStatH();
8910 if (stats) {
8911 stats->Clear();
8912 done = kTRUE;
8913 } else {
8914 stats = new TPaveStats(
8915 gStyle->GetStatX()-statw,
8916 gStyle->GetStatY()-stath,
8917 gStyle->GetStatX(),
8918 gStyle->GetStatY(),"brNDC");
8919
8920 stats->SetParent(fH);
8921 stats->SetOptFit(dofit);
8922 stats->SetOptStat(dostat);
8923 stats->SetFillColor(gStyle->GetStatColor());
8924 stats->SetFillStyle(gStyle->GetStatStyle());
8926 stats->SetName("stats");
8927
8929 stats->SetTextAlign(12);
8930 stats->SetTextFont(gStyle->GetStatFont());
8931 stats->SetFitFormat(gStyle->GetFitFormat());
8933 stats->SetBit(kCanDelete);
8934 stats->SetBit(kMustCleanup);
8935 }
8936 if (print_name) stats->AddText(h3->GetName());
8937 if (print_entries) {
8938 if (h3->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8939 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8940 stats->AddText(tt.Data());
8941 }
8942 if (print_mean) {
8943 if (print_mean == 1) {
8944 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8945 tt.Form(tf.Data(),h3->GetMean(1));
8946 stats->AddText(tt.Data());
8947 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8948 tt.Form(tf.Data(),h3->GetMean(2));
8949 stats->AddText(tt.Data());
8950 tf.Form("%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8951 tt.Form(tf.Data(),h3->GetMean(3));
8952 stats->AddText(tt.Data());
8953 } else {
8954 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8955 ,"%",stats->GetStatFormat());
8956 tt.Form(tf.Data(),h3->GetMean(1),h3->GetMeanError(1));
8957 stats->AddText(tt.Data());
8958 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8959 ,"%",stats->GetStatFormat());
8960 tt.Form(tf.Data(),h3->GetMean(2),h3->GetMeanError(2));
8961 stats->AddText(tt.Data());
8962 tf.Form("%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8963 ,"%",stats->GetStatFormat());
8964 tt.Form(tf.Data(),h3->GetMean(3),h3->GetMeanError(3));
8965 stats->AddText(tt.Data());
8966 }
8967 }
8968 if (print_stddev) {
8969 if (print_stddev == 1) {
8970 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8971 tt.Form(tf.Data(),h3->GetStdDev(1));
8972 stats->AddText(tt.Data());
8973 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8974 tt.Form(tf.Data(),h3->GetStdDev(2));
8975 stats->AddText(tt.Data());
8976 tf.Form("%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
8977 tt.Form(tf.Data(),h3->GetStdDev(3));
8978 stats->AddText(tt.Data());
8979 } else {
8980 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8981 ,"%",stats->GetStatFormat());
8982 tt.Form(tf.Data(),h3->GetStdDev(1),h3->GetStdDevError(1));
8983 stats->AddText(tt.Data());
8984 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8985 ,"%",stats->GetStatFormat());
8986 tt.Form(tf.Data(),h3->GetStdDev(2),h3->GetStdDevError(2));
8987 stats->AddText(tt.Data());
8988 tf.Form("%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
8989 ,"%",stats->GetStatFormat());
8990 tt.Form(tf.Data(),h3->GetStdDev(3),h3->GetStdDevError(3));
8991 stats->AddText(tt.Data());
8992 }
8993 }
8994 if (print_integral) {
8995 tt.Form("%s = %6.4g",gStringIntegral.Data(),h3->Integral());
8996 stats->AddText(tt.Data());
8997 }
8998 if (print_skew) {
8999 if (print_skew == 1) {
9000 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
9001 tt.Form(tf.Data(),h3->GetSkewness(1));
9002 stats->AddText(tt.Data());
9003 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
9004 tt.Form(tf.Data(),h3->GetSkewness(2));
9005 stats->AddText(tt.Data());
9006 tf.Form("%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
9007 tt.Form(tf.Data(),h3->GetSkewness(3));
9008 stats->AddText(tt.Data());
9009 } else {
9010 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
9011 ,"%",stats->GetStatFormat());
9012 tt.Form(tf.Data(),h3->GetSkewness(1),h3->GetSkewness(11));
9013 stats->AddText(tt.Data());
9014 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
9015 ,"%",stats->GetStatFormat());
9016 tt.Form(tf.Data(),h3->GetSkewness(2),h3->GetSkewness(12));
9017 stats->AddText(tt.Data());
9018 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
9019 ,"%",stats->GetStatFormat());
9020 tt.Form(tf.Data(),h3->GetSkewness(3),h3->GetSkewness(13));
9021 stats->AddText(tt.Data());
9022 }
9023 }
9024 if (print_kurt) {
9025 if (print_kurt == 1) {
9026 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
9027 tt.Form(tf.Data(),h3->GetKurtosis(1));
9028 stats->AddText(tt.Data());
9029 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
9030 tt.Form(tf.Data(),h3->GetKurtosis(2));
9031 stats->AddText(tt.Data());
9032 tf.Form("%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
9033 tt.Form(tf.Data(),h3->GetKurtosis(3));
9034 stats->AddText(tt.Data());
9035 } else {
9036 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
9037 ,"%",stats->GetStatFormat());
9038 tt.Form(tf.Data(),h3->GetKurtosis(1),h3->GetKurtosis(11));
9039 stats->AddText(tt.Data());
9040 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
9041 ,"%",stats->GetStatFormat());
9042 tt.Form(tf.Data(),h3->GetKurtosis(2),h3->GetKurtosis(12));
9043 stats->AddText(tt.Data());
9044 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
9045 ,"%",stats->GetStatFormat());
9046 tt.Form(tf.Data(),h3->GetKurtosis(3),h3->GetKurtosis(13));
9047 stats->AddText(tt.Data());
9048 }
9049 }
9050 if (print_under || print_over) {
9051 // no underflow - overflow printing for a 3D histogram
9052 // one would need a 3D table
9053 }
9054
9055 // Draw Fit parameters
9056 if (fit) {
9057 Int_t ndf = fit->GetNDF();
9058 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
9059 stats->AddText(tt.Data());
9060 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
9061 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
9062 ,(Float_t)fit->GetParameter(ipar)
9063 ,(Float_t)fit->GetParError(ipar));
9064 stats->AddText(tt.Data());
9065 }
9066 }
9067
9068 if (!done) fFunctions->Add(stats);
9069 stats->Paint();
9070}
9071
9072////////////////////////////////////////////////////////////////////////////////
9073/// [Control function to draw a 2D histogram as a surface plot.](#HP18)
9074
9076{
9077
9078 const Double_t ydiff = 1;
9079 const Double_t yligh1 = 10;
9080 const Double_t qa = 0.15;
9081 const Double_t qd = 0.15;
9082 const Double_t qs = 0.8;
9083 Double_t fmin, fmax;
9084 Int_t raster = 0;
9085 Int_t irep = 0;
9086
9087 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9090 Double_t zmin = Hparam.zmin;
9091 Double_t zmax = Hparam.zmax;
9092 Double_t xlab1 = Hparam.xmin;
9093 Double_t xlab2 = Hparam.xmax;
9094 Double_t ylab1 = Hparam.ymin;
9095 Double_t ylab2 = Hparam.ymax;
9096 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
9097 Double_t deltaz = TMath::Abs(zmin);
9098 if (deltaz == 0) deltaz = 1;
9099 if (zmin >= zmax) {
9100 zmin -= 0.5*deltaz;
9101 zmax += 0.5*deltaz;
9102 }
9103 Double_t z1c = zmin;
9104 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
9105 // Compute the lego limits and instantiate a lego object
9106 fXbuf[0] = -1;
9107 fYbuf[0] = 1;
9108 fXbuf[1] = -1;
9109 fYbuf[1] = 1;
9110 if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
9111 if (Hoption.System == kPOLAR) {
9112 fXbuf[2] = z1c;
9113 fYbuf[2] = z2c;
9114 } else if (Hoption.System == kCYLINDRICAL) {
9115 if (Hoption.Logy) {
9116 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
9117 else fXbuf[2] = 0;
9118 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
9119 else fYbuf[2] = 0;
9120 } else {
9121 fXbuf[2] = ylab1;
9122 fYbuf[2] = ylab2;
9123 }
9124 z1c = 0; z2c = 1;
9125 } else if (Hoption.System == kSPHERICAL) {
9126 fXbuf[2] = -1;
9127 fYbuf[2] = 1;
9128 z1c = 0; z2c = 1;
9129 } else if (Hoption.System == kRAPIDITY) {
9130 fXbuf[2] = -1/TMath::Tan(dangle);
9131 fYbuf[2] = 1/TMath::Tan(dangle);
9132 } else {
9133 fXbuf[0] = xlab1;
9134 fYbuf[0] = xlab2;
9135 fXbuf[1] = ylab1;
9136 fYbuf[1] = ylab2;
9137 fXbuf[2] = z1c;
9138 fYbuf[2] = z2c;
9139 }
9140
9144
9145 // Create axis object
9146
9147 TGaxis *axis = new TGaxis();
9148
9149 // Initialize the levels on the Z axis
9150 Int_t ndiv = fH->GetContour();
9151 if (ndiv == 0 ) {
9152 ndiv = gStyle->GetNumberContours();
9153 fH->SetContour(ndiv);
9154 }
9155 Int_t ndivz = TMath::Abs(ndiv);
9156 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9157
9158 if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
9159 if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
9160
9161 // Close the surface in case of non cartesian coordinates.
9162
9163 if (Hoption.System != kCARTESIAN) {nx++; ny++;}
9164
9165 // Now ready to draw the surface plot
9166
9167 TView *view = gPad->GetView();
9168 if (!view) {
9169 Error("PaintSurface", "no TView in current pad");
9170 return;
9171 }
9172
9173 Double_t thedeg = 90 - gPad->GetTheta();
9174 Double_t phideg = -90 - gPad->GetPhi();
9175 Double_t psideg = view->GetPsi();
9176 view->SetView(phideg, thedeg, psideg, irep);
9177
9178 // Set color/style for back box
9179 if (Hoption.Same) {
9180 fLego->SetFillStyle(0);
9181 fLego->SetFillColor(1);
9182 } else {
9183 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9184 fLego->SetFillColor(gPad->GetFrameFillColor());
9185 }
9186 fLego->TAttFill::Modify();
9187
9188 Int_t backcolor = gPad->GetFrameFillColor();
9189 if (Hoption.System != kCARTESIAN) backcolor = 0;
9190 view->PadRange(backcolor);
9191
9194 fLego->TAttFill::Modify();
9195
9196 // Draw the filled contour on top
9197 Int_t icol1 = fH->GetFillColor();
9198
9199 Int_t hoption35 = Hoption.Surf;
9200 if (Hoption.Surf == 13 || Hoption.Surf == 15) {
9201 DefineColorLevels(ndivz);
9202 Hoption.Surf = 23;
9205 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9206 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9207 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9208 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9209 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9210 Hoption.Surf = hoption35;
9211 fLego->SetMesh(1);
9212 }
9213
9214 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
9215 else fLego->InitMoveScreen(-1.1,1.1);
9216
9217 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
9221 fLego->BackBox(90);
9222 }
9223 }
9224
9225 // Gouraud Shading surface
9226 if (Hoption.Surf == 14) {
9227 // Set light sources
9228 fLego->LightSource(0, ydiff, 0,0,0,irep);
9229 fLego->LightSource(1, yligh1 ,1,1,1,irep);
9230 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
9231 fmin = ydiff*qa;
9232 fmax = fmin + (yligh1+0.1)*(qd+qs);
9233 Int_t nbcol = 28;
9234 icol1 = 201;
9235 Double_t dcol = 0.5/Double_t(nbcol);
9236 TColor *colref = gROOT->GetColor(fH->GetFillColor());
9237 if (!colref) return;
9238 Float_t r,g,b,hue,light,satur;
9239 colref->GetRGB(r,g,b);
9240 TColor::RGBtoHLS(r,g,b,hue,light,satur);
9241 TColor *acol;
9242 for (Int_t col=0;col<nbcol;col++) {
9243 acol = gROOT->GetColor(col+icol1);
9244 TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
9245 if (acol) acol->SetRGB(r,g,b);
9246 }
9247 fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
9250 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9251 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9252 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9253 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9254 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9255 } else if (Hoption.Surf == 15) {
9256 // The surface is not drawn in this case.
9257 } else {
9258 // Draw the surface
9259 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
9260 DefineColorLevels(ndivz);
9261 } else {
9263 }
9267 if (Hoption.System == kPOLAR) {
9268 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
9269 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
9270 } else if (Hoption.System == kCYLINDRICAL) {
9271 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9272 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9273 } else if (Hoption.System == kSPHERICAL) {
9274 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9275 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9276 } else if (Hoption.System == kRAPIDITY) {
9277 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9278 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9279 } else {
9282 if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
9283 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
9284 }
9285 }
9286
9287 // Paint the line contour on top for option SURF7
9288 if (Hoption.Surf == 17) {
9289 fLego->InitMoveScreen(-1.1,1.1);
9291 Hoption.Surf = 23;
9294 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
9295 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9296 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9297 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9298 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
9299 }
9300
9301 if ((!Hoption.Same) &&
9302 (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
9305 fLego->BackBox(90);
9306 }
9307 }
9308 if (Hoption.System == kCARTESIAN) {
9309 fLego->InitMoveScreen(-1.1,1.1);
9311 if (Hoption.FrontBox) fLego->FrontBox(90);
9312 }
9313 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9314
9316
9317 delete axis;
9318 delete fLego; fLego = 0;
9319}
9320
9321////////////////////////////////////////////////////////////////////////////////
9322/// Control function to draw a table using Delaunay triangles.
9323
9325{
9326
9327 TGraphDelaunay2D *dt = nullptr;
9328 TGraphDelaunay *dtOld = nullptr;
9329
9330 // Check if fH contains a TGraphDelaunay2D
9331 TList *hl = fH->GetListOfFunctions();
9332 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
9333 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
9334 if (!dt && !dtOld) return;
9335
9336 // If needed, create a TGraph2DPainter
9337 if (!fGraph2DPainter) {
9338 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
9339 else fGraph2DPainter = new TGraph2DPainter(dtOld);
9340 }
9341
9342 // Define the 3D view
9343 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9344 if (Hoption.Same) {
9345 TView *viewsame = gPad->GetView();
9346 if (!viewsame) {
9347 Error("PaintTriangles", "no TView in current pad, do not use option SAME");
9348 return;
9349 }
9350 Double_t *rmin = viewsame->GetRmin();
9351 Double_t *rmax = viewsame->GetRmax();
9352 if (!rmin || !rmax) return;
9353 fXbuf[0] = rmin[0];
9354 fYbuf[0] = rmax[0];
9355 fXbuf[1] = rmin[1];
9356 fYbuf[1] = rmax[1];
9357 fXbuf[2] = rmin[2];
9358 fYbuf[2] = rmax[2];
9359 } else {
9360 fXbuf[0] = Hparam.xmin;
9361 fYbuf[0] = Hparam.xmax;
9362 fXbuf[1] = Hparam.ymin;
9363 fYbuf[1] = Hparam.ymax;
9364 fXbuf[2] = Hparam.zmin;
9365 fYbuf[2] = Hparam.zmax;
9366 }
9367
9369 TView *view = gPad->GetView();
9370 if (!view) {
9371 Error("PaintTriangles", "no TView in current pad");
9372 return;
9373 }
9374 Double_t thedeg = 90 - gPad->GetTheta();
9375 Double_t phideg = -90 - gPad->GetPhi();
9376 Double_t psideg = view->GetPsi();
9377 Int_t irep;
9378 view->SetView(phideg, thedeg, psideg, irep);
9379
9380 // Set color/style for back box
9381 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9382 fLego->SetFillColor(gPad->GetFrameFillColor());
9383 fLego->TAttFill::Modify();
9384 Int_t backcolor = gPad->GetFrameFillColor();
9385 if (Hoption.System != kCARTESIAN) backcolor = 0;
9386 view->PadRange(backcolor);
9389 fLego->TAttFill::Modify();
9390
9391 // Paint the Back Box if needed
9392 if (Hoption.BackBox && !Hoption.Same) {
9393 fLego->InitMoveScreen(-1.1,1.1);
9396 fLego->BackBox(90);
9397 }
9398
9399 // Paint the triangles
9400 fGraph2DPainter->Paint(option);
9401
9402 // Paint the Front Box if needed
9403 if (Hoption.FrontBox) {
9404 fLego->InitMoveScreen(-1.1,1.1);
9406 fLego->FrontBox(90);
9407 }
9408
9409 // Paint the Axis if needed
9410 if (!Hoption.Axis && !Hoption.Same) {
9411 TGaxis *axis = new TGaxis();
9412 PaintLegoAxis(axis, 90);
9413 delete axis;
9414 }
9415
9417
9418 delete fLego; fLego = 0;
9419}
9420
9421////////////////////////////////////////////////////////////////////////////////
9422/// Define the color levels used to paint legos, surfaces etc..
9423
9425{
9426
9427 Int_t i, irep;
9428
9429 // Initialize the color levels
9430 if (ndivz >= 100) {
9431 Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
9432 ndivz = 8;
9433 }
9434 Double_t *funlevel = new Double_t[ndivz+1];
9435 Int_t *colorlevel = new Int_t[ndivz+1];
9436 Int_t theColor;
9437 Int_t ncolors = gStyle->GetNumberOfColors();
9438 for (i = 0; i < ndivz; ++i) {
9439 funlevel[i] = fH->GetContourLevelPad(i);
9440 theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9441 colorlevel[i] = gStyle->GetColorPalette(theColor);
9442 }
9443 colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9444 fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9445 delete [] colorlevel;
9446 delete [] funlevel;
9447}
9448
9449////////////////////////////////////////////////////////////////////////////////
9450/// [Control function to draw 2D/3D histograms (tables).](#HP01c)
9451
9453{
9454
9455 // Fill Hparam structure with histo parameters
9456 if (!TableInit()) return;
9457
9458 // Draw histogram frame
9459 PaintFrame();
9460
9461 // If palette option not specified, delete a possible existing palette
9462 if (!Hoption.Zscale) {
9463 TObject *palette = fFunctions->FindObject("palette");
9464 if (palette) { fFunctions->Remove(palette); delete palette;}
9465 }
9466
9467 // Do not draw the histogram. Only the attached functions will be drawn.
9468 if (Hoption.Func == 2) {
9469 if (Hoption.Zscale) {
9470 Int_t ndiv = fH->GetContour();
9471 if (ndiv == 0 ) {
9472 ndiv = gStyle->GetNumberContours();
9473 fH->SetContour(ndiv);
9474 }
9475 PaintPalette();
9476 }
9477
9478 // Draw the histogram according to the option
9479 } else {
9480 if (fH->InheritsFrom(TH2Poly::Class())) {
9481 if (Hoption.Fill) PaintTH2PolyBins("f");
9484 if (Hoption.Text) PaintTH2PolyText(option);
9485 if (Hoption.Line) PaintTH2PolyBins("l");
9486 if (Hoption.Mark) PaintTH2PolyBins("P");
9487 } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9488 if (Hoption.Scat) PaintScatterPlot(option);
9489 if (Hoption.Arrow) PaintArrows(option);
9490 if (Hoption.Box) PaintBoxes(option);
9491 if (Hoption.Color) {
9492 if (Hoption.Color == 3) PaintColorLevelsFast(option);
9493 else PaintColorLevels(option);
9494 }
9495 if (Hoption.Contour) PaintContour(option);
9496 if (Hoption.Text) PaintText(option);
9497 if (Hoption.Error >= 100) Paint2DErrors(option);
9498 if (Hoption.Candle) PaintCandlePlot(option);
9499 }
9500 if (Hoption.Lego) PaintLego(option);
9501 if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9502 if (Hoption.Tri) PaintTriangles(option);
9503 }
9504
9505 // Draw histogram title
9506 PaintTitle();
9507
9508 // Draw the axes
9509 if (!Hoption.Lego && !Hoption.Surf &&
9510 !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9511
9512 TF1 *fit = 0;
9513 TIter next(fFunctions);
9514 TObject *obj;
9515 while ((obj = next())) {
9516 if (obj->InheritsFrom(TF1::Class())) {
9517 fit = (TF1*)obj;
9518 break;
9519 }
9520 }
9521 if ((Hoption.Same%10) != 1) {
9522 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9523 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9524 //ALWAYS executed on non-iOS platform.
9525 //On iOS, depends on mode.
9527 }
9528 }
9529 }
9530}
9531
9532////////////////////////////////////////////////////////////////////////////////
9533/// Control function to draw a TH2Poly bins' contours.
9534///
9535/// - option = "F" draw the bins as filled areas.
9536/// - option = "L" draw the bins as line.
9537/// - option = "P" draw the bins as markers.
9538
9540{
9541
9542 //Do not highlight the histogram, if its part was picked.
9543 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9544
9545 TString opt = option;
9546 opt.ToLower();
9547 Bool_t line = kFALSE;
9548 Bool_t fill = kFALSE;
9549 Bool_t mark = kFALSE;
9550 if (opt.Contains("l")) line = kTRUE;
9551 if (opt.Contains("f")) fill = kTRUE;
9552 if (opt.Contains("p")) mark = kTRUE;
9553
9554 TH2PolyBin *b;
9555 Double_t z;
9556
9557 TIter next(((TH2Poly*)fH)->GetBins());
9558 TObject *obj, *poly;
9559
9560 while ((obj=next())) {
9561 b = (TH2PolyBin*)obj;
9562 z = b->GetContent();
9563 if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9564 poly = b->GetPolygon();
9565
9566 // Paint the TGraph bins.
9567 if (poly->IsA() == TGraph::Class()) {
9568 TGraph *g = (TGraph*)poly;
9569 g->TAttLine::Modify();
9570 g->TAttMarker::Modify();
9571 g->TAttFill::Modify();
9572 if (line) {
9573 Int_t fs = g->GetFillStyle();
9574 Int_t fc = g->GetFillColor();
9575 g->SetFillStyle(0);
9576 g->SetFillColor(g->GetLineColor());
9577 g->Paint("F");
9578 g->SetFillStyle(fs);
9579 g->SetFillColor(fc);
9580 }
9581 if (fill) g->Paint("F");
9582 if (mark) g->Paint("P");
9583 }
9584
9585 // Paint the TMultiGraph bins.
9586 if (poly->IsA() == TMultiGraph::Class()) {
9587 TMultiGraph *mg = (TMultiGraph*)poly;
9588 TList *gl = mg->GetListOfGraphs();
9589 if (!gl) return;
9590 TGraph *g;
9591 TIter nextg(gl);
9592 while ((g = (TGraph*) nextg())) {
9593 g->TAttLine::Modify();
9594 g->TAttMarker::Modify();
9595 g->TAttFill::Modify();
9596 if (line) {
9597 Int_t fs = g->GetFillStyle();
9598 Int_t fc = g->GetFillColor();
9599 g->SetFillStyle(0);
9600 g->SetFillColor(g->GetLineColor());
9601 g->Paint("F");
9602 g->SetFillStyle(fs);
9603 g->SetFillColor(fc);
9604 }
9605 if (fill) g->Paint("F");
9606 if (mark) g->Paint("P");
9607 }
9608 }
9609 }
9610}
9611
9612////////////////////////////////////////////////////////////////////////////////
9613/// [Control function to draw a TH2Poly as a color plot.](#HP20a)
9614
9616{
9617
9618 //Do not highlight the histogram, if its part was picked.
9619 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9620 return;
9621
9622 Int_t ncolors, color, theColor;
9623 Double_t z, zc;
9624 Double_t zmin = fH->GetMinimum();
9625 Double_t zmax = fH->GetMaximum();
9626 if (Hoption.Logz) {
9627 if (zmax > 0) {
9628 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9629 zmin = TMath::Log10(zmin);
9630 zmax = TMath::Log10(zmax);
9631 } else {
9632 return;
9633 }
9634 }
9635 Double_t dz = zmax - zmin;
9636
9637 // Initialize the levels on the Z axis
9638 ncolors = gStyle->GetNumberOfColors();
9639 Int_t ndiv = fH->GetContour();
9640 if (ndiv == 0 ) {
9641 ndiv = gStyle->GetNumberContours();
9642 fH->SetContour(ndiv);
9643 }
9644 Int_t ndivz = TMath::Abs(ndiv);
9645 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9646 Double_t scale = ndivz/dz;
9647
9648 TH2PolyBin *b;
9649
9650 TIter next(((TH2Poly*)fH)->GetBins());
9651 TObject *obj, *poly;
9652
9653 while ((obj=next())) {
9654 b = (TH2PolyBin*)obj;
9655 poly = b->GetPolygon();
9656
9657 z = b->GetContent();
9658 if (z==0 && Hoption.Zero) continue;
9659 if (Hoption.Logz) {
9660 if (z > 0) z = TMath::Log10(z);
9661 else z = zmin;
9662 }
9663 if (z < zmin) continue;
9664
9665 // Define the bin color.
9667 zc = fH->GetContourLevelPad(0);
9668 if (z < zc) continue;
9669 color = -1;
9670 for (Int_t k=0; k<ndiv; k++) {
9671 zc = fH->GetContourLevelPad(k);
9672 if (z < zc) {
9673 continue;
9674 } else {
9675 color++;
9676 }
9677 }
9678 } else {
9679 color = Int_t(0.01+(z-zmin)*scale);
9680 }
9681 theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9682 if (theColor > ncolors-1) theColor = ncolors-1;
9683
9684 // Paint the TGraph bins.
9685 if (poly->IsA() == TGraph::Class()) {
9686 TGraph *g = (TGraph*)poly;
9687 g->SetFillColor(gStyle->GetColorPalette(theColor));
9688 g->TAttFill::Modify();
9689 g->Paint("F");
9690 }
9691
9692 // Paint the TMultiGraph bins.
9693 if (poly->IsA() == TMultiGraph::Class()) {
9694 TMultiGraph *mg = (TMultiGraph*)poly;
9695 TList *gl = mg->GetListOfGraphs();
9696 if (!gl) return;
9697 TGraph *g;
9698 TIter nextg(gl);
9699 while ((g = (TGraph*) nextg())) {
9700 g->SetFillColor(gStyle->GetColorPalette(theColor));
9701 g->TAttFill::Modify();
9702 g->Paint("F");
9703 }
9704 }
9705 }
9707}
9708
9709////////////////////////////////////////////////////////////////////////////////
9710/// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
9711
9713{
9714
9715 //Do not highlight the histogram, if its part was selected.
9716 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9717 return;
9718
9719 Int_t k, loop, marker=0;
9720 Double_t z, xk,xstep, yk, ystep, xp, yp;
9721 Double_t scale = 1;
9722 Double_t zmin = fH->GetMinimum();
9723 Double_t zmax = fH->GetMaximum();
9724 if (Hoption.Logz) {
9725 if (zmax > 0) {
9726 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9727 zmin = TMath::Log10(zmin);
9728 zmax = TMath::Log10(zmax);
9729 } else {
9730 return;
9731 }
9732 }
9733 Double_t dz = zmax - zmin;
9734 scale = (kNMAX-1)/dz;
9735
9736
9737 // use an independent instance of a random generator
9738 // instead of gRandom to avoid conflicts and
9739 // to get same random numbers when drawing the same histogram
9740 TRandom2 random;
9741
9742 TH2PolyBin *b;
9743
9744 TIter next(((TH2Poly*)fH)->GetBins());
9745 TObject *obj, *poly;
9746
9747 Double_t maxarea = 0, a;
9748 while ((obj=next())) {
9749 b = (TH2PolyBin*)obj;
9750 a = b->GetArea();
9751 if (a>maxarea) maxarea = a;
9752 }
9753
9754 next.Reset();
9755
9756 while ((obj=next())) {
9757 b = (TH2PolyBin*)obj;
9758 poly = b->GetPolygon();
9759 z = b->GetContent();
9760 if (z < zmin) z = zmin;
9761 if (z > zmax) z = zmax;
9762 if (Hoption.Logz) {
9763 if (z > 0) z = TMath::Log10(z) - zmin;
9764 } else {
9765 z -= zmin;
9766 }
9767 k = Int_t((z*scale)*(b->GetArea()/maxarea));
9768 xk = b->GetXMin();
9769 yk = b->GetYMin();
9770 xstep = b->GetXMax()-xk;
9771 ystep = b->GetYMax()-yk;
9772
9773 // Paint the TGraph bins.
9774 if (poly->IsA() == TGraph::Class()) {
9775 TGraph *g = (TGraph*)poly;
9776 if (k <= 0 || z <= 0) continue;
9777 loop = 0;
9778 while (loop<k) {
9779 if (k+marker >= kNMAX) {
9780 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9781 marker=0;
9782 }
9783 xp = (random.Rndm()*xstep) + xk;
9784 yp = (random.Rndm()*ystep) + yk;
9785 if (g->IsInside(xp,yp)) {
9786 fXbuf[marker] = xp;
9787 fYbuf[marker] = yp;
9788 marker++;
9789 loop++;
9790 }
9791 }
9792 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9793 }
9794
9795 // Paint the TMultiGraph bins.
9796 if (poly->IsA() == TMultiGraph::Class()) {
9797 TMultiGraph *mg = (TMultiGraph*)poly;
9798 TList *gl = mg->GetListOfGraphs();
9799 if (!gl) return;
9800 if (k <= 0 || z <= 0) continue;
9801 loop = 0;
9802 while (loop<k) {
9803 if (k+marker >= kNMAX) {
9804 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9805 marker=0;
9806 }
9807 xp = (random.Rndm()*xstep) + xk;
9808 yp = (random.Rndm()*ystep) + yk;
9809 if (mg->IsInside(xp,yp)) {
9810 fXbuf[marker] = xp;
9811 fYbuf[marker] = yp;
9812 marker++;
9813 loop++;
9814 }
9815 }
9816 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9817 }
9818 }
9819 PaintTH2PolyBins("l");
9820}
9821
9822////////////////////////////////////////////////////////////////////////////////
9823/// [Control function to draw a TH2Poly as a text plot.](#HP20a)
9824
9826{
9827
9828 TLatex text;
9832
9833 Double_t x, y, z, e, angle = 0;
9834 TString tt, tf;
9835 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9836 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9837 Int_t opt = (Int_t)Hoption.Text/1000;
9838
9839 text.SetTextAlign(22);
9840 if (Hoption.Text == 1) angle = 0;
9841 text.SetTextAngle(angle);
9842 text.TAttText::Modify();
9843
9844 TH2PolyBin *b;
9845
9846 TIter next(((TH2Poly*)fH)->GetBins());
9847 TObject *obj, *p;
9848
9849 while ((obj=next())) {
9850 b = (TH2PolyBin*)obj;
9851 p = b->GetPolygon();
9852 x = (b->GetXMin()+b->GetXMax())/2;
9853 if (Hoption.Logx) {
9854 if (x > 0) x = TMath::Log10(x);
9855 else continue;
9856 }
9857 y = (b->GetYMin()+b->GetYMax())/2;
9858 if (Hoption.Logy) {
9859 if (y > 0) y = TMath::Log10(y);
9860 else continue;
9861 }
9862 z = b->GetContent();
9863 if (z < Hparam.zmin || (z == 0 && !Hoption.MinimumZero)) continue;
9864 if (opt==2) {
9865 e = fH->GetBinError(b->GetBinNumber());
9866 tf.Form("#splitline{%s%s}{#pm %s%s}",
9868 "%",gStyle->GetPaintTextFormat());
9869 tt.Form(tf.Data(),z,e);
9870 } else {
9871 tt.Form(tf.Data(),z);
9872 }
9873 if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
9874 else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),tt.Data());
9875 }
9876
9877 PaintTH2PolyBins("l");
9878}
9879
9880////////////////////////////////////////////////////////////////////////////////
9881/// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
9882
9884{
9885
9886 TLatex text;
9890
9891 Double_t x, y, z, e, angle = 0;
9892 TString tt, tf;
9893 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9894 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9895
9896 // 1D histograms
9897 if (fH->GetDimension() == 1) {
9898 Bool_t getentries = kFALSE;
9899 Double_t yt;
9900 TProfile *hp = (TProfile*)fH;
9901 if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
9902 Hoption.Text = Hoption.Text-2000;
9903 getentries = kTRUE;
9904 }
9905 if (Hoption.Text == 1) angle = 90;
9906 text.SetTextAlign(11);
9907 if (angle == 90) text.SetTextAlign(12);
9908 if (angle == 0) text.SetTextAlign(21);
9909 text.TAttText::Modify();
9910 Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9911 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9912 if (Hoption.Bar) {
9913 x = fH->GetXaxis()->GetBinLowEdge(i)+
9914 fH->GetXaxis()->GetBinWidth(i)*
9915 (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9916 } else {
9917 x = fH->GetXaxis()->GetBinCenter(i);
9918 }
9919 y = fH->GetBinContent(i);
9920 yt = y;
9921 if (Hoption.MinimumZero && y<0) y = 0;
9922 if (getentries) yt = hp->GetBinEntries(i);
9923 if (yt == 0.) continue;
9924 tt.Form(tf.Data(),yt);
9925 if (Hoption.Logx) {
9926 if (x > 0) x = TMath::Log10(x);
9927 else continue;
9928 }
9929 if (Hoption.Logy) {
9930 if (y > 0) y = TMath::Log10(y);
9931 else continue;
9932 }
9933 if (y >= gPad->GetY2()) continue;
9934 if (y <= gPad->GetY1()) continue;
9935 text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),tt.Data());
9936 }
9937
9938 // 2D histograms
9939 } else {
9940 text.SetTextAlign(22);
9941 if (Hoption.Text == 1) angle = 0;
9942 text.SetTextAngle(angle);
9943 text.TAttText::Modify();
9944 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9945 y = fYaxis->GetBinCenter(j);
9946 if (Hoption.Logy) {
9947 if (y > 0) y = TMath::Log10(y);
9948 else continue;
9949 }
9950 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9951 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9952 x = fXaxis->GetBinCenter(i);
9953 if (Hoption.Logx) {
9954 if (x > 0) x = TMath::Log10(x);
9955 else continue;
9956 }
9957 if (!IsInside(x,y)) continue;
9958 z = fH->GetBinContent(bin);
9959 if (z < Hparam.zmin || (z == 0 && !Hoption.MinimumZero)) continue;
9960 if (Hoption.Text>2000) {
9961 e = fH->GetBinError(bin);
9962 tf.Form("#splitline{%s%s}{#pm %s%s}",
9964 "%",gStyle->GetPaintTextFormat());
9965 tt.Form(tf.Data(),z,e);
9966 } else {
9967 tt.Form(tf.Data(),z);
9968 }
9969 text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9970 angle,0.02*fH->GetMarkerSize(),tt.Data());
9971 }
9972 }
9973 }
9974}
9975
9976////////////////////////////////////////////////////////////////////////////////
9977/// [Control function to draw a 3D implicit functions.](#HP27)
9978
9980{
9981
9982 Int_t irep;
9983
9984 TGaxis *axis = new TGaxis();
9985 TAxis *xaxis = fH->GetXaxis();
9986 TAxis *yaxis = fH->GetYaxis();
9987 TAxis *zaxis = fH->GetZaxis();
9988
9989 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
9990 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
9991 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
9992 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
9993 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
9994 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
9995
9997
9998 TView *view = gPad->GetView();
9999 if (!view) {
10000 Error("PaintTF3", "no TView in current pad");
10001 return;
10002 }
10003 Double_t thedeg = 90 - gPad->GetTheta();
10004 Double_t phideg = -90 - gPad->GetPhi();
10005 Double_t psideg = view->GetPsi();
10006 view->SetView(phideg, thedeg, psideg, irep);
10007
10008 fLego->InitMoveScreen(-1.1,1.1);
10009
10010 if (Hoption.BackBox) {
10013 fLego->BackBox(90);
10014 }
10015
10017
10019 fH->GetNbinsY(),
10020 fH->GetNbinsZ(), "BF");
10021
10022 if (Hoption.FrontBox) {
10023 fLego->InitMoveScreen(-1.1,1.1);
10025 fLego->FrontBox(90);
10026 }
10027 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
10028
10029 PaintTitle();
10030
10031 delete axis;
10032 delete fLego; fLego = 0;
10033}
10034
10035////////////////////////////////////////////////////////////////////////////////
10036/// Draw the histogram title
10037///
10038/// The title is drawn according to the title alignment returned by
10039/// `GetTitleAlign()`. It is a 2 digits integer): hv
10040///
10041/// where `h` is the horizontal alignment and `v` is the
10042/// vertical alignment.
10043///
10044/// - `h` can get the values 1 2 3 for left, center, and right
10045/// - `v` can get the values 1 2 3 for bottom, middle and top
10046///
10047/// for instance the default alignment is: 13 (left top)
10048
10050{
10051 // probably best place for calls PaintHighlightBin
10052 // calls after paint histo (1D or 2D) and before paint title and stats
10053 if (!gPad->GetView()) PaintHighlightBin();
10054
10055 if (Hoption.Same) return;
10056 if (fH->TestBit(TH1::kNoTitle)) return;
10057 Int_t nt = strlen(fH->GetTitle());
10058 TPaveText *title = 0;
10059 TObject *obj;
10060 TIter next(gPad->GetListOfPrimitives());
10061 while ((obj = next())) {
10062 if (!obj->InheritsFrom(TPaveText::Class())) continue;
10063 title = (TPaveText*)obj;
10064 if (strcmp(title->GetName(),"title")) {title = 0; continue;}
10065 break;
10066 }
10067 if (nt == 0 || gStyle->GetOptTitle() <= 0) {
10068 if (title) delete title;
10069 return;
10070 }
10071 Double_t ht = gStyle->GetTitleH();
10072 Double_t wt = gStyle->GetTitleW();
10073
10074 if (ht <= 0) {
10075 if (gStyle->GetTitleFont("")%10 == 3) {
10076 Double_t hw = TMath::Max((Double_t)gPad->XtoPixel(gPad->GetX2()),
10077 (Double_t)gPad->YtoPixel(gPad->GetY1()));
10078 ht = 1.1*(gStyle->GetTitleSize("")/hw);
10079 } else {
10080 ht = 1.1*gStyle->GetTitleFontSize();
10081 }
10082 }
10083 if (ht <= 0) ht = 0.05;
10084 if (wt <= 0) {
10085 TLatex l;
10086 l.SetTextSize(ht);
10087 l.SetTitle(fH->GetTitle());
10088 // adjustment in case the title has several lines (#splitline)
10089 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
10090 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
10091 wt = TMath::Min(0.7, 0.02+wndc);
10092 }
10093 if (title) {
10094 TText *t0 = (TText*)title->GetLine(0);
10095 if (t0) {
10096 if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
10097 t0->SetTitle(fH->GetTitle());
10098 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
10099 }
10100 return;
10101 }
10102
10103 Int_t talh = gStyle->GetTitleAlign()/10;
10104 if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
10105 Int_t talv = gStyle->GetTitleAlign()%10;
10106 if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
10107 Double_t xpos, ypos;
10108 xpos = gStyle->GetTitleX();
10109 ypos = gStyle->GetTitleY();
10110 if (talh == 2) xpos = xpos-wt/2.;
10111 if (talh == 3) xpos = xpos-wt;
10112 if (talv == 2) ypos = ypos+ht/2.;
10113 if (talv == 1) ypos = ypos+ht;
10114
10115 TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
10116
10117 // box with the histogram title
10119 ptitle->SetFillStyle(gStyle->GetTitleStyle());
10120 ptitle->SetName("title");
10123 ptitle->SetTextFont(gStyle->GetTitleFont(""));
10124 if (gStyle->GetTitleFont("")%10 > 2)
10126 ptitle->AddText(fH->GetTitle());
10127 ptitle->SetBit(kCanDelete);
10128 ptitle->Draw();
10129 ptitle->Paint();
10130
10131 if(!gPad->IsEditable()) delete ptitle;
10132}
10133
10134////////////////////////////////////////////////////////////////////////////////
10135/// Process message `mess`.
10136
10137void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
10138{
10139
10140 if (!strcmp(mess,"SetF3")) {
10142 } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
10144 } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
10145 TVectorD &v = (TVectorD&)(*obj);
10146 Double_t xclip = v(0);
10147 Double_t yclip = v(1);
10148 Double_t zclip = v(2);
10150 }
10151}
10152
10153////////////////////////////////////////////////////////////////////////////////
10154/// Static function.
10155///
10156/// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
10157/// This procedure can be used to create an all-sky map in Galactic
10158/// coordinates with an equal-area Aitoff projection. Output map
10159/// coordinates are zero longitude centered.
10160/// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
10161///
10162/// source: GMT
10163///
10164/// code from Ernst-Jan Buis
10165
10167{
10168
10169 Double_t x, y;
10170
10171 Double_t alpha2 = (l/2)*TMath::DegToRad();
10172 Double_t delta = b*TMath::DegToRad();
10173 Double_t r2 = TMath::Sqrt(2.);
10174 Double_t f = 2*r2/TMath::Pi();
10175 Double_t cdec = TMath::Cos(delta);
10176 Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
10177 x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
10178 y = TMath::Sin(delta)*r2/denom;
10179 x *= TMath::RadToDeg()/f;
10180 y *= TMath::RadToDeg()/f;
10181 // x *= -1.; // for a skymap swap left<->right
10182 Al = x;
10183 Ab = y;
10184
10185 return 0;
10186}
10187
10188////////////////////////////////////////////////////////////////////////////////
10189/// Static function
10190///
10191/// Probably the most famous of the various map projections, the Mercator projection
10192/// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
10193/// with no distortion along the equator.
10194/// The Mercator projection has been used extensively for world maps in which the distortion towards
10195/// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
10196/// Greenland is larger than South America. In reality, the latter is about eight times the size of
10197/// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
10198/// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
10199/// code from Ernst-Jan Buis
10200
10202{
10203
10204 Al = l;
10206 Ab = TMath::Log(aid);
10207 return 0;
10208}
10209
10210////////////////////////////////////////////////////////////////////////////////
10211/// Static function code from Ernst-Jan Buis
10212
10214{
10215
10216 Al = l*cos(b*TMath::DegToRad());
10217 Ab = b;
10218 return 0;
10219}
10220
10221////////////////////////////////////////////////////////////////////////////////
10222/// Static function code from Ernst-Jan Buis
10223
10225{
10226
10227 Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
10228 Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
10229 return 0;
10230}
10231
10232////////////////////////////////////////////////////////////////////////////////
10233/// Recompute the histogram range following graphics operations.
10234
10236{
10237
10238 if (Hoption.Same) return;
10239
10240 // Compute x,y range
10245
10246 Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
10247 if (Hoption.Proj ==1) {
10248 // TODO : check x range not lower than -180 and not higher than 180
10253
10254 if (xmin > xmin_aid) xmin = xmin_aid;
10255 if (ymin > ymin_aid) ymin = ymin_aid;
10256 if (xmax < xmax_aid) xmax = xmax_aid;
10257 if (ymax < ymax_aid) ymax = ymax_aid;
10258 if (Hparam.ymin<0 && Hparam.ymax>0) {
10259 // there is an 'equator', check its range in the plot..
10260 THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
10261 THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
10262 if (xmin >xmin_aid) xmin = xmin_aid;
10263 if (xmax <xmax_aid) xmax = xmax_aid;
10264 }
10265 if (Hparam.xmin<0 && Hparam.xmax>0) {
10266 THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10267 THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
10268 if (ymin >ymin_aid) ymin = ymin_aid;
10269 if (ymax <ymax_aid) ymax = ymax_aid;
10270 }
10271 } else if ( Hoption.Proj ==2) {
10272 if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
10273 Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
10274 Hoption.Proj = 0;
10275 } else {
10278 }
10279 } else if (Hoption.Proj == 3) {
10284
10285 if (xmin > xmin_aid) xmin = xmin_aid;
10286 if (ymin > ymin_aid) ymin = ymin_aid;
10287 if (xmax < xmax_aid) xmax = xmax_aid;
10288 if (ymax < ymax_aid) ymax = ymax_aid;
10289 if (Hparam.ymin<0 && Hparam.ymax>0) {
10290 THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10291 THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10292 if (xmin >xmin_aid) xmin = xmin_aid;
10293 if (xmax <xmax_aid) xmax = xmax_aid;
10294 }
10295 if (Hparam.xmin<0 && Hparam.xmax>0) {
10296 THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
10297 THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10298 if (ymin >ymin_aid) ymin = ymin_aid;
10299 if (ymax <ymax_aid) ymax = ymax_aid;
10300 }
10301 } else if (Hoption.Proj == 4) {
10306
10307 if (xmin > xmin_aid) xmin = xmin_aid;
10308 if (ymin > ymin_aid) ymin = ymin_aid;
10309 if (xmax < xmax_aid) xmax = xmax_aid;
10310 if (ymax < ymax_aid) ymax = ymax_aid;
10311 if (Hparam.ymin<0 && Hparam.ymax>0) {
10312 THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10313 THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10314 if (xmin >xmin_aid) xmin = xmin_aid;
10315 if (xmax <xmax_aid) xmax = xmax_aid;
10316 }
10317 if (Hparam.xmin<0 && Hparam.xmax>0) {
10318 THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10319 THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10320 if (ymin >ymin_aid) ymin = ymin_aid;
10321 if (ymax <ymax_aid) ymax = ymax_aid;
10322 }
10323 }
10324 Hparam.xmin= xmin;
10325 Hparam.xmax= xmax;
10326 Hparam.ymin= ymin;
10327 Hparam.ymax= ymax;
10328
10329 Double_t dx = xmax-xmin;
10330 Double_t dy = ymax-ymin;
10331 Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
10332 Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
10333
10334 // Range() could change the size of the pad pixmap and therefore should
10335 // be called before the other paint routines
10336 gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
10337 ymin - dyr*gPad->GetBottomMargin(),
10338 xmax + dxr*gPad->GetRightMargin(),
10339 ymax + dyr*gPad->GetTopMargin());
10340 gPad->RangeAxis(xmin, ymin, xmax, ymax);
10341}
10342
10343////////////////////////////////////////////////////////////////////////////////
10344/// Set current histogram to `h`
10345
10347{
10348
10349 if (h == 0) return;
10350 fH = h;
10351 fXaxis = h->GetXaxis();
10352 fYaxis = h->GetYaxis();
10353 fZaxis = h->GetZaxis();
10355}
10356
10357////////////////////////////////////////////////////////////////////////////////
10358/// Initialize various options to draw 2D histograms.
10359
10361{
10362
10363 static const char *where = "TableInit";
10364
10365 Int_t first, last;
10366 Double_t yMARGIN= gStyle->GetHistTopMargin();
10367 Double_t zmin, zmax;
10368 Int_t maximum = 0;
10369 Int_t minimum = 0;
10370 if (fH->GetMaximumStored() != -1111) maximum = 1;
10371 if (fH->GetMinimumStored() != -1111) minimum = 1;
10372
10373 // ----------------- Compute X axis parameters
10374 first = fXaxis->GetFirst();
10375 last = fXaxis->GetLast();
10376 Hparam.xlast = last;
10382
10383 // if log scale in X, replace xmin,max by the log
10384 if (Hoption.Logx) {
10385 // find the first edge of a bin that is > 0
10386 if (Hparam.xlowedge <=0 ) {
10389 }
10390 if (Hparam.xmin <=0 || Hparam.xmax <=0) {
10391 Error(where, "cannot set X axis to log scale");
10392 return 0;
10393 }
10397 if (Hparam.xlast > last) Hparam.xlast = last;
10400 }
10401
10402 // ----------------- Compute Y axis parameters
10403 first = fYaxis->GetFirst();
10404 last = fYaxis->GetLast();
10405 Hparam.ylast = last;
10409 if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10412
10413 // if log scale in Y, replace ymin,max by the log
10414 if (Hoption.Logy) {
10415 if (Hparam.ylowedge <=0 ) {
10418 }
10419 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10420 Error(where, "cannot set Y axis to log scale");
10421 return 0;
10422 }
10426 if (Hparam.ylast > last) Hparam.ylast = last;
10429 }
10430
10431
10432 // ----------------- Compute Z axis parameters
10433 Double_t bigp = TMath::Power(10,32);
10434 zmax = -bigp;
10435 zmin = bigp;
10436 Double_t c1, e1;
10437 Double_t allchan = 0;
10438 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10439 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10440 c1 = fH->GetBinContent(i,j);
10441 zmax = TMath::Max(zmax,c1);
10442 if (Hoption.Error) {
10443 e1 = fH->GetBinError(i,j);
10444 zmax = TMath::Max(zmax,c1+e1);
10445 }
10446 zmin = TMath::Min(zmin,c1);
10447 allchan += c1;
10448 }
10449 }
10450
10451 // Take into account maximum , minimum
10452
10453 if (maximum) zmax = fH->GetMaximumStored();
10454 if (minimum) zmin = fH->GetMinimumStored();
10455 if (Hoption.Logz && zmax < 0) {
10456 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10457 return 0;
10458 } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10459 zmin = 0.01;
10460 zmax = 10.;
10461 }
10462 if (zmin >= zmax) {
10463 if (Hoption.Logz) {
10464 if (zmax > 0) zmin = 0.001*zmax;
10465 else {
10466 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10467 return 0;
10468 }
10469 }
10470 }
10471
10472 // take into account normalization factor
10473 Hparam.allchan = allchan;
10474 Double_t factor = allchan;
10475 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10476 if (allchan) factor /= allchan;
10477 if (factor == 0) factor = 1;
10478 Hparam.factor = factor;
10479 zmax = factor*zmax;
10480 zmin = factor*zmin;
10481 c1 = zmax;
10482 if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10483
10484 // For log scales, histogram coordinates are log10(ymin) and
10485 // log10(ymax). Final adjustment (if not option "Same")
10486 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10487 // Maximum and Minimum are not defined.
10488 if (Hoption.Logz) {
10489 if (zmin <= 0) {
10490 zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10491 fH->SetMinimum(zmin);
10492 }
10493 zmin = TMath::Log10(zmin);
10494 if (!minimum) zmin += TMath::Log10(0.5);
10495 zmax = TMath::Log10(zmax);
10496 if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10497 goto LZMIN;
10498 }
10499
10500 // final adjustment of YMAXI for linear scale (if not option "Same"):
10501 // decrease histogram height to MAX% of allowed height if HMAXIM
10502 // has not been called.
10503 // MAX% is the value in percent which has been set in HPLSET
10504 // (default is 90%).
10505 if (!maximum) {
10506 zmax += yMARGIN*(zmax-zmin);
10507 }
10508
10509 // final adjustment of ymin for linear scale.
10510 // if minimum is not set , then ymin is set to zero if >0
10511 // or to ymin - yMARGIN if <0.
10512 if (!minimum) {
10513 if (Hoption.MinimumZero) {
10514 if (zmin >= 0) zmin = 0;
10515 else zmin -= yMARGIN*(zmax-zmin);
10516 } else {
10517 Double_t dzmin = yMARGIN*(zmax-zmin);
10518 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10519 else zmin -= dzmin;
10520 }
10521 }
10522
10523LZMIN:
10524 Hparam.zmin = zmin;
10525 Hparam.zmax = zmax;
10526
10527 // Set bar offset and width
10530
10531 return 1;
10532}
10533
10534////////////////////////////////////////////////////////////////////////////////
10535/// This function returns the best format to print the error value (e)
10536/// knowing the parameter value (v) and the format (f) used to print it.
10537
10539{
10540
10541 static TString ef;
10542 TString tf, tv;
10543
10544 // print v with the format f in tv.
10545 tf.Form("%s%s","%",f);
10546 tv.Form(tf.Data(),v);
10547
10548 // Analyse tv.
10549 int ie = tv.Index("e");
10550 int iE = tv.Index("E");
10551 int id = tv.Index(".");
10552
10553 // v has been printed with the exponent notation.
10554 // There is 2 cases, the exponent is positive or negative
10555 if (ie >= 0 || iE >= 0) {
10556 if (tv.Index("+") >= 0) {
10557 if (e < 1) {
10558 ef.Form("%s.1f","%");
10559 } else {
10560 if (ie >= 0) {
10561 ef.Form("%s.%de","%",ie-id-1);
10562 } else {
10563 ef.Form("%s.%dE","%",iE-id-1);
10564 }
10565 }
10566 } else {
10567 if (ie >= 0) {
10568 ef.Form("%s.%de","%",ie-id-1);
10569 } else {
10570 ef.Form("%s.%dE","%",iE-id-1);
10571 }
10572 }
10573
10574 // There is not '.' in tv. e will be printed with one decimal digit.
10575 } else if (id < 0) {
10576 ef.Form("%s.1f","%");
10577
10578 // There is a '.' in tv and no exponent notation. e's decimal part will
10579 // have the same number of digits as v's one.
10580 } else {
10581 ef.Form("%s.%df","%",tv.Length()-id-1);
10582 }
10583
10584 return ef.Data();
10585}
10586
10587////////////////////////////////////////////////////////////////////////////////
10588/// Set projection.
10589
10590void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10591{
10592
10593 if (fShowProjection) return;
10594 TString opt = option;
10595 opt.ToLower();
10596 Int_t projection = 0;
10597 if (opt.Contains("x")) projection = 1;
10598 if (opt.Contains("y")) projection = 2;
10599 if (opt.Contains("z")) projection = 3;
10600 if (opt.Contains("xy")) projection = 4;
10601 if (opt.Contains("yx")) projection = 5;
10602 if (opt.Contains("xz")) projection = 6;
10603 if (opt.Contains("zx")) projection = 7;
10604 if (opt.Contains("yz")) projection = 8;
10605 if (opt.Contains("zy")) projection = 9;
10606 if (projection < 4) fShowOption = option+1;
10607 else fShowOption = option+2;
10608 fShowProjection = projection+100*nbins;
10609 gROOT->MakeDefCanvas();
10610 gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
10611 gPad->SetGrid();
10612}
10613
10614////////////////////////////////////////////////////////////////////////////////
10615/// Show projection onto X.
10616
10618{
10619
10620 Int_t nbins = (Int_t)fShowProjection/100;
10621 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10622 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10623
10624 // Erase old position and draw a line at current position
10625 static int pyold1 = 0;
10626 static int pyold2 = 0;
10627 float uxmin = gPad->GetUxmin();
10628 float uxmax = gPad->GetUxmax();
10629 int pxmin = gPad->XtoAbsPixel(uxmin);
10630 int pxmax = gPad->XtoAbsPixel(uxmax);
10631 Float_t upy = gPad->AbsPixeltoY(py);
10632 Float_t y = gPad->PadtoY(upy);
10633 Int_t biny1 = fH->GetYaxis()->FindBin(y);
10634 Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10635 Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10636 Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10637
10638 if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10639 gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10640 pyold1 = py1;
10641 pyold2 = py2;
10642
10643 // Create or set the new canvas proj x
10644 TVirtualPad *padsav = gPad;
10645 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10647 if (c) {
10648 c->Clear();
10649 } else {
10650 fShowProjection = 0;
10651 pyold1 = 0;
10652 pyold2 = 0;
10653 return;
10654 }
10655 c->cd();
10656 c->SetLogy(padsav->GetLogz());
10657 c->SetLogx(padsav->GetLogx());
10658
10659 // Draw slice corresponding to mouse position
10660 TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10661 TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10662 if (hp) {
10663 hp->SetFillColor(38);
10664 // apply a patch from Oliver Freyermuth to set the title in the projection
10665 // using the range of the projected Y values
10666 if (biny1 == biny2) {
10667 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10668 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10669 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10670 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10671 if (fH->GetYaxis()->GetLabels() != NULL) {
10672 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10673 } else {
10674 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10675 }
10676 } else {
10677 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10678 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10679 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10680 // biny1 is used here to get equal precision no matter how large the binrange is,
10681 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10682 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10683 if (fH->GetYaxis()->GetLabels() != NULL) {
10684 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)));
10685 } else {
10686 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10687 }
10688 }
10689 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10690 hp->SetYTitle("Number of Entries");
10691 hp->Draw();
10692 c->Update();
10693 padsav->cd();
10694 }
10695}
10696
10697////////////////////////////////////////////////////////////////////////////////
10698/// Show projection onto Y.
10699
10701{
10702
10703 Int_t nbins = (Int_t)fShowProjection/100;
10704 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10705 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10706
10707 // Erase old position and draw a line at current position
10708 static int pxold1 = 0;
10709 static int pxold2 = 0;
10710 float uymin = gPad->GetUymin();
10711 float uymax = gPad->GetUymax();
10712 int pymin = gPad->YtoAbsPixel(uymin);
10713 int pymax = gPad->YtoAbsPixel(uymax);
10714 Float_t upx = gPad->AbsPixeltoX(px);
10715 Float_t x = gPad->PadtoX(upx);
10716 Int_t binx1 = fH->GetXaxis()->FindBin(x);
10717 Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10718 Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10719 Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10720
10721 if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10722 gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10723 pxold1 = px1;
10724 pxold2 = px2;
10725
10726 // Create or set the new canvas proj y
10727 TVirtualPad *padsav = gPad;
10728 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10730 if (c) {
10731 c->Clear();
10732 } else {
10733 fShowProjection = 0;
10734 pxold1 = 0;
10735 pxold2 = 0;
10736 return;
10737 }
10738 c->cd();
10739 c->SetLogy(padsav->GetLogz());
10740 c->SetLogx(padsav->GetLogy());
10741
10742 // Draw slice corresponding to mouse position
10743 TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10744 TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10745 if (hp) {
10746 hp->SetFillColor(38);
10747 // apply a patch from Oliver Freyermuth to set the title in the projection
10748 // using the range of the projected X values
10749 if (binx1 == binx2) {
10750 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10751 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10752 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10753 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10754 if (fH->GetXaxis()->GetLabels() != NULL) {
10755 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10756 } else {
10757 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10758 }
10759 } else {
10760 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10761 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10762 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10763 // binx1 is used here to get equal precision no matter how large the binrange is,
10764 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10765 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10766 if (fH->GetXaxis()->GetLabels() != NULL) {
10767 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)));
10768 } else {
10769 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10770 }
10771 }
10772 hp->SetXTitle(fH->GetYaxis()->GetTitle());
10773 hp->SetYTitle("Number of Entries");
10774 hp->Draw();
10775 c->Update();
10776 padsav->cd();
10777 }
10778}
10779
10780////////////////////////////////////////////////////////////////////////////////
10781/// Show projection (specified by `fShowProjection`) of a `TH3`.
10782/// The drawing option for the projection is in `fShowOption`.
10783///
10784/// First implementation; R.Brun
10785///
10786/// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10787
10789{
10790
10791 Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10792 if (fH->GetDimension() < 3) {
10793 if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10794 if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10795 }
10796
10797 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10798 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10799
10800 // Erase old position and draw a line at current position
10801 TView *view = gPad->GetView();
10802 if (!view) return;
10803 TH3 *h3 = (TH3*)fH;
10804 TAxis *xaxis = h3->GetXaxis();
10805 TAxis *yaxis = h3->GetYaxis();
10806 TAxis *zaxis = h3->GetZaxis();
10807 Double_t u[3],xx[3];
10808
10809 static TPoint line1[2];//store end points of a line, initialised 0 by default
10810 static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10811 static TPoint line3[2];
10812 static TPoint line4[2];
10813 static TPoint endface1[5];
10814 static TPoint endface2[5];
10815 static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10816 static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10817
10818 Double_t uxmin = gPad->GetUxmin();
10819 Double_t uxmax = gPad->GetUxmax();
10820 Double_t uymin = gPad->GetUymin();
10821 Double_t uymax = gPad->GetUymax();
10822
10823 int pxmin = gPad->XtoAbsPixel(uxmin);
10824 int pxmax = gPad->XtoAbsPixel(uxmax);
10825 if (pxmin==pxmax) return;
10826 int pymin = gPad->YtoAbsPixel(uymin);
10827 int pymax = gPad->YtoAbsPixel(uymax);
10828 if (pymin==pymax) return;
10829 Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10830 Double_t cy = (pymax-pymin)/(uymax-uymin);
10831 TVirtualPad *padsav = gPad;
10832 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10834 if (!c) {
10835 fShowProjection = 0;
10836 return;
10837 }
10838
10839 switch ((Int_t)fShowProjection%100) {
10840 case 1:
10841 // "x"
10842 {
10843 Int_t firstY = yaxis->GetFirst();
10844 Int_t lastY = yaxis->GetLast();
10845 Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10846 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10847 yaxis->SetRange(biny,biny2);
10848 Int_t firstZ = zaxis->GetFirst();
10849 Int_t lastZ = zaxis->GetLast();
10850 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10851 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10852 zaxis->SetRange(binz,binz2);
10853 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10854 if (nbins>1 && line1[0].GetX()) {
10855 gVirtualX->DrawPolyLine(2,line2);
10856 gVirtualX->DrawPolyLine(2,line3);
10857 gVirtualX->DrawPolyLine(2,line4);
10858 gVirtualX->DrawPolyLine(5,endface1);
10859 gVirtualX->DrawPolyLine(5,endface2);
10860 }
10861 xx[0] = xaxis->GetXmin();
10862 xx[2] = zaxis->GetBinCenter(binz);
10863 xx[1] = yaxis->GetBinCenter(biny);
10864 view->WCtoNDC(xx,u);
10865 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10866 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10867 xx[0] = xaxis->GetXmax();
10868 view->WCtoNDC(xx,u);
10869 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10870 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10871 gVirtualX->DrawPolyLine(2,line1);
10872 if (nbins>1) {
10873 xx[0] = xaxis->GetXmin();
10874 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10875 xx[1] = yaxis->GetBinCenter(biny);
10876 view->WCtoNDC(xx,u);
10877 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10878 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10879 xx[0] = xaxis->GetXmax();
10880 view->WCtoNDC(xx,u);
10881 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10882 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10883
10884 xx[0] = xaxis->GetXmin();
10885 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10886 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10887 view->WCtoNDC(xx,u);
10888 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10889 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10890 xx[0] = xaxis->GetXmax();
10891 view->WCtoNDC(xx,u);
10892 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10893 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10894
10895 xx[0] = xaxis->GetXmin();
10896 xx[2] = zaxis->GetBinCenter(binz);
10897 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10898 view->WCtoNDC(xx,u);
10899 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10900 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10901 xx[0] = xaxis->GetXmax();
10902 view->WCtoNDC(xx,u);
10903 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10904 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10905
10906 endface1[0].SetX(line1[0].GetX());
10907 endface1[0].SetY(line1[0].GetY());
10908 endface1[1].SetX(line2[0].GetX());
10909 endface1[1].SetY(line2[0].GetY());
10910 endface1[2].SetX(line3[0].GetX());
10911 endface1[2].SetY(line3[0].GetY());
10912 endface1[3].SetX(line4[0].GetX());
10913 endface1[3].SetY(line4[0].GetY());
10914 endface1[4].SetX(line1[0].GetX());
10915 endface1[4].SetY(line1[0].GetY());
10916
10917 endface2[0].SetX(line1[1].GetX());
10918 endface2[0].SetY(line1[1].GetY());
10919 endface2[1].SetX(line2[1].GetX());
10920 endface2[1].SetY(line2[1].GetY());
10921 endface2[2].SetX(line3[1].GetX());
10922 endface2[2].SetY(line3[1].GetY());
10923 endface2[3].SetX(line4[1].GetX());
10924 endface2[3].SetY(line4[1].GetY());
10925 endface2[4].SetX(line1[1].GetX());
10926 endface2[4].SetY(line1[1].GetY());
10927
10928 gVirtualX->DrawPolyLine(2,line2);
10929 gVirtualX->DrawPolyLine(2,line3);
10930 gVirtualX->DrawPolyLine(2,line4);
10931 gVirtualX->DrawPolyLine(5,endface1);
10932 gVirtualX->DrawPolyLine(5,endface2);
10933 }
10934 c->Clear();
10935 c->cd();
10936 TH1 *hp = h3->Project3D("x");
10937 yaxis->SetRange(firstY,lastY);
10938 zaxis->SetRange(firstZ,lastZ);
10939 if (hp) {
10940 hp->SetFillColor(38);
10941 if (nbins == 1)
10942 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10943 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10944 else {
10945 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),
10946 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10947 }
10948 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10949 hp->SetYTitle("Number of Entries");
10950 hp->Draw(fShowOption.Data());
10951 }
10952 }
10953 break;
10954
10955 case 2:
10956 // "y"
10957 {
10958 Int_t firstX = xaxis->GetFirst();
10959 Int_t lastX = xaxis->GetLast();
10960 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10961 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10962 xaxis->SetRange(binx,binx2);
10963 Int_t firstZ = zaxis->GetFirst();
10964 Int_t lastZ = zaxis->GetLast();
10965 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10966 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10967 zaxis->SetRange(binz,binz2);
10968 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10969 if (nbins>1 && line1[0].GetX()) {
10970 gVirtualX->DrawPolyLine(2,line2);
10971 gVirtualX->DrawPolyLine(2,line3);
10972 gVirtualX->DrawPolyLine(2,line4);
10973 gVirtualX->DrawPolyLine(5,endface1);
10974 gVirtualX->DrawPolyLine(5,endface2);
10975 }
10976 xx[0]=xaxis->GetBinCenter(binx);
10977 xx[2] = zaxis->GetBinCenter(binz);
10978 xx[1] = yaxis->GetXmin();
10979 view->WCtoNDC(xx,u);
10980 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10981 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10982 xx[1] = yaxis->GetXmax();
10983 view->WCtoNDC(xx,u);
10984 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10985 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10986 gVirtualX->DrawPolyLine(2,line1);
10987 if (nbins>1) {
10988 xx[1] = yaxis->GetXmin();
10989 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10990 xx[0] = xaxis->GetBinCenter(binx);
10991 view->WCtoNDC(xx,u);
10992 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10993 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10994 xx[1] = yaxis->GetXmax();
10995 view->WCtoNDC(xx,u);
10996 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10997 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10998
10999 xx[1] = yaxis->GetXmin();
11000 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11001 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11002 view->WCtoNDC(xx,u);
11003 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11004 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11005 xx[1] = yaxis->GetXmax();
11006 view->WCtoNDC(xx,u);
11007 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11008 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11009
11010 xx[1] = yaxis->GetXmin();
11011 xx[2] = zaxis->GetBinCenter(binz);
11012 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11013 view->WCtoNDC(xx,u);
11014 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11015 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11016 xx[1] = yaxis->GetXmax();
11017 view->WCtoNDC(xx,u);
11018 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11019 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11020
11021 endface1[0].SetX(line1[0].GetX());
11022 endface1[0].SetY(line1[0].GetY());
11023 endface1[1].SetX(line2[0].GetX());
11024 endface1[1].SetY(line2[0].GetY());
11025 endface1[2].SetX(line3[0].GetX());
11026 endface1[2].SetY(line3[0].GetY());
11027 endface1[3].SetX(line4[0].GetX());
11028 endface1[3].SetY(line4[0].GetY());
11029 endface1[4].SetX(line1[0].GetX());
11030 endface1[4].SetY(line1[0].GetY());
11031
11032 endface2[0].SetX(line1[1].GetX());
11033 endface2[0].SetY(line1[1].GetY());
11034 endface2[1].SetX(line2[1].GetX());
11035 endface2[1].SetY(line2[1].GetY());
11036 endface2[2].SetX(line3[1].GetX());
11037 endface2[2].SetY(line3[1].GetY());
11038 endface2[3].SetX(line4[1].GetX());
11039 endface2[3].SetY(line4[1].GetY());
11040 endface2[4].SetX(line1[1].GetX());
11041 endface2[4].SetY(line1[1].GetY());
11042
11043 gVirtualX->DrawPolyLine(2,line2);
11044 gVirtualX->DrawPolyLine(2,line3);
11045 gVirtualX->DrawPolyLine(2,line4);
11046 gVirtualX->DrawPolyLine(5,endface1);
11047 gVirtualX->DrawPolyLine(5,endface2);
11048 }
11049 c->Clear();
11050 c->cd();
11051 TH1 *hp = h3->Project3D("y");
11052 xaxis->SetRange(firstX,lastX);
11053 zaxis->SetRange(firstZ,lastZ);
11054 if (hp) {
11055 hp->SetFillColor(38);
11056 if (nbins == 1)
11057 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11058 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
11059 else
11060 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),
11061 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
11062 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11063 hp->SetYTitle("Number of Entries");
11064 hp->Draw(fShowOption.Data());
11065 }
11066 }
11067 break;
11068
11069 case 3:
11070 // "z"
11071 {
11072 Int_t firstX = xaxis->GetFirst();
11073 Int_t lastX = xaxis->GetLast();
11074 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
11075 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11076 xaxis->SetRange(binx,binx2);
11077 Int_t firstY = yaxis->GetFirst();
11078 Int_t lastY = yaxis->GetLast();
11079 Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
11080 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11081 yaxis->SetRange(biny,biny2);
11082 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
11083 if (nbins>1 && line1[0].GetX()) {
11084 gVirtualX->DrawPolyLine(2,line2);
11085 gVirtualX->DrawPolyLine(2,line3);
11086 gVirtualX->DrawPolyLine(2,line4);
11087 gVirtualX->DrawPolyLine(5,endface1);
11088 gVirtualX->DrawPolyLine(5,endface2);
11089 }
11090 xx[0] = xaxis->GetBinCenter(binx);
11091 xx[1] = yaxis->GetBinCenter(biny);
11092 xx[2] = zaxis->GetXmin();
11093 view->WCtoNDC(xx,u);
11094 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11095 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11096 xx[2] = zaxis->GetXmax();
11097 view->WCtoNDC(xx,u);
11098 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11099 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11100 gVirtualX->DrawPolyLine(2,line1);
11101 if (nbins>1) {
11102 xx[2] = zaxis->GetXmin();
11103 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11104 xx[0] = xaxis->GetBinCenter(binx);
11105 view->WCtoNDC(xx,u);
11106 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11107 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11108 xx[2] = zaxis->GetXmax();
11109 view->WCtoNDC(xx,u);
11110 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11111 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11112
11113 xx[2] = zaxis->GetXmin();
11114 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11115 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11116 view->WCtoNDC(xx,u);
11117 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11118 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11119 xx[2] = zaxis->GetXmax();
11120 view->WCtoNDC(xx,u);
11121 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11122 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11123
11124 xx[2] = zaxis->GetXmin();
11125 xx[1] = yaxis->GetBinCenter(biny);
11126 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11127 view->WCtoNDC(xx,u);
11128 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11129 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11130 xx[2] = zaxis->GetXmax();
11131 view->WCtoNDC(xx,u);
11132 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11133 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11134
11135 endface1[0].SetX(line1[0].GetX());
11136 endface1[0].SetY(line1[0].GetY());
11137 endface1[1].SetX(line2[0].GetX());
11138 endface1[1].SetY(line2[0].GetY());
11139 endface1[2].SetX(line3[0].GetX());
11140 endface1[2].SetY(line3[0].GetY());
11141 endface1[3].SetX(line4[0].GetX());
11142 endface1[3].SetY(line4[0].GetY());
11143 endface1[4].SetX(line1[0].GetX());
11144 endface1[4].SetY(line1[0].GetY());
11145
11146 endface2[0].SetX(line1[1].GetX());
11147 endface2[0].SetY(line1[1].GetY());
11148 endface2[1].SetX(line2[1].GetX());
11149 endface2[1].SetY(line2[1].GetY());
11150 endface2[2].SetX(line3[1].GetX());
11151 endface2[2].SetY(line3[1].GetY());
11152 endface2[3].SetX(line4[1].GetX());
11153 endface2[3].SetY(line4[1].GetY());
11154 endface2[4].SetX(line1[1].GetX());
11155 endface2[4].SetY(line1[1].GetY());
11156
11157 gVirtualX->DrawPolyLine(2,line2);
11158 gVirtualX->DrawPolyLine(2,line3);
11159 gVirtualX->DrawPolyLine(2,line4);
11160 gVirtualX->DrawPolyLine(5,endface1);
11161 gVirtualX->DrawPolyLine(5,endface2);
11162 }
11163 c->Clear();
11164 c->cd();
11165 TH1 *hp = h3->Project3D("z");
11166 xaxis->SetRange(firstX,lastX);
11167 yaxis->SetRange(firstY,lastY);
11168 if (hp) {
11169 hp->SetFillColor(38);
11170 if (nbins == 1)
11171 hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11172 biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
11173 else
11174 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),
11175 biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
11176 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11177 hp->SetYTitle("Number of Entries");
11178 hp->Draw(fShowOption.Data());
11179 }
11180 }
11181 break;
11182
11183 case 4:
11184 // "xy"
11185 {
11186 Int_t first = zaxis->GetFirst();
11187 Int_t last = zaxis->GetLast();
11188 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11189 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11190 zaxis->SetRange(binz,binz2);
11191 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11192 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11193 xx[0] = xaxis->GetXmin();
11194 xx[1] = yaxis->GetXmax();
11195 xx[2] = zaxis->GetBinCenter(binz);
11196 view->WCtoNDC(xx,u);
11197 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11198 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11199 rect1[4].SetX(rect1[0].GetX());
11200 rect1[4].SetY(rect1[0].GetY());
11201 xx[0] = xaxis->GetXmax();
11202 view->WCtoNDC(xx,u);
11203 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11204 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11205 xx[1] = yaxis->GetXmin();
11206 view->WCtoNDC(xx,u);
11207 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11208 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11209 xx[0] = xaxis->GetXmin();
11210 view->WCtoNDC(xx,u);
11211 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11212 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11213 gVirtualX->DrawPolyLine(5,rect1);
11214 if (nbins>1) {
11215 xx[0] = xaxis->GetXmin();
11216 xx[1] = yaxis->GetXmax();
11217 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11218 view->WCtoNDC(xx,u);
11219 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11220 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11221 rect2[4].SetX(rect2[0].GetX());
11222 rect2[4].SetY(rect2[0].GetY());
11223 xx[0] = xaxis->GetXmax();
11224 view->WCtoNDC(xx,u);
11225 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11226 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11227 xx[1] = yaxis->GetXmin();
11228 view->WCtoNDC(xx,u);
11229 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11230 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11231 xx[0] = xaxis->GetXmin();
11232 view->WCtoNDC(xx,u);
11233 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11234 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11235 gVirtualX->DrawPolyLine(5,rect2);
11236 }
11237
11238 c->Clear();
11239 c->cd();
11240 TH2 *hp = (TH2*)h3->Project3D("xy");
11241 zaxis->SetRange(first,last);
11242 if (hp) {
11243 hp->SetFillColor(38);
11244 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11245 else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11246 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11247 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11248 hp->SetZTitle("Number of Entries");
11249 hp->Draw(fShowOption.Data());
11250 }
11251 }
11252 break;
11253
11254 case 5:
11255 // "yx"
11256 {
11257 Int_t first = zaxis->GetFirst();
11258 Int_t last = zaxis->GetLast();
11259 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11260 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11261 zaxis->SetRange(binz,binz2);
11262 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11263 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11264 xx[0] = xaxis->GetXmin();
11265 xx[1] = yaxis->GetXmax();
11266 xx[2] = zaxis->GetBinCenter(binz);
11267 view->WCtoNDC(xx,u);
11268 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11269 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11270 rect1[4].SetX(rect1[0].GetX());
11271 rect1[4].SetY(rect1[0].GetY());
11272 xx[0] = xaxis->GetXmax();
11273 view->WCtoNDC(xx,u);
11274 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11275 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11276 xx[1] = yaxis->GetXmin();
11277 view->WCtoNDC(xx,u);
11278 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11279 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11280 xx[0] = xaxis->GetXmin();
11281 view->WCtoNDC(xx,u);
11282 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11283 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11284 gVirtualX->DrawPolyLine(5,rect1);
11285 if (nbins>1) {
11286 xx[0] = xaxis->GetXmin();
11287 xx[1] = yaxis->GetXmax();
11288 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11289 view->WCtoNDC(xx,u);
11290 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11291 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11292 rect2[4].SetX(rect2[0].GetX());
11293 rect2[4].SetY(rect2[0].GetY());
11294 xx[0] = xaxis->GetXmax();
11295 view->WCtoNDC(xx,u);
11296 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11297 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11298 xx[1] = yaxis->GetXmin();
11299 view->WCtoNDC(xx,u);
11300 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11301 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11302 xx[0] = xaxis->GetXmin();
11303 view->WCtoNDC(xx,u);
11304 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11305 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11306 gVirtualX->DrawPolyLine(5,rect2);
11307 }
11308 c->Clear();
11309 c->cd();
11310 TH2 *hp = (TH2*)h3->Project3D("yx");
11311 zaxis->SetRange(first,last);
11312 if (hp) {
11313 hp->SetFillColor(38);
11314 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11315 else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11316 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11317 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11318 hp->SetZTitle("Number of Entries");
11319 hp->Draw(fShowOption.Data());
11320 }
11321 }
11322 break;
11323
11324 case 6:
11325 // "xz"
11326 {
11327 Int_t first = yaxis->GetFirst();
11328 Int_t last = yaxis->GetLast();
11329 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11330 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11331 yaxis->SetRange(biny,biny2);
11332 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11333 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11334 xx[0] = xaxis->GetXmin();
11335 xx[2] = zaxis->GetXmax();
11336 xx[1] = yaxis->GetBinCenter(biny);
11337 view->WCtoNDC(xx,u);
11338 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11339 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11340 rect1[4].SetX(rect1[0].GetX());
11341 rect1[4].SetY(rect1[0].GetY());
11342 xx[0] = xaxis->GetXmax();
11343 view->WCtoNDC(xx,u);
11344 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11345 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11346 xx[2] = zaxis->GetXmin();
11347 view->WCtoNDC(xx,u);
11348 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11349 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11350 xx[0] = xaxis->GetXmin();
11351 view->WCtoNDC(xx,u);
11352 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11353 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11354 gVirtualX->DrawPolyLine(5,rect1);
11355 if (nbins>1) {
11356 xx[0] = xaxis->GetXmin();
11357 xx[2] = zaxis->GetXmax();
11358 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11359 view->WCtoNDC(xx,u);
11360 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11361 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11362 rect2[4].SetX(rect2[0].GetX());
11363 rect2[4].SetY(rect2[0].GetY());
11364 xx[0] = xaxis->GetXmax();
11365 view->WCtoNDC(xx,u);
11366 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11367 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11368 xx[2] = zaxis->GetXmin();
11369 view->WCtoNDC(xx,u);
11370 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11371 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11372 xx[0] = xaxis->GetXmin();
11373 view->WCtoNDC(xx,u);
11374 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11375 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11376 gVirtualX->DrawPolyLine(5,rect2);
11377 }
11378 c->Clear();
11379 c->cd();
11380 TH2 *hp = (TH2*)h3->Project3D("xz");
11381 yaxis->SetRange(first,last);
11382 if (hp) {
11383 hp->SetFillColor(38);
11384 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11385 else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11386 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11387 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11388 hp->SetZTitle("Number of Entries");
11389 hp->Draw(fShowOption.Data());
11390 }
11391 }
11392 break;
11393
11394 case 7:
11395 // "zx"
11396 {
11397 Int_t first = yaxis->GetFirst();
11398 Int_t last = yaxis->GetLast();
11399 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11400 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11401 yaxis->SetRange(biny,biny2);
11402 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11403 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11404 xx[0] = xaxis->GetXmin();
11405 xx[2] = zaxis->GetXmax();
11406 xx[1] = yaxis->GetBinCenter(biny);
11407 view->WCtoNDC(xx,u);
11408 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11409 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11410 rect1[4].SetX(rect1[0].GetX());
11411 rect1[4].SetY(rect1[0].GetY());
11412 xx[0] = xaxis->GetXmax();
11413 view->WCtoNDC(xx,u);
11414 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11415 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11416 xx[2] = zaxis->GetXmin();
11417 view->WCtoNDC(xx,u);
11418 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11419 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11420 xx[0] = xaxis->GetXmin();
11421 view->WCtoNDC(xx,u);
11422 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11423 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11424 gVirtualX->DrawPolyLine(5,rect1);
11425 if (nbins>1) {
11426 xx[0] = xaxis->GetXmin();
11427 xx[2] = zaxis->GetXmax();
11428 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11429 view->WCtoNDC(xx,u);
11430 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11431 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11432 rect2[4].SetX(rect2[0].GetX());
11433 rect2[4].SetY(rect2[0].GetY());
11434 xx[0] = xaxis->GetXmax();
11435 view->WCtoNDC(xx,u);
11436 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11437 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11438 xx[2] = zaxis->GetXmin();
11439 view->WCtoNDC(xx,u);
11440 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11441 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11442 xx[0] = xaxis->GetXmin();
11443 view->WCtoNDC(xx,u);
11444 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11445 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11446 gVirtualX->DrawPolyLine(5,rect2);
11447 }
11448 c->Clear();
11449 c->cd();
11450 TH2 *hp = (TH2*)h3->Project3D("zx");
11451 yaxis->SetRange(first,last);
11452 if (hp) {
11453 hp->SetFillColor(38);
11454 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11455 else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11456 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11457 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11458 hp->SetZTitle("Number of Entries");
11459 hp->Draw(fShowOption.Data());
11460 }
11461 }
11462 break;
11463
11464 case 8:
11465 // "yz"
11466 {
11467 Int_t first = xaxis->GetFirst();
11468 Int_t last = xaxis->GetLast();
11469 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11470 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11471 xaxis->SetRange(binx,binx2);
11472 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11473 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11474 xx[2] = zaxis->GetXmin();
11475 xx[1] = yaxis->GetXmax();
11476 xx[0] = xaxis->GetBinCenter(binx);
11477 view->WCtoNDC(xx,u);
11478 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11479 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11480 rect1[4].SetX(rect1[0].GetX());
11481 rect1[4].SetY(rect1[0].GetY());
11482 xx[2] = zaxis->GetXmax();
11483 view->WCtoNDC(xx,u);
11484 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11485 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11486 xx[1] = yaxis->GetXmin();
11487 view->WCtoNDC(xx,u);
11488 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11489 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11490 xx[2] = zaxis->GetXmin();
11491 view->WCtoNDC(xx,u);
11492 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11493 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11494 gVirtualX->DrawPolyLine(5,rect1);
11495 if (nbins>1) {
11496 xx[2] = zaxis->GetXmin();
11497 xx[1] = yaxis->GetXmax();
11498 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11499 view->WCtoNDC(xx,u);
11500 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11501 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11502 rect2[4].SetX(rect2[0].GetX());
11503 rect2[4].SetY(rect2[0].GetY());
11504 xx[2] = zaxis->GetXmax();
11505 view->WCtoNDC(xx,u);
11506 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11507 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11508 xx[1] = yaxis->GetXmin();
11509 view->WCtoNDC(xx,u);
11510 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11511 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11512 xx[2] = zaxis->GetXmin();
11513 view->WCtoNDC(xx,u);
11514 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11515 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11516 gVirtualX->DrawPolyLine(5,rect2);
11517 }
11518 c->Clear();
11519 c->cd();
11520 TH2 *hp = (TH2*)h3->Project3D("yz");
11521 xaxis->SetRange(first,last);
11522 if (hp) {
11523 hp->SetFillColor(38);
11524 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11525 else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11526 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11527 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11528 hp->SetZTitle("Number of Entries");
11529 hp->Draw(fShowOption.Data());
11530 }
11531 }
11532 break;
11533
11534 case 9:
11535 // "zy"
11536 {
11537 Int_t first = xaxis->GetFirst();
11538 Int_t last = xaxis->GetLast();
11539 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11540 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11541 xaxis->SetRange(binx,binx2);
11542 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11543 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11544 xx[2] = zaxis->GetXmin();
11545 xx[1] = yaxis->GetXmax();
11546 xx[0] = xaxis->GetBinCenter(binx);
11547 view->WCtoNDC(xx,u);
11548 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11549 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11550 rect1[4].SetX(rect1[0].GetX());
11551 rect1[4].SetY(rect1[0].GetY());
11552 xx[2] = zaxis->GetXmax();
11553 view->WCtoNDC(xx,u);
11554 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11555 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11556 xx[1] = yaxis->GetXmin();
11557 view->WCtoNDC(xx,u);
11558 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11559 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11560 xx[2] = zaxis->GetXmin();
11561 view->WCtoNDC(xx,u);
11562 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11563 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11564 gVirtualX->DrawPolyLine(5,rect1);
11565 if (nbins>1) {
11566 xx[2] = zaxis->GetXmin();
11567 xx[1] = yaxis->GetXmax();
11568 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11569 view->WCtoNDC(xx,u);
11570 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11571 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11572 rect2[4].SetX(rect2[0].GetX());
11573 rect2[4].SetY(rect2[0].GetY());
11574 xx[2] = zaxis->GetXmax();
11575 view->WCtoNDC(xx,u);
11576 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11577 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11578 xx[1] = yaxis->GetXmin();
11579 view->WCtoNDC(xx,u);
11580 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11581 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11582 xx[2] = zaxis->GetXmin();
11583 view->WCtoNDC(xx,u);
11584 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11585 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11586 gVirtualX->DrawPolyLine(5,rect2);
11587 }
11588 c->Clear();
11589 c->cd();
11590 TH2 *hp = (TH2*)h3->Project3D("zy");
11591 xaxis->SetRange(first,last);
11592 if (hp) {
11593 hp->SetFillColor(38);
11594 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11595 else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11596 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11597 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11598 hp->SetZTitle("Number of Entries");
11599 hp->Draw(fShowOption.Data());
11600 }
11601 }
11602 break;
11603 }
11604 c->Update();
11605 padsav->cd();
11606}
@ 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
SVector< double, 2 > v
Definition: Dict.h:5
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:414
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
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:44
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:42
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:190
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:657
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:2273
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:2895
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:6309
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:7104
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:8476
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:7050
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7155
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7862
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:1225
@ 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:4784
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:7964
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:8492
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7905
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:7413
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:8635
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8565
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4277
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:7081
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2981
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:8145
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:7994
@ 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:4882
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:8576
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8523
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:7142
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:8049
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7389
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:705
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7833
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1346
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7225
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:289
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:248
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:2297
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:2257
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH2.cxx:1142
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH2.h:82
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:2146
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 const char * GetFitFormat() const
Definition: TPaveStats.h:35
void SetParent(TObject *obj)
Definition: TPaveStats.h:52
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:232
Color_t GetStatTextColor() const
Definition: TStyle.h:245
Float_t GetTitleX() const
Definition: TStyle.h:267
Int_t GetOptTitle() const
Definition: TStyle.h:233
Float_t GetStatFontSize() const
Definition: TStyle.h:248
Float_t GetBarOffset() const
Definition: TStyle.h:170
Float_t GetStatX() const
Definition: TStyle.h:251
Float_t GetTitleSize(Option_t *axis="X") const
Return title size.
Definition: TStyle.cxx:1045
Float_t GetTitleY() const
Definition: TStyle.h:268
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:1021
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:224
Float_t GetStatY() const
Definition: TStyle.h:252
Color_t GetTitleFillColor() const
Definition: TStyle.h:258
Style_t GetTitleStyle() const
Definition: TStyle.h:260
Color_t GetStatColor() const
Definition: TStyle.h:244
Float_t GetBarWidth() const
Definition: TStyle.h:171
Float_t GetStatH() const
Definition: TStyle.h:254
Width_t GetTitleBorderSize() const
Definition: TStyle.h:262
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:913
Float_t GetErrorX() const
Definition: TStyle.h:174
Double_t GetHistTopMargin() const
Definition: TStyle.h:225
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:313
Float_t GetEndErrorSize() const
Definition: TStyle.h:173
Width_t GetStatBorderSize() const
Definition: TStyle.h:246
Int_t GetTitleAlign()
Definition: TStyle.h:257
Color_t GetTitleTextColor() const
Definition: TStyle.h:259
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:314
Float_t GetTitleH() const
Definition: TStyle.h:270
Style_t GetStatStyle() const
Definition: TStyle.h:249
Float_t GetStatW() const
Definition: TStyle.h:253
const char * GetFitFormat() const
Definition: TStyle.h:187
const char * GetStatFormat() const
Definition: TStyle.h:250
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:979
Int_t GetOptFit() const
Definition: TStyle.h:231
Int_t GetNumberContours() const
Definition: TStyle.h:228
const char * GetPaintTextFormat() const
Definition: TStyle.h:237
Style_t GetStatFont() const
Definition: TStyle.h:247
Float_t GetTitleFontSize() const
Definition: TStyle.h:261
Float_t GetTitleW() const
Definition: TStyle.h:269
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1843
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:701
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:663
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:748
constexpr Double_t DegToRad()
Conversion from degree to radian:
Definition: TMath.h:82
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:723
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
Double_t Cos(Double_t)
Definition: TMath.h:629
constexpr Double_t Pi()
Definition: TMath.h:38
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:416
Double_t Sin(Double_t)
Definition: TMath.h:625
Double_t Tan(Double_t)
Definition: TMath.h:633
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:752
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