Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
THistPainter.cxx
Go to the documentation of this file.
1// @(#)root/histpainter:$Id$
2// Author: Rene Brun, Olivier Couet
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <cstdlib>
13#include <cstring>
14#include <cstdio>
15#include <cctype>
16#include <iostream>
17
18#include "TROOT.h"
19#include "TSystem.h"
20#include "THistPainter.h"
21#include "TH2.h"
22#include "TH2Poly.h"
23#include "TH3.h"
24#include "TProfile.h"
25#include "TProfile2D.h"
26#include "THStack.h"
27#include "TF2.h"
28#include "TF3.h"
29#include "TCutG.h"
30#include "TMatrixDBase.h"
31#include "TMatrixFBase.h"
32#include "TVectorD.h"
33#include "TVectorF.h"
34#include "TCanvas.h"
35#include "TPad.h"
36#include "TPaveStats.h"
37#include "TFrame.h"
38#include "TLatex.h"
39#include "TPolyLine.h"
40#include "TPoints.h"
41#include "TStyle.h"
42#include "TGraph.h"
43#include "TMultiGraph.h"
44#include "TPie.h"
45#include "TGaxis.h"
46#include "TColor.h"
48#include "TGraph2DPainter.h"
49#include "TGraphDelaunay2D.h"
50#include "TView.h"
51#include "TMath.h"
52#include "TRandom2.h"
53#include "TObjArray.h"
54#include "Hoption.h"
55#include "Hparam.h"
56#include "TPluginManager.h"
57#include "TPaletteAxis.h"
58#include "TCrown.h"
59#include "TArrow.h"
60#include "TVirtualPadEditor.h"
61#include "TVirtualX.h"
62#include "TEnv.h"
63#include "TPoint.h"
64#include "TImage.h"
65#include "TCandle.h"
66#include "strlcpy.h"
67
68/*! \class THistPainter
69 \ingroup Histpainter
70 \brief The histogram painter class. Implements all histograms' drawing's options.
71
72- [Introduction](\ref HP00)
73- [Histograms' plotting options](\ref HP01)
74 - [Options supported for 1D and 2D histograms](\ref HP01a)
75 - [Options supported for 1D histograms](\ref HP01b)
76 - [Options supported for 2D histograms](\ref HP01c)
77 - [Options supported for 3D histograms](\ref HP01d)
78 - [Options supported for histograms' stacks (THStack)](\ref HP01e)
79- [Setting the Style](\ref HP02)
80- [Setting line, fill, marker, and text attributes](\ref HP03)
81- [Setting Tick marks on the histogram axis](\ref HP04)
82- [Giving titles to the X, Y and Z axis](\ref HP05)
83- [The option \"SAME\"](\ref HP060)
84 - [Limitations](\ref HP060a)
85- [Colors automatically picked in palette](\ref HP061)
86- [Superimposing two histograms with different scales in the same pad](\ref HP06)
87- [Statistics Display](\ref HP07)
88- [Fit Statistics](\ref HP08)
89- [The error bars options](\ref HP09)
90- [The bar chart option](\ref HP100)
91- [The \"BAR\" and \"HBAR\" options](\ref HP10)
92- [The SCATter plot option (default for 2D histograms)](\ref HP11)
93- [The ARRow option](\ref HP12)
94- [The BOX option](\ref HP13)
95- [The COLor option](\ref HP14)
96- [The CANDLE and VIOLIN options](\ref HP140)
97 - [The CANDLE option](\ref HP140a)
98 - [The VIOLIN option](\ref HP140b)
99- [The TEXT and TEXTnn Option](\ref HP15)
100- [The CONTour options](\ref HP16)
101 - [The LIST option](\ref HP16a)
102 - [The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options](\ref HP16b)
103- [The LEGO options](\ref HP17)
104- [The \"SURFace\" options](\ref HP18)
105- [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](\ref HP19)
106- [Base line for bar-charts and lego plots](\ref HP20)
107- [TH2Poly Drawing](\ref HP20a)
108- [The SPEC option](\ref HP21)
109- [Option \"Z\" : Adding the color palette on the right side of the pad](\ref HP22)
110- [Setting the color palette](\ref HP23)
111- [Drawing a sub-range of a 2-D histogram; the [cutg] option](\ref HP24)
112- [Drawing options for 3D histograms](\ref HP25)
113- [Drawing option for histograms' stacks](\ref HP26)
114- [Drawing of 3D implicit functions](\ref HP27)
115- [Associated functions drawing](\ref HP28)
116- [Drawing using OpenGL](\ref HP29)
117 - [General information: plot types and supported options](\ref HP29a)
118 - [TH3 as color boxes](\ref HP290)
119 - [TH3 as boxes (spheres)](\ref HP29b)
120 - [TH3 as iso-surface(s)](\ref HP29c)
121 - [TF3 (implicit function)](\ref HP29d)
122 - [Parametric surfaces](\ref HP29e)
123 - [Interaction with the plots](\ref HP29f)
124 - [Selectable parts](\ref HP29g)
125 - [Rotation and zooming](\ref HP29h)
126 - [Panning](\ref HP29i)
127 - [Box cut](\ref HP29j)
128 - [Plot specific interactions (dynamic slicing etc.)](\ref HP29k)
129 - [Surface with option \"GLSURF\"](\ref HP29l)
130 - [TF3](\ref HP29m)
131 - [Box](\ref HP29n)
132 - [Iso](\ref HP29o)
133 - [Parametric plot](\ref HP29p)
134- [Highlight mode for histogram](\ref HP30)
135 - [Highlight mode and user function](\ref HP30a)
136
137
138\anchor HP00
139## Introduction
140
141
142Histograms are drawn via the `THistPainter` class. Each histogram has a
143pointer to its own painter (to be usable in a multithreaded program). When the
144canvas has to be redrawn, the `Paint` function of each objects in the
145pad is called. In case of histograms, `TH1::Paint` invokes directly
146`THistPainter::Paint`.
147
148To draw a histogram `h` it is enough to do:
149
150 h->Draw();
151
152`h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
153be drawn, the `Draw()` method can be invoked with an option. For instance
154to draw a 2D histogram as a lego plot it is enough to do:
155
156 h->Draw("lego");
157
158`THistPainter` offers many options to paint 1D, 2D and 3D histograms.
159
160When the `Draw()` method of a histogram is called for the first time
161(`TH1::Draw`), it creates a `THistPainter` object and saves a
162pointer to this "painter" as a data member of the histogram. The
163`THistPainter` class specializes in the drawing of histograms. It is
164separated from the histogram so that one can have histograms without the
165graphics overhead, for example in a batch program. Each histogram having its own
166painter (rather than a central singleton painter painting all histograms), allows
167two histograms to be drawn in two threads without overwriting the painter's
168values.
169
170When a displayed histogram is filled again, there is no need to call the
171`Draw()` method again; the image will be refreshed the next time the
172pad will be updated.
173
174A pad is updated after one of these three actions:
175
1761. a carriage control on the ROOT command line,
1772. a click inside the pad,
1783. a call to `TPad::Update`.
179
180
181By default a call to `TH1::Draw()` clears the pad of all objects
182before drawing the new image of the histogram. One can use the `SAME`
183option to leave the previous display intact and superimpose the new histogram.
184The same histogram can be drawn with different graphics options in different
185pads.
186
187When a displayed histogram is deleted, its image is automatically removed
188from the pad.
189
190To create a copy of the histogram when drawing it, one can use
191`TH1::DrawClone()`. This will clone the histogram and allow to change
192and delete the original one without affecting the clone.
193
194
195\anchor HP01
196### Histograms' plotting options
197
198
199Most options can be concatenated with or without spaces or commas, for example:
200
201 h->Draw("E1 SAME");
202
203The options are not case sensitive:
204
205 h->Draw("e1 same");
206
207
208The default drawing option can be set with `TH1::SetOption` and retrieve
209using `TH1::GetOption`:
210
211 root [0] h->Draw(); // Draw "h" using the standard histogram representation.
212 root [1] h->Draw("E"); // Draw "h" using error bars
213 root [3] h->SetOption("E"); // Change the default drawing option for "h"
214 root [4] h->Draw(); // Draw "h" using error bars
215 root [5] h->GetOption(); // Retrieve the default drawing option for "h"
216 (const Option_t* 0xa3ff948)"E"
217
218
219\anchor HP01a
220#### Options supported for 1D and 2D histograms
221
222| Option | Description |
223|----------|-------------------------------------------------------------------|
224| "E" | Draw error bars. |
225| "AXIS" | Draw only axis. |
226| "AXIG" | Draw only grid (if the grid is requested). |
227| \anchor OPTHIST "HIST" | When an histogram has errors it is visualized by default with error bars. To visualize it without errors use the option "HIST" together with the required option (eg "hist same c"). The "HIST" option can also be used to plot only the histogram and not the associated function(s). |
228| "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
229| "SAME" | Superimpose on previous picture in the same pad. |
230| "SAMES" | Same as "SAME" and draw the statistics box|
231| "PFC" | Palette Fill Color: histogram's fill color is taken in the current palette. |
232| "PLC" | Palette Line Color: histogram's line color is taken in the current palette. |
233| "PMC" | Palette Marker Color: histogram's marker color is taken in the current palette. |
234| "LEGO" | Draw a lego plot with hidden line removal. |
235| "LEGO1" | Draw a lego plot with hidden surface removal. |
236| "LEGO2" | Draw a lego plot using colors to show the cell contents When the option "0" is used with any LEGO option, the empty bins are not drawn.|
237| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
238| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
239| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
240| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
241| "X+" | The X-axis is drawn on the top side of the plot. |
242| "Y+" | The Y-axis is drawn on the right side of the plot. |
243| "MIN0" | Set minimum value for the Y axis to 0, equivalent to gStyle->SetHistMinimumZero(). |
244
245\anchor HP01b
246#### Options supported for 1D histograms
247
248| Option | Description |
249|----------|-------------------------------------------------------------------|
250| " " | Default. |
251| "AH" | Draw histogram without axis. "A" can be combined with any drawing option. For instance, "AC" draws the histogram as a smooth Curve without axis.|
252| "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
253| "B" | Bar chart option.|
254| "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
255| "HBAR" | Like option "BAR", but bars are drawn horizontally.|
256| "C" | Draw a smooth Curve through the histogram bins.|
257| "E0" | Draw error bars. Markers are drawn for bins with 0 contents. Combined with E1 or E2 it avoids error bars clipping|
258| "E1" | Draw error bars with perpendicular lines at the edges.|
259| "E2" | Draw error bars with rectangles.|
260| "E3" | Draw a fill area through the end points of the vertical error bars.|
261| "E4" | Draw a smoothed filled area through the end points of the error bars.|
262| "E5" | Like E3 but ignore the bins with 0 contents.|
263| "E6" | Like E4 but ignore the bins with 0 contents.|
264| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
265| "L" | Draw a line through the bin contents.|
266| "P" | Draw current marker at each bin except empty bins.|
267| "P*" | Draw a star marker at each bin except empty bins.|
268| "P0" | Draw current marker at each bin including empty bins.|
269| "PIE" | Draw histogram as a Pie Chart.|
270| "*H" | Draw histogram with a * at each bin.|
271| "LF2" | Draw histogram like with option "L" but with a fill area. Note that "L" draws also a fill area if the hist fill color is set but the fill area corresponds to the histogram contour.|
272
273
274\anchor HP01c
275#### Options supported for 2D histograms
276
277| Option | Description |
278|--------------|------------------------------------------------------------------|
279| " " | Default (scatter plot).|
280| "ARR" | Arrow mode. Shows gradient between adjacent cells.|
281| "BOX" | A box is drawn for each cell with surface proportional to the content's absolute value. A negative content is marked with a X.|
282| "BOX1" | A button is drawn for each cell with surface proportional to content's absolute value. A sunken button is drawn for negative values a raised one for positive.|
283| "COL" | A box is drawn for each cell with a color scale varying with contents. All the none empty bins are painted. Empty bins are not painted unless some bins have a negative content because in that case the null bins might be not empty. `TProfile2D` histograms are handled differently because, for this type of 2D histograms, it is possible to know if an empty bin has been filled or not. So even if all the bins' contents are positive some empty bins might be painted. And vice versa, if some bins have a negative content some empty bins might be not painted.|
284| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
285| "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
286| "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
287| "Z CJUST" | In combination with colored options "COL","CONT0" etc: Justify labels in the color palette at color boudaries. For more details see `TPaletteAxis`|
288| "CANDLE" | Draw a candle plot along X axis.|
289| "CANDLEX" | Same as "CANDLE".|
290| "CANDLEY" | Draw a candle plot along Y axis.|
291| "CANDLEXn" | Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
292| "CANDLEYn" | Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
293| "VIOLIN" | Draw a violin plot along X axis.|
294| "VIOLINX" | Same as "VIOLIN".|
295| "VIOLINY" | Draw a violin plot along Y axis.|
296| "VIOLINXn" | Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
297| "VIOLINYn" | Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
298| "CONT" | Draw a contour plot (same as CONT0).|
299| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
300| "CONT1" | Draw a contour plot using line styles to distinguish contours.|
301| "CONT2" | Draw a contour plot using the same line style for all contours.|
302| "CONT3" | Draw a contour plot using fill area colors.|
303| "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
304| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
305| "LIST" | Generate a list of TGraph objects for each contour.|
306| "SAME0" | Same as "SAME" but do not use the z-axis range of the first plot. |
307| "SAMES0" | Same as "SAMES" but do not use the z-axis range of the first plot. |
308| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
309| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
310| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
311| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
312| "SURF" | Draw a surface plot with hidden line removal.|
313| "SURF1" | Draw a surface plot with hidden surface removal.|
314| "SURF2" | Draw a surface plot using colors to show the cell contents.|
315| "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
316| "SURF4" | Draw a surface using Gouraud shading.|
317| "SURF5" | Same as SURF3 but only the colored contour is drawn. Used with option CYL, SPH or PSR it allows to draw colored contours on a sphere, a cylinder or a in pseudo rapidity space. In cartesian or polar coordinates, option SURF3 is used.|
318| "AITOFF" | Draw a contour via an AITOFF projection.|
319| "MERCATOR" | Draw a contour via an Mercator projection.|
320| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
321| "PARABOLIC" | Draw a contour via an Parabolic projection.|
322| "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
323| "FB" | With LEGO or SURFACE, suppress the Front-Box.|
324| "BB" | With LEGO or SURFACE, suppress the Back-Box.|
325| "A" | With LEGO or SURFACE, suppress the axis.|
326| "SCAT" | Draw a scatter-plot (default).|
327| "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
328
329
330\anchor HP01d
331#### Options supported for 3D histograms
332
333| Option | Description |
334|----------|-------------------------------------------------------------------|
335| " " | Default (scatter plot).|
336| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`.|
337| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
338| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
339| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
340| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
341| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
342| "LEGO" | Same as `BOX`.|
343
344
345\anchor HP01e
346#### Options supported for histograms' stacks (`THStack`)
347
348| Option | Description |
349|------------|-----------------------------------------------------------------|
350| " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
351| "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
352| "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
353| "PADS" | The current pad/canvas is subdivided into a number of pads equal to the number of histograms in the stack and each histogram is paint into a separate pad.|
354| "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
355| "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
356| "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
357
358
359
360\anchor HP02
361### Setting the Style
362
363
364Histograms use the current style (`gStyle`). When one changes the current
365style and would like to propagate the changes to the histogram,
366`TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
367each histogram is needed.
368
369To force all the histogram to use the current style use:
370
371 gROOT->ForceStyle();
372
373All the histograms read after this call will use the current style.
374
375
376\anchor HP03
377### Setting line, fill, marker, and text attributes
378
379
380The histogram classes inherit from the attribute classes:
381`TAttLine`, `TAttFill` and `TAttMarker`.
382See the description of these classes for the list of options.
383
384
385\anchor HP04
386### Setting Tick marks on the histogram axis
387
388
389The `TPad::SetTicks` method specifies the type of tick marks on the axis.
390If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
391
392 tx = 1; tick marks on top side are drawn (inside)
393 tx = 2; tick marks and labels on top side are drawn
394 ty = 1; tick marks on right side are drawn (inside)
395 ty = 2; tick marks and labels on right side are drawn
396
397By default only the left Y axis and X bottom axis are drawn
398(`tx = ty = 0`)
399
400`TPad::SetTicks(tx,ty)` allows to set these options.
401See also The `TAxis` functions to set specific axis attributes.
402
403In case multiple color filled histograms are drawn on the same pad, the fill
404area may hide the axis tick marks. One can force a redraw of the axis over all
405the histograms by calling:
406
407 gPad->RedrawAxis();
408
409
410\anchor HP05
411### Giving titles to the X, Y and Z axis
412
413
414 h->GetXaxis()->SetTitle("X axis title");
415 h->GetYaxis()->SetTitle("Y axis title");
416
417The histogram title and the axis titles can be any `TLatex` string.
418The titles are part of the persistent histogram.
419
420
421\anchor HP060
422### The option "SAME"
423
424
425By default, when an histogram is drawn, the current pad is cleared before
426drawing. In order to keep the previous drawing and draw on top of it the
427option `SAME` should be use. The histogram drawn with the option
428`SAME` uses the coordinates system available in the current pad.
429
430This option can be used alone or combined with any valid drawing option but
431some combinations must be use with care.
432
433\anchor HP060a
434#### Limitations
435
436- It does not work when combined with the `LEGO` and `SURF` options unless the
437 histogram plotted with the option `SAME` has exactly the same
438 ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
439 lego plots [histograms' stacks](\ref HP26) should be used.
440
441
442\anchor HP061
443### Colors automatically picked in palette
444
445\since **ROOT version 6.09/01**
446
447When several histograms are painted in the same canvas thanks to the option "SAME"
448or via a `THStack` it might be useful to have an easy and automatic way to choose
449their color. The simplest way is to pick colors in the current active color
450palette. Palette coloring for histogram is activated thanks to the options `PFC`
451(Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
452When one of these options is given to `TH1::Draw` the histogram get its color
453from the current color palette defined by `gStyle->SetPalette(…)`. The color
454is determined according to the number of objects having palette coloring in
455the current pad.
456
457Begin_Macro(source)
458../../../tutorials/hist/histpalettecolor.C
459End_Macro
460
461Begin_Macro(source)
462../../../tutorials/hist/thstackpalettecolor.C
463End_Macro
464
465Begin_Macro(source)
466../../../tutorials/hist/thstack2palettecolor.C
467End_Macro
468
469\anchor HP06
470### Superimposing two histograms with different scales in the same pad
471
472
473The following example creates two histograms, the second histogram is the bins
474integral of the first one. It shows a procedure to draw the two histograms in
475the same pad and it draws the scale of the second histogram using a new vertical
476axis on the right side. See also the tutorial `transpad.C` for a variant
477of this example.
478
479Begin_Macro(source)
480{
481 auto c1 = new TCanvas("c1","c1",600,400);
482 // create/fill draw h1
483 gStyle->SetOptStat(kFALSE);
484 auto h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
485 Int_t i;
486 for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
487 h1->Draw();
488 c1->Update();
489
490 // create hint1 filled with the bins integral of h1
491 auto hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
492 float sum = 0.f;
493 for (i=1;i<=100;i++) {
494 sum += h1->GetBinContent(i);
495 hint1->SetBinContent(i,sum);
496 }
497
498 // scale hint1 to the pad coordinates
499 float rightmax = 1.1*hint1->GetMaximum();
500 float scale = gPad->GetUymax()/rightmax;
501 hint1->SetLineColor(kRed);
502 hint1->Scale(scale);
503 hint1->Draw("same");
504
505 // draw an axis on the right side
506 auto axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
507 gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
508 axis->SetLineColor(kRed);
509 axis->SetTextColor(kRed);
510 axis->Draw();
511}
512End_Macro
513
514
515\anchor HP07
516### Statistics Display
517
518
519The type of information shown in the histogram statistics box can be selected
520with:
521
522 gStyle->SetOptStat(mode);
523
524The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
525
526 mode = ksiourmen (default = 000001111)
527 k = 1; kurtosis printed
528 k = 2; kurtosis and kurtosis error printed
529 s = 1; skewness printed
530 s = 2; skewness and skewness error printed
531 i = 1; integral of bins printed
532 i = 2; integral of bins with option "width" printed
533 o = 1; number of overflows printed
534 u = 1; number of underflows printed
535 r = 1; standard deviation printed
536 r = 2; standard deviation and standard deviation error printed
537 m = 1; mean value printed
538 m = 2; mean and mean error values printed
539 e = 1; number of entries printed
540 n = 1; name of histogram is printed
541
542For example:
543
544 gStyle->SetOptStat(11);
545
546displays only the name of histogram and the number of entries, whereas:
547
548 gStyle->SetOptStat(1101);
549
550displays the name of histogram, mean value and standard deviation.
551
552<b>WARNING 1:</b> never do:
553
554 gStyle->SetOptStat(0001111);
555
556but instead do:
557
558 gStyle->SetOptStat(1111);
559
560because `0001111` will be taken as an octal number!
561
562<b>WARNING 2:</b> for backward compatibility with older versions
563
564 gStyle->SetOptStat(1);
565
566is taken as:
567
568 gStyle->SetOptStat(1111)
569
570To print only the name of the histogram do:
571
572 gStyle->SetOptStat(1000000001);
573
574<b>NOTE</b> that in case of 2D histograms, when selecting only underflow
575(10000) or overflow (100000), the statistics box will show all combinations
576of underflow/overflows and not just one single number.
577
578The parameter mode can be any combination of the letters `kKsSiIourRmMen`
579
580 k : kurtosis printed
581 K : kurtosis and kurtosis error printed
582 s : skewness printed
583 S : skewness and skewness error printed
584 i : integral of bins printed
585 I : integral of bins with option "width" printed
586 o : number of overflows printed
587 u : number of underflows printed
588 r : standard deviation printed
589 R : standard deviation and standard deviation error printed
590 m : mean value printed
591 M : mean value mean error values printed
592 e : number of entries printed
593 n : name of histogram is printed
594
595For example, to print only name of histogram and number of entries do:
596
597 gStyle->SetOptStat("ne");
598
599To print only the name of the histogram do:
600
601 gStyle->SetOptStat("n");
602
603The default value is:
604
605 gStyle->SetOptStat("nemr");
606
607When a histogram is painted, a `TPaveStats` object is created and added
608to the list of functions of the histogram. If a `TPaveStats` object
609already exists in the histogram list of functions, the existing object is just
610updated with the current histogram parameters.
611
612Once a histogram is painted, the statistics box can be accessed using
613`h->FindObject("stats")`. In the command line it is enough to do:
614
615 Root > h->Draw()
616 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
617
618because after `h->Draw()` the histogram is automatically painted. But
619in a script file the painting should be forced using `gPad->Update()`
620in order to make sure the statistics box is created:
621
622 h->Draw();
623 gPad->Update();
624 TPaveStats *st = (TPaveStats*)h->FindObject("stats");
625
626Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
627
628When a histogram is drawn with the option `SAME`, the statistics box
629is not drawn. To force the statistics box drawing with the option
630`SAME`, the option `SAMES` must be used.
631If the new statistics box hides the previous statistics box, one can change
632its position with these lines (`h` being the pointer to the histogram):
633
634 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
635 Root > st->SetX1NDC(newx1); //new x start position
636 Root > st->SetX2NDC(newx2); //new x end position
637
638To change the type of information for an histogram with an existing
639`TPaveStats` one should do:
640
641 st->SetOptStat(mode);
642
643Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
644(see above).
645
646One can delete the statistics box for a histogram `TH1* h` with:
647
648 h->SetStats(0)
649
650and activate it again with:
651
652 h->SetStats(1).
653
654Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
655`$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
656
657
658\anchor HP08
659### Fit Statistics
660
661
662The type of information about fit parameters printed in the histogram statistics
663box can be selected via the parameter mode. The parameter mode can be
664`= pcev` (default `= 0111`)
665
666 p = 1; print Probability
667 c = 1; print Chisquare/Number of degrees of freedom
668 e = 1; print errors (if e=1, v must be 1)
669 v = 1; print name/values of parameters
670
671Example:
672
673 gStyle->SetOptFit(1011);
674
675print fit probability, parameter names/values and errors.
676
6771. When `v = 1` is specified, only the non-fixed parameters are shown.
6782. When `v = 2` all parameters are shown.
679
680Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
681to `gStyle->SetOptFit(111)`
682
683
684\anchor HP09
685### The error bars options
686
687
688| Option | Description |
689|----------|-------------------------------------------------------------------|
690| "E" | Default. Shows only the error bars, not a marker.|
691| "E1" | Small lines are drawn at the end of the error bars.|
692| "E2" | Error rectangles are drawn.|
693| "E3" | A filled area is drawn through the end points of the vertical error bars.|
694| "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
695| "E0" | Draw error bars. Markers are drawn for bins with 0 contents. Combined with E1 or E2 it avoids error bars clipping|
696| "E5" | Like E3 but ignore the bins with 0 contents.|
697| "E6" | Like E4 but ignore the bins with 0 contents.|
698| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
699
700Begin_Macro(source)
701{
702 auto c1 = new TCanvas("c1","c1",600,400);
703 auto he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
704 for (int i=0; i<10000; i++) he->Fill(gRandom->Gaus(0,1));
705 gStyle->SetEndErrorSize(3);
706 gStyle->SetErrorX(1.);
707 he->SetMarkerStyle(20);
708 he->Draw("E1");
709}
710End_Macro
711
712The options "E3" and "E4" draw an error band through the end points of the
713vertical error bars. With "E4" the error band is smoothed. Because of the
714smoothing algorithm used some artefacts may appear at the end of the band
715like in the following example. In such cases "E3" should be used instead
716of "E4".
717
718Begin_Macro(source)
719{
720 auto ce4 = new TCanvas("ce4","ce4",600,400);
721 ce4->Divide(2,1);
722 auto he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
723 Int_t i;
724 for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
725 he4->SetFillColor(kRed);
726 he4->GetXaxis()->SetRange(40,48);
727 ce4->cd(1);
728 he4->Draw("E4");
729 ce4->cd(2);
730 auto he3 = (TH1F*)he4->DrawClone("E3");
731 he3->SetTitle("Distribution drawn option E3");
732}
733End_Macro
734
7352D histograms can be drawn with error bars as shown is the following example:
736
737Begin_Macro(source)
738{
739 auto c2e = new TCanvas("c2e","c2e",600,400);
740 auto h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
741 float px, py;
742 for (Int_t i = 0; i < 25000; i++) {
743 gRandom->Rannor(px,py);
744 h2e->Fill(px,5*py);
745 }
746 h2e->Draw("E");
747}
748End_Macro
749
750
751\anchor HP100
752### The bar chart option
753
754
755The option "B" allows to draw simple vertical bar charts.
756The bar width is controlled with `TH1::SetBarWidth()`,
757and the bar offset within the bin, with `TH1::SetBarOffset()`.
758These two settings are useful to draw several histograms on the
759same plot as shown in the following example:
760
761Begin_Macro(source)
762{
763 int i;
764 const Int_t nx = 8;
765 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
766 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
767 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
768
769 auto cb = new TCanvas("cb","cb",600,400);
770 cb->SetGrid();
771
772 gStyle->SetHistMinimumZero();
773
774 auto h1b = new TH1F("h1b","Option B example",nx,0,nx);
775 h1b->SetFillColor(4);
776 h1b->SetBarWidth(0.4);
777 h1b->SetBarOffset(0.1);
778 h1b->SetStats(0);
779 h1b->SetMinimum(-5);
780 h1b->SetMaximum(5);
781
782 for (i=1; i<=nx; i++) {
783 h1b->SetBinContent(i, d_35_0[i-1]);
784 h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
785 }
786
787 h1b->Draw("b");
788
789 auto h2b = new TH1F("h2b","h2b",nx,0,nx);
790 h2b->SetFillColor(38);
791 h2b->SetBarWidth(0.4);
792 h2b->SetBarOffset(0.5);
793 h2b->SetStats(0);
794 for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
795
796 h2b->Draw("b same");
797}
798End_Macro
799
800
801\anchor HP10
802### The "BAR" and "HBAR" options
803
804
805When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
806bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
807An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
808`hbar2`, `hbar3`, `hbar4` (hbars.C).
809
810- The bar is filled with the histogram fill color.
811- The left side of the bar is drawn with a light fill color.
812- The right side of the bar is drawn with a dark fill color.
813- The percentage of the bar drawn with either the light or dark color is:
814 - 0% for option "(h)bar" or "(h)bar0"
815 - 10% for option "(h)bar1"
816 - 20% for option "(h)bar2"
817 - 30% for option "(h)bar3"
818 - 40% for option "(h)bar4"
819
820When an histogram has errors the option [\"HIST\"](\ref OPTHIST) together with the `(h)bar` option.
821
822Begin_Macro(source)
823../../../tutorials/hist/hbars.C
824End_Macro
825
826To control the bar width (default is the bin width) `TH1::SetBarWidth()`
827should be used.
828
829To control the bar offset (default is 0) `TH1::SetBarOffset()` should
830be used.
831
832These two parameters are useful when several histograms are plotted using
833the option `SAME`. They allow to plot the histograms next to each other.
834
835
836\anchor HP11
837### The SCATter plot option (default for 2D histograms)
838
839
840For each cell (i,j) a number of points proportional to the cell content is
841drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
842`kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
843If option is of the form `scat=ff`, (eg `scat=1.8`,
844`scat=1e-3`), then `ff` is used as a scale factor to compute the
845number of dots. `scat=1` is the default.
846
847By default the scatter plot is painted with a "dot marker" which not scalable
848(see the `TAttMarker` documentation). To change the marker size, a scalable marker
849type should be used. For instance a circle (marker style 20).
850
851Begin_Macro(source)
852{
853 auto c1 = new TCanvas("c1","c1",600,400);
854 auto hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
855 float px, py;
856 for (Int_t i = 0; i < 25000; i++) {
857 gRandom->Rannor(px,py);
858 hscat->Fill(px,5*py);
859 hscat->Fill(3+0.5*px,2*py-10.);
860 }
861 hscat->Draw("scat=0.5");
862}
863End_Macro
864
865
866\anchor HP12
867### The ARRow option
868
869
870Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
871The orientation of the arrow follows the cell gradient.
872
873Begin_Macro(source)
874{
875 auto c1 = new TCanvas("c1","c1",600,400);
876 auto harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
877 harr->SetLineColor(kRed);
878 float px, py;
879 for (Int_t i = 0; i < 25000; i++) {
880 gRandom->Rannor(px,py);
881 harr->Fill(px,5*py);
882 harr->Fill(3+0.5*px,2*py-10.,0.1);
883 }
884 harr->Draw("ARR");
885}
886End_Macro
887
888\since **ROOT version 6.17/01**
889
890The option `ARR` can be combined with the option `COL` or `COLZ`.
891
892Begin_Macro(source)
893{
894 auto c1 = new TCanvas("c1","c1",600,400);
895 auto harr = new TH2F("harr","Option ARR + COLZ example",20,-4,4,20,-20,20);
896 harr->SetStats(0);
897 float px, py;
898 for (Int_t i = 0; i < 25000; i++) {
899 gRandom->Rannor(px,py);
900 harr->Fill(px,5*py);
901 harr->Fill(3+0.5*px,2*py-10.,0.1);
902 }
903 harr->Draw("ARR COLZ");
904}
905End_Macro
906
907
908\anchor HP13
909### The BOX option
910
911
912For each cell (i,j) a box is drawn. The size (surface) of the box is
913proportional to the absolute value of the cell content.
914The cells with a negative content are drawn with a `X` on top of the box.
915
916Begin_Macro(source)
917{
918 auto c1 = new TCanvas("c1","c1",600,400);
919 auto hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
920 hbox->SetFillColor(42);
921 hbox->Fill(0.5, 0.5, 1.);
922 hbox->Fill(0.5, 1.5, 4.);
923 hbox->Fill(0.5, 2.5, 3.);
924 hbox->Fill(1.5, 0.5, 2.);
925 hbox->Fill(1.5, 1.5, 12.);
926 hbox->Fill(1.5, 2.5, -6.);
927 hbox->Fill(2.5, 0.5, -4.);
928 hbox->Fill(2.5, 1.5, 6.);
929 hbox->Fill(2.5, 2.5, 0.5);
930 hbox->Draw("BOX");
931}
932End_Macro
933
934With option `BOX1` a button is drawn for each cell with surface
935proportional to content's absolute value. A sunken button is drawn for
936negative values a raised one for positive.
937
938Begin_Macro(source)
939{
940 auto c1 = new TCanvas("c1","c1",600,400);
941 auto hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
942 hbox1->SetFillColor(42);
943 hbox1->Fill(0.5, 0.5, 1.);
944 hbox1->Fill(0.5, 1.5, 4.);
945 hbox1->Fill(0.5, 2.5, 3.);
946 hbox1->Fill(1.5, 0.5, 2.);
947 hbox1->Fill(1.5, 1.5, 12.);
948 hbox1->Fill(1.5, 2.5, -6.);
949 hbox1->Fill(2.5, 0.5, -4.);
950 hbox1->Fill(2.5, 1.5, 6.);
951 hbox1->Fill(2.5, 2.5, 0.5);
952 hbox1->Draw("BOX1");
953}
954End_Macro
955
956When the option `SAME` (or "SAMES") is used with the option `BOX`,
957the boxes' sizes are computing taking the previous plots into account. The range
958along the Z axis is imposed by the first plot (the one without option
959`SAME`); therefore the order in which the plots are done is relevant.
960
961Begin_Macro(source)
962{
963 auto c1 = new TCanvas("c1","c1",600,400);
964 auto hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
965 auto hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
966 auto hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
967 auto hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
968 for (Int_t i=0;i<1000;i++) {
969 double x,y;
970 gRandom->Rannor(x,y);
971 if (x>0 && y>0) hb1->Fill(x,y,4);
972 if (x<0 && y<0) hb2->Fill(x,y,3);
973 if (x>0 && y<0) hb3->Fill(x,y,2);
974 if (x<0 && y>0) hb4->Fill(x,y,1);
975 }
976 hb1->SetFillColor(1);
977 hb2->SetFillColor(2);
978 hb3->SetFillColor(3);
979 hb4->SetFillColor(4);
980 hb1->Draw("box");
981 hb2->Draw("box same");
982 hb3->Draw("box same");
983 hb4->Draw("box same");
984}
985End_Macro
986
987\since **ROOT version 6.17/01:**
988
989Sometimes the change of the range of the Z axis is unwanted, in which case, one
990can use `SAME0` (or `SAMES0`) option to opt out of this change.
991
992Begin_Macro(source)
993{
994 auto h2 = new TH2F("h2"," ",10,0,10,10,20,30);
995 auto hf = (TH2F*)h2->Clone("hf");
996 h2->SetBit(TH1::kNoStats);
997 hf->SetBit(TH1::kNoStats);
998 h2->Fill(5,22);
999 h2->Fill(5,23);
1000 h2->Fill(6,22);
1001 h2->Fill(6,23);
1002 hf->Fill(6,23);
1003 hf->Fill(6,23);
1004 hf->Fill(6,23);
1005 hf->Fill(6,23);
1006 hf->Fill(5,23);
1007
1008 auto hf_copy1 = hf->Clone("hf_copy1");
1009 auto lt = new TLatex();
1010
1011 auto cx = new TCanvas(); cx->Divide(2,1);
1012
1013 cx->cd(1);
1014 h2->Draw("box");
1015 hf->Draw("text colz same");
1016 lt->DrawLatexNDC(0.3,0.5,"SAME");
1017
1018 cx->cd(2);
1019 h2->Draw("box");
1020 hf_copy1->Draw("text colz same0");
1021 lt->DrawLatexNDC(0.3,0.5,"SAME0");
1022}
1023End_Macro
1024
1025
1026\anchor HP14
1027### The COLor option
1028
1029
1030For each cell (i,j) a box is drawn with a color proportional to the cell
1031content.
1032
1033The color table used is defined in the current style.
1034
1035If the histogram's minimum and maximum are the same (flat histogram), the
1036mapping on colors is not possible, therefore nothing is painted. To paint a
1037flat histogram it is enough to set the histogram minimum
1038(`TH1::SetMinimum()`) different from the bins' content.
1039
1040The default number of color levels used to paint the cells is 20.
1041It can be changed with `TH1::SetContour()` or
1042`TStyle::SetNumberContours()`. The higher this number is, the smoother
1043is the color change between cells.
1044
1045The color palette in TStyle can be modified via `gStyle->SetPalette()`.
1046
1047All the non-empty bins are painted. Empty bins are not painted unless
1048some bins have a negative content because in that case the null bins
1049might be not empty.
1050
1051`TProfile2D` histograms are handled differently because, for this type of 2D
1052histograms, it is possible to know if an empty bin has been filled or not. So even
1053if all the bins' contents are positive some empty bins might be painted. And vice versa,
1054if some bins have a negative content some empty bins might be not painted.
1055
1056Combined with the option `COL`, the option `Z` allows to
1057display the color palette defined by `gStyle->SetPalette()`.
1058
1059In the following example, the histogram has only positive bins; the empty
1060bins (containing 0) are not drawn.
1061
1062Begin_Macro(source)
1063{
1064 auto c1 = new TCanvas("c1","c1",600,400);
1065 auto hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
1066 float px, py;
1067 for (Int_t i = 0; i < 25000; i++) {
1068 gRandom->Rannor(px,py);
1069 hcol1->Fill(px,5*py);
1070 }
1071 hcol1->Draw("COLZ");
1072}
1073End_Macro
1074
1075In the first plot of following example, the histogram has some negative bins;
1076the empty bins (containing 0) are drawn. In some cases one wants to not draw
1077empty bins (containing 0) of histograms having a negative minimum. The option
1078`1`, used to produce the second plot in the following picture, allows to do that.
1079
1080Begin_Macro(source)
1081{
1082 auto c1 = new TCanvas("c1","c1",600,600);
1083 c1->Divide(1,2);
1084 auto hcol23 = new TH2F("hcol23","Option COLZ example ",40,-4,4,40,-20,20);
1085 auto hcol24 = new TH2F("hcol24","Option COLZ1 example ",40,-4,4,40,-20,20);
1086 float px, py;
1087 for (Int_t i = 0; i < 25000; i++) {
1088 gRandom->Rannor(px,py);
1089 hcol23->Fill(px,5*py);
1090 hcol24->Fill(px,5*py);
1091 }
1092 hcol23->Fill(0.,0.,-200.);
1093 hcol24->Fill(0.,0.,-200.);
1094 c1->cd(1); hcol23->Draw("COLZ");
1095 c1->cd(2); hcol24->Draw("COLZ1");
1096}
1097End_Macro
1098
1099When the maximum of the histogram is set to a smaller value than the real maximum,
1100 the bins having a content between the new maximum and the real maximum are
1101painted with the color corresponding to the new maximum.
1102
1103When the minimum of the histogram is set to a greater value than the real minimum,
1104 the bins having a value between the real minimum and the new minimum are not drawn
1105 unless the option `0` is set.
1106
1107The following example illustrates the option `0` combined with the option `COL`.
1108
1109Begin_Macro(source)
1110{
1111 auto c1 = new TCanvas("c1","c1",600,600);
1112 c1->Divide(1,2);
1113 auto hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1114 auto hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1115 float px, py;
1116 for (Int_t i = 0; i < 25000; i++) {
1117 gRandom->Rannor(px,py);
1118 hcol21->Fill(px,5*py);
1119 hcol22->Fill(px,5*py);
1120 }
1121 hcol21->SetBit(TH1::kNoStats);
1122 hcol22->SetBit(TH1::kNoStats);
1123 c1->cd(1); hcol21->Draw("COLZ");
1124 c1->cd(2); hcol22->Draw("COLZ0");
1125 hcol22->SetMaximum(100);
1126 hcol22->SetMinimum(40);
1127}
1128End_Macro
1129
1130\since **ROOT version 6.09/01:**
1131
1132When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1133are computing taking the previous plots into account. The range along the Z axis
1134is imposed by the first plot (the one without option SAME); therefore the order
1135in which the plots are done is relevant. Same as [in the `BOX` option](\ref HP13), one can use
1136`SAME0` (or `SAMES0`) to opt out of this imposition.
1137
1138Begin_Macro(source)
1139{
1140 auto c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1141 auto h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1142 auto h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1143 auto h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1144 auto h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1145 h1->SetBit(TH1::kNoStats);
1146 for (Int_t i=0;i<5000;i++) {
1147 double x,y;
1148 gRandom->Rannor(x,y);
1149 if(x>0 && y>0) h1->Fill(x,y,4);
1150 if(x<0 && y<0) h2->Fill(x,y,3);
1151 if(x>0 && y<0) h3->Fill(x,y,2);
1152 if(x<0 && y>0) h4->Fill(x,y,1);
1153 }
1154 h1->Draw("colz");
1155 h2->Draw("col same");
1156 h3->Draw("col same");
1157 h4->Draw("col same");
1158}
1159End_Macro
1160
1161The option `COL` can be combined with the option `POL`:
1162
1163Begin_Macro(source)
1164{
1165 auto c1 = new TCanvas("c1","c1",600,400);
1166 auto hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1167 float px, py;
1168 for (Int_t i = 0; i < 25000; i++) {
1169 gRandom->Rannor(px,py);
1170 hcol1->Fill(px,py);
1171 }
1172 hcol1->Draw("COLZPOL");
1173}
1174End_Macro
1175
1176\since **ROOT version 6.07/03:**
1177
1178A second rendering technique is also available with the COL2 and COLZ2 options.
1179
1180These options provide potential performance improvements compared to the standard
1181COL option. The performance comparison of the COL2 to the COL option depends on
1182the histogram and the size of the rendering region in the current pad. In general,
1183a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1184faster with the COL option.
1185
1186However, for larger histograms (approx. more than 100 bins per axis)
1187that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1188For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1189faster with the COL2 option.
1190
1191The COL2 option will also scale its performance based on the size of the
1192pixmap the histogram image is being rendered into. It also is much better optimized for
1193sessions where the user is forwarding X11 windows through an `ssh` connection.
1194
1195For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1196and COLZ options. There is one major difference and that concerns the treatment of
1197bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1198
1199COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1200graphics file format like PostScript or PDF (an empty image will be generated). It can
1201be saved only in bitmap files like PNG format for instance.
1202
1203
1204\anchor HP140
1205### The CANDLE and VIOLIN options
1206
1207The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1208implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1209the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1210vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1211(1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1212
1213Instead of using the predefined representations, the candle and violin parameters can be
1214changed individually. In that case the option have the following form:
1215
1216 CANDLEX(<option-string>)
1217 CANDLEY(<option-string>)
1218 VIOLINX(<option-string>)
1219 VIOLINY(<option-string>).
1220
1221All zeros at the beginning of `option-string` can be omitted.
1222
1223`option-string` consists eight values, defined as follow:
1224
1225 "CANDLEX(zhpawMmb)"
1226
1227Where:
1228
1229 - `b = 0`; no box drawn
1230 - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1231 makes sense in the very most cases to always draw the box
1232 - `b = 2`; draw a filled box with border
1233
1234 - `m = 0`; no median drawn
1235 - `m = 1`; median is drawn as a line
1236 - `m = 2`; median is drawn with errors (notches)
1237 - `m = 3`; median is drawn as a circle
1238
1239 - `M = 0`; no mean drawn
1240 - `M = 1`; mean is drawn as a dashed line
1241 - `M = 3`; mean is drawn as a circle
1242
1243 - `w = 0`; no whisker drawn
1244 - `w = 1`; whisker is drawn to end of distribution.
1245 - `w = 2`; whisker is drawn to max 1.5*iqr
1246
1247 - `a = 0`; no anchor drawn
1248 - `a = 1`; the anchors are drawn
1249
1250 - `p = 0`; no points drawn
1251 - `p = 1`; only outliers are drawn
1252 - `p = 2`; all datapoints are drawn
1253 - `p = 3`: all datapoints are drawn scattered
1254
1255 - `h = 0`; no histogram is drawn
1256 - `h = 1`; histogram at the left or bottom side is drawn
1257 - `h = 2`; histogram at the right or top side is drawn
1258 - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1259
1260 - `z = 0`; no zero indicator line is drawn
1261 - `z = 1`; zero indicator line is drawn.
1262
1263As one can see all individual options for both candle and violin plots can be accessed by this
1264mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1265meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1266vice versa, if you wish.
1267
1268Using a logarithmic x- or y-axis is possible for candle and violin charts.
1269
1270\since **ROOT version 6.11/01**
1271
1272a logarithmic z-axis is possible, too but will only affect violin charts of course.
1273
1274\anchor HP140a
1275#### The CANDLE option
1276
1277<a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1278a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1279way to describe graphically a data distribution (D) with only five numbers:
1280
1281 1. The minimum value of the distribution D (bottom or left whisker).
1282 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1283 3. The median (M): 50% of the data points in D are less than M.
1284 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1285 5. The maximum value of the distribution D (top or right whisker).
1286
1287In this implementation a TH2 is considered as a collection of TH1 along
1288X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1289Each TH1 is represented as one candle.
1290
1291Begin_Macro(source)
1292../../../tutorials/hist/candleplotwhiskers.C
1293End_Macro
1294
1295The candle reduces the information coming from a whole distribution into few values.
1296Independently from the number of entries or the significance of the underlying distribution
1297a candle will always look like a candle. So candle plots should be used carefully in
1298particular with unknown distributions. The definition of a candle is based on
1299__unbinned data__. Here, candles are created from binned data. Because of this, the
1300deviation is connected to the bin width used. The calculation of the quantiles
1301normally done on unbinned data also. Because data are binned, this will
1302only work the best possible way within the resolution of one bin
1303
1304Because of all these facts one should take care that:
1305
1306 - there are enough points per candle
1307 - the bin width is small enough (more bins will increase the maximum
1308 available resolution of the quantiles although there will be some
1309 bins with no entries)
1310 - never make a candle-plot if the underlying distribution is double-distributed
1311 - only create candles of distributions that are more-or-less gaussian (the
1312 MPV should be not too far away from the mean).
1313
1314#### What a candle is made of
1315
1316\since **ROOT version 6.07/05**
1317
1318##### The box
1319The box displays the position of the inter-quantile-range of the underlying
1320distribution. The box contains 25% of the distribution below the median
1321and 25% of the distribution above the median. If the underlying distribution is large
1322enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1323(Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1324the position of the box can be modified by SetBarWidth() and SetBarOffset().
1325The +-25% quantiles are calculated by the GetQuantiles() methods.
1326
1327\since **ROOT version 6.11/01**
1328
1329Using the static function TCandle::SetBoxRange(double) the box definition will be
1330overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1331to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1332The static function will affect all candle-charts in the running program.
1333Default is 0.5.
1334
1335Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1336whole candle) can be influenced. Deactivated, the width is constant (to be set by
1337SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1338amount of data in the corresponding candle, the maximum width can be influenced by
1339SetBarWidth(). The static function will affect all candle-charts in the running program.
1340Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1341supported, yet
1342
1343##### The Median
1344For a sorted list of numbers, the median is the value in the middle of the list.
1345E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1346because it is in the middle of the list. If the number of entries is even the
1347average of the two values in the middle will be used. As histograms are binned
1348data, the situation is a bit more complex. The following example shows this:
1349
1350~~~ {.cpp}
1351void quantiles() {
1352 auto h = new TH1I("h","h",10,0,10);
1353 //h->Fill(3);
1354 //h->Fill(3);
1355 h->Fill(4);
1356 h->Draw();
1357 double p = 0.;
1358 double q = 0.;
1359 h->GetQuantiles(1,&q,&p);
1360
1361 cout << "Median is: " << q << std::endl;
1362}
1363~~~
1364
1365Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1366the example will return a calculated median of 4.5, because that's the bin center
1367of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1368commented out, it will return 3.75, because the algorithm tries to evenly distribute
1369the individual values of a bin with bin content > 0. It means the sorted list
1370would be "3.25, 3.75, 4.5".
1371
1372The consequence is a median of 3.75. This shows how important it is to use a
1373small enough bin-width when using candle-plots on binned data.
1374If the distribution is large enough and gaussian shaped the median will be exactly
1375equal to the mean.
1376The median can be shown as a line or as a circle or not shown at all.
1377
1378In order to show the significance of the median notched candle plots apply a "notch" or
1379narrowing of the box around the median. The significance is defined by
1380\f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1381(where iqr is the size of the box and N is the number of entries of the whole
1382distribution). Candle plots like these are usually called "notched candle plots".
1383
1384In case the significance of the median is greater that the size of the box, the
1385box will have an unnatural shape. Usually it means the chart has not enough data,
1386or that representing this uncertainty is not useful
1387
1388##### The Mean
1389The mean can be drawn as a dashed line or as a circle or not drawn at all.
1390The mean is the arithmetic average of the values in the distribution.
1391It is calculated using GetMean(). Because histograms are
1392binned data, the mean value can differ from a calculation on the raw-data.
1393If the distribution is large enough and gaussian shaped the mean will be
1394exactly the median.
1395
1396##### The Whiskers
1397The whiskers represent the part of the distribution not covered by the box.
1398The upper 25% and the lower 25% of the distribution are located within the whiskers.
1399Two representations are available.
1400
1401 - A simple one (using w=1) defining the lower whisker from the lowest data value
1402 to the bottom of the box, and the upper whisker from the top of the box to the
1403 highest data value. In this representation the whisker-lines are dashed.
1404 - A more complex one having a further restriction. The whiskers are still connected
1405 to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1406 be that the outermost part of the underlying distribution will not be covered
1407 by the whiskers. Usually these missing parts will be represented by the outliers
1408 (see points). Of course the upper and the lower whisker may differ in length.
1409 In this representation the whiskers are drawn as solid lines.
1410
1411\since **ROOT version 6.11/01**
1412
1413Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1414will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1415the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1416that candle. The static function will affect all candle-charts in the running program.
1417Default is 1.
1418
1419If the distribution is large enough and gaussian shaped, the maximum length of
1420the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
14211.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1422(see picture above). In that case 99.3% of the total distribution will be covered
1423by the box and the whiskers, whereas 0.7% are represented by the outliers.
1424
1425##### The Anchors
1426The anchors have no special meaning in terms of statistical calculation. They mark
1427the end of the whiskers and they have the width of the box. Both representation
1428with and without anchors are common.
1429
1430##### The Points
1431Depending on the configuration the points can have different meanings:
1432 - If p=1 the points represent the outliers. If they are shown, it means
1433 some parts of the underlying distribution are not covered by the whiskers.
1434 This can only occur when the whiskers are set to option w=2. Here the whiskers
1435 can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1436 whiskers will be drawn as outliers. The outliers will be represented by crosses.
1437 - If p=2 all points in the distribution will be painted as crosses. This is
1438 useful for small datasets only (up to 10 or 20 points per candle).
1439 The outliers are shown along the candle. Because the underlying distribution
1440 is binned, is frequently occurs that a bin contains more than one value.
1441 Because of this the points will be randomly scattered within their bin along
1442 the candle axis. If the bin content for a bin is exactly 1 (usually
1443 this happens for the outliers) if will be drawn in the middle of the bin along
1444 the candle axis. As the maximum number of points per candle is limited by kNMax/2
1445 on very large datasets scaling will be performed automatically. In that case one
1446 would loose all outliers because they have usually a bin content of 1 (and a
1447 bin content between 0 and 1 after the scaling). Because of this all bin contents
1448 between 0 and 1 - after the scaling - will be forced to be 1.
1449 - As the drawing of all values on large datasets can lead to big amounts of crosses,
1450 one can show all values as a scatter plot instead by choosing p=3. The points will be
1451 drawn as dots and will be scattered within the width of the candle. The color
1452 of the points will be the color of the candle-chart.
1453
1454##### Other Options
1455Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1456with a histogram.
1457
1458#### How to use the candle-plots drawing option
1459
1460There are six predefined candle-plot representations:
1461
1462 - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1463 - "CANDLEX2": Standard candle with better whisker definition + outliers.
1464 It is a good compromise
1465 - "CANDLEX3": Like candle2 but with a mean as a circle.
1466 It is easier to distinguish mean and median
1467 - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1468 (notched candle plots).
1469 For bigger datasets per candle
1470 - "CANDLEX5": Like candle2 but showing all data points.
1471 For very small datasets
1472 - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1473 For huge datasets
1474
1475
1476The following picture shows how the six predefined representations look.
1477
1478Begin_Macro
1479{
1480 auto c1 = new TCanvas("c1","c1",700,800);
1481 c1->Divide(2,3);
1482 gStyle->SetOptStat(kFALSE);
1483
1484 auto hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1485 float px, py;
1486 for (Int_t i = 0; i < 15000; i++) {
1487 gRandom->Rannor(px,py);
1488 hcandle->Fill(px,5*py);
1489 }
1490 hcandle->SetMarkerSize(0.5);
1491
1492 TH2F *h2;
1493 for (Int_t i=1; i<7; i++) {
1494 c1->cd(i);
1495 h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1496 h2->SetTitle(Form("CANDLE%d",i));
1497 }
1498}
1499End_Macro
1500
1501
1502#### Example 1
1503Box and improved whisker, no mean, no median, no anchor no outliers
1504
1505 h1->Draw("CANDLEX(2001)");
1506
1507#### Example 2
1508A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1509
1510 h1->Draw("CANDLEX(112111)");
1511
1512#### Example 3
1513The following example shows how several candle plots can be super-imposed using
1514the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1515Also the color, the line width, the size of the points and so on can be changed by the
1516standard attribute setting methods such as SetLineColor() SetLineWidth().
1517
1518Begin_Macro(source)
1519../../../tutorials/hist/candleplot.C
1520End_Macro
1521
1522\anchor HP140b
1523#### The VIOLIN option
1524
1525<a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1526that also encodes the pdf information at each point.
1527
1528
1529Quartiles and mean are also represented at each point, with a marker
1530and two lines.
1531
1532In this implementation a TH2 is considered as a collection of TH1 along
1533X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1534
1535#### What a violin is made of
1536
1537\since **ROOT version 6.09/02**
1538
1539##### The histogram
1540The histogram is typically drawn to both directions with respect to the middle-line of the
1541corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1542one side (h=1, or h=2).
1543The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1544histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1545be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1546A solid fill style is recommended.
1547
1548\since **ROOT version 6.11/01**
1549
1550Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1551violin can be influenced. Activated, the height of the bins of the individual violins will be
1552scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1553Deactivated, the height of the bin with the maximum content of each individual violin is
1554set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1555in the running program. Default is true. Scaling between multiple violin-charts
1556(using "same" or THStack) is not supported, yet.
1557
1558##### The zero indicator line
1559Typical for violin charts is a line in the background over the whole histogram indicating
1560the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1561will always be the same as the fill-color of the histogram.
1562
1563##### The Mean
1564The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1565
1566##### Whiskers
1567The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1568difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1569the whiskers will be forced to be solid (usually hashed)
1570
1571##### Points
1572The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1573better whisker definition (w=2) and outliers (p=1).
1574
1575##### Other options
1576It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1577including a box-plot.
1578
1579#### How to use the violin-plots drawing option
1580
1581There are two predefined violin-plot representations:
1582 - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1583 zero indicator line)
1584 - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1585
1586A solid fill style is recommended for this plot (as opposed to a hollow or
1587hashed style).
1588
1589Begin_Macro(source)
1590{
1591 auto c1 = new TCanvas("c1","c1",600,400);
1592 Int_t nx(6), ny(40);
1593 double xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1594 auto hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1595 TF1 f1("f1", "gaus", +0,0 +4.0);
1596 double x,y;
1597 for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1598 double xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1599 f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1600 for(Int_t i=0; i<10000; ++i){
1601 x = xc;
1602 y = f1.GetRandom();
1603 hviolin->Fill(x, y);
1604 }
1605 }
1606 hviolin->SetFillColor(kGray);
1607 hviolin->SetMarkerStyle(20);
1608 hviolin->SetMarkerSize(0.5);
1609 hviolin->Draw("VIOLIN");
1610 c1->Update();
1611}
1612End_Macro
1613
1614The next example illustrates a time development of a certain value:
1615
1616Begin_Macro(source)
1617../../../tutorials/hist/candledecay.C
1618End_Macro
1619
1620
1621\anchor HP15
1622### The TEXT and TEXTnn Option
1623
1624
1625For each bin the content is printed. The text attributes are:
1626
1627- text font = current TStyle font (`gStyle->SetTextFont()`).
1628- text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1629 with the option `TEXT` the marker size can be changed with
1630 `h->SetMarkerSize(markersize)`).
1631- text color = marker color.
1632
1633By default the format `g` is used. This format can be redefined
1634by calling `gStyle->SetPaintTextFormat()`.
1635
1636It is also possible to use `TEXTnn` in order to draw the text with
1637the angle `nn` (`0 < nn < 90`).
1638
1639For 2D histograms the text is plotted in the center of each non empty cells.
1640It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`
1641or providing MIN0 draw option. For 1D histogram the text is plotted at a y
1642position equal to the bin content.
1643
1644For 2D histograms when the option "E" (errors) is combined with the option
1645text ("TEXTE"), the error for each bin is also printed.
1646
1647Begin_Macro(source)
1648{
1649 auto c01 = new TCanvas("c01","c01",700,400);
1650 c01->Divide(2,1);
1651 auto htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1652 auto htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1653 float px, py;
1654 for (Int_t i = 0; i < 25000; i++) {
1655 gRandom->Rannor(px,py);
1656 htext1->Fill(px,0.1);
1657 htext2->Fill(px,5*py,0.1);
1658 }
1659 gStyle->SetPaintTextFormat("4.1f m");
1660 htext2->SetMarkerSize(1.8);
1661 c01->cd(1);
1662 htext2->Draw("TEXT45");
1663 c01->cd(2);
1664 htext1->Draw();
1665 htext1->Draw("HIST TEXT0 SAME");
1666}
1667End_Macro
1668
1669\since **ROOT version 6.07/07:**
1670
1671In case several histograms are drawn on top ot each other (using option `SAME`),
1672the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1673text position in each cell, in percentage of the bin width.
1674
1675Begin_Macro(source)
1676{
1677 auto c03 = new TCanvas("c03","c03",700,400);
1678 gStyle->SetOptStat(0);
1679 auto htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1680 auto htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1681 auto htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1682 float px, py;
1683 for (Int_t i = 0; i < 25000; i++) {
1684 gRandom->Rannor(px,py);
1685 htext3->Fill(4*px,20*py,0.1);
1686 htext4->Fill(4*px,20*py,0.5);
1687 htext5->Fill(4*px,20*py,1.0);
1688 }
1689 htext4->SetMarkerSize(1.8);
1690 htext5->SetMarkerSize(1.8);
1691 htext5->SetMarkerColor(kRed);
1692 htext3->Draw("COL");
1693 htext4->SetBarOffset(0.2);
1694 htext4->Draw("TEXT SAME");
1695 htext5->SetBarOffset(-0.2);
1696 htext5->Draw("TEXT SAME");
1697}
1698End_Macro
1699
1700In the case of profile histograms it is possible to print the number
1701of entries instead of the bin content. It is enough to combine the
1702option "E" (for entries) with the option "TEXT".
1703
1704Begin_Macro(source)
1705{
1706 auto c02 = new TCanvas("c02","c02",700,400);
1707 c02->Divide(2,1);
1708 gStyle->SetPaintTextFormat("g");
1709
1710 auto profile = new TProfile("profile","profile",10,0,10);
1711 profile->SetMarkerSize(2.2);
1712 profile->Fill(0.5,1);
1713 profile->Fill(1.5,2);
1714 profile->Fill(2.5,3);
1715 profile->Fill(3.5,4);
1716 profile->Fill(4.5,5);
1717 profile->Fill(5.5,5);
1718 profile->Fill(6.5,4);
1719 profile->Fill(7.5,3);
1720 profile->Fill(8.5,2);
1721 profile->Fill(9.5,1);
1722 c02->cd(1); profile->Draw("HIST TEXT0");
1723 c02->cd(2); profile->Draw("HIST TEXT0E");
1724}
1725End_Macro
1726
1727\anchor HP16
1728### The CONTour options
1729
1730
1731The following contour options are supported:
1732
1733| Option | Description |
1734|----------|-----------------------------------------------------------------------------|
1735| "CONT" | Draw a contour plot (same as CONT0). |
1736| "CONT0" | Draw a contour plot using surface colors to distinguish contours. |
1737| "CONT1" | Draw a contour plot using the line colors to distinguish contours. |
1738| "CONT2" | Draw a contour plot using the line styles (1 to 5) to distinguish contours. |
1739| "CONT3" | Draw a contour plot using the same line style for all contours. |
1740| "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0). |
1741| "CONT5" | Draw a contour plot using Delaunay triangles. |
1742
1743
1744
1745The following example shows a 2D histogram plotted with the option
1746`CONTZ`. The option `CONT` draws a contour plot using surface
1747colors to distinguish contours. Combined with the option `CONT` (or
1748`CONT0`), the option `Z` allows to display the color palette
1749defined by `gStyle->SetPalette()`.
1750
1751Begin_Macro(source)
1752{
1753 auto c1 = new TCanvas("c1","c1",600,400);
1754 auto hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1755 float px, py;
1756 for (Int_t i = 0; i < 25000; i++) {
1757 gRandom->Rannor(px,py);
1758 hcontz->Fill(px-1,5*py);
1759 hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1760 }
1761 hcontz->Draw("CONTZ");
1762}
1763End_Macro
1764
1765The following example shows a 2D histogram plotted with the option
1766`CONT1Z`. The option `CONT1` draws a contour plot using the
1767line colors to distinguish contours. Combined with the option `CONT1`,
1768the option `Z` allows to display the color palette defined by
1769`gStyle->SetPalette()`.
1770
1771Begin_Macro(source)
1772{
1773 auto c1 = new TCanvas("c1","c1",600,400);
1774 auto hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1775 float px, py;
1776 for (Int_t i = 0; i < 25000; i++) {
1777 gRandom->Rannor(px,py);
1778 hcont1->Fill(px-1,5*py);
1779 hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1780 }
1781 hcont1->Draw("CONT1Z");
1782}
1783End_Macro
1784
1785The following example shows a 2D histogram plotted with the option
1786`CONT2`. The option `CONT2` draws a contour plot using the
1787line styles (1 to 5) to distinguish contours.
1788
1789Begin_Macro(source)
1790{
1791 auto c1 = new TCanvas("c1","c1",600,400);
1792 auto hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1793 float px, py;
1794 for (Int_t i = 0; i < 25000; i++) {
1795 gRandom->Rannor(px,py);
1796 hcont2->Fill(px-1,5*py);
1797 hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1798 }
1799 hcont2->Draw("CONT2");
1800}
1801End_Macro
1802
1803The following example shows a 2D histogram plotted with the option
1804`CONT3`. The option `CONT3` draws contour plot using the same line style for
1805all contours.
1806
1807Begin_Macro(source)
1808{
1809 auto c1 = new TCanvas("c1","c1",600,400);
1810 auto hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1811 float px, py;
1812 for (Int_t i = 0; i < 25000; i++) {
1813 gRandom->Rannor(px,py);
1814 hcont3->Fill(px-1,5*py);
1815 hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1816 }
1817 hcont3->SetLineStyle(kDotted);
1818 hcont3->Draw("CONT3");
1819}
1820End_Macro
1821
1822The following example shows a 2D histogram plotted with the option
1823`CONT4`. The option `CONT4` draws a contour plot using surface
1824colors to distinguish contours (`SURF` option at theta = 0). Combined
1825with the option `CONT` (or `CONT0`), the option `Z`
1826allows to display the color palette defined by `gStyle->SetPalette()`.
1827
1828Begin_Macro(source)
1829{
1830 auto c1 = new TCanvas("c1","c1",600,400);
1831 auto hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1832 float px, py;
1833 for (Int_t i = 0; i < 25000; i++) {
1834 gRandom->Rannor(px,py);
1835 hcont4->Fill(px-1,5*py);
1836 hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1837 }
1838 hcont4->Draw("CONT4Z");
1839}
1840End_Macro
1841
1842The default number of contour levels is 20 equidistant levels and can be changed
1843with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1844
1845\anchor HP16a
1846#### The LIST option
1847
1848When option `LIST` is specified together with option
1849`CONT`, the points used to draw the contours are saved in
1850`TGraph` objects:
1851
1852 h->Draw("CONT LIST");
1853 gPad->Update();
1854
1855The contour are saved in `TGraph` objects once the pad is painted.
1856Therefore to use this functionality in a macro, `gPad->Update()`
1857should be performed after the histogram drawing. Once the list is
1858built, the contours are accessible in the following way:
1859
1860 TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
1861 Int_t ncontours = contours->GetSize();
1862 TList *list = (TList*)contours->At(i);
1863
1864Where `i` is a contour number, and list contains a list of
1865`TGraph` objects.
1866For one given contour, more than one disjoint polyline may be generated.
1867The number of TGraphs per contour is given by:
1868
1869 list->GetSize();
1870
1871To access the first graph in the list one should do:
1872
1873 TGraph *gr1 = (TGraph*)list->First();
1874
1875
1876The following example (ContourList.C) shows how to use this functionality.
1877
1878Begin_Macro(source)
1879../../../tutorials/hist/ContourList.C
1880End_Macro
1881
1882\anchor HP16b
1883#### The AITOFF, MERCATOR, SINUSOIDAL and PARABOLIC options
1884
1885The following options select the `CONT4` option and are useful for
1886sky maps or exposure maps (earth.C).
1887
1888| Option | Description |
1889|--------------|---------------------------------------------------------------|
1890| "AITOFF" | Draw a contour via an AITOFF projection.|
1891| "MERCATOR" | Draw a contour via an Mercator projection.|
1892| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1893| "PARABOLIC" | Draw a contour via an Parabolic projection.|
1894
1895Begin_Macro(source)
1896../../../tutorials/graphics/earth.C
1897End_Macro
1898
1899
1900\anchor HP17
1901### The LEGO options
1902
1903
1904In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1905is proportional to the cell content. The lego aspect is control with the
1906following options:
1907
1908| Option | Description |
1909|----------|-------------------------------------------------------------------|
1910| "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1911| "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1912| "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1913| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1914| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1915| "0" | When used with any LEGO option, the empty bins are not drawn.|
1916
1917
1918See the limitations with [the option "SAME"](\ref HP060a).
1919
1920Line attributes can be used in lego plots to change the edges' style.
1921
1922The following example shows a 2D histogram plotted with the option
1923`LEGO`. The option `LEGO` draws a lego plot using the hidden
1924lines removal technique.
1925
1926Begin_Macro(source)
1927{
1928 auto c2 = new TCanvas("c2","c2",600,400);
1929 auto hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1930 float px, py;
1931 for (Int_t i = 0; i < 25000; i++) {
1932 gRandom->Rannor(px,py);
1933 hlego->Fill(px-1,5*py);
1934 hlego->Fill(2+0.5*px,2*py-10.,0.1);
1935 }
1936 hlego->Draw("LEGO");
1937}
1938End_Macro
1939
1940The following example shows a 2D histogram plotted with the option
1941`LEGO1`. The option `LEGO1` draws a lego plot using the
1942hidden surface removal technique. Combined with any `LEGOn` option, the
1943option `0` allows to not drawn the empty bins.
1944
1945Begin_Macro(source)
1946{
1947 auto c2 = new TCanvas("c2","c2",600,400);
1948 auto hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1949 float px, py;
1950 for (Int_t i = 0; i < 25000; i++) {
1951 gRandom->Rannor(px,py);
1952 hlego1->Fill(px-1,5*py);
1953 hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1954 }
1955 hlego1->SetFillColor(kYellow);
1956 hlego1->Draw("LEGO1 0");
1957}
1958End_Macro
1959
1960The following example shows a 2D histogram plotted with the option
1961`LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1962draws a lego plot using the hidden surface removal technique but doesn't draw
1963the border lines of each individual lego-bar. This is very useful for histograms
1964having many bins. With such histograms the option `LEGO1` gives a black
1965image because of the border lines. This option also works with stacked legos.
1966
1967Begin_Macro(source)
1968{
1969 auto c2 = new TCanvas("c2","c2",600,400);
1970 auto hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1971 float px, py;
1972 for (Int_t i = 0; i < 25000; i++) {
1973 gRandom->Rannor(px,py);
1974 hlego3->Fill(px-1,5*py);
1975 hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1976 }
1977 hlego3->SetFillColor(kRed);
1978 hlego3->Draw("LEGO3");
1979}
1980End_Macro
1981
1982The following example shows a 2D histogram plotted with the option
1983`LEGO2`. The option `LEGO2` draws a lego plot using colors to
1984show the cell contents. Combined with the option `LEGO2`, the option
1985`Z` allows to display the color palette defined by
1986`gStyle->SetPalette()`.
1987
1988Begin_Macro(source)
1989{
1990 auto c2 = new TCanvas("c2","c2",600,400);
1991 auto hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1992 float px, py;
1993 for (Int_t i = 0; i < 25000; i++) {
1994 gRandom->Rannor(px,py);
1995 hlego2->Fill(px-1,5*py);
1996 hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1997 }
1998 hlego2->Draw("LEGO2Z");
1999}
2000End_Macro
2001
2002
2003
2004\anchor HP18
2005### The "SURFace" options
2006
2007
2008In a surface plot, cell contents are represented as a mesh.
2009The height of the mesh is proportional to the cell content.
2010
2011| Option | Description |
2012|----------|-------------------------------------------------------------------|
2013| "SURF" | Draw a surface plot using the hidden line removal technique.|
2014| "SURF1" | Draw a surface plot using the hidden surface removal technique.|
2015| "SURF2" | Draw a surface plot using colors to show the cell contents.|
2016| "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
2017| "SURF4" | Draw a surface using the Gouraud shading technique.|
2018| "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
2019| "SURF6" | This option should not be used directly. It is used internally when the CONT is used with option the option SAME on a 3D plot.|
2020| "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
2021
2022
2023
2024See the limitations with [the option "SAME"](\ref HP060a).
2025
2026The following example shows a 2D histogram plotted with the option
2027`SURF`. The option `SURF` draws a lego plot using the hidden
2028lines removal technique.
2029
2030Begin_Macro(source)
2031{
2032 auto c2 = new TCanvas("c2","c2",600,400);
2033 auto hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
2034 float px, py;
2035 for (Int_t i = 0; i < 25000; i++) {
2036 gRandom->Rannor(px,py);
2037 hsurf->Fill(px-1,5*py);
2038 hsurf->Fill(2+0.5*px,2*py-10.,0.1);
2039 }
2040 hsurf->Draw("SURF");
2041}
2042End_Macro
2043
2044The following example shows a 2D histogram plotted with the option
2045`SURF1`. The option `SURF1` draws a surface plot using the
2046hidden surface removal technique. Combined with the option `SURF1`,
2047the option `Z` allows to display the color palette defined by
2048`gStyle->SetPalette()`.
2049
2050Begin_Macro(source)
2051{
2052 auto c2 = new TCanvas("c2","c2",600,400);
2053 auto hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
2054 float px, py;
2055 for (Int_t i = 0; i < 25000; i++) {
2056 gRandom->Rannor(px,py);
2057 hsurf1->Fill(px-1,5*py);
2058 hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
2059 }
2060 hsurf1->Draw("SURF1");
2061}
2062End_Macro
2063
2064The following example shows a 2D histogram plotted with the option
2065`SURF2`. The option `SURF2` draws a surface plot using colors
2066to show the cell contents. Combined with the option `SURF2`, the option
2067`Z` allows to display the color palette defined by
2068`gStyle->SetPalette()`.
2069
2070Begin_Macro(source)
2071{
2072 auto c2 = new TCanvas("c2","c2",600,400);
2073 auto hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
2074 float px, py;
2075 for (Int_t i = 0; i < 25000; i++) {
2076 gRandom->Rannor(px,py);
2077 hsurf2->Fill(px-1,5*py);
2078 hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2079 }
2080 hsurf2->Draw("SURF2");
2081}
2082End_Macro
2083
2084The following example shows a 2D histogram plotted with the option
2085`SURF3`. The option `SURF3` draws a surface plot using the
2086hidden line removal technique with, in addition, a filled contour view drawn on the
2087top. Combined with the option `SURF3`, the option `Z` allows
2088to display the color palette defined by `gStyle->SetPalette()`.
2089
2090Begin_Macro(source)
2091{
2092 auto c2 = new TCanvas("c2","c2",600,400);
2093 auto hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2094 float px, py;
2095 for (Int_t i = 0; i < 25000; i++) {
2096 gRandom->Rannor(px,py);
2097 hsurf3->Fill(px-1,5*py);
2098 hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2099 }
2100 hsurf3->Draw("SURF3");
2101}
2102End_Macro
2103
2104The following example shows a 2D histogram plotted with the option
2105`SURF4`. The option `SURF4` draws a surface using the Gouraud
2106shading technique.
2107
2108Begin_Macro(source)
2109{
2110 auto c2 = new TCanvas("c2","c2",600,400);
2111 auto hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2112 float px, py;
2113 for (Int_t i = 0; i < 25000; i++) {
2114 gRandom->Rannor(px,py);
2115 hsurf4->Fill(px-1,5*py);
2116 hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2117 }
2118 hsurf4->SetFillColor(kOrange);
2119 hsurf4->Draw("SURF4");
2120}
2121End_Macro
2122
2123The following example shows a 2D histogram plotted with the option
2124`SURF5 CYL`. Combined with the option `SURF5`, the option
2125`Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2126
2127Begin_Macro(source)
2128{
2129 auto c2 = new TCanvas("c2","c2",600,400);
2130 auto hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2131 float px, py;
2132 for (Int_t i = 0; i < 25000; i++) {
2133 gRandom->Rannor(px,py);
2134 hsurf5->Fill(px-1,5*py);
2135 hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2136 }
2137 hsurf5->Draw("SURF5 CYL");
2138}
2139End_Macro
2140
2141The following example shows a 2D histogram plotted with the option
2142`SURF7`. The option `SURF7` draws a surface plot using the
2143hidden surfaces removal technique with, in addition, a line contour view drawn on the
2144top. Combined with the option `SURF7`, the option `Z` allows
2145to display the color palette defined by `gStyle->SetPalette()`.
2146
2147Begin_Macro(source)
2148{
2149 auto c2 = new TCanvas("c2","c2",600,400);
2150 auto hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2151 float px, py;
2152 for (Int_t i = 0; i < 25000; i++) {
2153 gRandom->Rannor(px,py);
2154 hsurf7->Fill(px-1,5*py);
2155 hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2156 }
2157 hsurf7->Draw("SURF7");
2158}
2159End_Macro
2160
2161As shown in the following example, when a contour plot is painted on top of a
2162surface plot using the option `SAME`, the contours appear in 3D on the
2163surface.
2164
2165Begin_Macro(source)
2166{
2167 auto c20=new TCanvas("c20","c20",600,400);
2168 int NBins = 50;
2169 double d = 2;
2170 auto hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2171 for (int bx = 1; bx <= NBins; ++bx) {
2172 for (int by = 1; by <= NBins; ++by) {
2173 double x = hsc->GetXaxis()->GetBinCenter(bx);
2174 double y = hsc->GetYaxis()->GetBinCenter(by);
2175 hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2176 }
2177 }
2178 hsc->Draw("surf2");
2179 hsc->Draw("CONT1 SAME");
2180}
2181End_Macro
2182
2183
2184\anchor HP19
2185### Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2186
2187
2188Legos and surfaces plots are represented by default in Cartesian coordinates.
2189Combined with any `LEGOn` or `SURFn` options the following
2190options allow to draw a lego or a surface in other coordinates systems.
2191
2192| Option | Description |
2193|----------|-------------------------------------------------------------------|
2194| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2195| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2196| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2197| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2198
2199
2200
2201<b>WARNING:</b> Axis are not drawn with these options.
2202
2203The following example shows the same histogram as a lego plot is the four
2204different coordinates systems.
2205
2206Begin_Macro(source)
2207{
2208 auto c3 = new TCanvas("c3","c3",600,400);
2209 c3->Divide(2,2);
2210 auto hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2211 float px, py;
2212 for (Int_t i = 0; i < 25000; i++) {
2213 gRandom->Rannor(px,py);
2214 hlcc->Fill(px-1,5*py);
2215 hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2216 }
2217 hlcc->SetFillColor(kYellow);
2218 c3->cd(1); hlcc->Draw("LEGO1 CYL");
2219 c3->cd(2); auto hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2220 hlpc->SetTitle("Polar coordinates");
2221 c3->cd(3); auto hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2222 hlsc->SetTitle("Spherical coordinates");
2223 c3->cd(4); auto hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2224 hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2225}
2226End_Macro
2227
2228The following example shows the same histogram as a surface plot is the four different coordinates systems.
2229
2230Begin_Macro(source)
2231{
2232 auto c4 = new TCanvas("c4","c4",600,400);
2233 c4->Divide(2,2);
2234 auto hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2235 float px, py;
2236 for (Int_t i = 0; i < 25000; i++) {
2237 gRandom->Rannor(px,py);
2238 hscc->Fill(px-1,5*py);
2239 hscc->Fill(2+0.5*px,2*py-10.,0.1);
2240 }
2241 c4->cd(1); hscc->Draw("SURF1 CYL");
2242 c4->cd(2); auto hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2243 hspc->SetTitle("Polar coordinates");
2244 c4->cd(3); auto hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2245 hssc->SetTitle("Spherical coordinates");
2246 c4->cd(4); auto hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2247 hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2248}
2249End_Macro
2250
2251
2252\anchor HP20
2253### Base line for bar-charts and lego plots
2254
2255
2256By default the base line used to draw the boxes for bar-charts and lego plots is
2257the histogram minimum. It is possible to force this base line to be 0, using MIN0 draw
2258option or with the command:
2259
2260 gStyle->SetHistMinimumZero();
2261
2262Begin_Macro(source)
2263{
2264 auto c5 = new TCanvas("c5","c5",700,400);
2265 c5->Divide(2,1);
2266 auto hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2267 auto hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2268 Int_t i;
2269 double x,y;
2270 hz1->SetFillColor(kBlue);
2271 hz2->SetFillColor(kBlue);
2272 for (i=0;i<10000;i++) {
2273 x = gRandom->Gaus(0,1);
2274 y = gRandom->Gaus(0,1);
2275 if (x>0) {
2276 hz1->Fill(x,1);
2277 hz2->Fill(x,y,1);
2278 } else {
2279 hz1->Fill(x,-1);
2280 hz2->Fill(x,y,-2);
2281 }
2282 }
2283 c5->cd(1); hz1->Draw("bar2 min0");
2284 c5->cd(2); hz2->Draw("lego1 min0");
2285}
2286End_Macro
2287
2288This option also works for horizontal plots. The example given in the section
2289["The bar chart option"](\ref HP100) appears as follow:
2290
2291Begin_Macro(source)
2292{
2293 int i;
2294 const Int_t nx = 8;
2295 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2296 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2297 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2298
2299 auto cbh = new TCanvas("cbh","cbh",400,600);
2300 cbh->SetGrid();
2301
2302 auto h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2303 h1bh->SetFillColor(4);
2304 h1bh->SetBarWidth(0.4);
2305 h1bh->SetBarOffset(0.1);
2306 h1bh->SetStats(0);
2307 h1bh->SetMinimum(-5);
2308 h1bh->SetMaximum(5);
2309
2310 for (i=1; i<=nx; i++) {
2311 h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2312 h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2313 }
2314
2315 h1bh->Draw("hbar min0");
2316
2317 auto h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2318 h2bh->SetFillColor(38);
2319 h2bh->SetBarWidth(0.4);
2320 h2bh->SetBarOffset(0.5);
2321 h2bh->SetStats(0);
2322 for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2323
2324 h2bh->Draw("hbar min0 same");
2325}
2326End_Macro
2327
2328
2329\anchor HP20a
2330### TH2Poly Drawing
2331
2332
2333The following options are supported:
2334
2335| Option | Description |
2336|----------|-------------------------------------------------------------------|
2337| "SCAT" | Draw a scatter plot (default).|
2338| "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2339| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2340| "0" | When used with any COL options, the empty bins are not drawn.|
2341| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2342| "TEXTN" | Draw bin names as text.|
2343| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2344| "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2345| "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2346| "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2347
2348
2349
2350`TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2351shapes. The bins are defined as graphs. The following macro is a very simple
2352example showing how to book a TH2Poly and draw it.
2353
2354Begin_Macro(source)
2355{
2356 auto ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2357 auto h2p = new TH2Poly();
2358 h2p->SetName("h2poly_name");
2359 h2p->SetTitle("h2poly_title");
2360 double px1[] = {0, 5, 6};
2361 double py1[] = {0, 0, 5};
2362 double px2[] = {0, -1, -1, 0};
2363 double py2[] = {0, 0, -1, 3};
2364 double px3[] = {4, 3, 0, 1, 2.4};
2365 double py3[] = {4, 3.7, 1, 3.7, 2.5};
2366 h2p->AddBin(3, px1, py1);
2367 h2p->AddBin(4, px2, py2);
2368 h2p->AddBin(5, px3, py3);
2369 h2p->Fill(0.1, 0.01, 3);
2370 h2p->Fill(-0.5, -0.5, 7);
2371 h2p->Fill(-0.7, -0.5, 1);
2372 h2p->Fill(1, 3, 1.5);
2373 double fx[] = {0.1, -0.5, -0.7, 1};
2374 double fy[] = {0.01, -0.5, -0.5, 3};
2375 double fw[] = {3, 1, 1, 1.5};
2376 h2p->FillN(4, fx, fy, fw);
2377 h2p->Draw("col");
2378}
2379End_Macro
2380
2381Rectangular bins are a frequent case. The special version of
2382the `AddBin` method allows to define them more easily like
2383shown in the following example (th2polyBoxes.C).
2384
2385Begin_Macro(source)
2386../../../tutorials/hist/th2polyBoxes.C
2387End_Macro
2388
2389One `TH2Poly` bin can be a list of polygons. Such bins are defined
2390by calling `AddBin` with a `TMultiGraph`. The following example
2391shows a such case:
2392
2393Begin_Macro(source)
2394{
2395 auto ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2396
2397 Int_t i, bin;
2398 const Int_t nx = 48;
2399 const char *states [nx] = {
2400 "alabama", "arizona", "arkansas", "california",
2401 "colorado", "connecticut", "delaware", "florida",
2402 "georgia", "idaho", "illinois", "indiana",
2403 "iowa", "kansas", "kentucky", "louisiana",
2404 "maine", "maryland", "massachusetts", "michigan",
2405 "minnesota", "mississippi", "missouri", "montana",
2406 "nebraska", "nevada", "new_hampshire", "new_jersey",
2407 "new_mexico", "new_york", "north_carolina", "north_dakota",
2408 "ohio", "oklahoma", "oregon", "pennsylvania",
2409 "rhode_island", "south_carolina", "south_dakota", "tennessee",
2410 "texas", "utah", "vermont", "virginia",
2411 "washington", "west_virginia", "wisconsin", "wyoming"
2412 };
2413 Double_t pop[nx] = {
2414 4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2415 9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2416 1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2417 1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2418 11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2419 24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2420 };
2421
2422 Double_t lon1 = -130;
2423 Double_t lon2 = -65;
2424 Double_t lat1 = 24;
2425 Double_t lat2 = 50;
2426 auto p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2427
2428 TFile::SetCacheFileDir(".");
2429 auto f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2430
2431 TMultiGraph *mg;
2432 TKey *key;
2433 TIter nextkey(gDirectory->GetListOfKeys());
2434 while ((key = (TKey*)nextkey())) {
2435 TObject *obj = key->ReadObj();
2436 if (obj->InheritsFrom("TMultiGraph")) {
2437 mg = (TMultiGraph*)obj;
2438 bin = p->AddBin(mg);
2439 }
2440 }
2441
2442 for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2443
2444 gStyle->SetOptStat(11);
2445 p->Draw("COLZ L");
2446}
2447End_Macro
2448
2449`TH2Poly` histograms can also be plotted using the GL interface using
2450the option "GLLEGO".
2451
2452\since **ROOT version 6.09/01**
2453
2454In some cases it can be useful to not draw the empty bins. the option "0"
2455combined with the option "COL" et COLZ allows to do that.
2456
2457Begin_Macro(source)
2458{
2459 auto chc = new TCanvas("chc","chc",600,400);
2460
2461 auto hc = new TH2Poly();
2462 hc->Honeycomb(0,0,.1,25,25);
2463 hc->SetName("hc");
2464 hc->SetTitle("Option COLZ 0");
2465 TRandom ran;
2466 for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2467 hc->Draw("colz 0");
2468}
2469End_Macro
2470
2471\anchor HP21
2472### The SPEC option
2473
2474
2475This option allows to use the `TSpectrum2Painter` tools. See the full
2476documentation in `TSpectrum2Painter::PaintSpectrum`.
2477
2478
2479\anchor HP22
2480### Option "Z" : Adding the color palette on the right side of the pad
2481
2482
2483When this option is specified, a color palette with an axis indicating the value
2484of the corresponding color is drawn on the right side of the picture. In case,
2485not enough space is left, one can increase the size of the right margin by
2486calling `TPad::SetRightMargin()`. The attributes used to display the
2487palette axis values are taken from the Z axis of the object. For example, to
2488set the labels size on the palette axis do:
2489
2490 hist->GetZaxis()->SetLabelSize().
2491
2492<b>WARNING:</b> The palette axis is always drawn vertically.
2493
2494
2495\anchor HP23
2496### Setting the color palette
2497
2498
2499To change the color palette `TStyle::SetPalette` should be used, eg:
2500
2501 gStyle->SetPalette(ncolors,colors);
2502
2503For example the option `COL` draws a 2D histogram with cells
2504represented by a box filled with a color index which is a function
2505of the cell content.
2506If the cell content is N, the color index used will be the color number
2507in `colors[N]`, etc. If the maximum cell content is greater than
2508`ncolors`, all cell contents are scaled to `ncolors`.
2509
2510If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2511defined. This palette is recommended for pads, labels ...
2512
2513`if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2514Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2515palette.
2516
2517Other pre-defined palettes with 255 colors are available when `colors == 0`.
2518The following value of `ncolors` give access to:
2519
2520
2521 if ncolors = 51 and colors=0, a Deep Sea palette is used.
2522 if ncolors = 52 and colors=0, a Grey Scale palette is used.
2523 if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2524 if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2525 if ncolors = 55 and colors=0, a Rain Bow palette is used.
2526 if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2527
2528
2529If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2530
2531The default palette defines:
2532
2533- index 0 to 9 : shades of grey
2534- index 10 to 19 : shades of brown
2535- index 20 to 29 : shades of blue
2536- index 30 to 39 : shades of red
2537- index 40 to 49 : basic colors
2538
2539The color numbers specified in the palette can be viewed by selecting
2540the item `colors` in the `VIEW` menu of the canvas tool bar.
2541The red, green, and blue components of a color can be changed thanks to
2542`TColor::SetRGB()`.
2543
2544\since **ROOT version 6.19/01**
2545
2546As default labels and ticks are drawn by `TGAxis` at equidistant (lin or log)
2547points as controlled by SetNdivisions.
2548If option "CJUST" is given labels and ticks are justified at the
2549color boundaries defined by the contour levels.
2550For more details see `TPaletteAxis`
2551
2552\anchor HP24
2553### Drawing a sub-range of a 2D histogram; the [cutg] option
2554
2555
2556Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2557histogram. One must create a graphical cut (mouse or C++) and specify the name
2558of the cut between `[]` in the `Draw()` option.
2559For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2560
2561 myhist->Draw("surf1 [cutg]");
2562
2563To invert the cut, it is enough to put a `-` in front of its name:
2564
2565 myhist->Draw("surf1 [-cutg]");
2566
2567It is possible to apply several cuts (`,` means logical AND):
2568
2569 myhist->Draw("surf1 [cutg1,cutg2]");
2570
2571Begin_Macro(source)
2572../../../tutorials/fit/fit2a.C
2573End_Macro
2574
2575\anchor HP25
2576### Drawing options for 3D histograms
2577
2578
2579| Option | Description |
2580|----------|-------------------------------------------------------------------|
2581| "ISO" | Draw a Gouraud shaded 3d iso surface through a 3d histogram. It paints one surface at the value computed as follow: `SumOfWeights/(NbinsX*NbinsY*NbinsZ)`|
2582| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2583| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2584| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2585| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2586| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2587
2588Note that instead of `BOX` one can also use `LEGO`.
2589
2590By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2591
2592The following example shows a 3D histogram plotted as a scatter plot.
2593
2594Begin_Macro(source)
2595{
2596 auto c06 = new TCanvas("c06","c06",600,400);
2597 gStyle->SetOptStat(kFALSE);
2598 auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2599 double x, y, z;
2600 for (Int_t i=0;i<10000;i++) {
2601 gRandom->Rannor(x, y);
2602 z = x*x + y*y;
2603 h3scat->Fill(x,y,z);
2604 }
2605 h3scat->Draw();
2606}
2607End_Macro
2608
2609The following example shows a 3D histogram plotted with the option `BOX`.
2610
2611Begin_Macro(source)
2612{
2613 auto c16 = new TCanvas("c16","c16",600,400);
2614 gStyle->SetOptStat(kFALSE);
2615 auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2616 double x, y, z;
2617 for (Int_t i=0;i<10000;i++) {
2618 gRandom->Rannor(x, y);
2619 z = x*x + y*y;
2620 h3box->Fill(x,y,z);
2621 }
2622 h3box->Draw("BOX");
2623}
2624End_Macro
2625
2626The following example shows a 3D histogram plotted with the option `BOX1`.
2627
2628Begin_Macro(source)
2629{
2630 auto c36 = new TCanvas("c36","c36",600,400);
2631 gStyle->SetOptStat(kFALSE);
2632 auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2633 double x, y, z;
2634 for (Int_t i=0;i<10000;i++) {
2635 gRandom->Rannor(x, y);
2636 z = abs(sin(x)/x + cos(y)*y);
2637 h3box->Fill(x,y,z);
2638 }
2639 h3box->SetFillColor(9);
2640 h3box->Draw("BOX1");
2641}
2642End_Macro
2643
2644The following example shows a 3D histogram plotted with the option `BOX2`.
2645
2646Begin_Macro(source)
2647{
2648 auto c56 = new TCanvas("c56","c56",600,400);
2649 gStyle->SetOptStat(kFALSE);
2650 auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2651 double x, y, z;
2652 for (Int_t i=0;i<10000;i++) {
2653 gRandom->Rannor(x, y);
2654 z = abs(sin(x)/x + cos(y)*y);
2655 h3box->Fill(x,y,z);
2656 }
2657 h3box->Draw("BOX2 Z");
2658}
2659End_Macro
2660
2661The following example shows a 3D histogram plotted with the option `BOX3`.
2662
2663Begin_Macro(source)
2664{
2665 auto c46 = new TCanvas("c46","c46",600,400);
2666 c46->SetFillColor(38);
2667 gStyle->SetOptStat(kFALSE);
2668 auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2669 double x, y, z;
2670 for (Int_t i=0;i<10000;i++) {
2671 gRandom->Rannor(x, y);
2672 z = x*x + y*y;
2673 h3box->Fill(x,y,z);
2674 }
2675 h3box->Draw("BOX3");
2676}
2677End_Macro
2678
2679For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2680to the absolute value of the bin content. The bins with a negative content are
2681drawn with a X on each face of the box as shown in the following example:
2682
2683Begin_Macro(source)
2684{
2685 auto c = new TCanvas("c","c",600,400);
2686 gStyle->SetOptStat(kFALSE);
2687 auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2688 h3box->Fill(0., 2., 2., 10.);
2689 h3box->Fill(2., 2., 2., 5.);
2690 h3box->Fill(2., 2., .5, 2.);
2691 h3box->Fill(2., 2., 3., -1.);
2692 h3box->Fill(3., 2., 2., -10.);
2693 h3box->SetFillColor(8);
2694 h3box->Draw("box1");
2695}
2696End_Macro
2697
2698The following example shows a 3D histogram plotted with the option `ISO`.
2699
2700Begin_Macro(source)
2701{
2702 auto c26 = new TCanvas("c26","c26",600,400);
2703 gStyle->SetOptStat(kFALSE);
2704 auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2705 double x, y, z;
2706 for (Int_t i=0;i<10000;i++) {
2707 gRandom->Rannor(x, y);
2708 z = x*x + y*y;
2709 h3iso->Fill(x,y,z);
2710 }
2711 h3iso->SetFillColor(kCyan);
2712 h3iso->Draw("ISO");
2713}
2714End_Macro
2715
2716
2717\anchor HP26
2718### Drawing option for histograms' stacks
2719
2720
2721Stacks of histograms are managed with the `THStack`. A `THStack`
2722is a collection of `TH1` (or derived) objects. For painting only the
2723`THStack` containing `TH1` only or
2724`THStack` containing `TH2` only will be considered.
2725
2726By default, histograms are shown stacked:
2727
27281. The first histogram is paint.
27292. The the sum of the first and second, etc...
2730
2731If the option `NOSTACK` is specified, the histograms are all paint in
2732the same pad as if the option `SAME` had been specified. This allows to
2733compute X and Y scales common to all the histograms, like
2734`TMultiGraph` does for graphs.
2735
2736If the option `PADS` is specified, the current pad/canvas is
2737subdivided into a number of pads equal to the number of histograms and each
2738histogram is paint into a separate pad.
2739
2740The following example shows various types of stacks (hstack.C).
2741
2742Begin_Macro(source)
2743../../../tutorials/hist/hstack.C
2744End_Macro
2745
2746The option `nostackb` allows to draw the histograms next to each
2747other as bar charts:
2748
2749Begin_Macro(source)
2750{
2751 auto cst0 = new TCanvas("cst0","cst0",600,400);
2752 auto hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2753
2754 auto h1 = new TH1F("h1","h1",10,-4,4);
2755 h1->FillRandom("gaus",20000);
2756 h1->SetFillColor(kRed);
2757 hs->Add(h1);
2758
2759 auto h2 = new TH1F("h2","h2",10,-4,4);
2760 h2->FillRandom("gaus",15000);
2761 h2->SetFillColor(kBlue);
2762 hs->Add(h2);
2763
2764 auto h3 = new TH1F("h3","h3",10,-4,4);
2765 h3->FillRandom("gaus",10000);
2766 h3->SetFillColor(kGreen);
2767 hs->Add(h3);
2768
2769 hs->Draw("nostackb");
2770 hs->GetXaxis()->SetNdivisions(-10);
2771 cst0->SetGridx();
2772}
2773End_Macro
2774
2775If at least one of the histograms in the stack has errors, the whole stack is
2776visualized by default with error bars. To visualize it without errors the
2777option `HIST` should be used.
2778
2779Begin_Macro(source)
2780{
2781 auto cst1 = new TCanvas("cst1","cst1",700,400);
2782 cst1->Divide(2,1);
2783
2784 auto hst11 = new TH1F("hst11", "", 20, -10, 10);
2785 hst11->Sumw2();
2786 hst11->FillRandom("gaus", 1000);
2787 hst11->SetFillColor(kViolet);
2788 hst11->SetLineColor(kViolet);
2789
2790 auto hst12 = new TH1F("hst12", "", 20, -10, 10);
2791 hst12->FillRandom("gaus", 500);
2792 hst12->SetFillColor(kBlue);
2793 hst12->SetLineColor(kBlue);
2794
2795 THStack st1("st1", "st1");
2796 st1.Add(hst11);
2797 st1.Add(hst12);
2798
2799 cst1->cd(1); st1.Draw();
2800 cst1->cd(2); st1.Draw("hist");
2801}
2802End_Macro
2803
2804\anchor HP27
2805### Drawing of 3D implicit functions
2806
2807
28083D implicit functions (`TF3`) can be drawn as iso-surfaces.
2809The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2810In the following example the options "FB" and "BB" suppress the
2811"Front Box" and "Back Box" around the plot.
2812
2813Begin_Macro(source)
2814{
2815 auto c2 = new TCanvas("c2","c2",600,400);
2816 auto f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2817 f3->SetClippingBoxOn(0,0,0);
2818 f3->SetFillColor(30);
2819 f3->SetLineColor(15);
2820 f3->Draw("FBBB");
2821}
2822End_Macro
2823
2824
2825\anchor HP28
2826### Associated functions drawing
2827
2828
2829An associated function is created by `TH1::Fit`. More than on fitted
2830function can be associated with one histogram (see `TH1::Fit`).
2831
2832A `TF1` object `f1` can be added to the list of associated
2833functions of an histogram `h` without calling `TH1::Fit`
2834simply doing:
2835
2836 h->GetListOfFunctions()->Add(f1);
2837
2838or
2839
2840 h->GetListOfFunctions()->Add(f1,someoption);
2841
2842To retrieve a function by name from this list, do:
2843
2844 TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2845
2846or
2847
2848 TF1 *f1 = h->GetFunction(name);
2849
2850Associated functions are automatically painted when an histogram is drawn.
2851To avoid the painting of the associated functions the option `HIST`
2852should be added to the list of the options used to paint the histogram.
2853
2854
2855\anchor HP29
2856### Drawing using OpenGL
2857
2858
2859The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2860graphics library. The plotting options start with `GL` keyword.
2861In addition, in order to inform canvases that OpenGL should be used to render
28623D representations, the following option should be set:
2863
2864 gStyle->SetCanvasPreferGL(true);
2865
2866
2867\anchor HP29a
2868#### General information: plot types and supported options
2869
2870The following types of plots are provided:
2871
2872For lego plots the supported options are:
2873
2874| Option | Description |
2875|----------|-------------------------------------------------------------------|
2876| "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2877| "GLLEGO2"| Bins with color levels.|
2878| "GLLEGO3"| Cylindrical bars.|
2879
2880
2881
2882Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2883In polar only Z axis can be logarithmic, in cylindrical only Y.
2884
2885For surface plots (`TF2` and `TH2`) the supported options are:
2886
2887| Option | Description |
2888|-----------|------------------------------------------------------------------|
2889| "GLSURF" | Draw a surface.|
2890| "GLSURF1" | Surface with color levels|
2891| "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2892| "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2893| "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2894
2895
2896
2897The surface painting in cartesian coordinates supports logarithmic scales along
2898X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2899in cylindrical coordinates only the Y axis.
2900
2901Additional options to SURF and LEGO - Coordinate systems:
2902
2903| Option | Description |
2904|----------|-------------------------------------------------------------------|
2905| " " | Default, cartesian coordinates system.|
2906| "POL" | Polar coordinates system.|
2907| "CYL" | Cylindrical coordinates system.|
2908| "SPH" | Spherical coordinates system.|
2909
2910
2911
2912\anchor HP290
2913#### TH3 as color boxes
2914
2915The supported option is:
2916
2917| Option | Description |
2918|----------|-------------------------------------------------------------------|
2919| "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2920
2921
2922
2923\anchor HP29b
2924#### TH3 as boxes (spheres)
2925
2926The supported options are:
2927
2928| Option | Description |
2929|----------|-------------------------------------------------------------------|
2930| "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2931| "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2932
2933
2934
2935\anchor HP29c
2936#### TH3 as iso-surface(s)
2937
2938The supported option is:
2939
2940| Option | Description |
2941|----------|-------------------------------------------------------------------|
2942| "GLISO" | TH3 is drawn using iso-surfaces.|
2943
2944
2945
2946\anchor HP29d
2947#### TF3 (implicit function)
2948
2949The supported option is:
2950
2951| Option | Description |
2952|----------|-------------------------------------------------------------------|
2953| "GL" | Draw a TF3.|
2954
2955
2956
2957\anchor HP29e
2958#### Parametric surfaces
2959
2960`$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2961equations and visualize the surface.
2962
2963\anchor HP29f
2964#### Interaction with the plots
2965
2966All the interactions are implemented via standard methods
2967`DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2968interactions with the OpenGL plots are possible only when the mouse cursor is
2969in the plot's area (the plot's area is the part of a the pad occupied by
2970gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2971pad interaction is performed.
2972
2973\anchor HP29g
2974#### Selectable parts
2975
2976Different parts of the plot can be selected:
2977
2978- xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2979 if the dynamic slicing by this plane is supported, and it's highlighted in red,
2980 if the dynamic slicing is not supported.
2981- The plot itself:
2982 On surfaces, the selected surface is outlined in red. (TF3 and
2983 ISO are not outlined). On lego plots, the selected bin is
2984 highlighted. The bin number and content are displayed in pad's
2985 status bar. In box plots, the box or sphere is highlighted and
2986 the bin info is displayed in pad's status bar.
2987
2988
2989\anchor HP29h
2990#### Rotation and zooming
2991
2992
2993- Rotation:
2994 When the plot is selected, it can be rotated by pressing and
2995 holding the left mouse button and move the cursor.
2996- Zoom/Unzoom:
2997 Mouse wheel or 'j', 'J', 'k', 'K' keys.
2998
2999
3000\anchor HP29i
3001#### Panning
3002
3003The selected plot can be moved in a pad's area by pressing and
3004holding the left mouse button and the shift key.
3005
3006\anchor HP29j
3007#### Box cut
3008
3009Surface, iso, box, TF3 and parametric painters support box cut by
3010pressing the 'c' or 'C' key when the mouse cursor is in a plot's
3011area. That will display a transparent box, cutting away part of the
3012surface (or boxes) in order to show internal part of plot. This box
3013can be moved inside the plot's area (the full size of the box is
3014equal to the plot's surrounding box) by selecting one of the box
3015cut axes and pressing the left mouse button to move it.
3016
3017\anchor HP29k
3018#### Plot specific interactions (dynamic slicing etc.)
3019
3020Currently, all gl-plots support some form of slicing. When back plane
3021is selected (and if it's highlighted in green) you can press and hold
3022left mouse button and shift key and move this back plane inside
3023plot's area, creating the slice. During this "slicing" plot becomes
3024semi-transparent. To remove all slices (and projected curves for
3025surfaces) double click with left mouse button in a plot's area.
3026
3027\anchor HP29l
3028#### Surface with option "GLSURF"
3029
3030The surface profile is displayed on the slicing plane.
3031The profile projection is drawn on the back plane
3032by pressing `'p'` or `'P'` key.
3033
3034\anchor HP29m
3035#### TF3
3036
3037The contour plot is drawn on the slicing plane. For TF3 the color
3038scheme can be changed by pressing 's' or 'S'.
3039
3040\anchor HP29n
3041#### Box
3042
3043The contour plot corresponding to slice plane position is drawn in real time.
3044
3045\anchor HP29o
3046#### Iso
3047
3048Slicing is similar to "GLBOX" option.
3049
3050\anchor HP29p
3051#### Parametric plot
3052
3053No slicing. Additional keys: 's' or 'S' to change color scheme -
3054about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
3055increase number of polygons ('l' for "level" of details), 'w' or 'W'
3056to show outlines ('w' for "wireframe").
3057
3058\anchor HP30
3059#### Highlight mode for histogram
3060
3061\since **ROOT version 6.15/01**
3062
3063\image html hlHisto3_top.gif "Highlight mode"
3064
3065Highlight mode is implemented for `TH1` (and for `TGraph`) class. When
3066highlight mode is on, mouse movement over the bin will be represented
3067graphically. Bin will be highlighted as "bin box" (presented by box
3068object). Moreover, any highlight (change of bin) emits signal
3069`TCanvas::Highlighted()` which allows the user to react and call their own
3070function. For a better understanding see also the tutorials
3071`$ROOTSYS/tutorials/hist/hlHisto*.C` files.
3072
3073Highlight mode is switched on/off by `TH1::SetHighlight()` function
3074or interactively from `TH1` context menu. `TH1::IsHighlight()` to verify
3075whether the highlight mode enabled or disabled, default it is disabled.
3076
3077~~~ {.cpp}
3078 root [0] .x $ROOTSYS/tutorials/hsimple.C
3079 root [1] hpx->SetHighlight(kTRUE) // or interactively from TH1 context menu
3080 root [2] hpx->IsHighlight()
3081 (bool) true
3082~~~
3083
3084\image html hlsimple_nofun.gif "Highlight mode for histogram"
3085
3086\anchor HP30a
3087#### Highlight mode and user function
3088
3089The user can use (connect) `TCanvas::Highlighted()` signal, which is always
3090emitted if there is a highlight bin and call user function via signal
3091and slot communication mechanism. `TCanvas::Highlighted()` is similar
3092`TCanvas::Picked()`
3093
3094- when selected object (histogram as a whole) is different from previous
3095then emit `Picked()` signal
3096- when selected (highlighted) bin from histogram is different from previous
3097then emit `Highlighted()` signal
3098
3099Any user function (or functions) has to be defined
3100`UserFunction(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)`.
3101In example (see below) has name `PrintInfo()`. All parameters of user
3102function are taken from
3103
3104 void TCanvas::Highlighted(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3105
3106- `pad` is pointer to pad with highlighted histogram
3107- `obj` is pointer to highlighted histogram
3108- `x` is highlighted x bin for 1D histogram
3109- `y` is highlighted y bin for 2D histogram (for 1D histogram not in use)
3110
3111Example how to create a connection from any `TCanvas` object to a user
3112`UserFunction()` slot (see also `TQObject::Connect()` for additional info)
3113
3114 TQObject::Connect("TCanvas", "Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
3115 0, 0, "UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3116
3117or use non-static "simplified" function
3118`TCanvas::HighlightConnect(const char *slot)`
3119
3120 c1->HighlightConnect("UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3121
3122NOTE the signal and slot string must have a form
3123"(TVirtualPad*,TObject*,Int_t,Int_t)"
3124
3125 root [0] .x $ROOTSYS/tutorials/hsimple.C
3126 root [1] hpx->SetHighlight(kTRUE)
3127 root [2] .x hlprint.C
3128
3129file `hlprint.C`
3130~~~ {.cpp}
3131void PrintInfo(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3132{
3133 auto h = (TH1F *)obj;
3134 if (!h->IsHighlight()) // after highlight disabled
3135 h->SetTitle("highlight disable");
3136 else
3137 h->SetTitle(TString::Format("bin[%03d] (%5.2f) content %g", x,
3138 h->GetBinCenter(x), h->GetBinContent(x)));
3139 pad->Update();
3140}
3141
3142void hlprint()
3143{
3144 if (!gPad) return;
3145 gPad->GetCanvas()->HighlightConnect("PrintInfo(TVirtualPad*,TObject*,Int_t,Int_t)");
3146}
3147~~~
3148
3149\image html hlsimple.gif "Highlight mode and simple user function"
3150
3151For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperature.C` file.
3152
3153*/
3154
3156
3159
3160const Int_t kNMAX = 2000;
3161
3162const Int_t kMAXCONTOUR = 104;
3164
3165static TBox *gXHighlightBox = 0; // highlight X box
3166static TBox *gYHighlightBox = 0; // highlight Y box
3167
3189
3191
3192////////////////////////////////////////////////////////////////////////////////
3193/// Default constructor.
3194
3196{
3197
3198 fH = 0;
3199 fXaxis = 0;
3200 fYaxis = 0;
3201 fZaxis = 0;
3202 fFunctions = 0;
3203 fXbuf = 0;
3204 fYbuf = 0;
3205 fNcuts = 0;
3206 fStack = 0;
3207 fLego = 0;
3208 fPie = 0;
3209 fGraph2DPainter = 0;
3210 fShowProjection = 0;
3211 fShowOption = "";
3212 for (int i=0; i<kMaxCuts; i++) {
3213 fCuts[i] = 0;
3214 fCutsOpt[i] = 0;
3215 }
3216 fXHighlightBin = -1;
3217 fYHighlightBin = -1;
3218 fCurrentF3 = nullptr;
3219
3220 gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
3221 gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
3222 gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
3223 gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
3224 gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3225 gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3226 gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3227 gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3228 gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3229 gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3230 gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3231 gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3232 gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3233 gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3234 gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3235 gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3236 gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3237 gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3238 gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3239 gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3240 gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3241}
3242
3243////////////////////////////////////////////////////////////////////////////////
3244/// Default destructor.
3245
3247{
3248 if (fPie) delete fPie;
3249}
3250
3251////////////////////////////////////////////////////////////////////////////////
3252/// Compute the distance from the point px,py to a line.
3253///
3254/// Compute the closest distance of approach from point px,py to elements of
3255/// an histogram. The distance is computed in pixels units.
3256///
3257/// Algorithm: Currently, this simple model computes the distance from the mouse
3258/// to the histogram contour only.
3259
3261{
3262
3263 Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3264
3265 const Int_t big = 9999;
3266 const Int_t kMaxDiff = 7;
3267
3268 if (fPie) return fPie->DistancetoPrimitive(px, py);
3269
3270 Double_t x = gPad->AbsPixeltoX(px);
3271 Double_t x1 = gPad->AbsPixeltoX(px+1);
3272
3273 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3274 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3275 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3276 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3277 Int_t curdist = big;
3278 Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3279 Bool_t dsame;
3280 TObject *PadPointer = gPad->GetPadPointer();
3281 if (!PadPointer) return 0;
3282 TString doption = PadPointer->GetDrawOption();
3283 Double_t factor = 1;
3284 if (fH->GetNormFactor() != 0) {
3285 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3286 }
3287 // return if point is not in the histogram area
3288
3289 // If a 3D view exists, check distance to axis
3290 TView *view = gPad->GetView();
3291 Int_t d1,d2,d3;
3292 if (view && Hoption.Contour != 14) {
3293 Double_t ratio;
3294 d3 = view->GetDistancetoAxis(3, px, py, ratio);
3295 if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3296 d1 = view->GetDistancetoAxis(1, px, py, ratio);
3297 if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3298 d2 = view->GetDistancetoAxis(2, px, py, ratio);
3299 if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3300 if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3301 goto FUNCTIONS;
3302 }
3303 // check if point is close to an axis
3304 doption.ToLower();
3305 dsame = kFALSE;
3306 if (doption.Contains("same")) dsame = kTRUE;
3307
3308 dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3309 if (doption.Contains("y+")) {
3310 xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3311 if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3312 if (!dsame) {
3313 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3314 else gPad->SetSelected(fXaxis);
3315 return 0;
3316 }
3317 }
3318 } else {
3319 xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3320 if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3321 if (!dsame) {
3322 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3323 else gPad->SetSelected(fXaxis);
3324 return 0;
3325 }
3326 }
3327 }
3328
3329 dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3330 if (doption.Contains("x+")) {
3331 yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3332 if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3333 if (!dsame) {
3334 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3335 else gPad->SetSelected(fYaxis);
3336 return 0;
3337 }
3338 }
3339 } else {
3340 yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3341 if (yxaxis < puymin) yxaxis = puymin;
3342 if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3343 if (!dsame) {
3344 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3345 else gPad->SetSelected(fYaxis);
3346 return 0;
3347 }
3348 }
3349 }
3350
3351 if (fH->IsHighlight()) { // only if highlight is enable
3352 if ((px > puxmin) && (py < puymin) && (px < puxmax) && (py > puymax))
3353 HighlightBin(px, py);
3354 }
3355
3356 // if object is 2D or 3D return this object
3357 if (fH->GetDimension() == 2) {
3358 if (fH->InheritsFrom(TH2Poly::Class())) {
3359 TH2Poly *th2 = (TH2Poly*)fH;
3361 gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3362 Double_t pxu = gPad->AbsPixeltoX(px);
3363 Double_t pyu = gPad->AbsPixeltoY(py);
3364 if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3365 curdist = big;
3366 goto FUNCTIONS;
3367 } else {
3368 Int_t bin = th2->FindBin(pxu, pyu);
3369 if (bin>0) curdist = 1;
3370 else curdist = big;
3371 goto FUNCTIONS;
3372 }
3373 }
3374 Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3375 if ( px > puxmin + delta2
3376 && px < puxmax - delta2
3377 && py > puymax + delta2
3378 && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3379 }
3380
3381 // point is inside histogram area. Find channel number
3382 if (gPad->IsVertical()) {
3383 Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3384 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3385 Double_t binval = factor*fH->GetBinContent(bin);
3386 Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3387 if (binval == 0 && pybin < puymin) pybin = 10000;
3388 // special case if more than one bin for the pixel
3389 if (binsup-bin>1) {
3390 Double_t binvalmin, binvalmax;
3391 binvalmin=binval;
3392 binvalmax=binval;
3393 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3394 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3395 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3396 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3397 }
3398 Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3399 Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3400 if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3401 }
3402 if (bin != binsup) { // Mouse on bin border
3403 Double_t binsupval = factor*fH->GetBinContent(binsup);
3404 Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3405 if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3406 }
3407 if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3408 } else {
3409 Double_t y = gPad->AbsPixeltoY(py);
3410 Double_t y1 = gPad->AbsPixeltoY(py+1);
3411 Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3412 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3413 Double_t binval = factor*fH->GetBinContent(bin);
3414 Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3415 if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3416 // special case if more than one bin for the pixel
3417 if (binsup-bin>1) {
3418 Double_t binvalmin, binvalmax;
3419 binvalmin=binval;
3420 binvalmax=binval;
3421 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3422 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3423 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3424 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3425 }
3426 Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3427 Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3428 if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3429 }
3430 if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3431 }
3432 // Loop on the list of associated functions and user objects
3433FUNCTIONS:
3434 TObject *f;
3435 TIter next(fFunctions);
3436 while ((f = (TObject*) next())) {
3437 Int_t dist;
3438 if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3439 else dist = f->DistancetoPrimitive(px,py);
3440 if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3441 }
3442 return curdist;
3443}
3444
3445////////////////////////////////////////////////////////////////////////////////
3446/// Display a panel with all histogram drawing options.
3447
3449{
3450
3451 gCurrentHist = fH;
3452 if (!gPad) {
3453 Error("DrawPanel", "need to draw histogram first");
3454 return;
3455 }
3457 editor->Show();
3458 gROOT->ProcessLine(Form("((TCanvas*)0x%zx)->Selected((TVirtualPad*)0x%zx,(TObject*)0x%zx,1)",
3459 (size_t)gPad->GetCanvas(), (size_t)gPad, (size_t)fH));
3460}
3461
3462////////////////////////////////////////////////////////////////////////////////
3463/// Execute the actions corresponding to `event`.
3464///
3465/// This function is called when a histogram is clicked with the locator at
3466/// the pixel position px,py.
3467
3469{
3470
3471 if (!gPad) return;
3472
3473 static Int_t bin, px1, py1, px2, py2, pyold;
3474 static TBox *zoombox = nullptr;
3475 Double_t zbx1,zbx2,zby1,zby2;
3476
3477 Int_t bin1, bin2;
3478 Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3479 Bool_t opaque = gPad->OpaqueMoving();
3480
3481 if (!gPad->IsEditable()) return;
3482
3483 if (fPie) {
3484 fPie->ExecuteEvent(event, px, py);
3485 return;
3486 }
3487 // come here if we have a lego/surface in the pad
3488 TView *view = gPad->GetView();
3489
3490 if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3491 view->ExecuteRotateView(event, px, py);
3492 return;
3493 }
3494
3495 TAxis *xaxis = fH->GetXaxis();
3496 TAxis *yaxis = fH->GetYaxis();
3497 Int_t dimension = fH->GetDimension();
3498
3499 // In case of option SAME the axis must be the ones of the first drawn histogram
3500 TString IsSame = fH->GetDrawOption();
3501 IsSame.ToLower();
3502 if (IsSame.Index("same")>=0) {
3503 TH1 *h1;
3504 TIter next(gPad->GetListOfPrimitives());
3505 while ((h1 = (TH1 *)next())) {
3506 if (!h1->InheritsFrom(TH1::Class())) continue;
3507 xaxis = h1->GetXaxis();
3508 yaxis = h1->GetYaxis();
3509 break;
3510 }
3511 }
3512
3513 Double_t factor = 1;
3514 if (fH->GetNormFactor() != 0) {
3515 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3516 }
3517
3518 switch (event) {
3519
3520 case kButton1Down:
3521
3522 if (!opaque) gVirtualX->SetLineColor(-1);
3523 fH->TAttLine::Modify();
3524
3525 if (opaque && dimension ==2) {
3526 zbx1 = gPad->AbsPixeltoX(px);
3527 zbx2 = gPad->AbsPixeltoX(px);
3528 zby1 = gPad->AbsPixeltoY(py);
3529 zby2 = gPad->AbsPixeltoY(py);
3530 px1 = px;
3531 py1 = py;
3532 if (gPad->GetLogx()) {
3533 zbx1 = TMath::Power(10,zbx1);
3534 zbx2 = TMath::Power(10,zbx2);
3535 }
3536 if (gPad->GetLogy()) {
3537 zby1 = TMath::Power(10,zby1);
3538 zby2 = TMath::Power(10,zby2);
3539 }
3540 if (zoombox) Error("ExecuteEvent", "Last zoom box was not deleted");
3541 zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3542 Int_t ci = TColor::GetColor("#7d7dff");
3543 TColor *zoomcolor = gROOT->GetColor(ci);
3544 if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3545 else zoomcolor->SetAlpha(0.5);
3546 zoombox->SetFillColor(ci);
3547 zoombox->Draw();
3548 gPad->Modified();
3549 gPad->Update();
3550 }
3551 // No break !!!
3552
3553 case kMouseMotion:
3554
3555 if (fShowProjection) {ShowProjection3(px,py); break;}
3556
3557 gPad->SetCursor(kPointer);
3558 if (dimension ==1) {
3559 if (Hoption.Bar) {
3560 baroffset = fH->GetBarOffset();
3561 barwidth = fH->GetBarWidth();
3562 } else {
3563 baroffset = 0;
3564 barwidth = 1;
3565 }
3566 x = gPad->AbsPixeltoX(px);
3567 bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3568 binwidth = fXaxis->GetBinWidth(bin);
3569 xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3570 xup = gPad->XtoPad(xlow + barwidth*binwidth);
3571 ylow = gPad->GetUymin();
3572 px1 = gPad->XtoAbsPixel(xlow);
3573 px2 = gPad->XtoAbsPixel(xup);
3574 py1 = gPad->YtoAbsPixel(ylow);
3575 py2 = py;
3576 pyold = py;
3577 if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3578 }
3579
3580 break;
3581
3582 case kButton1Motion:
3583
3584 if (dimension ==1) {
3585 if (gROOT->GetEditHistograms()) {
3586 if (!opaque) {
3587 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3588 py2 += py - pyold;
3589 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3590 pyold = py;
3591 } else {
3592 py2 += py - pyold;
3593 pyold = py;
3594 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3595 fH->SetBinContent(bin,binval);
3596 gPad->Modified(kTRUE);
3597 }
3598 }
3599 }
3600
3601 if (opaque && dimension ==2) {
3602 if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3603 zbx2 = gPad->AbsPixeltoX(px);
3604 zby2 = gPad->AbsPixeltoY(py);
3605 if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3606 if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3607 if (zoombox) {
3608 zoombox->SetX2(zbx2);
3609 zoombox->SetY2(zby2);
3610 }
3611 gPad->Modified();
3612 gPad->Update();
3613 }
3614 }
3615
3616 break;
3617
3618 case kWheelUp:
3619
3620 if (dimension ==2) {
3621 bin1 = xaxis->GetFirst()+1;
3622 bin2 = xaxis->GetLast()-1;
3623 bin1 = TMath::Max(bin1, 1);
3624 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3625 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3626 bin1 = yaxis->GetFirst()+1;
3627 bin2 = yaxis->GetLast()-1;
3628 bin1 = TMath::Max(bin1, 1);
3629 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3630 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3631 }
3632 gPad->Modified();
3633 gPad->Update();
3634
3635 break;
3636
3637 case kWheelDown:
3638
3639 if (dimension == 2) {
3640 bin1 = xaxis->GetFirst()-1;
3641 bin2 = xaxis->GetLast()+1;
3642 bin1 = TMath::Max(bin1, 1);
3643 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3644 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3645 bin1 = yaxis->GetFirst()-1;
3646 bin2 = yaxis->GetLast()+1;
3647 bin1 = TMath::Max(bin1, 1);
3648 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3649 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3650 }
3651 gPad->Modified();
3652 gPad->Update();
3653
3654 break;
3655
3656 case kButton1Up:
3657 if (dimension ==1) {
3658 if (gROOT->GetEditHistograms()) {
3659 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3660 fH->SetBinContent(bin,binval);
3661 PaintInit(); // recalculate Hparam structure and recalculate range
3662 }
3663
3664 // might resize pad pixmap so should be called before any paint routine
3666 }
3667 if (opaque && dimension ==2) {
3668 if (zoombox) {
3669 Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3670 Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3671 Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3672 Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3673 x1 = TMath::Max(x1,xaxis->GetXmin());
3674 x2 = TMath::Min(x2,xaxis->GetXmax());
3675 y1 = TMath::Max(y1,yaxis->GetXmin());
3676 y2 = TMath::Min(y2,yaxis->GetXmax());
3677 if (x1<x2 && y1<y2) {
3678 xaxis->SetRangeUser(x1, x2);
3679 yaxis->SetRangeUser(y1, y2);
3680 }
3681 zoombox->Delete();
3682 zoombox = nullptr;
3683 }
3684 }
3685 gPad->Modified(kTRUE);
3686 if (opaque) gVirtualX->SetLineColor(-1);
3687
3688 break;
3689
3690 case kButton1Locate:
3691
3692 ExecuteEvent(kButton1Down, px, py);
3693
3694 while (1) {
3695 px = py = 0;
3696 event = gVirtualX->RequestLocator(1, 1, px, py);
3697
3699
3700 if (event != -1) { // button is released
3701 ExecuteEvent(kButton1Up, px, py);
3702 return;
3703 }
3704 }
3705 }
3706}
3707
3708////////////////////////////////////////////////////////////////////////////////
3709/// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3710
3712{
3713
3714
3715
3716 // Check if fH contains a TGraphDelaunay2D
3717 TList *hl = fH->GetListOfFunctions();
3718 TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3719 // try with the old painter
3720 TGraphDelaunay *dtOld = nullptr;
3721 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3722
3723 if (!dt && !dtOld) return nullptr;
3724
3725 gCurrentHist = fH;
3726
3727 if (!fGraph2DPainter) {
3728 if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3729 else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3730 }
3731
3732 return fGraph2DPainter->GetContourList(contour);
3733}
3734
3735////////////////////////////////////////////////////////////////////////////////
3736/// Display the histogram info (bin number, contents, integral up to bin
3737/// corresponding to cursor position px,py.
3738
3740{
3741
3742 if (!gPad) return (char*)"";
3743
3744 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3745 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3746 Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3747 TString drawOption = fH->GetDrawOption();
3748 drawOption.ToLower();
3749 Double_t xmin, xmax, uxmin,uxmax;
3750 Double_t ymin, ymax, uymin,uymax;
3751 if (fH->GetDimension() == 2) {
3752 if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3753 uxmin=gPad->GetUxmin();
3754 uxmax=gPad->GetUxmax();
3757 x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3758 uymin=gPad->GetUymin();
3759 uymax=gPad->GetUymax();
3762 y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3763 }
3764 }
3765 Int_t binx,biny,binmin=0,binx1;
3766 if (gPad->IsVertical()) {
3767 binx = fXaxis->FindFixBin(x);
3768 if (drawOption.Index("same") >= 0) {
3769 TH1 *h1;
3770 TIter next(gPad->GetListOfPrimitives());
3771 while ((h1 = (TH1 *)next())) {
3772 if (!h1->InheritsFrom(TH1::Class())) continue;
3773 binmin = h1->GetXaxis()->GetFirst();
3774 break;
3775 }
3776 } else {
3777 binmin = fXaxis->GetFirst();
3778 }
3779 binx1 = fXaxis->FindFixBin(x1);
3780 // special case if more than 1 bin in x per pixel
3781 if (binx1-binx>1 && fH->GetDimension() == 1) {
3782 Double_t binval=fH->GetBinContent(binx);
3783 Int_t binnear=binx;
3784 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3785 Double_t binvaltmp = fH->GetBinContent(ibin);
3786 if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3787 binval=binvaltmp;
3788 binnear=ibin;
3789 }
3790 }
3791 binx = binnear;
3792 }
3793 } else {
3794 x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3795 binx = fXaxis->FindFixBin(y);
3796 if (drawOption.Index("same") >= 0) {
3797 TH1 *h1;
3798 TIter next(gPad->GetListOfPrimitives());
3799 while ((h1 = (TH1 *)next())) {
3800 if (!h1->InheritsFrom(TH1::Class())) continue;
3801 binmin = h1->GetXaxis()->GetFirst();
3802 break;
3803 }
3804 } else {
3805 binmin = fXaxis->GetFirst();
3806 }
3807 binx1 = fXaxis->FindFixBin(x1);
3808 // special case if more than 1 bin in x per pixel
3809 if (binx1-binx>1 && fH->GetDimension() == 1) {
3810 Double_t binval=fH->GetBinContent(binx);
3811 Int_t binnear=binx;
3812 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3813 Double_t binvaltmp = fH->GetBinContent(ibin);
3814 if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3815 binval=binvaltmp;
3816 binnear=ibin;
3817 }
3818 }
3819 binx = binnear;
3820 }
3821 }
3822 if (fH->GetDimension() == 1) {
3823 if (fH->InheritsFrom(TProfile::Class())) {
3824 TProfile *tp = (TProfile*)fH;
3825 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3826 x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3827 (Int_t) tp->GetBinEntries(binx));
3828 }
3829 else {
3830 Double_t integ = 0;
3831 for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3832 fObjectInfo.Form("(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3833 x,y,binx,fH->GetBinContent(binx),integ);
3834 }
3835 } else if (fH->GetDimension() == 2) {
3836 if (fH->InheritsFrom(TH2Poly::Class())) {
3837 TH2Poly *th2 = (TH2Poly*)fH;
3838 biny = th2->FindBin(x,y);
3839 fObjectInfo.Form("%s (x=%g, y=%g, bin=%d, binc=%g)",
3840 th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3841 }
3842 else if (fH->InheritsFrom(TProfile2D::Class())) {
3843 TProfile2D *tp = (TProfile2D*)fH;
3844 biny = fYaxis->FindFixBin(y);
3845 Int_t bin = fH->GetBin(binx,biny);
3846 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3847 x, y, binx, biny, fH->GetBinContent(bin),
3848 fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3849 } else {
3850 biny = fYaxis->FindFixBin(y);
3851 fObjectInfo.Form("(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3852 x,y,binx,biny,fH->GetBinContent(binx,biny),
3853 fH->GetBinError(binx,biny));
3854 }
3855 } else {
3856 // 3d case: retrieving the x,y,z bin is not yet implemented
3857 // print just the x,y info
3858 fObjectInfo.Form("(x=%g, y=%g)",x,y);
3859 }
3860
3861 return (char *)fObjectInfo.Data();
3862}
3863
3864////////////////////////////////////////////////////////////////////////////////
3865/// Set highlight (enable/disable) mode for fH
3866
3868{
3869 if (fH->IsHighlight()) return;
3870
3871 fXHighlightBin = -1;
3872 fYHighlightBin = -1;
3873 // delete previous highlight box
3876 // emit Highlighted() signal (user can check on disabled)
3877 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3878}
3879
3880////////////////////////////////////////////////////////////////////////////////
3881/// Check on highlight bin
3882
3884{
3885 // call from DistancetoPrimitive (only if highlight is enable)
3886
3887 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3888 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3889 Int_t binx = fXaxis->FindFixBin(x);
3890 Int_t biny = fYaxis->FindFixBin(y);
3891 if (!gPad->IsVertical()) binx = fXaxis->FindFixBin(y);
3892
3893 Bool_t changedBin = kFALSE;
3894 if (binx != fXHighlightBin) {
3895 fXHighlightBin = binx;
3896 changedBin = kTRUE;
3897 } else if (fH->GetDimension() == 1) return;
3898 if (biny != fYHighlightBin) {
3899 fYHighlightBin = biny;
3900 changedBin = kTRUE;
3901 }
3902 if (!changedBin) return;
3903
3904 // Info("HighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3905 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3906
3907 // paint highlight bin as box (recursive calls PaintHighlightBin)
3908 gPad->Modified(kTRUE);
3909 gPad->Update();
3910
3911 // emit Highlighted() signal
3912 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3913}
3914
3915////////////////////////////////////////////////////////////////////////////////
3916/// Paint highlight bin as TBox object
3917
3919{
3920 // call from PaintTitle
3921
3922 if (!fH->IsHighlight()) return;
3923
3924 Double_t uxmin = gPad->GetUxmin();
3925 Double_t uxmax = gPad->GetUxmax();
3926 Double_t uymin = gPad->GetUymin();
3927 Double_t uymax = gPad->GetUymax();
3928 if (gPad->GetLogx()) {
3929 uxmin = TMath::Power(10.0, uxmin);
3930 uxmax = TMath::Power(10.0, uxmax);
3931 }
3932 if (gPad->GetLogy()) {
3933 uymin = TMath::Power(10.0, uymin);
3934 uymax = TMath::Power(10.0, uymax);
3935 }
3936
3937 // testing specific possibility (after zoom, draw with "same", log, etc.)
3938 Double_t hcenter;
3939 if (gPad->IsVertical()) {
3941 if ((hcenter < uxmin) || (hcenter > uxmax)) return;
3942 } else {
3944 if ((hcenter < uymin) || (hcenter > uymax)) return;
3945 }
3946 if (fH->GetDimension() == 2) {
3948 if ((hcenter < uymin) || (hcenter > uymax)) return;
3949 }
3950
3951 // paint X highlight bin (for 1D or 2D)
3952 Double_t hbx1, hbx2, hby1, hby2;
3953 if (gPad->IsVertical()) {
3956 hby1 = uymin;
3957 hby2 = uymax;
3958 } else {
3959 hbx1 = uxmin;
3960 hbx2 = uxmax;
3963 }
3964
3965 if (!gXHighlightBox) {
3966 gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3970 else gROOT->GetColor(gXHighlightBox->GetFillColor())->SetAlpha(0.5);
3971 }
3972 gXHighlightBox->SetX1(hbx1);
3973 gXHighlightBox->SetX2(hbx2);
3974 gXHighlightBox->SetY1(hby1);
3975 gXHighlightBox->SetY2(hby2);
3977
3978 // Info("PaintHighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3979 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3980
3981 // paint Y highlight bin (only for 2D)
3982 if (fH->GetDimension() != 2) return;
3983 hbx1 = uxmin;
3984 hbx2 = uxmax;
3987
3988 if (!gYHighlightBox) {
3989 gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3993 }
3994 gYHighlightBox->SetX1(hbx1);
3995 gYHighlightBox->SetX2(hbx2);
3996 gYHighlightBox->SetY1(hby1);
3997 gYHighlightBox->SetY2(hby2);
3999}
4000
4001////////////////////////////////////////////////////////////////////////////////
4002/// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
4003
4005{
4006
4007 for (Int_t i=0;i<fNcuts;i++) {
4010 if (fCutsOpt[i] > 0) {
4011 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
4012 } else {
4013 if (fCuts[i]->IsInside(x,y)) return kFALSE;
4014 }
4015 }
4016 return kTRUE;
4017}
4018
4019////////////////////////////////////////////////////////////////////////////////
4020/// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
4021
4023{
4024
4025 for (Int_t i=0;i<fNcuts;i++) {
4026 if (fCutsOpt[i] > 0) {
4027 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
4028 } else {
4029 if (fCuts[i]->IsInside(x,y)) return kFALSE;
4030 }
4031 }
4032 return kTRUE;
4033}
4034
4035////////////////////////////////////////////////////////////////////////////////
4036/// Decode string `choptin` and fill Hoption structure.
4037
4039{
4040
4041 char *l;
4042 char chopt[128];
4043 Int_t nch = strlen(choptin);
4044 strlcpy(chopt,choptin,128);
4045 Int_t hdim = fH->GetDimension();
4046
4054 Hoption.Candle = 0;
4055
4056 // special 2D options
4057 Hoption.List = 0;
4058 Hoption.Zscale = 0;
4059 Hoption.FrontBox = 1;
4060 Hoption.BackBox = 1;
4062
4063 Hoption.Zero = 0;
4064
4066
4067 //check for graphical cuts
4068 MakeCuts(chopt);
4069
4070 for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
4071 if (hdim > 1) Hoption.Scat = 1;
4072 if (!nch) Hoption.Hist = 1;
4073 if (fFunctions->First()) Hoption.Func = 1;
4074 if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
4075
4076 char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
4077 char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
4078 char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
4079 if (l1 || l2 || l3) {
4080 Int_t i = gPad->NextPaletteColor();
4081 if (l1) {memcpy(l1," ",3); fH->SetFillColor(i);}
4082 if (l2) {memcpy(l2," ",3); fH->SetLineColor(i);}
4083 if (l3) {memcpy(l3," ",3); fH->SetMarkerColor(i);}
4084 Hoption.Hist = 1; // Make sure something is drawn in case there is no drawing option specified.
4085 }
4086
4087 l = strstr(chopt,"MIN0");
4088 if (l) {
4089 Hoption.MinimumZero = 1;
4090 memcpy(l," ",4);
4091 }
4092
4093 l = strstr(chopt,"SPEC");
4094 if (l) {
4095 Hoption.Scat = 0;
4096 memcpy(l," ",4);
4097 Int_t bs=0;
4098 l = strstr(chopt,"BF(");
4099 if (l) {
4100 if (sscanf(&l[3],"%d",&bs) > 0) {
4101 Int_t i=0;
4102 while (l[i]!=')') {
4103 l[i] = ' ';
4104 i++;
4105 }
4106 l[i] = ' ';
4107 }
4108 }
4109 Hoption.Spec = TMath::Max(1600,bs);
4110 return 1;
4111 }
4112
4113 l = strstr(chopt,"GL");
4114 if (l) {
4115 memcpy(l," ",2);
4116 }
4117 l = strstr(chopt,"X+");
4118 if (l) {
4119 Hoption.AxisPos = 10;
4120 memcpy(l," ",2);
4121 }
4122 l = strstr(chopt,"Y+");
4123 if (l) {
4124 Hoption.AxisPos += 1;
4125 memcpy(l," ",2);
4126 }
4127 if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
4128 if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
4129
4130 l = strstr(chopt,"SAMES");
4131 if (l) {
4132 if (nch == 5) Hoption.Hist = 1;
4133 Hoption.Same = 2;
4134 memcpy(l," ",5);
4135 if (l[5] == '0') { Hoption.Same += 10; l[5] = ' '; }
4136 }
4137 l = strstr(chopt,"SAME");
4138 if (l) {
4139 if (nch == 4) Hoption.Hist = 1;
4140 Hoption.Same = 1;
4141 memcpy(l," ",4);
4142 if (l[4] == '0') { Hoption.Same += 10; l[4] = ' '; }
4143 }
4144
4145 l = strstr(chopt,"PIE");
4146 if (l) {
4147 Hoption.Pie = 1;
4148 memcpy(l," ",3);
4149 }
4150
4151
4152 l = strstr(chopt,"CANDLE");
4153 if (l) {
4154 TCandle candle;
4155 Hoption.Candle = candle.ParseOption(l);
4156 Hoption.Scat = 0;
4157 }
4158
4159 l = strstr(chopt,"VIOLIN");
4160 if (l) {
4161 TCandle candle;
4162 Hoption.Candle = candle.ParseOption(l);
4163 Hoption.Scat = 0;
4164 }
4165
4166 l = strstr(chopt,"LEGO");
4167 if (l) {
4168 Hoption.Scat = 0;
4169 Hoption.Lego = 1; memcpy(l," ",4);
4170 if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
4171 if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
4172 if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
4173 if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
4174 if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
4175 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4176 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4177 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4178 }
4179
4180 l = strstr(chopt,"SURF");
4181 if (l) {
4182 Hoption.Scat = 0;
4183 Hoption.Surf = 1; memcpy(l," ",4);
4184 if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
4185 if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
4186 if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
4187 if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
4188 if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
4189 if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
4190 if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
4191 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4192 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4193 }
4194
4195 l = strstr(chopt,"TF3");
4196 if (l) {
4197 memcpy(l," ",3);
4198 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4199 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4200 }
4201
4202 l = strstr(chopt,"ISO");
4203 if (l) {
4204 memcpy(l," ",3);
4205 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4206 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4207 }
4208
4209 l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; memcpy(l," ",4);}
4210
4211 l = strstr(chopt,"CONT");
4212 if (l) {
4213 memcpy(l," ",4);
4214 if (hdim>1) {
4215 Hoption.Scat = 0;
4216 Hoption.Contour = 1;
4217 if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
4218 if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
4219 if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
4220 if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
4221 if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
4222 } else {
4223 Hoption.Hist = 1;
4224 }
4225 }
4226 l = strstr(chopt,"HBAR");
4227 if (l) {
4228 Hoption.Hist = 0;
4229 Hoption.Bar = 20; memcpy(l," ",4);
4230 if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
4231 if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
4232 if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
4233 if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
4234 }
4235 l = strstr(chopt,"BAR");
4236 if (l) {
4237 Hoption.Hist = 0;
4238 Hoption.Bar = 10; memcpy(l," ",3);
4239 if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
4240 if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
4241 if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
4242 if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
4243 }
4244
4245 l = strstr(chopt,"ARR" );
4246 if (l) {
4247 memcpy(l," ", 3);
4248 if (hdim>1) {
4249 Hoption.Arrow = 1;
4250 Hoption.Scat = 0;
4251 l = strstr(chopt,"COL"); if (l) { Hoption.Arrow = 2; memcpy(l," ",3); }
4252 l = strstr(chopt,"Z"); if (l) { Hoption.Zscale = 1; memcpy(l," ",1); }
4253 } else {
4254 Hoption.Hist = 1;
4255 }
4256 }
4257 l = strstr(chopt,"BOX" );
4258 if (l) {
4259 memcpy(l," ", 3);
4260 if (hdim>1) {
4261 Hoption.Scat = 0;
4262 Hoption.Box = 1;
4263 if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
4264 if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
4265 if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
4266 } else {
4267 Hoption.Hist = 1;
4268 }
4269 }
4270 l = strstr(chopt,"COLZ");
4271 if (l) {
4272 memcpy(l," ",4);
4273 if (hdim>1) {
4274 Hoption.Color = 1;
4275 Hoption.Scat = 0;
4276 Hoption.Zscale = 1;
4277 if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
4278 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4279 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4280 } else {
4281 Hoption.Hist = 1;
4282 }
4283 }
4284 l = strstr(chopt,"COL" );
4285 if (l) {
4286 memcpy(l," ", 3);
4287 if (hdim>1) {
4288 Hoption.Color = 1;
4289 Hoption.Scat = 0;
4290 if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
4291 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4292 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4293 } else {
4294 Hoption.Hist = 1;
4295 }
4296 }
4297 l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; memcpy(l," ",4); Hoption.Hist = 0; }
4298 l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; memcpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
4299 l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; memcpy(l," ",4); }
4300 l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; memcpy(l," ",4); }
4301 l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; memcpy(l," ",4); }
4302 l = strstr(chopt,"TEXT");
4303 if (l) {
4304 Int_t angle;
4305 if (sscanf(&l[4],"%d",&angle) > 0) {
4306 if (angle < 0) angle=0;
4307 if (angle > 90) angle=90;
4308 Hoption.Text = 1000+angle;
4309 } else {
4310 Hoption.Text = 1;
4311 }
4312 memcpy(l," ", 4);
4313 l = strstr(chopt,"N");
4314 if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
4315 Hoption.Scat = 0;
4316 }
4317 l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; memcpy(l," ",3); }
4318 l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; memcpy(l," ",3); }
4319 l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; memcpy(l," ",3); }
4320 l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; memcpy(l," ",3); }
4321
4322 l = strstr(chopt,"TRI");
4323 if (l) {
4324 Hoption.Scat = 0;
4325 Hoption.Color = 0;
4326 Hoption.Tri = 1; memcpy(l," ",3);
4327 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4328 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4329 l = strstr(chopt,"ERR"); if (l) memcpy(l," ",3);
4330 }
4331
4332 l = strstr(chopt,"AITOFF");
4333 if (l) {
4334 Hoption.Proj = 1; memcpy(l," ",6); //Aitoff projection
4335 }
4336 l = strstr(chopt,"MERCATOR");
4337 if (l) {
4338 Hoption.Proj = 2; memcpy(l," ",8); //Mercator projection
4339 }
4340 l = strstr(chopt,"SINUSOIDAL");
4341 if (l) {
4342 Hoption.Proj = 3; memcpy(l," ",10); //Sinusoidal projection
4343 }
4344 l = strstr(chopt,"PARABOLIC");
4345 if (l) {
4346 Hoption.Proj = 4; memcpy(l," ",9); //Parabolic projection
4347 }
4348 if (Hoption.Proj > 0) {
4349 Hoption.Scat = 0;
4350 Hoption.Contour = 14;
4351 }
4352
4353 if (strstr(chopt,"A")) Hoption.Axis = -1;
4354 if (strstr(chopt,"B")) Hoption.Bar = 1;
4355 if (strstr(chopt,"C") && !strstr(chopt,"CJUST")) { Hoption.Curve =1; Hoption.Hist = -1;}
4356 if (strstr(chopt,"F")) Hoption.Fill =1;
4357 if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
4358 if (strstr(chopt,"F2")) Hoption.Fill =2;
4359 if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
4360 if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
4361 if (strstr(chopt,"Z")) Hoption.Zscale =1;
4362 if (strstr(chopt,"*")) Hoption.Star =1;
4363 if (strstr(chopt,"H")) Hoption.Hist =2;
4364 if (strstr(chopt,"P0")) Hoption.Mark =10;
4365
4366 if (fH->InheritsFrom(TH2Poly::Class())) {
4368 }
4369
4370 if (strstr(chopt,"E")) {
4371 if (hdim == 1) {
4372 Hoption.Error = 1;
4373 if (strstr(chopt,"E1")) Hoption.Error = 11;
4374 if (strstr(chopt,"E2")) Hoption.Error = 12;
4375 if (strstr(chopt,"E3")) Hoption.Error = 13;
4376 if (strstr(chopt,"E4")) Hoption.Error = 14;
4377 if (strstr(chopt,"E5")) Hoption.Error = 15;
4378 if (strstr(chopt,"E6")) Hoption.Error = 16;
4379 if (strstr(chopt,"E0")) Hoption.Error += 40;
4380 if (strstr(chopt,"X0")) {
4381 if (Hoption.Error == 1) Hoption.Error += 20;
4382 Hoption.Error += 10;
4383 }
4384 if (Hoption.Text && fH->InheritsFrom(TProfile::Class())) {
4385 Hoption.Text += 2000;
4386 Hoption.Error = 0;
4387 }
4388 } else {
4389 if (Hoption.Error == 0) {
4390 Hoption.Error = 100;
4391 Hoption.Scat = 0;
4392 }
4393 if (Hoption.Text) {
4394 Hoption.Text += 2000;
4395 Hoption.Error = 0;
4396 }
4397 }
4398 }
4399
4400 if (Hoption.Surf == 15) {
4402 Hoption.Surf = 13;
4403 Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4404 }
4405 }
4406
4407 // Copy options from current style
4408 Hoption.Logx = gPad->GetLogx();
4409 Hoption.Logy = gPad->GetLogy();
4410 Hoption.Logz = gPad->GetLogz();
4411
4412 // Check options incompatibilities
4413 if (Hoption.Bar == 1) Hoption.Hist = -1;
4414 return 1;
4415}
4416
4417////////////////////////////////////////////////////////////////////////////////
4418/// Decode string `choptin` and fill Graphical cuts structure.
4419
4421{
4422
4423 fNcuts = 0;
4424 char *left = (char*)strchr(choptin,'[');
4425 if (!left) return 0;
4426 char *right = (char*)strchr(choptin,']');
4427 if (!right) return 0;
4428 Int_t nch = right-left;
4429 if (nch < 2) return 0;
4430 char *cuts = left+1;
4431 *right = 0;
4432 char *comma, *minus;
4433 Int_t i;
4434 while (1) {
4435 comma = strchr(cuts,',');
4436 if (comma) *comma = 0;
4437 minus = strchr(cuts,'-');
4438 if (minus) cuts = minus+1;
4439 while (*cuts == ' ') cuts++;
4440 Int_t nc = strlen(cuts);
4441 while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4442 TIter next(gROOT->GetListOfSpecials());
4443 TCutG *cut=0;
4444 TObject *obj;
4445 while ((obj = next())) {
4446 if (!obj->InheritsFrom(TCutG::Class())) continue;
4447 if (strcmp(obj->GetName(),cuts)) continue;
4448 cut = (TCutG*)obj;
4449 break;
4450 }
4451 if (cut) {
4452 fCuts[fNcuts] = cut;
4453 fCutsOpt[fNcuts] = 1;
4454 if (minus) fCutsOpt[fNcuts] = -1;
4455 fNcuts++;
4456 }
4457 if (!comma) break;
4458 cuts = comma+1;
4459 }
4460 for (i=0;i<=nch;i++) left[i] = ' ';
4461 return fNcuts;
4462}
4463
4464////////////////////////////////////////////////////////////////////////////////
4465/// [Control routine to paint any kind of histograms](\ref HP00)
4466
4468{
4469
4470 if (fH->GetBuffer()) fH->BufferEmpty(-1);
4471
4472 //For iOS: put the histogram on the top of stack of pickable objects.
4473 const TPickerStackGuard topPush(fH);
4474
4475 gPad->SetVertical(kTRUE);
4476
4477 TH1 *oldhist = gCurrentHist;
4478 gCurrentHist = fH;
4479 TH1 *hsave = fH;
4480 Double_t minsav = fH->GetMinimumStored();
4481
4482 if (!MakeChopt(option)) return; //check options and fill Hoption structure
4483
4484 // Paint using TSpectrum2Painter
4485 if (Hoption.Spec) {
4486 if (!TableInit()) return;
4487 if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4488 gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%zx,\"%s\",%d)",
4489 (size_t)fH, option, Hoption.Spec));
4490 return;
4491 }
4492
4493 // Deflate the labels in case of alphanumeric labels
4497
4498 if (Hoption.Pie) {
4499 if (fH->GetDimension() == 1) {
4500 if (!fPie) fPie = new TPie(fH);
4501 fPie->Paint(option);
4502 } else {
4503 Error("Paint", "Option PIE is for 1D histograms only");
4504 }
4505 return;
4506 } else {
4507 if (fPie) delete fPie;
4508 fPie = 0;
4509 }
4510
4511 fXbuf = new Double_t[kNMAX];
4512 fYbuf = new Double_t[kNMAX];
4513 if (fH->GetDimension() > 2) {
4514 PaintH3(option);
4515 fH->SetMinimum(minsav);
4516 if (Hoption.Func) {
4517 Hoption_t hoptsave = Hoption;
4518 Hparam_t hparsave = Hparam;
4519 PaintFunction(option);
4520 SetHistogram(hsave);
4521 Hoption = hoptsave;
4522 Hparam = hparsave;
4523 }
4524 gCurrentHist = oldhist;
4525 delete [] fXbuf; delete [] fYbuf;
4526 return;
4527 }
4528 TView *view = gPad->GetView();
4529 if (view) {
4530 if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4531 delete view;
4532 gPad->SetView(0);
4533 }
4534 }
4535 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4536 // In case of 1D histogram, Z axis becomes Y axis.
4537 Int_t logysav=0, logzsav=0;
4538 if (fH->GetDimension() == 1) {
4539 logysav = Hoption.Logy;
4540 logzsav = Hoption.Logz;
4541 Hoption.Logz = 0;
4542 if (Hoption.Logy) {
4543 Hoption.Logz = 1;
4544 Hoption.Logy = 0;
4545 }
4546 }
4547 PaintTable(option);
4548 if (Hoption.Func) {
4549 Hoption_t hoptsave = Hoption;
4550 Hparam_t hparsave = Hparam;
4551 PaintFunction(option);
4552 SetHistogram(hsave);
4553 Hoption = hoptsave;
4554 Hparam = hparsave;
4555 }
4556 fH->SetMinimum(minsav);
4557 gCurrentHist = oldhist;
4558 delete [] fXbuf; delete [] fYbuf;
4559 if (fH->GetDimension() == 1) {
4560 Hoption.Logy = logysav;
4561 Hoption.Logz = logzsav;
4562 }
4563 return;
4564 }
4565
4566 if (Hoption.Bar >= 20) {
4567 PaintBarH(option);
4568 delete [] fXbuf; delete [] fYbuf;
4569 return;
4570 }
4571
4572 gPad->RangeAxisChanged(); //emit RangeAxisChanged() signal to sync axes
4573 // fill Hparam structure with histo parameters
4574 if (!PaintInit()) {
4575 delete [] fXbuf; delete [] fYbuf;
4576 return;
4577 }
4578
4579 // Picture surround (if new page) and page number (if requested).
4580 // Histogram surround (if not option "Same").
4581 PaintFrame();
4582
4583 // Paint histogram axis only
4584 Bool_t gridx = gPad->GetGridx();
4585 Bool_t gridy = gPad->GetGridy();
4586 if (Hoption.Axis > 0) {
4587 if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4588 else {
4589 if (gridx) gPad->SetGridx(0);
4590 if (gridy) gPad->SetGridy(0);
4592 if (gridx) gPad->SetGridx(1);
4593 if (gridy) gPad->SetGridy(1);
4594 }
4595 if ((Hoption.Same%10) ==1) Hoption.Same += 1;
4596 goto paintstat;
4597 }
4598 if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4599
4600 // test for options BAR or HBAR
4601 if (Hoption.Bar >= 10) {
4602 PaintBar(option);
4603 }
4604
4605 // do not draw histogram if error bars required
4606 if (!Hoption.Error) {
4607 if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4608 }
4609
4610 // test for error bars or option E
4611 if (Hoption.Error) {
4612 PaintErrors(option);
4613 if (Hoption.Hist == 2) PaintHist(option);
4614 }
4615
4616 if (Hoption.Text) PaintText(option);
4617
4618 // test for associated function
4619 if (Hoption.Func) {
4620 Hoption_t hoptsave = Hoption;
4621 Hparam_t hparsave = Hparam;
4622 PaintFunction(option);
4623 SetHistogram(hsave);
4624 Hoption = hoptsave;
4625 Hparam = hparsave;
4626 }
4627
4628 if (gridx) gPad->SetGridx(0);
4629 if (gridy) gPad->SetGridy(0);
4631 if (gridx) gPad->SetGridx(1);
4632 if (gridy) gPad->SetGridy(1);
4633
4634 PaintTitle(); // Draw histogram title
4635
4636 // Draw box with histogram statistics and/or fit parameters
4637paintstat:
4638 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4639 TIter next(fFunctions);
4640 TObject *obj = 0;
4641 while ((obj = next())) {
4642 if (obj->InheritsFrom(TF1::Class())) break;
4643 obj = 0;
4644 }
4645
4646 //Stat is painted twice (first, it will be in canvas' list of primitives),
4647 //second, it will be here, this is not required on iOS.
4648 //Condition is ALWAYS true on a platform different from iOS.
4649 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4650 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4651 }
4652 fH->SetMinimum(minsav);
4653 gCurrentHist = oldhist;
4654 delete [] fXbuf; fXbuf = 0;
4655 delete [] fYbuf; fYbuf = 0;
4656
4657}
4658
4659////////////////////////////////////////////////////////////////////////////////
4660/// [Control function to draw a table as an arrow plot](\ref HP12)
4661
4663{
4664 Double_t xk, xstep, yk, ystep;
4665 Double_t dx, dy, x1, x2, y1, y2, xc, yc, dxn, dyn;
4668 Double_t xrg = gPad->GetUxmin();
4669 Double_t yrg = gPad->GetUymin();
4670 Double_t xln = gPad->GetUxmax() - xrg;
4671 Double_t yln = gPad->GetUymax() - yrg;
4672 Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4673 Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4674 Double_t dn = 1.E-30;
4675
4676 auto arrow = new TArrow();
4677 arrow->SetAngle(30);
4678 arrow->SetFillStyle(1001);
4679 arrow->SetFillColor(fH->GetLineColor());
4680 arrow->SetLineColor(fH->GetLineColor());
4681 arrow->SetLineWidth(fH->GetLineWidth());
4682
4683 // Initialize the levels on the Z axis
4684 Int_t ncolors=0, ndivz=0;
4685 Double_t scale=0.;
4686 if (Hoption.Arrow>1) {
4687 ncolors = gStyle->GetNumberOfColors();
4688 Int_t ndiv = fH->GetContour();
4689 if (ndiv == 0 ) {
4690 ndiv = gStyle->GetNumberContours();
4691 fH->SetContour(ndiv);
4692 }
4693 ndivz = TMath::Abs(ndiv);
4694 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
4695 scale = ndivz/(fH->GetMaximum()-fH->GetMinimum());
4696 }
4697
4698 for (Int_t id=1;id<=2;id++) {
4699 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4700 yk = fYaxis->GetBinLowEdge(j);
4701 ystep = fYaxis->GetBinWidth(j);
4702 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4703 xk = fXaxis->GetBinLowEdge(i);
4704 xstep = fXaxis->GetBinWidth(i);
4705 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4706 if (i == Hparam.xfirst) {
4707 dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4708 } else if (i == Hparam.xlast) {
4709 dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4710 } else {
4711 dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4712 }
4713 if (j == Hparam.yfirst) {
4714 dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4715 } else if (j == Hparam.ylast) {
4716 dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4717 } else {
4718 dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4719 }
4720 if (id == 1) {
4721 dn = TMath::Max(dn, TMath::Abs(dx));
4722 dn = TMath::Max(dn, TMath::Abs(dy));
4723 } else if (id == 2) {
4724 xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4725 dxn = cx*dx/dn;
4726 x1 = xc - dxn;
4727 x2 = xc + dxn;
4728 yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4729 dyn = cy*dy/dn;
4730 y1 = yc - dyn;
4731 y2 = yc + dyn;
4732 if (Hoption.Arrow>1) {
4733 int color = Int_t(0.01+(fH->GetBinContent(i, j)-fH->GetMinimum())*scale);
4734 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
4735 if (theColor > ncolors-1) theColor = ncolors-1;
4736 arrow->SetFillColor(gStyle->GetColorPalette(theColor));
4737 arrow->SetLineColor(gStyle->GetColorPalette(theColor));
4738 }
4739 if (TMath::Abs(x2-x1) > 0. || TMath::Abs(y2-y1) > 0.) {
4740 arrow->PaintArrow(x1, y1, x2, y2, 0.015, "|>");
4741 } else {
4742 arrow->PaintArrow(x1, y1, x2, y2, 0.005, "|>");
4743 }
4744 }
4745 }
4746 }
4747 }
4748
4750}
4751
4752////////////////////////////////////////////////////////////////////////////////
4753/// Draw axis (2D case) of an histogram.
4754///
4755/// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4756/// to draw the grid and the axis separately. In `THistPainter::Paint` this
4757/// feature is used to make sure that the grid is drawn in the background and
4758/// the axis tick marks in the foreground of the pad.
4759
4761{
4762
4763 //On iOS, grid should not be pickable and can not be highlighted.
4764 //Condition is never true on a platform different from iOS.
4765 if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4766 return;
4767
4768 if (Hoption.Axis == -1) return;
4769 if (Hoption.Same && Hoption.Axis <= 0) return;
4770
4771 // Repainting alphanumeric labels axis on a plot done with
4772 // the option HBAR (horizontal) needs some adjustments.
4773 TAxis *xaxis = 0;
4774 TAxis *yaxis = 0;
4775 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4776 if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4777 TIter next(gPad->GetListOfPrimitives());
4778 TObject *obj;
4779 // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4780 while ((obj = next())) {
4781 if (!obj->InheritsFrom(TH1::Class()) &&
4782 !obj->InheritsFrom(THStack::Class())) continue;
4783 TString opt = obj->GetDrawOption();
4784 opt.ToLower();
4785 // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4786 if (strstr(opt,"hbar")) {
4787 gPad->SetVertical(kFALSE);
4788 xaxis = fXaxis;
4789 yaxis = fYaxis;
4790 if (!strcmp(xaxis->GetName(),"xaxis")) {
4791 fXaxis = yaxis;
4792 fYaxis = xaxis;
4793 }
4794 }
4795 break;
4796 }
4797 }
4798 }
4799
4800 static char chopt[10] = "";
4801 Double_t gridl = 0;
4802 Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4803 Int_t useHparam = 0;
4804 Double_t umin, umax, uminsave, umaxsave;
4805 Short_t xAxisPos = Hoption.AxisPos/10;
4806 Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4807
4808 Double_t axmin = gPad->GetUxmin();
4809 Double_t axmax = gPad->GetUxmax();
4810 Double_t aymin = gPad->GetUymin();
4811 Double_t aymax = gPad->GetUymax();
4812 char *cw = 0;
4813 TGaxis axis;
4814
4815 // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4816 // Hparam must be use for the axis limits.
4817 if (Hoption.Contour == 14) useHparam = 1;
4818 if (Hoption.Same) {
4819 TObject *obj;
4820 TIter next(gPad->GetListOfPrimitives());
4821 while ((obj=next())) {
4822 if (strstr(obj->GetDrawOption(),"cont4")) {
4823 useHparam = 1;
4824 break;
4825 }
4826 }
4827 }
4828
4829 // Paint X axis
4830
4831 //To make X-axis selectable on iOS device.
4832 if (gPad->PadInSelectionMode())
4833 gPad->PushSelectableObject(fXaxis);
4834
4835 //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4836 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4837 ndivx = fXaxis->GetNdivisions();
4838 if (ndivx > 1000) {
4839 nx2 = ndivx/100;
4840 nx1 = TMath::Max(1, ndivx%100);
4841 ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4842 }
4843 axis.SetTextAngle(0);
4845
4846 chopt[0] = 0;
4847 strlcat(chopt, "SDH",10);
4848 if (ndivx < 0) strlcat(chopt, "N",10);
4849 if (gPad->GetGridx()) {
4850 gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4851 strlcat(chopt, "W",10);
4852 }
4853
4854 // Define X-Axis limits
4855 if (Hoption.Logx) {
4856 strlcat(chopt, "G",10);
4857 ndiv = TMath::Abs(ndivx);
4858 if (useHparam) {
4859 umin = TMath::Power(10,Hparam.xmin);
4860 umax = TMath::Power(10,Hparam.xmax);
4861 } else {
4862 umin = TMath::Power(10,axmin);
4863 umax = TMath::Power(10,axmax);
4864 }
4865 } else {
4866 ndiv = TMath::Abs(ndivx);
4867 if (useHparam) {
4868 umin = Hparam.xmin;
4869 umax = Hparam.xmax;
4870 } else {
4871 umin = axmin;
4872 umax = axmax;
4873 }
4874 }
4875
4876 // Display axis as time
4877 if (fXaxis->GetTimeDisplay()) {
4878 strlcat(chopt,"t",10);
4879 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4881 }
4882 }
4883
4884 // The main X axis can be on the bottom or on the top of the pad
4885 Double_t xAxisYPos1, xAxisYPos2;
4886 if (xAxisPos == 1) {
4887 // Main X axis top
4888 xAxisYPos1 = aymax;
4889 xAxisYPos2 = aymin;
4890 } else {
4891 // Main X axis bottom
4892 xAxisYPos1 = aymin;
4893 xAxisYPos2 = aymax;
4894 }
4895
4896 // Paint the main X axis (always)
4897 uminsave = umin;
4898 umaxsave = umax;
4899 ndivsave = ndiv;
4900 axis.SetOption(chopt);
4901 if (xAxisPos) {
4902 strlcat(chopt, "-",10);
4903 gridl = -gridl;
4904 }
4905 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4906 axis.SetLabelSize(0.);
4907 axis.SetTitle("");
4908 }
4909 axis.PaintAxis(axmin, xAxisYPos1,
4910 axmax, xAxisYPos1,
4911 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4912
4913 // Paint additional X axis (if needed)
4914 // On iOS, this additional X axis is neither pickable, nor highlighted.
4915 // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4916 if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4917 if (xAxisPos) {
4918 cw=strstr(chopt,"-");
4919 *cw='z';
4920 } else {
4921 strlcat(chopt, "-",10);
4922 }
4923 if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4924 if ((cw=strstr(chopt,"W"))) *cw='z';
4925 axis.SetTitle("");
4926 axis.PaintAxis(axmin, xAxisYPos2,
4927 axmax, xAxisYPos2,
4928 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4929 }
4930 }//End of "if pad in selection mode etc".
4931
4932 // Paint Y axis
4933 //On iOS, Y axis must pushed into the stack of selectable objects.
4934 if (gPad->PadInSelectionMode())
4935 gPad->PushSelectableObject(fYaxis);
4936
4937 //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4938 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4939 ndivy = fYaxis->GetNdivisions();
4941
4942 chopt[0] = 0;
4943 strlcat(chopt, "SDH",10);
4944 if (ndivy < 0) strlcat(chopt, "N",10);
4945 if (gPad->GetGridy()) {
4946 gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4947 strlcat(chopt, "W",10);
4948 }
4949
4950 // Define Y-Axis limits
4951 if (Hoption.Logy) {
4952 strlcat(chopt, "G",10);
4953 ndiv = TMath::Abs(ndivy);
4954 if (useHparam) {
4955 umin = TMath::Power(10,Hparam.ymin);
4956 umax = TMath::Power(10,Hparam.ymax);
4957 } else {
4958 umin = TMath::Power(10,aymin);
4959 umax = TMath::Power(10,aymax);
4960 }
4961 } else {
4962 ndiv = TMath::Abs(ndivy);
4963 if (useHparam) {
4964 umin = Hparam.ymin;
4965 umax = Hparam.ymax;
4966 } else {
4967 umin = aymin;
4968 umax = aymax;
4969 }
4970 }
4971
4972 // Display axis as time
4973 if (fYaxis->GetTimeDisplay()) {
4974 strlcat(chopt,"t",10);
4975 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4977 }
4978 }
4979
4980 // The main Y axis can be on the left or on the right of the pad
4981 Double_t yAxisXPos1, yAxisXPos2;
4982 if (yAxisPos == 1) {
4983 // Main Y axis left
4984 yAxisXPos1 = axmax;
4985 yAxisXPos2 = axmin;
4986 } else {
4987 // Main Y axis right
4988 yAxisXPos1 = axmin;
4989 yAxisXPos2 = axmax;
4990 }
4991
4992 // Paint the main Y axis (always)
4993 uminsave = umin;
4994 umaxsave = umax;
4995 ndivsave = ndiv;
4996 axis.SetOption(chopt);
4997 if (yAxisPos) {
4998 strlcat(chopt, "+L",10);
4999 gridl = -gridl;
5000 }
5001 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
5002 axis.SetLabelSize(0.);
5003 axis.SetTitle("");
5004 }
5005 axis.PaintAxis(yAxisXPos1, aymin,
5006 yAxisXPos1, aymax,
5007 umin, umax, ndiv, chopt, gridl, drawGridOnly);
5008
5009 // Paint the additional Y axis (if needed)
5010 // Additional checks for pad mode are required on iOS: this "second" axis is
5011 // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
5012 if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
5013 if (gPad->GetTicky() < 2) {
5014 strlcat(chopt, "U",10);
5016 } else {
5017 strlcat(chopt, "+L",10);
5018 }
5019 if ((cw=strstr(chopt,"W"))) *cw='z';
5020 axis.SetTitle("");
5021 axis.PaintAxis(yAxisXPos2, aymin,
5022 yAxisXPos2, aymax,
5023 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
5024 }
5025 }//End of "if pad is in selection mode etc."
5026
5027 // Reset the axis if they have been inverted in case of option HBAR
5028 if (xaxis) {
5029 fXaxis = xaxis;
5030 fYaxis = yaxis;
5031 }
5032}
5033
5034////////////////////////////////////////////////////////////////////////////////
5035/// [Draw a bar-chart in a normal pad.](\ref HP10)
5036
5038{
5039
5040 Int_t bar = Hoption.Bar - 10;
5041 Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
5042 Double_t offset = fH->GetBarOffset();
5044 TBox box;
5045 Int_t hcolor = fH->GetFillColor();
5046 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5047 Int_t hstyle = fH->GetFillStyle();
5048 box.SetFillColor(hcolor);
5049 box.SetFillStyle(hstyle);
5050 box.SetLineStyle(fH->GetLineStyle());
5051 box.SetLineColor(fH->GetLineColor());
5052 box.SetLineWidth(fH->GetLineWidth());
5053 for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
5054 y = fH->GetBinContent(bin);
5055 xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
5056 xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
5057 ymin = gPad->GetUymin();
5058 ymax = gPad->YtoPad(y);
5059 if (ymax < gPad->GetUymin()) continue;
5060 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
5061 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
5062 if (Hoption.MinimumZero && ymin < 0)
5063 ymin=TMath::Min(0.,gPad->GetUymax());
5064 w = (xmax-xmin)*width;
5065 xmin += offset*(xmax-xmin);
5066 xmax = xmin + w;
5067 if (bar < 1) {
5068 box.PaintBox(xmin,ymin,xmax,ymax);
5069 } else {
5070 umin = xmin + bar*(xmax-xmin)/10.;
5071 umax = xmax - bar*(xmax-xmin)/10.;
5072 //box.SetFillColor(hcolor+150); //bright
5073 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5074 box.PaintBox(xmin,ymin,umin,ymax);
5075 box.SetFillColor(hcolor);
5076 box.PaintBox(umin,ymin,umax,ymax);
5077 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5078 box.PaintBox(umax,ymin,xmax,ymax);
5079 }
5080 }
5081}
5082
5083////////////////////////////////////////////////////////////////////////////////
5084/// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](\ref HP10)
5085
5087{
5088
5089 gPad->SetVertical(kFALSE);
5090
5091 PaintInitH();
5092
5093 TAxis *xaxis = fXaxis;
5094 TAxis *yaxis = fYaxis;
5095 if (!strcmp(xaxis->GetName(),"xaxis")) {
5096 fXaxis = yaxis;
5097 fYaxis = xaxis;
5098 }
5099
5100 PaintFrame();
5102
5103 Int_t bar = Hoption.Bar - 20;
5104 Double_t xmin,xmax,ymin,ymax,umin,umax,w;
5105 Double_t offset = fH->GetBarOffset();
5107 TBox box;
5108 Int_t hcolor = fH->GetFillColor();
5109 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
5110 Int_t hstyle = fH->GetFillStyle();
5111 box.SetFillColor(hcolor);
5112 box.SetFillStyle(hstyle);
5113 box.SetLineStyle(fH->GetLineStyle());
5114 box.SetLineColor(fH->GetLineColor());
5115 box.SetLineWidth(fH->GetLineWidth());
5116 for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
5117 ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
5118 ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
5119 xmin = gPad->GetUxmin();
5120 xmax = gPad->XtoPad(fH->GetBinContent(bin));
5121 if (xmax < gPad->GetUxmin()) continue;
5122 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
5123 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
5124 if (Hoption.MinimumZero && xmin < 0)
5125 xmin=TMath::Min(0.,gPad->GetUxmax());
5126 w = (ymax-ymin)*width;
5127 ymin += offset*(ymax-ymin);
5128 ymax = ymin + w;
5129 if (bar < 1) {
5130 box.PaintBox(xmin,ymin,xmax,ymax);
5131 } else {
5132 umin = ymin + bar*(ymax-ymin)/10.;
5133 umax = ymax - bar*(ymax-ymin)/10.;
5134 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
5135 box.PaintBox(xmin,ymin,xmax,umin);
5136 box.SetFillColor(hcolor);
5137 box.PaintBox(xmin,umin,xmax,umax);
5138 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
5139 box.PaintBox(xmin,umax,xmax,ymax);
5140 }
5141 }
5142
5143 PaintTitle();
5144
5145 // Draw box with histogram statistics and/or fit parameters
5146 if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
5147 TIter next(fFunctions);
5148 TObject *obj = 0;
5149 while ((obj = next())) {
5150 if (obj->InheritsFrom(TF1::Class())) break;
5151 obj = 0;
5152 }
5153 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
5154 }
5155
5156 fXaxis = xaxis;
5157 fYaxis = yaxis;
5158}
5159
5160////////////////////////////////////////////////////////////////////////////////
5161/// [Control function to draw a 2D histogram as a box plot](\ref HP13)
5162
5164{
5165
5166 Style_t fillsav = fH->GetFillStyle();
5167 Style_t colsav = fH->GetFillColor();
5168 if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
5169 if (Hoption.Box == 11) fH->SetFillStyle(1001);
5170 fH->TAttLine::Modify();
5171 fH->TAttFill::Modify();
5172
5173 Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
5174 Double_t ux1 = gPad->PixeltoX(1);
5175 Double_t ux0 = gPad->PixeltoX(0);
5176 Double_t uy1 = gPad->PixeltoY(1);
5177 Double_t uy0 = gPad->PixeltoY(0);
5178 Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
5179 Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
5180
5181 Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
5184 Double_t zminlin = zmin, zmaxlin = zmax;
5185
5186 // In case of option SAME, zmin and zmax values are taken from the
5187 // first plotted 2D histogram.
5188 if (Hoption.Same > 0 && Hoption.Same < 10) {
5189 TH2 *h2;
5190 TIter next(gPad->GetListOfPrimitives());
5191 while ((h2 = (TH2 *)next())) {
5192 if (!h2->InheritsFrom(TH2::Class())) continue;
5193 zmin = TMath::Max(h2->GetMinimum(), 0.);
5194 zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
5195 TMath::Abs(h2->GetMinimum()));
5196 zminlin = zmin;
5197 zmaxlin = zmax;
5198 if (Hoption.Logz) {
5199 if (zmin <= 0) {
5200 zmin = TMath::Log10(zmax*0.001);
5201 } else {
5202 zmin = TMath::Log10(zmin);
5203 }
5204 zmax = TMath::Log10(zmax);
5205 }
5206 break;
5207 }
5208 } else {
5209 if (Hoption.Logz) {
5210 if (zmin > 0) {
5211 zmin = TMath::Log10(zmin);
5212 zmax = TMath::Log10(zmax);
5213 } else {
5214 return;
5215 }
5216 }
5217 }
5218
5219 Double_t zratio, dz = zmax - zmin;
5220 Bool_t kZminNeg = kFALSE;
5221 if (fH->GetMinimum()<0) kZminNeg = kTRUE;
5222 Bool_t kZNeg = kFALSE;
5223
5224 // Define the dark and light colors the "button style" boxes.
5225 Color_t color = fH->GetFillColor();
5226 Color_t light=0, dark=0;
5227 if (Hoption.Box == 11) {
5228 light = TColor::GetColorBright(color);
5229 dark = TColor::GetColorDark(color);
5230 }
5231
5232 // Loop over all the bins and draw the boxes
5233 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5234 yk = fYaxis->GetBinLowEdge(j);
5235 ystep = fYaxis->GetBinWidth(j);
5236 ycent = 0.5*ystep;
5237 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5238 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5239 xk = fXaxis->GetBinLowEdge(i);
5240 xstep = fXaxis->GetBinWidth(i);
5241 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5242 xcent = 0.5*xstep;
5243 z = Hparam.factor*fH->GetBinContent(bin);
5244 kZNeg = kFALSE;
5245
5246 if (TMath::Abs(z) < zminlin) continue; // Can be the case with ...
5247 if (TMath::Abs(z) > zmaxlin) z = zmaxlin; // ... option Same
5248 if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with negative bins.
5249
5250 if (z < 0) {
5251 if (Hoption.Logz) continue;
5252 z = -z;
5253 kZNeg = kTRUE;
5254 }
5255 if (Hoption.Logz) {
5256 if (z != 0) z = TMath::Log10(z);
5257 else z = zmin;
5258 }
5259
5260 if (dz == 0) continue;
5261 zratio = TMath::Sqrt((z-zmin)/dz);
5262 if (zratio == 0) continue;
5263
5264 xup = xcent*zratio + xk + xcent;
5265 xlow = 2*(xk + xcent) - xup;
5266 if (xup-xlow < dxmin) xup = xlow+dxmin;
5267 if (Hoption.Logx) {
5268 if (xup > 0) xup = TMath::Log10(xup);
5269 else continue;
5270 if (xlow > 0) xlow = TMath::Log10(xlow);
5271 else continue;
5272 }
5273
5274 yup = ycent*zratio + yk + ycent;
5275 ylow = 2*(yk + ycent) - yup;
5276 if (yup-ylow < dymin) yup = ylow+dymin;
5277 if (Hoption.Logy) {
5278 if (yup > 0) yup = TMath::Log10(yup);
5279 else continue;
5280 if (ylow > 0) ylow = TMath::Log10(ylow);
5281 else continue;
5282 }
5283
5284 xlow = TMath::Max(xlow, gPad->GetUxmin());
5285 ylow = TMath::Max(ylow, gPad->GetUymin());
5286 xup = TMath::Min(xup , gPad->GetUxmax());
5287 yup = TMath::Min(yup , gPad->GetUymax());
5288
5289 if (xlow >= xup) continue;
5290 if (ylow >= yup) continue;
5291
5292 if (Hoption.Box == 1) {
5293 fH->SetFillColor(color);
5294 fH->TAttFill::Modify();
5295 gPad->PaintBox(xlow, ylow, xup, yup);
5296 if (kZNeg) {
5297 gPad->PaintLine(xlow, ylow, xup, yup);
5298 gPad->PaintLine(xlow, yup, xup, ylow);
5299 }
5300 } else if (Hoption.Box == 11) {
5301 // Draw the center of the box
5302 fH->SetFillColor(color);
5303 fH->TAttFill::Modify();
5304 gPad->PaintBox(xlow, ylow, xup, yup);
5305
5306 // Draw top&left part of the box
5307 Double_t x[7], y[7];
5308 Double_t bwidth = 0.1;
5309 x[0] = xlow; y[0] = ylow;
5310 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5311 x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
5312 x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
5313 x[4] = xup; y[4] = yup;
5314 x[5] = xlow; y[5] = yup;
5315 x[6] = xlow; y[6] = ylow;
5316 if (kZNeg) fH->SetFillColor(dark);
5317 else fH->SetFillColor(light);
5318 fH->TAttFill::Modify();
5319 gPad->PaintFillArea(7, x, y);
5320
5321 // Draw bottom&right part of the box
5322 x[0] = xlow; y[0] = ylow;
5323 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5324 x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
5325 x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
5326 x[4] = xup; y[4] = yup;
5327 x[5] = xup; y[5] = ylow;
5328 x[6] = xlow; y[6] = ylow;
5329 if (kZNeg) fH->SetFillColor(light);
5330 else fH->SetFillColor(dark);
5331 fH->TAttFill::Modify();
5332 gPad->PaintFillArea(7, x, y);
5333 }
5334 }
5335 }
5336
5338 fH->SetFillStyle(fillsav);
5339 fH->SetFillColor(colsav);
5340 fH->TAttFill::Modify();
5341}
5342
5343
5344
5345////////////////////////////////////////////////////////////////////////////////
5346/// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](\ref HP14)
5347
5349{
5350 TH1D *hproj = nullptr;
5351 TH2D *h2 = (TH2D*)fH;
5352
5353 TCandle myCandle;
5355 myCandle.SetMarkerColor(fH->GetLineColor());
5356 myCandle.SetLineColor(fH->GetLineColor());
5357 myCandle.SetLineWidth(fH->GetLineWidth());
5358 myCandle.SetFillColor(fH->GetFillColor());
5359 myCandle.SetFillStyle(fH->GetFillStyle());
5360 myCandle.SetMarkerSize(fH->GetMarkerSize());
5361 myCandle.SetMarkerStyle(fH->GetMarkerStyle());
5363
5364 Bool_t swapXY = myCandle.IsHorizontal();
5365 const Double_t standardCandleWidth = 0.66;
5366 const Double_t standardHistoWidth = 0.8;
5367
5368 double allMaxContent = 0, allMaxIntegral = 0;
5369 if (myCandle.IsViolinScaled())
5370 allMaxContent = h2->GetBinContent(h2->GetMaximumBin());
5371
5372 if (!swapXY) { // Vertical candle
5373 //Determining the slice with the maximum integral - if necessary
5374 if (myCandle.IsCandleScaled())
5375 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5376 hproj = h2->ProjectionY("_px", i, i);
5377 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5378 }
5379 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5380 Double_t binPosX = fXaxis->GetBinLowEdge(i);
5381 Double_t binWidth = fXaxis->GetBinWidth(i);
5382 hproj = h2->ProjectionY("_px", i, i);
5383 if (hproj->GetEntries() != 0) {
5384 Double_t candleWidth = fH->GetBarWidth();
5385 Double_t offset = fH->GetBarOffset()*binWidth;
5386 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5387 double myIntegral = hproj->Integral();
5388 Double_t histoWidth = candleWidth;
5389 if (candleWidth > 0.999 && candleWidth < 1.001) {
5390 candleWidth = standardCandleWidth;
5391 histoWidth = standardHistoWidth;
5392 }
5393 if (Hoption.Logz && myMaxContent > 0) {
5394 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5395 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0)
5396 histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5397 } else if (myCandle.IsViolinScaled() && (allMaxContent > 0))
5398 histoWidth *= myMaxContent/allMaxContent;
5399 if (myCandle.IsCandleScaled() && (allMaxIntegral > 0))
5400 candleWidth *= myIntegral/allMaxIntegral;
5401
5402 myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
5403 myCandle.SetCandleWidth(candleWidth*binWidth);
5404 myCandle.SetHistoWidth(histoWidth*binWidth);
5405 myCandle.SetHistogram(hproj);
5406 myCandle.Paint();
5407 }
5408 }
5409 } else { // Horizontal candle
5410 //Determining the slice with the maximum integral - if necessary
5411 if (myCandle.IsCandleScaled())
5412 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5413 hproj = h2->ProjectionX("_py", i, i);
5414 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5415 }
5416 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5417 Double_t binPosY = fYaxis->GetBinLowEdge(i);
5418 Double_t binWidth = fYaxis->GetBinWidth(i);
5419 hproj = h2->ProjectionX("_py", i, i);
5420 if (hproj->GetEntries() != 0) {
5421 Double_t candleWidth = fH->GetBarWidth();
5422 Double_t offset = fH->GetBarOffset()*binWidth;
5423 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5424 double myIntegral = hproj->Integral();
5425 Double_t histoWidth = candleWidth;
5426 if (candleWidth > 0.999 && candleWidth < 1.001) {
5427 candleWidth = standardCandleWidth;
5428 histoWidth = standardHistoWidth;
5429 }
5430 if (Hoption.Logz && myMaxContent > 0) {
5431 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5432 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0)
5433 histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5434 } else if (myCandle.IsViolinScaled() && (allMaxContent > 0))
5435 histoWidth *= myMaxContent/allMaxContent;
5436 if (myCandle.IsCandleScaled() && (allMaxIntegral > 0))
5437 candleWidth *= myIntegral/allMaxIntegral;
5438
5439 myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
5440 myCandle.SetCandleWidth(candleWidth*binWidth);
5441 myCandle.SetHistoWidth(histoWidth*binWidth);
5442 myCandle.SetHistogram(hproj);
5443 myCandle.Paint();
5444 }
5445 }
5446 }
5447 delete hproj;
5448}
5449
5450
5451
5452////////////////////////////////////////////////////////////////////////////////
5453/// Returns the rendering regions for an axis to use in the COL2 option
5454///
5455/// The algorithm analyses the size of the axis compared to the size of
5456/// the rendering region. It figures out the boundaries to use for each color
5457/// of the rendering region. Only one axis is computed here.
5458///
5459/// This allows for a single computation of the boundaries before iterating
5460/// through all of the bins.
5461///
5462/// \param pAxis the axis to consider
5463/// \param nPixels the number of pixels to render axis into
5464/// \param isLog whether the axis is log scale
5465
5466std::vector<THistRenderingRegion>
5468{
5469 std::vector<THistRenderingRegion> regions;
5470
5471 enum STRATEGY { Bins, Pixels } strategy;
5472
5473 Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
5474
5475 if (nBins >= nPixels) {
5476 // more bins than pixels... we should loop over pixels and sample
5477 strategy = Pixels;
5478 } else {
5479 // fewer bins than pixels... we should loop over bins
5480 strategy = Bins;
5481 }
5482
5483 if (isLog) {
5484
5485 Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5486 Int_t binOffset=0;
5487 while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5488 binOffset++;
5489 xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5490 }
5491 if (xMin <= 0) {
5492 // this should cause an error if we have
5493 return regions;
5494 }
5495 Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5496
5497 if (strategy == Bins) {
5498 // logarithmic plot. we find the pixel for the bin
5499 // pixel = eta * log10(V) - alpha
5500 // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5501 // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5502 // and V is axis value
5503 Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5504 Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5505
5506 for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5507
5508 // linear plot. we simply need to find the appropriate bin
5509 // for the
5510 Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5511 Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5512 Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5513 Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5514 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5515 std::make_pair(bin, bin+1)};
5516 regions.push_back(region);
5517 }
5518
5519 } else {
5520
5521 // loop over pixels
5522
5523 Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5524
5525 for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5526 // linear plot
5527 Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5528 Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5529 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5530 std::make_pair(binLow, binHigh)};
5531 regions.push_back(region);
5532 }
5533 }
5534 } else {
5535 // standard linear plot
5536
5537 if (strategy == Bins) {
5538 // loop over bins
5539 for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5540
5541 // linear plot. we simply need to find the appropriate bin
5542 // for the
5543 Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5544 Int_t xPx1 = xPx0 + nPixels/nBins;
5545
5546 // make sure we don't compute beyond our bounds
5547 if (xPx1>= nPixels) xPx1 = nPixels-1;
5548
5549 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5550 std::make_pair(bin, bin+1)};
5551 regions.push_back(region);
5552 }
5553 } else {
5554 // loop over pixels
5555 for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5556 // linear plot
5557 Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5558 Int_t binHigh = binLow + nBins/nPixels;
5559 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5560 std::make_pair(binLow, binHigh)};
5561 regions.push_back(region);
5562 }
5563 }
5564 }
5565
5566 return regions;
5567}
5568
5569////////////////////////////////////////////////////////////////////////////////
5570/// [Rendering scheme for the COL2 and COLZ2 options] (\ref HP14)
5571
5573{
5574
5575 if (Hoption.System != kCARTESIAN) {
5576 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5577 "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5578 PaintColorLevels(nullptr);
5579 return;
5580 }
5581
5582 Double_t z;
5583
5584 // Use existing max or min values. If either is already set
5585 // the appropriate value to use.
5586 Double_t zmin = fH->GetMinimumStored();
5587 Double_t zmax = fH->GetMaximumStored();
5588 Double_t originalZMin = zmin;
5589 Double_t originalZMax = zmax;
5590 if ((zmin == -1111) && (zmax == -1111)) {
5591 fH->GetMinimumAndMaximum(zmin, zmax);
5592 fH->SetMinimum(zmin);
5593 fH->SetMaximum(zmax);
5594 } else if (zmin == -1111) {
5595 zmin = fH->GetMinimum();
5596 fH->SetMinimum(zmin);
5597 } else if (zmax == -1111) {
5598 zmax = fH->GetMaximum();
5599 fH->SetMaximum(zmax);
5600 }
5601
5602 Double_t dz = zmax - zmin;
5603 if (dz <= 0) { // Histogram filled with a constant value
5604 zmax += 0.1*TMath::Abs(zmax);
5605 zmin -= 0.1*TMath::Abs(zmin);
5606 dz = zmax - zmin;
5607 }
5608
5609 if (Hoption.Logz) {
5610 if (zmin > 0) {
5611 zmin = TMath::Log10(zmin);
5612 zmax = TMath::Log10(zmax);
5613 dz = zmax - zmin;
5614 } else {
5615 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5616 "Cannot plot logz because bin content is less than 0.");
5617 return;
5618 }
5619 }
5620
5621 // Initialize the levels on the Z axis
5622 Int_t ndiv = fH->GetContour();
5623 if (ndiv == 0 ) {
5624 ndiv = gStyle->GetNumberContours();
5625 fH->SetContour(ndiv);
5626 }
5627 std::vector<Double_t> colorBounds(ndiv);
5628 std::vector<Double_t> contours(ndiv, 0);
5629 if (fH->TestBit(TH1::kUserContour) == 0) {
5630 fH->SetContour(ndiv);
5631 } else {
5632 fH->GetContour(contours.data());
5633 }
5634
5635 Double_t step = 1.0/ndiv;
5636 for (Int_t i=0; i<ndiv; ++i) {
5637 colorBounds[i] = step*i;
5638 }
5639
5640 auto pFrame = gPad->GetFrame();
5641 Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5642 Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5643 Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5644 Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5645 Int_t nXPixels = px1-px0;
5646 Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5647
5648 std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5649
5650 auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5651 auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5652 if (xRegions.size() == 0 || yRegions.size() == 0) {
5653 Error("THistPainter::PaintColorLevelFast(Option_t*)",
5654 "Encountered error while computing rendering regions.");
5655 return;
5656 }
5657
5658 Bool_t minExists = kFALSE;
5659 Bool_t maxExists = kFALSE;
5660 Double_t minValue = 1.;
5661 Double_t maxValue = 0.;
5662 for (auto& yRegion : yRegions) {
5663 for (auto& xRegion : xRegions ) {
5664
5665 const auto& xBinRange = xRegion.fBinRange;
5666 const auto& yBinRange = yRegion.fBinRange;
5667
5668 // sample the range
5669 z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5670
5671 if (Hoption.Logz) {
5672 if (z > 0) z = TMath::Log10(z);
5673 else z = zmin;
5674 }
5675
5676 // obey the user's max and min values if they were set
5677 if (z > zmax) z = zmax;
5678 if (z < zmin) z = zmin;
5679
5680 if (fH->TestBit(TH1::kUserContour) == 1) {
5681 // contours are absolute values
5682 auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5683 z = colorBounds[index];
5684 } else {
5685 Int_t index = 0;
5686 if (dz != 0) {
5687 index = 0.001 + ((z - zmin)/dz)*ndiv;
5688 }
5689
5690 if (index == static_cast<Int_t>(colorBounds.size())) {
5691 index--;
5692 }
5693
5694 // Do a little bookkeeping to use later for getting libAfterImage to produce
5695 // the correct colors
5696 if (index == 0) {
5697 minExists = kTRUE;
5698 } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5699 maxExists = kTRUE;
5700 }
5701
5702 z = colorBounds[index];
5703
5704 if (z < minValue) {
5705 minValue = z;
5706 }
5707 if (z > maxValue) {
5708 maxValue = z;
5709 }
5710 }
5711
5712 // fill in the actual pixels
5713 const auto& xPixelRange = xRegion.fPixelRange;
5714 const auto& yPixelRange = yRegion.fPixelRange;
5715 for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5716 for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5717 Int_t pixel = yPx*nXPixels + xPx;
5718 buffer[pixel] = z;
5719 }
5720 }
5721 } // end px loop
5722 } // end py loop
5723
5724 // This is a bit of a hack to ensure that we span the entire color range and
5725 // don't screw up the colors for a sparse histogram. No one will notice that I set a
5726 // single pixel on the edge of the image to a different color. This is even more
5727 // true because the chosen pixels will be covered by the axis.
5728 if (minValue != maxValue) {
5729 if ( !minExists) {
5730 buffer.front() = 0;
5731 }
5732
5733 if ( !maxExists) {
5734 buffer[buffer.size()-nXPixels] = 0.95;
5735 }
5736 }
5737
5738 // Generate the TImage
5740 TImage* pImage = TImage::Create();
5742 pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5743 delete pPalette;
5744
5745 Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5746 pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5747 delete pImage;
5748
5750
5751 // Reset the maximum and minimum values to their original values
5752 // when this function was called. If we don't do this, an initial
5753 // value of -1111 will be replaced with the true max or min values.
5754 fH->SetMinimum(originalZMin);
5755 fH->SetMaximum(originalZMax);
5756}
5757
5758////////////////////////////////////////////////////////////////////////////////
5759/// [Control function to draw a 2D histogram as a color plot.](\ref HP14)
5760
5762{
5763 Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5764
5765 Double_t zmin = fH->GetMinimum();
5766 Double_t zmax = fH->GetMaximum();
5767
5768 Double_t dz = zmax - zmin;
5769 if (dz <= 0) { // Histogram filled with a constant value
5770 zmax += 0.1*TMath::Abs(zmax);
5771 zmin -= 0.1*TMath::Abs(zmin);
5772 dz = zmax - zmin;
5773 }
5774
5775 // In case of option SAME, zmin and zmax values are taken from the
5776 // first plotted 2D histogram.
5777 if (Hoption.Same > 0 && Hoption.Same < 10) {
5778 TH2 *h2;
5779 TIter next(gPad->GetListOfPrimitives());
5780 while ((h2 = (TH2 *)next())) {
5781 if (!h2->InheritsFrom(TH2::Class())) continue;
5782 zmin = h2->GetMinimum();
5783 zmax = h2->GetMaximum();
5784 fH->SetMinimum(zmin);
5785 fH->SetMaximum(zmax);
5786 if (Hoption.Logz) {
5787 if (zmin <= 0) {
5788 zmin = TMath::Log10(zmax*0.001);
5789 } else {
5790 zmin = TMath::Log10(zmin);
5791 }
5792 zmax = TMath::Log10(zmax);
5793 }
5794 dz = zmax - zmin;
5795 break;
5796 }
5797 } else {
5798 if (Hoption.Logz) {
5799 if (zmin > 0) {
5800 zmin = TMath::Log10(zmin);
5801 zmax = TMath::Log10(zmax);
5802 dz = zmax - zmin;
5803 } else {
5804 return;
5805 }
5806 }
5807 }
5808
5809 Style_t fillsav = fH->GetFillStyle();
5810 Style_t colsav = fH->GetFillColor();
5811 fH->SetFillStyle(1001);
5812 fH->TAttFill::Modify();
5813
5814 // Initialize the levels on the Z axis
5815 Int_t ncolors = gStyle->GetNumberOfColors();
5816 Int_t ndiv = fH->GetContour();
5817 if (ndiv == 0 ) {
5818 ndiv = gStyle->GetNumberContours();
5819 fH->SetContour(ndiv);
5820 }
5821 Int_t ndivz = TMath::Abs(ndiv);
5822 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5823 Double_t scale = (dz ? ndivz / dz : 1.0);
5824
5825 Int_t color;
5826 TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5827 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5828 yk = fYaxis->GetBinLowEdge(j);
5829 ystep = fYaxis->GetBinWidth(j);
5830 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5831 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5832 xk = fXaxis->GetBinLowEdge(i);
5833 xstep = fXaxis->GetBinWidth(i);
5834 if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5835 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5836 z = fH->GetBinContent(bin);
5837 // if fH is a profile histogram do not draw empty bins
5838 if (prof2d) {
5839 const Double_t binEntries = prof2d->GetBinEntries(bin);
5840 if (binEntries == 0)
5841 continue;
5842 } else {
5843 // don't draw the empty bins for non-profile histograms
5844 // with positive content
5845 if (z == 0) {
5846 if (zmin >= 0 || Hoption.Logz) continue;
5847 if (Hoption.Color == 2) continue;
5848 }
5849 }
5850
5851 if (Hoption.Logz) {
5852 if (z > 0) z = TMath::Log10(z);
5853 else z = zmin;
5854 }
5855 if (z < zmin && !Hoption.Zero) continue;
5856 xup = xk + xstep;
5857 xlow = xk;
5858 if (Hoption.Logx) {
5859 if (xup > 0) xup = TMath::Log10(xup);
5860 else continue;
5861 if (xlow > 0) xlow = TMath::Log10(xlow);
5862 else continue;
5863 }
5864 yup = yk + ystep;
5865 ylow = yk;
5866 if (Hoption.System != kPOLAR) {
5867 if (Hoption.Logy) {
5868 if (yup > 0) yup = TMath::Log10(yup);
5869 else continue;
5870 if (ylow > 0) ylow = TMath::Log10(ylow);
5871 else continue;
5872 }
5873 if (xup < gPad->GetUxmin()) continue;
5874 if (yup < gPad->GetUymin()) continue;
5875 if (xlow > gPad->GetUxmax()) continue;
5876 if (ylow > gPad->GetUymax()) continue;
5877 if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5878 if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5879 if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5880 if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5881 }
5882
5884 zc = fH->GetContourLevelPad(0);
5885 if (z < zc) continue;
5886 color = -1;
5887 for (Int_t k=0; k<ndiv; k++) {
5888 zc = fH->GetContourLevelPad(k);
5889 if (z < zc) {
5890 continue;
5891 } else {
5892 color++;
5893 }
5894 }
5895 } else {
5896 color = Int_t(0.01+(z-zmin)*scale);
5897 }
5898
5899 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5900 if (theColor > ncolors-1) theColor = ncolors-1;
5902 fH->TAttFill::Modify();
5903 if (Hoption.System != kPOLAR) {
5904 gPad->PaintBox(xlow, ylow, xup, yup);
5905 } else {
5906 TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5907 crown.SetFillColor(gStyle->GetColorPalette(theColor));
5908 crown.Paint();
5909 }
5910 }
5911 }
5912
5914
5915 fH->SetFillStyle(fillsav);
5916 fH->SetFillColor(colsav);
5917 fH->TAttFill::Modify();
5918
5919}
5920
5921////////////////////////////////////////////////////////////////////////////////
5922/// [Control function to draw a 2D histogram as a contour plot.](\ref HP16)
5923
5925{
5926
5927 Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5928 Int_t itars, mode, ir[4];
5929 Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5930
5931 if (Hoption.Contour == 14) {
5932 Hoption.Surf = 12;
5933 Hoption.Axis = 1;
5934 thesave = gPad->GetTheta();
5935 phisave = gPad->GetPhi();
5936 gPad->SetPhi(0.);
5937 gPad->SetTheta(90.);
5938 PaintSurface(option);
5939 gPad->SetPhi(phisave);
5940 gPad->SetTheta(thesave);
5941 TView *view = gPad->GetView();
5942 if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5943 PaintAxis();
5944 return;
5945 }
5946
5947 if (Hoption.Same) {
5948 // If the contour is painted on a 3d plot, the contour lines are
5949 // paint in 3d too.
5950 TObject *obj;
5951 TIter next(gPad->GetListOfPrimitives());
5952 while ((obj=next())) {
5953 if (strstr(obj->GetDrawOption(),"surf") ||
5954 strstr(obj->GetDrawOption(),"lego") ||
5955 strstr(obj->GetDrawOption(),"tri")) {
5956 Hoption.Surf = 16;
5957 PaintSurface(option);
5958 return;
5959 }
5960 }
5961 }
5962
5963 if (Hoption.Contour == 15) {
5964 TGraphDelaunay2D *dt = nullptr;
5965 TGraphDelaunay *dtOld = nullptr;
5966 TList *hl = fH->GetListOfFunctions();
5967 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5968 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5969 if (!dt && !dtOld) return;
5970 if (!fGraph2DPainter) {
5971 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5972 else fGraph2DPainter = new TGraph2DPainter(dtOld);
5973 }
5974 fGraph2DPainter->Paint(option);
5975 return;
5976 }
5977
5978 gPad->SetBit(TGraph::kClipFrame);
5979
5980 Double_t *levels = new Double_t[2*kMAXCONTOUR];
5981 Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5982 Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5983 Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5984
5985 Int_t npmax = 0;
5986 for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5987
5988 ncontour = fH->GetContour();
5989 if (ncontour == 0) {
5990 ncontour = gStyle->GetNumberContours();
5991 fH->SetContour(ncontour);
5992 }
5993 if (ncontour > kMAXCONTOUR) {
5994 Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5995 kMAXCONTOUR, ncontour);
5996 ncontour = kMAXCONTOUR-1;
5997 }
5998 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5999
6000 for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
6001 Int_t linesav = fH->GetLineStyle();
6002 Int_t colorsav = fH->GetLineColor();
6003 Int_t fillsav = fH->GetFillColor();
6004 if (Hoption.Contour == 13) {
6005 fH->TAttLine::Modify();
6006 }
6007
6008 TPolyLine **polys = 0;
6009 TPolyLine *poly=0;
6010 TObjArray *contours = 0;
6011 TList *list = 0;
6012 TGraph *graph = 0;
6013 Int_t *np = 0;
6014 if (Hoption.Contour == 1) {
6015 np = new Int_t[ncontour];
6016 for (i=0;i<ncontour;i++) np[i] = 0;
6017 polys = new TPolyLine*[ncontour];
6018 for (i=0;i<ncontour;i++) {
6019 polys[i] = new TPolyLine(100);
6020 }
6021 if (Hoption.List == 1) {
6022 contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
6023 if (contours) {
6024 gROOT->GetListOfSpecials()->Remove(contours);
6025 count = contours->GetSize();
6026 for (i=0;i<count;i++) {
6027 list = (TList*)contours->At(i);
6028 if (list) list->Delete();
6029 }
6030 }
6031 contours = new TObjArray(ncontour);
6032 contours->SetName("contours");
6033 gROOT->GetListOfSpecials()->Add(contours);
6034 for (i=0;i<ncontour;i++) {
6035 list = new TList();
6036 contours->Add(list);
6037 }
6038 }
6039 }
6040 Int_t theColor;
6041 Int_t ncolors = gStyle->GetNumberOfColors();
6042 Int_t ndivz = TMath::Abs(ncontour);
6043
6044 Int_t k,ipoly;
6045 for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
6046 y[0] = fYaxis->GetBinCenter(j);
6047 y[1] = y[0];
6048 y[2] = fYaxis->GetBinCenter(j+1);
6049 y[3] = y[2];
6050 for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
6051 zc[0] = fH->GetBinContent(i, j);
6052 zc[1] = fH->GetBinContent(i+1, j);
6053 zc[2] = fH->GetBinContent(i+1, j+1);
6054 zc[3] = fH->GetBinContent(i, j+1);
6055 if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
6056 if (Hoption.Logz) {
6057 if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
6058 else zc[0] = Hparam.zmin;
6059 if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
6060 else zc[1] = Hparam.zmin;
6061 if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
6062 else zc[2] = Hparam.zmin;
6063 if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
6064 else zc[3] = Hparam.zmin;
6065 }
6066 for (k=0;k<4;k++) {
6067 ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
6068 }
6069 if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
6070 x[0] = fXaxis->GetBinCenter(i);
6071 x[3] = x[0];
6072 x[1] = fXaxis->GetBinCenter(i+1);
6073 x[2] = x[1];
6074 if (zc[0] <= zc[1]) n = 0; else n = 1;
6075 if (zc[2] <= zc[3]) m = 2; else m = 3;
6076 if (zc[n] > zc[m]) n = m;
6077 n++;
6078 lj=1;
6079 for (ix=1;ix<=4;ix++) {
6080 m = n%4 + 1;
6081 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
6082 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
6083 lj += 2*ljfill;
6084 n = m;
6085 }
6086
6087 if (zc[0] <= zc[1]) n = 0; else n = 1;
6088 if (zc[2] <= zc[3]) m = 2; else m = 3;
6089 if (zc[n] > zc[m]) n = m;
6090 n++;
6091 lj=2;
6092 for (ix=1;ix<=4;ix++) {
6093 if (n == 1) m = 4;
6094 else m = n-1;
6095 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
6096 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
6097 lj += 2*ljfill;
6098 n = m;
6099 }
6100
6101 // Re-order endpoints
6102
6103 count = 0;
6104 for (ix=1; ix<=lj-5; ix +=2) {
6105 //count = 0;
6106 while (itarr[ix-1] != itarr[ix]) {
6107 xsave = xarr[ix];
6108 ysave = yarr[ix];
6109 itars = itarr[ix];
6110 for (jx=ix; jx<=lj-5; jx +=2) {
6111 xarr[jx] = xarr[jx+2];
6112 yarr[jx] = yarr[jx+2];
6113 itarr[jx] = itarr[jx+2];
6114 }
6115 xarr[lj-3] = xsave;
6116 yarr[lj-3] = ysave;
6117 itarr[lj-3] = itars;
6118 if (count > 100) break;
6119 count++;
6120 }
6121 }
6122
6123 if (count > 100) continue;
6124 for (ix=1; ix<=lj-2; ix +=2) {
6125 theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
6126 icol = gStyle->GetColorPalette(theColor);
6127 if (Hoption.Contour == 11) {
6128 fH->SetLineColor(icol);
6129 }
6130 if (Hoption.Contour == 12) {
6131 mode = icol%5;
6132 if (mode == 0) mode = 5;
6133 fH->SetLineStyle(mode);
6134 }
6135 if (Hoption.Contour != 1) {
6136 fH->TAttLine::Modify();
6137 gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
6138 continue;
6139 }
6140
6141 ipoly = itarr[ix-1];
6142 if (ipoly >=0 && ipoly <ncontour) {
6143 poly = polys[ipoly];
6144 poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
6145 poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
6146 np[ipoly] += 2;
6147 if (npmax < np[ipoly]) npmax = np[ipoly];
6148 }
6149 }
6150 } // end of if (ir[0]
6151 } //end of for (i
6152 } //end of for (j
6153
6155 Double_t *xp, *yp;
6156 Int_t nadd,iminus,iplus;
6157 Double_t *xx, *yy;
6158 Int_t istart;
6159 Int_t first = ncontour;
6160 Int_t *polysort = 0;
6161 Int_t contListNb;
6162 if (Hoption.Contour != 1) goto theEND;
6163
6164 //The 2 points line generated above are now sorted/merged to generate
6165 //a list of consecutive points.
6166 // If the option "List" has been specified, the list of points is saved
6167 // in the form of TGraph objects in the ROOT list of special objects.
6168 xmin = gPad->GetUxmin();
6169 ymin = gPad->GetUymin();
6170 xp = new Double_t[2*npmax];
6171 yp = new Double_t[2*npmax];
6172 polysort = new Int_t[ncontour];
6173 //find first positive contour
6174 for (ipoly=0;ipoly<ncontour;ipoly++) {
6175 if (levels[ipoly] >= 0) {first = ipoly; break;}
6176 }
6177 //store negative contours from 0 to minimum, then all positive contours
6178 k = 0;
6179 for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
6180 for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
6181 // we can now draw sorted contours
6182 contListNb = 0;
6183 fH->SetFillStyle(1001);
6184 for (k=0;k<ncontour;k++) {
6185 ipoly = polysort[k];
6186 if (np[ipoly] == 0) continue;
6187 if (Hoption.List) list = (TList*)contours->At(contListNb);
6188 contListNb++;
6189 poly = polys[ipoly];
6190 xx = poly->GetX();
6191 yy = poly->GetY();
6192 istart = 0;
6193 while (1) {
6194 iminus = npmax;
6195 iplus = iminus+1;
6196 xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
6197 xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
6198 xx[istart] = xmin; yy[istart] = ymin;
6199 xx[istart+1] = xmin; yy[istart+1] = ymin;
6200 while (1) {
6201 nadd = 0;
6202 for (i=2;i<np[ipoly];i+=2) {
6203 if ((iplus < 2*npmax-1) && (xx[i] == xp[iplus]) && (yy[i] == yp[iplus])) {
6204 iplus++;
6205 xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
6206 xx[i] = xmin; yy[i] = ymin;
6207 xx[i+1] = xmin; yy[i+1] = ymin;
6208 nadd++;
6209 }
6210 if ((iminus > 0) && (xx[i+1] == xp[iminus]) && (yy[i+1] == yp[iminus])) {
6211 iminus--;
6212 xp[iminus] = xx[i]; yp[iminus] = yy[i];
6213 xx[i] = xmin; yy[i] = ymin;
6214 xx[i+1] = xmin; yy[i+1] = ymin;
6215 nadd++;
6216 }
6217 }
6218 if (nadd == 0) break;
6219 }
6220 theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
6221 icol = gStyle->GetColorPalette(theColor);
6222 if (ndivz > 1) fH->SetFillColor(icol);
6223 fH->TAttFill::Modify();
6224 gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6225 if (Hoption.List) {
6226 graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6227 graph->SetFillColor(icol);
6228 graph->SetLineWidth(fH->GetLineWidth());
6229 list->Add(graph);
6230 }
6231 //check if more points are left
6232 istart = 0;
6233 for (i=2;i<np[ipoly];i+=2) {
6234 if (xx[i] != xmin && yy[i] != ymin) {
6235 istart = i;
6236 break;
6237 }
6238 }
6239 if (istart == 0) break;
6240 }
6241 }
6242
6243 for (i=0;i<ncontour;i++) delete polys[i];
6244 delete [] polys;
6245 delete [] xp;
6246 delete [] yp;
6247 delete [] polysort;
6248
6249theEND:
6250 gPad->ResetBit(TGraph::kClipFrame);
6252 fH->SetLineStyle(linesav);
6253 fH->SetLineColor(colorsav);
6254 fH->SetFillColor(fillsav);
6255 if (np) delete [] np;
6256 delete [] xarr;
6257 delete [] yarr;
6258 delete [] itarr;
6259 delete [] levels;
6260}
6261
6262////////////////////////////////////////////////////////////////////////////////
6263/// Fill the matrix `xarr` and `yarr` for Contour Plot.
6264
6266 Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
6267 Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
6268{
6269
6270 Bool_t vert;
6271 Double_t tlen, tdif, elev, diff, pdif, xlen;
6272 Int_t n, i, icount;
6273
6274 if (x1 == x2) {
6275 vert = kTRUE;
6276 tlen = y2 - y1;
6277 } else {
6278 vert = kFALSE;
6279 tlen = x2 - x1;
6280 }
6281
6282 n = icont1 +1;
6283 tdif = elev2 - elev1;
6284 i = 0;
6285 icount = 0;
6286 while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
6287 //elev = fH->GetContourLevel(n);
6288 elev = levels[n];
6289 diff = elev - elev1;
6290 pdif = diff/tdif;
6291 xlen = tlen*pdif;
6292 if (vert) {
6293 if (Hoption.Logx)
6294 xarr[i] = TMath::Log10(x1);
6295 else
6296 xarr[i] = x1;
6297 if (Hoption.Logy)
6298 yarr[i] = TMath::Log10(y1 + xlen);
6299 else
6300 yarr[i] = y1 + xlen;
6301 } else {
6302 if (Hoption.Logx)
6303 xarr[i] = TMath::Log10(x1 + xlen);
6304 else
6305 xarr[i] = x1 + xlen;
6306 if (Hoption.Logy)
6307 yarr[i] = TMath::Log10(y1);
6308 else
6309 yarr[i] = y1;
6310 }
6311 itarr[i] = n;
6312 icount++;
6313 i +=2;
6314 n++;
6315 }
6316 return icount;
6317}
6318
6319////////////////////////////////////////////////////////////////////////////////
6320/// [Draw 1D histograms error bars.](\ref HP09)
6321
6323{
6324
6325 // On iOS, we do not highlight histogram, if it's not picked at the moment
6326 // (but part of histogram (axis or pavestat) was picked, that's why this code
6327 // is called at all. This conditional statement never executes on non-iOS platform.
6328 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
6329
6330 const Int_t kBASEMARKER=8;
6331 Double_t xp, yp, ex1, ex2, ey1, ey2;
6332 Double_t delta;
6333 Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbasex, sbasey;
6334 Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
6336 Double_t logxmin = 0;
6337 Double_t logymin = 0;
6338 Double_t offset = 0.;
6339 Double_t width = 0.;
6340 Int_t i, k, npoints, first, last, fixbin;
6341 Int_t if1 = 0;
6342 Int_t if2 = 0;
6343 Int_t drawmarker, errormarker;
6344 Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
6345 static Float_t cxx[30] = {1.0,1.0,0.5,0.5,1.0,1.0,0.5,0.6,1.0,0.5,0.5,1.0,0.5,0.6,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,0.5,0.5,0.5,1.0};
6346 static Float_t cyy[30] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,0.5,0.5,0.5,1.0};
6347
6348 Double_t *xline = 0;
6349 Double_t *yline = 0;
6350 option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
6351 if (Hoption.Error >= 40) {Hoption.Error -=40; option0 = 1;}
6352 if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
6353 if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
6354 if (Hoption.Error == 11) option1 = 1;
6355 if (Hoption.Error == 12) option2 = 1;
6356 if (Hoption.Error == 13) option3 = 1;
6357 if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
6358 if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
6359 if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
6360 if (option2+option3 == 0) optionE = 1;
6361 if (Hoption.Error == 0) optionE = 0;
6362 if (fXaxis->GetXbins()->fN) fixbin = 0;
6363 else fixbin = 1;
6364
6365 offset = fH->GetBarOffset();
6366 width = fH->GetBarWidth();
6367
6369 if (optionEX0) {
6370 xerror = 0;
6371 } else {
6372 xerror = gStyle->GetErrorX();
6373 }
6374 symbolsize = fH->GetMarkerSize();
6375 if (errormarker == 1) symbolsize = 0.01;
6376 sbasex = sbasey = symbolsize*kBASEMARKER;
6377 if (errormarker >= 20 && errormarker <= 49) {
6378 sbasex *= cxx[errormarker-20];
6379 sbasey *= cyy[errormarker-20];
6380 }
6381 // set the graphics attributes
6382
6383 fH->TAttLine::Modify();
6384 fH->TAttFill::Modify();
6385 fH->TAttMarker::Modify();
6386
6387 // set the first and last bin
6388
6389 Double_t factor = Hparam.factor;
6391 last = Hparam.xlast;
6392 npoints = last - first +1;
6393 xmin = gPad->GetUxmin();
6394 xmax = gPad->GetUxmax();
6395 ymin = gPad->GetUymin();
6396 ymax = gPad->GetUymax();
6397
6398
6399 if (option3) {
6400 xline = new Double_t[2*npoints];
6401 yline = new Double_t[2*npoints];
6402 if (!xline || !yline) {
6403 Error("PaintErrors", "too many points, out of memory");
6404 return;
6405 }
6406 if1 = 1;
6407 if2 = 2*npoints;
6408 }
6409
6410 // compute the offset of the error bars due to the symbol size
6411 s2x = gPad->PixeltoX(Int_t(0.5*sbasex)) - gPad->PixeltoX(0);
6412 s2y =-gPad->PixeltoY(Int_t(0.5*sbasey)) + gPad->PixeltoY(0);
6413
6414 // compute size of the lines at the end of the error bars
6415 Int_t dxend = Int_t(gStyle->GetEndErrorSize());
6416 bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
6417 bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
6418
6419
6420 if (fixbin) {
6421 if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
6422 else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
6423 } else {
6424 delta = fH->GetBinWidth(first);
6425 xp = fH->GetBinLowEdge(first) + 0.5*delta;
6426 }
6427
6428 // if errormarker = 0 or symbolsize = 0. no symbol is drawn
6429 if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
6430 if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
6431
6432 // ---------------------- Loop over the points---------------------
6433 for (k=first; k<=last; k++) {
6434
6435 // get the data
6436 // xp = X position of the current point
6437 // yp = Y position of the current point
6438 // ex1 = Low X error
6439 // ex2 = Up X error
6440 // ey1 = Low Y error
6441 // ey2 = Up Y error
6442 // (xi,yi) = Error bars coordinates
6443
6444 // apply offset on errors for bar histograms
6445 Double_t xminTmp = gPad->XtoPad(fXaxis->GetBinLowEdge(k));
6446 Double_t xmaxTmp = gPad->XtoPad(fXaxis->GetBinUpEdge(k));
6447 if (Hoption.Logx) {
6448 xminTmp = TMath::Power(10, xminTmp);
6449 xmaxTmp = TMath::Power(10, xmaxTmp);
6450 }
6451 Double_t w = (xmaxTmp-xminTmp)*width;
6452 xminTmp += offset*(xmaxTmp-xminTmp);
6453 xmaxTmp = xminTmp + w;
6454 xp = (xminTmp+xmaxTmp)/2.;
6455
6456 if (Hoption.Logx) {
6457 if (xp <= 0) goto L30;
6458 if (xp < logxmin) goto L30;
6459 if (xp > TMath::Power(10,xmax)) break;
6460 } else {
6461 if (xp < xmin) goto L30;
6462 if (xp > xmax) break;
6463 }
6464 yp = factor*fH->GetBinContent(k);
6465 if (optionI0 && yp==0) goto L30;
6466 if (fixbin) {
6467 ex1 = xerror*Hparam.xbinsize;
6468 } else {
6469 delta = fH->GetBinWidth(k);
6470 ex1 = xerror*delta;
6471 }
6472 if (fH->GetBinErrorOption() == TH1::kNormal) {
6473 ey1 = factor*fH->GetBinError(k);
6474 ey2 = ey1;
6475 } else {
6476 ey1 = factor*fH->GetBinErrorLow(k);
6477 ey2 = factor*fH->GetBinErrorUp(k);
6478 }
6479 ex2 = ex1;
6480
6481 xi4 = xp;
6482 xi3 = xp;
6483 xi2 = xp + ex2;
6484 xi1 = xp - ex1;
6485
6486 yi1 = yp;
6487 yi2 = yp;
6488 yi3 = yp - ey1;
6489 yi4 = yp + ey2;
6490
6491 // take the LOG if necessary
6492 if (Hoption.Logx) {
6493 xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
6494 xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
6495 xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
6496 xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
6497 }
6498 if (Hoption.Logy) {
6499 yi1 = TMath::Log10(TMath::Max(yi1,logymin));
6500 yi2 = TMath::Log10(TMath::Max(yi2,logymin));
6501 yi3 = TMath::Log10(TMath::Max(yi3,logymin));
6502 yi4 = TMath::Log10(TMath::Max(yi4,logymin));
6503 }
6504
6505 // test if error bars are not outside the limits
6506 // otherwise they are truncated
6507
6508 xi1 = TMath::Max(xi1,xmin);
6509 xi2 = TMath::Min(xi2,xmax);
6510 yi3 = TMath::Max(yi3,ymin);
6511 yi4 = TMath::Min(yi4,ymax);
6512
6513 // test if the marker is on the frame limits. If "Yes", the
6514 // marker will not be drawn and the error bars will be readjusted.
6515
6516 drawmarker = kTRUE;
6517 if (!option0 && !option3) {
6518 if (Hoption.Logy && yp < logymin) goto L30;
6519 if (yi1 < ymin || yi1 > ymax) goto L30;
6520 if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6521 }
6522 if (!symbolsize || !errormarker) drawmarker = kFALSE;
6523
6524 // draw the error rectangles
6525 if (option2) {
6526 if (yi3 >= ymax) goto L30;
6527 if (yi4 <= ymin) goto L30;
6528 gPad->PaintBox(xi1,yi3,xi2,yi4);
6529 }
6530
6531 // keep points for fill area drawing
6532 if (option3) {
6533 xline[if1-1] = xi3;
6534 xline[if2-1] = xi3;
6535 yline[if1-1] = yi4;
6536 yline[if2-1] = yi3;
6537 if1++;
6538 if2--;
6539 }
6540
6541 // draw the error bars
6542 if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6543 if (optionE && drawmarker) {
6544 if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6545 if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6546 // don't duplicate the horizontal line
6547 if (Hoption.Hist != 2) {
6548 if (yi1<ymax && yi1>ymin) {
6549 if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6550 if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6551 }
6552 }
6553 }
6554 if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6555 if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6556 if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6557 // don't duplicate the horizontal line
6558 if (Hoption.Hist != 2) {
6559 if (yi1<ymax && yi1>ymin) {
6560 if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6561 if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6562 }
6563 }
6564 }
6565
6566 // draw line at the end of the error bars
6567
6568 if (option1 && drawmarker) {
6569
6570 if (yi3 < yi1-s2y && yi3 < ymax && yi3 > ymin) gPad->PaintLine(xi3 - bxsize, yi3 , xi3 + bxsize, yi3);
6571 if (yi4 > yi1+s2y && yi4 < ymax && yi4 > ymin) gPad->PaintLine(xi3 - bxsize, yi4 , xi3 + bxsize, yi4);
6572 if (yi1 <= ymax && yi1 >= ymin) {
6573 if (xi1 < xi3-s2x) gPad->PaintLine(xi1 , yi1 - bysize, xi1 , yi1 + bysize);
6574 if (xi2 > xi3+s2x) gPad->PaintLine(xi2 , yi1 - bysize, xi2 , yi1 + bysize);
6575 }
6576 }
6577
6578 // draw the marker
6579
6580 if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6581
6582L30:
6583 if (fixbin) xp += Hparam.xbinsize;
6584 else {
6585 if (k < last) {
6586 delta = fH->GetBinWidth(k+1);
6587 xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6588 }
6589 }
6590 } //end of for loop
6591
6592 // draw the filled area
6593
6594 if (option3) {
6595 TGraph graph;
6596 graph.SetLineStyle(fH->GetLineStyle());
6597 graph.SetLineColor(fH->GetLineColor());
6598 graph.SetLineWidth(fH->GetLineWidth());
6599 graph.SetFillStyle(fH->GetFillStyle());
6600 graph.SetFillColor(fH->GetFillColor());
6601 Int_t logx = gPad->GetLogx();
6602 Int_t logy = gPad->GetLogy();
6603 gPad->SetLogx(0);
6604 gPad->SetLogy(0);
6605
6606 // In some cases the number of points in the fill area is smaller than
6607 // 2*npoints. In such cases the array xline and yline must be arranged
6608 // before being plotted. The next loop does that.
6609 if (if2 > npoints) {
6610 for (i=1; i<if1; i++) {
6611 xline[if1-2+i] = xline[if2-1+i];
6612 yline[if1-2+i] = yline[if2-1+i];
6613 }
6614 npoints = if1-1;
6615 }
6616 if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6617 else graph.PaintGraph(2*npoints,xline,yline,"F");
6618 gPad->SetLogx(logx);
6619 gPad->SetLogy(logy);
6620 delete [] xline;
6621 delete [] yline;
6622 }
6623}
6624
6625////////////////////////////////////////////////////////////////////////////////
6626/// Draw 2D histograms errors.
6627
6629{
6630
6631 fH->TAttMarker::Modify();
6632 fH->TAttLine::Modify();
6633
6634 // Define the 3D view
6635 fXbuf[0] = Hparam.xmin;
6636 fYbuf[0] = Hparam.xmax;
6637 fXbuf[1] = Hparam.ymin;
6638 fYbuf[1] = Hparam.ymax;
6639 fXbuf[2] = Hparam.zmin;
6640 fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6642 TView *view = gPad->GetView();
6643 if (!view) {
6644 Error("Paint2DErrors", "no TView in current pad");
6645 return;
6646 }
6647 Double_t thedeg = 90 - gPad->GetTheta();
6648 Double_t phideg = -90 - gPad->GetPhi();
6649 Double_t psideg = view->GetPsi();
6650 Int_t irep;
6651 view->SetView(phideg, thedeg, psideg, irep);
6652
6653 // Set color/style for back box
6654 fLego->SetFillStyle(gPad->GetFrameFillStyle());
6655 fLego->SetFillColor(gPad->GetFrameFillColor());
6656 fLego->TAttFill::Modify();
6657 Int_t backcolor = gPad->GetFrameFillColor();
6658 if (Hoption.System != kCARTESIAN) backcolor = 0;
6659 view->PadRange(backcolor);
6662 fLego->TAttFill::Modify();
6663
6664 // Paint the Back Box if needed
6665 if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6666 fLego->InitMoveScreen(-1.1,1.1);
6669 fLego->BackBox(90);
6670 }
6671
6672 // Paint the Errors
6673 Double_t x, ex, x1, x2;
6674 Double_t y, ey, y1, y2;
6675 Double_t z, ez1, ez2, z1, z2;
6676 Double_t temp1[3],temp2[3];
6677 Double_t xyerror;
6678 if (Hoption.Error == 110) {
6679 xyerror = 0;
6680 } else {
6681 xyerror = gStyle->GetErrorX();
6682 }
6683
6684 Double_t xk, xstep, yk, ystep;
6685 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6686 y = fYaxis->GetBinCenter(j);
6687 ey = fYaxis->GetBinWidth(j)*xyerror;
6688 y1 = y-ey;
6689 y2 = y+ey;
6690 if (Hoption.Logy) {
6691 if (y > 0) y = TMath::Log10(y);
6692 else continue;
6693 if (y1 > 0) y1 = TMath::Log10(y1);
6694 else y1 = Hparam.ymin;
6695 if (y2 > 0) y2 = TMath::Log10(y2);
6696 else y2 = Hparam.ymin;
6697 }
6698 yk = fYaxis->GetBinLowEdge(j);
6699 ystep = fYaxis->GetBinWidth(j);
6700 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6701 xk = fXaxis->GetBinLowEdge(i);
6702 xstep = fXaxis->GetBinWidth(i);
6703 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6704 Int_t bin = fH->GetBin(i,j);
6705 x = fXaxis->GetBinCenter(i);
6706 ex = fXaxis->GetBinWidth(i)*xyerror;
6707 x1 = x-ex;
6708 x2 = x+ex;
6709 if (Hoption.Logx) {
6710 if (x > 0) x = TMath::Log10(x);
6711 else continue;
6712 if (x1 > 0) x1 = TMath::Log10(x1);
6713 else x1 = Hparam.xmin;
6714 if (x2 > 0) x2 = TMath::Log10(x2);
6715 else x2 = Hparam.xmin;
6716 }
6717 z = fH->GetBinContent(bin);
6718 if (fH->GetBinErrorOption() == TH1::kNormal) {
6719 ez1 = fH->GetBinError(bin);
6720 ez2 = ez1;
6721 }
6722 else {
6723 ez1 = fH->GetBinErrorLow(bin);
6724 ez2 = fH->GetBinErrorUp(bin);
6725 }
6726 z1 = z - ez1;
6727 z2 = z + ez2;
6728 if (Hoption.Logz) {
6729 if (z > 0) z = TMath::Log10(z);
6730 else z = Hparam.zmin;
6731 if (z1 > 0) z1 = TMath::Log10(z1);
6732 else z1 = Hparam.zmin;
6733 if (z2 > 0) z2 = TMath::Log10(z2);
6734 else z2 = Hparam.zmin;
6735
6736 }
6737 if (z <= Hparam.zmin) continue;
6738 if (z > Hparam.zmax) z = Hparam.zmax;
6739
6740 temp1[0] = x1;
6741 temp1[1] = y;
6742 temp1[2] = z;
6743 temp2[0] = x2;
6744 temp2[1] = y;
6745 temp2[2] = z;
6746 gPad->PaintLine3D(temp1, temp2);
6747 temp1[0] = x;
6748 temp1[1] = y1;
6749 temp1[2] = z;
6750 temp2[0] = x;
6751 temp2[1] = y2;
6752 temp2[2] = z;
6753 gPad->PaintLine3D(temp1, temp2);
6754 temp1[0] = x;
6755 temp1[1] = y;
6756 temp1[2] = z1;
6757 temp2[0] = x;
6758 temp2[1] = y;
6759 temp2[2] = z2;
6760 gPad->PaintLine3D(temp1, temp2);
6761 temp1[0] = x;
6762 temp1[1] = y;
6763 temp1[2] = z;
6764 view->WCtoNDC(temp1, &temp2[0]);
6765 gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6766 }
6767 }
6768
6769 // Paint the Front Box if needed
6770 if (Hoption.FrontBox) {
6771 fLego->InitMoveScreen(-1.1,1.1);
6773 fLego->FrontBox(90);
6774 }
6775
6776 // Paint the Axis if needed
6777 if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6778 TGaxis *axis = new TGaxis();
6779 PaintLegoAxis(axis, 90);
6780 delete axis;
6781 }
6782
6783 delete fLego; fLego = 0;
6784}
6785
6786////////////////////////////////////////////////////////////////////////////////
6787/// Calculate range and clear pad (canvas).
6788
6790{
6791
6792 if (Hoption.Same) return;
6793
6795
6796 if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6797 Hoption.Contour == 14 || Hoption.Error >= 100) {
6798 TObject *frame = gPad->FindObject("TFrame");
6799 if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6800 return;
6801 }
6802
6803 //The next statement is always executed on non-iOS platform,
6804 //on iOS depends on pad mode.
6805 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6806 gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6807}
6808
6809////////////////////////////////////////////////////////////////////////////////
6810/// [Paint functions associated to an histogram.](\ref HP28")
6811
6813{
6814
6816 TObject *obj;
6817
6818 while (lnk) {
6819 obj = lnk->GetObject();
6820 TVirtualPad *padsave = gPad;
6821 if (obj->InheritsFrom(TF2::Class())) {
6822 if (obj->TestBit(TF2::kNotDraw) == 0) {
6823 if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) {
6824 TF2 *f2 = (TF2*)obj;
6825 f2->SetMinimum(fH->GetMinimum());
6826 f2->SetMaximum(fH->GetMaximum());
6827 f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6828 f2->Paint("surf same");
6829 } else {
6830 obj->Paint("cont3 same");
6831 }
6832 }
6833 } else if (obj->InheritsFrom(TF1::Class())) {
6834 if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6835 } else {
6836 //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6837 gPad->PushSelectableObject(obj);
6838
6839 //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6840 //and picked object.
6841 if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6842 obj->Paint(lnk->GetOption());
6843 }
6844 lnk = (TObjOptLink*)lnk->Next();
6845 padsave->cd();
6846 }
6847}
6848
6849////////////////////////////////////////////////////////////////////////////////
6850/// [Control routine to draw 1D histograms](\ref HP01b)
6851
6853{
6854
6855 //On iOS: do not highlight hist, if part of it was selected.
6856 //Never executes on non-iOS platform.
6857 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6858 return;
6859
6860 static char chopth[17];
6861
6862 Int_t htype, oldhtype;
6863 Int_t i, j, first, last, nbins, fixbin;
6864 Double_t c1, yb;
6865 yb = 0;
6866
6867 strlcpy(chopth, " ",17);
6868
6871 Double_t baroffset = fH->GetBarOffset();
6872 Double_t barwidth = fH->GetBarWidth();
6873 Double_t baroffsetsave = gStyle->GetBarOffset();
6874 Double_t barwidthsave = gStyle->GetBarWidth();
6875 gStyle->SetBarOffset(baroffset);
6876 gStyle->SetBarWidth(barwidth);
6877
6878 // Create "LIFE" structure to keep current histogram status
6879
6881 last = Hparam.xlast;
6882 nbins = last - first + 1;
6883
6884 Double_t *keepx = 0;
6885 Double_t *keepy = 0;
6886 if (fXaxis->GetXbins()->fN) fixbin = 0;
6887 else fixbin = 1;
6888 if (fixbin) keepx = new Double_t[2];
6889 else keepx = new Double_t[nbins+1];
6890 keepy = new Double_t[nbins];
6891 Double_t logymin = 0;
6892 if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6893
6894 // Loop on histogram bins
6895
6896 for (j=first; j<=last;j++) {
6898 if (TMath::Abs(ymax-ymin) > 0) {
6899 if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6900 else yb = c1;
6901 }
6902 if (!Hoption.Line) {
6903 yb = TMath::Max(yb, ymin);
6904 yb = TMath::Min(yb, ymax);
6905 }
6906 keepy[j-first] = yb;
6907 }
6908
6909 // Draw histogram according to value of FillStyle and FillColor
6910
6911 if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6912 else {
6913 for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6914 keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6915 }
6916
6917 // Prepare Fill area (systematic with option "Bar").
6918
6919 oldhtype = fH->GetFillStyle();
6920 htype = oldhtype;
6921 if (Hoption.Bar) {
6922 if (htype == 0 || htype == 1000) htype = 1001;
6923 }
6924
6925 Width_t lw = (Width_t)fH->GetLineWidth();
6926
6927 // Code option for GrapHist
6928
6929 if (Hoption.Line) chopth[0] = 'L';
6930 if (Hoption.Star) chopth[1] = '*';
6931 if (Hoption.Mark) chopth[2] = 'P';
6932 if (Hoption.Mark == 10) chopth[3] = '0';
6934 if (Hoption.Curve) chopth[3] = 'C';
6935 if (Hoption.Hist > 0) chopth[4] = 'H';
6936 else if (Hoption.Bar) chopth[5] = 'B';
6937 if (fH->GetFillColor() && htype) {
6938 if (Hoption.Logy) {
6939 chopth[6] = '1';
6940 }
6941 if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6942 chopth[7] = 'F';
6943 }
6944 }
6945 }
6946 if (!fixbin && strlen(chopth)) {
6947 chopth[8] = 'N';
6948 }
6949
6950 if (Hoption.Fill == 2) chopth[13] = '2';
6951
6952 // Option LOGX
6953
6954 if (Hoption.Logx) {
6955 chopth[9] = 'G';
6956 chopth[10] = 'X';
6957 if (fixbin) {
6958 keepx[0] = TMath::Power(10,keepx[0]);
6959 keepx[1] = TMath::Power(10,keepx[1]);
6960 }
6961 }
6962
6963 if (Hoption.Off) {
6964 chopth[11] = ']';
6965 chopth[12] = '[';
6966 }
6967
6968 // Draw the histogram
6969
6970 TGraph graph;
6971 graph.SetLineWidth(lw);
6972 graph.SetLineStyle(fH->GetLineStyle());
6973 graph.SetLineColor(fH->GetLineColor());
6974 graph.SetFillStyle(htype);
6975 graph.SetFillColor(fH->GetFillColor());
6976 graph.SetMarkerStyle(fH->GetMarkerStyle());
6977 graph.SetMarkerSize(fH->GetMarkerSize());
6978 graph.SetMarkerColor(fH->GetMarkerColor());
6979 if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6980
6981 graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6982
6983 delete [] keepx;
6984 delete [] keepy;
6985 gStyle->SetBarOffset(baroffsetsave);
6986 gStyle->SetBarWidth(barwidthsave);
6987
6988 htype=oldhtype;
6989}
6990
6991////////////////////////////////////////////////////////////////////////////////
6992/// [Control function to draw a 3D histograms.](\ref HP01d)
6993
6995{
6996
6997 char *cmd;
6998 TString opt = option;
6999 opt.ToLower();
7000 Int_t irep;
7001
7002 if (fCurrentF3) {
7003 PaintTF3();
7004 return;
7005 } else if (Hoption.Box || Hoption.Lego) {
7006 if (Hoption.Box == 11 || Hoption.Lego == 11) {
7007 PaintH3Box(1);
7008 } else if (Hoption.Box == 12 || Hoption.Lego == 12) {
7009 PaintH3Box(2);
7010 } else if (Hoption.Box == 13 || Hoption.Lego == 13) {
7011 PaintH3Box(3);
7012 } else {
7014 }
7015 return;
7016 } else if (strstr(opt,"iso")) {
7017 PaintH3Iso();
7018 return;
7019 } else if (strstr(opt,"tf3")) {
7020 PaintTF3();
7021 return;
7022 } else {
7023 cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%zx,\"%s\");",(size_t)fH,option);
7024 }
7025
7026 if (strstr(opt,"fb")) Hoption.FrontBox = 0;
7027 if (strstr(opt,"bb")) Hoption.BackBox = 0;
7028
7029 TView *view = gPad->GetView();
7030 if (!view) return;
7031 Double_t thedeg = 90 - gPad->GetTheta();
7032 Double_t phideg = -90 - gPad->GetPhi();
7033 Double_t psideg = view->GetPsi();
7034 view->SetView(phideg, thedeg, psideg, irep);
7035
7036 // Paint the data
7037 gROOT->ProcessLine(cmd);
7038
7039 if (Hoption.Same) return;
7040
7041 // Draw axis
7042 view->SetOutlineToCube();
7043 TSeqCollection *ol = view->GetOutline();
7044 if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
7046 TGaxis *axis = new TGaxis();
7047 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7048 delete axis;
7049
7050 // Draw palette. In case of 4D plot with TTree::Draw() the palette should
7051 // be painted with the option colz.
7052 if (fH->GetDrawOption() && strstr(opt,"colz")) {
7053 Int_t ndiv = fH->GetContour();
7054 if (ndiv == 0 ) {
7055 ndiv = gStyle->GetNumberContours();
7056 fH->SetContour(ndiv);
7057 }
7058 PaintPalette();
7059 }
7060
7061 // Draw title
7062 PaintTitle();
7063
7064 //Draw stats and fit results
7065 TF1 *fit = 0;
7066 TIter next(fFunctions);
7067 TObject *obj;
7068 while ((obj = next())) {
7069 if (obj->InheritsFrom(TF1::Class())) {
7070 fit = (TF1*)obj;
7071 break;
7072 }
7073 }
7074 if ((Hoption.Same%10) != 1) {
7075 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
7077 }
7078 }
7079
7080}
7081
7082////////////////////////////////////////////////////////////////////////////////
7083/// Compute histogram parameters used by the drawing routines.
7084
7086{
7087
7088 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
7089
7090 Int_t i;
7091 static const char *where = "PaintInit";
7092 Double_t yMARGIN = gStyle->GetHistTopMargin();
7093 Int_t maximum = 0;
7094 Int_t minimum = 0;
7095 if (fH->GetMaximumStored() != -1111) maximum = 1;
7096 if (fH->GetMinimumStored() != -1111) minimum = 1;
7097
7098 // Compute X axis parameters
7099
7100 Int_t last = fXaxis->GetLast();
7104 Hparam.xlast = last;
7108
7109 // if log scale in X, replace xmin,max by the log
7110 if (Hoption.Logx) {
7111 if (Hparam.xmax<=0) {
7112 Error(where, "cannot set X axis to log scale");
7113 return 0;
7114 }
7115 if (Hparam.xlowedge <=0 ) {
7116 if (Hoption.Same) {
7117 Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
7118 } else {
7119 for (i=first; i<=last; i++) {
7120 Double_t binLow = fXaxis->GetBinLowEdge(i);
7121 if (binLow>0) {
7122 Hparam.xlowedge = binLow;
7123 break;
7124 }
7125 if (binLow == 0 && fH->GetBinContent(i) !=0) {
7126 Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
7127 break;
7128 }
7129 }
7130 if (Hparam.xlowedge<=0) {
7131 Error(where, "cannot set X axis to log scale");
7132 return 0;
7133 }
7134 }
7136 }
7141 if (Hparam.xlast > last) Hparam.xlast = last;
7143 }
7144
7145 // Compute Y axis parameters
7146 Double_t bigp = TMath::Power(10,32);
7147 Double_t ymax = -bigp;
7148 Double_t ymin = bigp;
7149 Double_t c1, e1;
7150 Double_t xv[1];
7151 Double_t fval;
7152 TObject *f;
7153 TF1 *f1;
7154 Double_t allchan = 0;
7155 Int_t nonNullErrors = 0;
7156 TIter next(fFunctions);
7157 for (i=first; i<=last;i++) {
7158 c1 = fH->GetBinContent(i);
7160 if (Hoption.Logy) {
7161 if (c1 > 0) ymin = TMath::Min(ymin,c1);
7162 } else {
7164 }
7165 if (Hoption.Error) {
7167 e1 = fH->GetBinError(i);
7168 else
7169 e1 = fH->GetBinErrorUp(i);
7170 if (e1 > 0) nonNullErrors++;
7171 ymax = TMath::Max(ymax,c1+e1);
7173 e1 = fH->GetBinErrorLow(i);
7174
7175 if (Hoption.Logy) {
7176 if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
7177 } else {
7178 ymin = TMath::Min(ymin,c1-e1);
7179 }
7180 }
7181 if (Hoption.Func) {
7182 xv[0] = fXaxis->GetBinCenter(i);
7183 while ((f = (TObject*) next())) {
7184 if (f->IsA() == TF1::Class()) {
7185 f1 = (TF1*)f;
7186 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7187 fval = f1->Eval(xv[0],0,0);
7188 if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
7189 ymax = TMath::Max(ymax,fval);
7190 if (Hoption.Logy) {
7191 if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
7192 }
7193 }
7194 }
7195 next.Reset();
7196 }
7197 allchan += c1;
7198 }
7199 if (!nonNullErrors) {
7200 if (Hoption.Error) {
7201 if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
7202 Hoption.Error=0;
7203 }
7204 }
7205
7206
7207 // Take into account maximum , minimum
7208
7209 if (Hoption.Logy && ymin <= 0) {
7210 if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
7211 else ymin = 0.001*ymax;
7212 }
7213
7214 Double_t xm = ymin;
7215 if (maximum) ymax = fH->GetMaximumStored();
7216 if (minimum) xm = fH->GetMinimumStored();
7217 if (Hoption.Logy && xm < 0) {
7218 Error(where, "log scale requested with a negative argument (%f)", xm);
7219 return 0;
7220 } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
7221 ymin = 0.01;
7222 ymax = 10.;
7223 } else {
7224 ymin = xm;
7225 }
7226
7227 if (ymin >= ymax) {
7228 if (Hoption.Logy) {
7229 if (ymax > 0) ymin = 0.001*ymax;
7230 else {
7231 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
7232 return 0;
7233 }
7234 }
7235 else {
7236 if (ymin > 0) {
7237 ymin = 0;
7238 ymax *= 2;
7239 } else if (ymin < 0) {
7240 ymax = 0;
7241 ymin *= 2;
7242 } else {
7243 ymin = 0;
7244 ymax = 1;
7245 }
7246 }
7247 }
7248
7249 // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
7250 if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
7251 ymin = ymin*(1-1E-14);
7252 ymax = ymax*(1+1E-14);
7253 }
7254
7255 // take into account normalization factor
7256 Hparam.allchan = allchan;
7257 Double_t factor = allchan;
7258 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7259 if (allchan) factor /= allchan;
7260 if (factor == 0) factor = 1;
7261 Hparam.factor = factor;
7262 ymax = factor*ymax;
7263 ymin = factor*ymin;
7264 //just in case the norm factor is negative
7265 // this may happen with a positive norm factor and a negative integral !
7266 if (ymax < ymin) {
7267 Double_t temp = ymax;
7268 ymax = ymin;
7269 ymin = temp;
7270 }
7271
7272 // For log scales, histogram coordinates are LOG10(ymin) and
7273 // LOG10(ymax). Final adjustment (if not option "Same"
7274 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7275 // Maximum and Minimum are not defined.
7276 if (Hoption.Logy) {
7277 if (ymin <=0 || ymax <=0) {
7278 Error(where, "Cannot set Y axis to log scale");
7279 return 0;
7280 }
7282 if (!minimum) ymin += TMath::Log10(0.5);
7284 if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
7285 if (!Hoption.Same) {
7286 Hparam.ymin = ymin;
7287 Hparam.ymax = ymax;
7288 }
7289 return 1;
7290 }
7291
7292 // final adjustment of ymin for linear scale.
7293 // if minimum is not set , then ymin is set to zero if >0
7294 // or to ymin - margin if <0.
7295 if (!minimum) {
7296 if (Hoption.MinimumZero) {
7297 if (ymin >= 0) ymin = 0;
7298 else ymin -= yMARGIN*(ymax-ymin);
7299 } else {
7300 Double_t dymin = yMARGIN*(ymax-ymin);
7301 if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
7302 else ymin -= dymin;
7303 }
7304 }
7305
7306 // final adjustment of YMAXI for linear scale (if not option "Same"):
7307 // decrease histogram height to MAX% of allowed height if HMAXIM
7308 // has not been called.
7309 if (!maximum) {
7310 ymax += yMARGIN*(ymax-ymin);
7311 }
7312
7313 Hparam.ymin = ymin;
7314 Hparam.ymax = ymax;
7315 return 1;
7316}
7317
7318////////////////////////////////////////////////////////////////////////////////
7319/// Compute histogram parameters used by the drawing routines for a rotated pad.
7320
7322{
7323
7324 static const char *where = "PaintInitH";
7325 Double_t yMARGIN = gStyle->GetHistTopMargin();
7326 Int_t maximum = 0;
7327 Int_t minimum = 0;
7328 if (fH->GetMaximumStored() != -1111) maximum = 1;
7329 if (fH->GetMinimumStored() != -1111) minimum = 1;
7330
7331 // Compute X axis parameters
7332
7333 Int_t last = fXaxis->GetLast();
7337 Hparam.xlast = last;
7341
7342 // if log scale in Y, replace ymin,max by the log
7343 if (Hoption.Logy) {
7344 if (Hparam.xlowedge <=0 ) {
7347 }
7348 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
7349 Error(where, "cannot set Y axis to log scale");
7350 return 0;
7351 }
7356 if (Hparam.xlast > last) Hparam.xlast = last;
7357 }
7358
7359 // Compute Y axis parameters
7360 Double_t bigp = TMath::Power(10,32);
7361 Double_t xmax = -bigp;
7362 Double_t xmin = bigp;
7363 Double_t c1, e1;
7364 Double_t xv[1];
7365 Double_t fval;
7366 Int_t i;
7367 TObject *f;
7368 TF1 *f1;
7369 Double_t allchan = 0;
7370 TIter next(fFunctions);
7371 for (i=first; i<=last;i++) {
7372 c1 = fH->GetBinContent(i);
7375 if (Hoption.Error) {
7376 e1 = fH->GetBinError(i);
7377 xmax = TMath::Max(xmax,c1+e1);
7378 xmin = TMath::Min(xmin,c1-e1);
7379 }
7380 if (Hoption.Func) {
7381 xv[0] = fXaxis->GetBinCenter(i);
7382 while ((f = (TObject*) next())) {
7383 if (f->IsA() == TF1::Class()) {
7384 f1 = (TF1*)f;
7385 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7386 fval = f1->Eval(xv[0],0,0);
7387 xmax = TMath::Max(xmax,fval);
7388 if (Hoption.Logy) {
7389 if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
7390 }
7391 }
7392 }
7393 next.Reset();
7394 }
7395 allchan += c1;
7396 }
7397
7398 // Take into account maximum , minimum
7399
7400 if (Hoption.Logx && xmin <= 0) {
7401 if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
7402 else xmin = 0.001*xmax;
7403 }
7404 Double_t xm = xmin;
7405 if (maximum) xmax = fH->GetMaximumStored();
7406 if (minimum) xm = fH->GetMinimumStored();
7407 if (Hoption.Logx && xm <= 0) {
7408 Error(where, "log scale requested with zero or negative argument (%f)", xm);
7409 return 0;
7410 }
7411 else xmin = xm;
7412 if (xmin >= xmax) {
7413 if (Hoption.Logx) {
7414 if (xmax > 0) xmin = 0.001*xmax;
7415 else {
7416 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
7417 return 0;
7418 }
7419 }
7420 else {
7421 if (xmin > 0) {
7422 xmin = 0;
7423 xmax *= 2;
7424 } else if (xmin < 0) {
7425 xmax = 0;
7426 xmin *= 2;
7427 } else {
7428 xmin = -1;
7429 xmax = 1;
7430 }
7431 }
7432 }
7433
7434 // take into account normalization factor
7435 Hparam.allchan = allchan;
7436 Double_t factor = allchan;
7437 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7438 if (allchan) factor /= allchan;
7439 if (factor == 0) factor = 1;
7440 Hparam.factor = factor;
7441 xmax = factor*xmax;
7442 xmin = factor*xmin;
7443
7444 // For log scales, histogram coordinates are LOG10(ymin) and
7445 // LOG10(ymax). Final adjustment (if not option "Same"
7446 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7447 // Maximum and Minimum are not defined.
7448 if (Hoption.Logx) {
7449 if (xmin <=0 || xmax <=0) {
7450 Error(where, "Cannot set Y axis to log scale");
7451 return 0;
7452 }
7454 if (!minimum) xmin += TMath::Log10(0.5);
7456 if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
7457 if (!Hoption.Same) {
7458 Hparam.xmin = xmin;
7459 Hparam.xmax = xmax;
7460 }
7461 return 1;
7462 }
7463
7464 // final adjustment of ymin for linear scale.
7465 // if minimum is not set , then ymin is set to zero if >0
7466 // or to ymin - margin if <0.
7467 if (!minimum) {
7468 if (xmin >= 0) xmin = 0;
7469 else xmin -= yMARGIN*(xmax-xmin);
7470 }
7471
7472 // final adjustment of YMAXI for linear scale (if not option "Same"):
7473 // decrease histogram height to MAX% of allowed height if HMAXIM
7474 // has not been called.
7475 if (!maximum) {
7476 xmax += yMARGIN*(xmax-xmin);
7477 }
7478 Hparam.xmin = xmin;
7479 Hparam.xmax = xmax;
7480 return 1;
7481}
7482
7483////////////////////////////////////////////////////////////////////////////////
7484/// [Control function to draw a 3D histogram with boxes.](\ref HP25)
7485
7487{
7488 // Predefined box structure
7489 Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
7490 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
7491 Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
7492 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
7493
7494 // Define dimensions of world space
7495 TGaxis *axis = new TGaxis();
7496 TAxis *xaxis = fH->GetXaxis();
7497 TAxis *yaxis = fH->GetYaxis();
7498 TAxis *zaxis = fH->GetZaxis();
7499
7500 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7501 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7502 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7503 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7504 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7505 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7506
7508
7509 // Set view
7510 TView *view = gPad->GetView();
7511 if (!view) {
7512 Error("PaintH3", "no TView in current pad");
7513 return;
7514 }
7515 Double_t thedeg = 90 - gPad->GetTheta();
7516 Double_t phideg = -90 - gPad->GetPhi();
7517 Double_t psideg = view->GetPsi();
7518 Int_t irep;
7519 view->SetView(phideg, thedeg, psideg, irep);
7520
7521 Int_t backcolor = gPad->GetFrameFillColor();
7522 view->PadRange(backcolor);
7523
7524 // Draw back surfaces of frame box
7525 fLego->InitMoveScreen(-1.1,1.1);
7526 if (Hoption.BackBox) {
7529 fLego->BackBox(90);
7530 }
7531
7533
7534 // Define order of drawing
7535 Double_t *tnorm = view->GetTnorm();
7536 if (!tnorm) return;
7537 Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7538 Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7539 Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7540 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7541 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7542 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7543 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7544 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7545 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7546
7547 // Set graphic attributes (colour, style, etc.)
7548 Style_t fillsav = fH->GetFillStyle();
7549 Style_t colsav = fH->GetFillColor();
7550 Style_t coldark = TColor::GetColorDark(colsav);
7551 Style_t colbright = TColor::GetColorBright(colsav);
7552
7553 fH->SetFillStyle(1001);
7554 fH->TAttFill::Modify();
7555 fH->TAttLine::Modify();
7556 Int_t ncolors = gStyle->GetNumberOfColors();
7557 Int_t theColor;
7558
7559 // Create bin boxes and draw
7560 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7563
7564 Double_t pmin[3], pmax[3], sxyz[8][3];
7565 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7566 pmin[0] = xaxis->GetBinLowEdge(ix);
7567 pmax[0] = xaxis->GetBinUpEdge(ix);
7568 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7569 pmin[1] = yaxis->GetBinLowEdge(iy);
7570 pmax[1] = yaxis->GetBinUpEdge(iy);
7571 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7572 pmin[2] = zaxis->GetBinLowEdge(iz);
7573 pmax[2] = zaxis->GetBinUpEdge(iz);
7574 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7575 Bool_t neg = kFALSE;
7576 Int_t n = 5;
7577 if (w<0) {
7578 w = -w;
7579 neg = kTRUE;
7580 }
7581 if (w < wmin) continue;
7582 if (w > wmax) w = wmax;
7583 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7584 if (scale == 0) continue;
7585 for (Int_t i=0; i<3; ++i) {
7586 Double_t c = (pmax[i] + pmin[i])*0.5;
7587 Double_t d = (pmax[i] - pmin[i])*scale;
7588 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7589 sxyz[k][i] = wxyz[k][i]*d + c;
7590 }
7591 }
7592 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7593 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7594 }
7595 Double_t x[8], y[8]; // draw bin box faces
7596 for (Int_t k=0; k<6; ++k) {
7597 for (Int_t i=0; i<4; ++i) {
7598 Int_t iv = iface[k][i];
7599 x[i] = sxyz[iv][0];
7600 y[i] = sxyz[iv][1];
7601 }
7602 x[4] = x[0] ; y[4] = y[0];
7603 if (neg) {
7604 x[5] = x[2] ; y[5] = y[2];
7605 x[6] = x[3] ; y[6] = y[3];
7606 x[7] = x[1] ; y[7] = y[1];
7607 n = 8;
7608 } else {
7609 n = 5;
7610 }
7611 Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7612 if (z <= 0.) continue;
7613 if (iopt == 2) {
7614 theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7616 } else {
7617 if (k == 3 || k == 5) {
7618 fH->SetFillColor(coldark);
7619 } else if (k == 0 || k == 1) {
7620 fH->SetFillColor(colbright);
7621 } else {
7622 fH->SetFillColor(colsav);
7623 }
7624 }
7625 fH->TAttFill::Modify();
7626 gPad->PaintFillArea(4, x, y);
7627 if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7628 }
7629 }
7630 }
7631 }
7632
7633 // Draw front surfaces of frame box
7634 if (Hoption.FrontBox) fLego->FrontBox(90);
7635
7636 // Draw axis and title
7637 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7638 PaintTitle();
7639
7640 // Draw palette. if needed.
7641 if (Hoption.Zscale) {
7642 Int_t ndiv = fH->GetContour();
7643 if (ndiv == 0 ) {
7644 ndiv = gStyle->GetNumberContours();
7645 fH->SetContour(ndiv);
7646 }
7647 PaintPalette();
7648 }
7649
7650 delete axis;
7651 delete fLego; fLego = 0;
7652
7653 fH->SetFillStyle(fillsav);
7654 fH->SetFillColor(colsav);
7655 fH->TAttFill::Modify();
7656}
7657
7658////////////////////////////////////////////////////////////////////////////////
7659/// [Control function to draw a 3D histogram with boxes.](\ref HP25)
7660
7662{
7663 // Predefined box structure
7664 Double_t wxyz[8][3] = {
7665 {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7666 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7667 };
7668 Int_t iface[6][4] = {
7669 {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7670 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7671 };
7672 Double_t normal[6][3] = {
7673 {0,0,-1}, {0,0,1}, // Z-, Z+
7674 {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7675 };
7676
7677 // Define dimensions of world space
7678 TGaxis *axis = new TGaxis();
7679 TAxis *xaxis = fH->GetXaxis();
7680 TAxis *yaxis = fH->GetYaxis();
7681 TAxis *zaxis = fH->GetZaxis();
7682
7683 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7684 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7685 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7686 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7687 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7688 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7689
7691
7692 // Set view
7693 TView *view = gPad->GetView();
7694 if (!view) {
7695 Error("PaintH3", "no TView in current pad");
7696 return;
7697 }
7698 Double_t thedeg = 90 - gPad->GetTheta();
7699 Double_t phideg = -90 - gPad->GetPhi();
7700 Double_t psideg = view->GetPsi();
7701 Int_t irep;
7702 view->SetView(phideg, thedeg, psideg, irep);
7703
7704 Int_t backcolor = gPad->GetFrameFillColor();
7705 view->PadRange(backcolor);
7706
7707 // Draw front surfaces of frame box
7708 if (Hoption.FrontBox) {
7709 fLego->InitMoveScreen(-1.1,1.1);
7711 }
7712
7713 // Initialize hidden line removal algorithm "raster screen"
7714 fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7715
7716 // Define order of drawing
7717 Double_t *tnorm = view->GetTnorm();
7718 if (!tnorm) return;
7719 Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7720 Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7721 Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7722 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7723 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7724 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7725 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7726 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7727 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7728
7729 // Set line attributes (colour, style, etc.)
7730 fH->TAttLine::Modify();
7731
7732 // Create bin boxes and draw
7733 const Int_t NTMAX = 100;
7734 Double_t tt[NTMAX][2];
7735 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7738 Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7739 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7740 pmin[0] = xaxis->GetBinLowEdge(ix);
7741 pmax[0] = xaxis->GetBinUpEdge(ix);
7742 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7743 pmin[1] = yaxis->GetBinLowEdge(iy);
7744 pmax[1] = yaxis->GetBinUpEdge(iy);
7745 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7746 pmin[2] = zaxis->GetBinLowEdge(iz);
7747 pmax[2] = zaxis->GetBinUpEdge(iz);
7748 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7749 Bool_t neg = kFALSE;
7750 if (w<0) {
7751 w = -w;
7752 neg = kTRUE;
7753 }
7754 if (w < wmin) continue;
7755 if (w > wmax) w = wmax;
7756 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7757 if (scale == 0) continue;
7758 for (Int_t i=0; i<3; ++i) {
7759 Double_t c = (pmax[i] + pmin[i])*0.5;
7760 Double_t d = (pmax[i] - pmin[i])*scale;
7761 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7762 sxyz[k][i] = wxyz[k][i]*d + c;
7763 }
7764 }
7765 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7766 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7767 }
7768 for (Int_t k=0; k<6; ++k) { // draw box faces
7769 Double_t zn;
7770 view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7771 if (zn <= 0) continue;
7772 for (Int_t i=0; i<4; ++i) {
7773 Int_t ip = iface[k][i];
7774 pp[i][0] = sxyz[ip][0];
7775 pp[i][1] = sxyz[ip][1];
7776 }
7777 for (Int_t i=0; i<4; ++i) {
7778 Int_t i1 = i;
7779 Int_t i2 = (i == 3) ? 0 : i + 1;
7780 Int_t nt;
7781 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7782 Double_t xdel = pp[i2][0] - pp[i1][0];
7783 Double_t ydel = pp[i2][1] - pp[i1][1];
7784 Double_t x[2], y[2];
7785 for (Int_t it = 0; it < nt; ++it) {
7786 x[0] = pp[i1][0] + xdel*tt[it][0];
7787 y[0] = pp[i1][1] + ydel*tt[it][0];
7788 x[1] = pp[i1][0] + xdel*tt[it][1];
7789 y[1] = pp[i1][1] + ydel*tt[it][1];
7790 gPad->PaintPolyLine(2, x, y);
7791 }
7792 }
7793 if (neg) {
7794 Int_t i1 = 0;
7795 Int_t i2 = 2;
7796 Int_t nt;
7797 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7798 Double_t xdel = pp[i2][0] - pp[i1][0];
7799 Double_t ydel = pp[i2][1] - pp[i1][1];
7800 Double_t x[2], y[2];
7801 for (Int_t it = 0; it < nt; ++it) {
7802 x[0] = pp[i1][0] + xdel*tt[it][0];
7803 y[0] = pp[i1][1] + ydel*tt[it][0];
7804 x[1] = pp[i1][0] + xdel*tt[it][1];
7805 y[1] = pp[i1][1] + ydel*tt[it][1];
7806 gPad->PaintPolyLine(2, x, y);
7807 }
7808 i1 = 1;
7809 i2 = 3;
7810 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7811 xdel = pp[i2][0] - pp[i1][0];
7812 ydel = pp[i2][1] - pp[i1][1];
7813 for (Int_t it = 0; it < nt; ++it) {
7814 x[0] = pp[i1][0] + xdel*tt[it][0];
7815 y[0] = pp[i1][1] + ydel*tt[it][0];
7816 x[1] = pp[i1][0] + xdel*tt[it][1];
7817 y[1] = pp[i1][1] + ydel*tt[it][1];
7818 gPad->PaintPolyLine(2, x, y);
7819 }
7820 }
7821 fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7822 }
7823 }
7824 }
7825 }
7826
7827 // Draw frame box
7828 if (Hoption.BackBox) {
7831 fLego->BackBox(90);
7832 }
7833
7834 if (Hoption.FrontBox) fLego->FrontBox(90);
7835
7836 // Draw axis and title
7837 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7838 PaintTitle();
7839
7840 delete axis;
7841 delete fLego; fLego = 0;
7842}
7843
7844////////////////////////////////////////////////////////////////////////////////
7845/// [Control function to draw a 3D histogram with Iso Surfaces.](\ref HP25)
7846
7848{
7849
7850 const Double_t ydiff = 1;
7851 const Double_t yligh1 = 10;
7852 const Double_t qa = 0.15;
7853 const Double_t qd = 0.15;
7854 const Double_t qs = 0.8;
7855 Double_t fmin, fmax;
7856 Int_t i, irep;
7857 Int_t nbcol = 28;
7858 Int_t icol1 = 201;
7859 Int_t ic1 = icol1;
7860 Int_t ic2 = ic1+nbcol;
7861 Int_t ic3 = ic2+nbcol;
7862
7863 TGaxis *axis = new TGaxis();
7864 TAxis *xaxis = fH->GetXaxis();
7865 TAxis *yaxis = fH->GetYaxis();
7866 TAxis *zaxis = fH->GetZaxis();
7867
7868 Int_t nx = fH->GetNbinsX();
7869 Int_t ny = fH->GetNbinsY();
7870 Int_t nz = fH->GetNbinsZ();
7871
7872 Double_t *x = new Double_t[nx];
7873 Double_t *y = new Double_t[ny];
7874 Double_t *z = new Double_t[nz];
7875
7876 for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7877 for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7878 for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7879
7880 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7881 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7882 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7883 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7884 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7885 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7886
7887 Double_t s[3];
7888 s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7889 s[1] = 0.5*s[0];
7890 s[2] = 1.5*s[0];
7891
7893
7894 TView *view = gPad->GetView();
7895 if (!view) {
7896 Error("PaintH3Iso", "no TView in current pad");
7897 delete [] x;
7898 delete [] y;
7899 delete [] z;
7900 return;
7901 }
7902 Double_t thedeg = 90 - gPad->GetTheta();
7903 Double_t phideg = -90 - gPad->GetPhi();
7904 Double_t psideg = view->GetPsi();
7905 view->SetView(phideg, thedeg, psideg, irep);
7906
7907 Int_t backcolor = gPad->GetFrameFillColor();
7908 if (Hoption.System != kCARTESIAN) backcolor = 0;
7909 view->PadRange(backcolor);
7910
7911 Double_t dcol = 0.5/Double_t(nbcol);
7912 TColor *colref = gROOT->GetColor(fH->GetFillColor());
7913 if (!colref) {
7914 delete [] x;
7915 delete [] y;
7916 delete [] z;
7917 return;
7918 }
7919 Float_t r, g, b, hue, light, satur;
7920 colref->GetRGB(r,g,b);
7921 TColor::RGBtoHLS(r,g,b,hue,light,satur);
7922 TColor *acol;
7923 for (Int_t col=0;col<nbcol;col++) {
7924 acol = gROOT->GetColor(col+icol1);
7925 TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7926 if (acol) acol->SetRGB(r, g, b);
7927 }
7928
7929 fLego->InitMoveScreen(-1.1,1.1);
7930
7931 if (Hoption.BackBox) {
7934 fLego->BackBox(90);
7935 }
7936
7937 fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7938 fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7939 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7940 fmin = ydiff*qa;
7941 fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7942 fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7943
7944 fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7945
7946 if (Hoption.FrontBox) {
7947 fLego->InitMoveScreen(-1.1,1.1);
7949 fLego->FrontBox(90);
7950 }
7951 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7952
7953 PaintTitle();
7954
7955 delete axis;
7956 delete fLego; fLego = 0;
7957 delete [] x;
7958 delete [] y;
7959 delete [] z;
7960}
7961
7962////////////////////////////////////////////////////////////////////////////////
7963/// [Control function to draw a 2D histogram as a lego plot.](\ref HP17)
7964
7966{
7967
7968 Int_t raster = 1;
7969 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7970 Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7971 Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7972 Double_t zmin = Hparam.zmin;
7973 Double_t zmax = Hparam.zmax;
7974 Double_t xlab1 = Hparam.xmin;
7975 Double_t xlab2 = Hparam.xmax;
7976 Double_t ylab1 = Hparam.ymin;
7977 Double_t ylab2 = Hparam.ymax;
7978 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7979 Double_t deltaz = TMath::Abs(zmin);
7980 if (deltaz == 0) deltaz = 1;
7981 if (zmin >= zmax) {
7982 zmin -= 0.5*deltaz;
7983 zmax += 0.5*deltaz;
7984 }
7985 Double_t z1c = zmin;
7986 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7987
7988 // Compute the lego limits and instantiate a lego object
7989 fXbuf[0] = -1;
7990 fYbuf[0] = 1;
7991 fXbuf[1] = -1;
7992 fYbuf[1] = 1;
7993 if (Hoption.System == kPOLAR) {
7994 fXbuf[2] = z1c;
7995 fYbuf[2] = z2c;
7996 } else if (Hoption.System == kCYLINDRICAL) {
7997 if (Hoption.Logy) {
7998 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7999 else fXbuf[2] = 0;
8000 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
8001 else fYbuf[2] = 0;
8002 } else {
8003 fXbuf[2] = ylab1;
8004 fYbuf[2] = ylab2;
8005 }
8006 z1c = 0; z2c = 1;
8007 } else if (Hoption.System == kSPHERICAL) {
8008 fXbuf[2] = -1;
8009 fYbuf[2] = 1;
8010 z1c = 0; z2c = 1;
8011 } else if (Hoption.System == kRAPIDITY) {
8012 fXbuf[2] = -1/TMath::Tan(dangle);
8013 fYbuf[2] = 1/TMath::Tan(dangle);
8014 } else {
8015 fXbuf[0] = xlab1;
8016 fYbuf[0] = xlab2;
8017 fXbuf[1] = ylab1;
8018 fYbuf[1] = ylab2;
8019 fXbuf[2] = z1c;
8020 fYbuf[2] = z2c;
8021 raster = 0;
8022 }
8023
8025
8026 Int_t nids = -1;
8027 TH1 * hid = NULL;
8028 Color_t colormain = -1, colordark = -1;
8029 Bool_t drawShadowsInLego1 = kTRUE;
8030
8031 // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
8032 if (Hoption.Lego == 13) {
8033 Hoption.Lego = 11;
8034 fLego->SetMesh(0);
8035 }
8036 // LEGO4 is like LEGO1 except no shadows are drawn.
8037 if (Hoption.Lego == 14) {
8038 Hoption.Lego = 11;
8039 drawShadowsInLego1 = kFALSE;
8040 }
8041
8042 // Create axis object
8043
8044 TGaxis *axis = new TGaxis();
8045
8046 // Initialize the levels on the Z axis
8047 Int_t ndiv = fH->GetContour();
8048 if (ndiv == 0 ) {
8049 ndiv = gStyle->GetNumberContours();
8050 fH->SetContour(ndiv);
8051 }
8052 Int_t ndivz = TMath::Abs(ndiv);
8053 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
8054
8055 // Initialize colors
8056 if (!fStack) {
8058 } else {
8059 for (Int_t id=0;id<=fStack->GetSize();id++) {
8060 hid = (TH1*)fStack->At((id==0)?id:id-1);
8062 }
8063 }
8064
8065 if (Hoption.Lego == 11) {
8066 nids = 1;
8067 if (fStack) nids = fStack->GetSize();
8068 hid = fH;
8069 for (Int_t id=0;id<=nids;id++) {
8070 if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
8071 colormain = hid->GetFillColor();
8072 if (colormain == 1) colormain = 17; //avoid drawing with black
8073 if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
8074 else colordark = colormain;
8075 fLego->SetColorMain(colormain,id);
8076 fLego->SetColorDark(colordark,id);
8077 if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
8078 if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
8079 }
8080 }
8081
8082 // Now ready to draw the lego plot
8083 Int_t irep = 0;
8084
8085 TView *view = gPad->GetView();
8086 if (!view) {
8087 Error("PaintLego", "no TView in current pad");
8088 return;
8089 }
8090
8091 Double_t thedeg = 90 - gPad->GetTheta();
8092 Double_t phideg = -90 - gPad->GetPhi();
8093 Double_t psideg = view->GetPsi();
8094 view->SetView(phideg, thedeg, psideg, irep);
8095
8096 fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
8098
8099 // Set color/style for back box
8100 fLego->SetFillStyle(gPad->GetFrameFillStyle());
8101 fLego->SetFillColor(gPad->GetFrameFillColor());
8102 fLego->TAttFill::Modify();
8103
8104 Int_t backcolor = gPad->GetFrameFillColor();
8105 if (Hoption.System != kCARTESIAN) backcolor = 0;
8106 view->PadRange(backcolor);
8107
8110 fLego->TAttFill::Modify();
8111
8113
8114 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
8115 else fLego->InitMoveScreen(-1.1,1.1);
8116
8117 if (Hoption.Lego == 19) {
8119 if (Hoption.BackBox) fLego->BackBox(90);
8120 if (Hoption.FrontBox) fLego->FrontBox(90);
8121 if (!Hoption.Axis) PaintLegoAxis(axis, 90);
8122 return;
8123 }
8124
8125 if (Hoption.Lego == 11 || Hoption.Lego == 12) {
8128 fLego->BackBox(90);
8129 }
8130 }
8131
8132 if (Hoption.Lego == 12) DefineColorLevels(ndivz);
8133
8138 if (Hoption.System == kPOLAR) {
8139 if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
8140 if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
8141 if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
8142 } else if (Hoption.System == kCYLINDRICAL) {
8143 if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
8144 if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
8145 if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
8146 } else if (Hoption.System == kSPHERICAL) {
8147 if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
8148 if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
8149 if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
8150 } else if (Hoption.System == kRAPIDITY) {
8151 if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
8152 if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
8153 if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
8154 } else {
8155 if (Hoption.Lego == 1) {
8157 fLego->LegoCartesian(90,nx,ny,"FB");}
8158 if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
8159 if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
8160 }
8161
8162 if (Hoption.Lego == 1 || Hoption.Lego == 11) {
8165 fLego->BackBox(90);
8166 }
8167 }
8168 if (Hoption.System == kCARTESIAN) {
8169 fLego->InitMoveScreen(-1.1,1.1);
8171 if (Hoption.FrontBox) fLego->FrontBox(90);
8172 }
8173 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
8175 delete axis;
8176 delete fLego; fLego = 0;
8177}
8178
8179////////////////////////////////////////////////////////////////////////////////
8180/// Draw the axis for legos and surface plots.
8181
8183{
8184
8185 static Double_t epsil = 0.001;
8186
8187 Double_t cosa, sina;
8188 Double_t bmin, bmax;
8189 Double_t r[24] /* was [3][8] */;
8190 Int_t ndivx, ndivy, ndivz, i;
8191 Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
8192 static char chopax[8], chopay[8], chopaz[8];
8193 Int_t ix1, ix2, iy1, iy2, iz1, iz2;
8194 Double_t rad;
8195
8196 TView *view = gPad->GetView();
8197 if (!view) {
8198 Error("PaintLegoAxis", "no TView in current pad");
8199 return;
8200 }
8201
8202 // In polar coordinates, draw a short line going from the external circle
8203 // corresponding to r = 1 up to r = 1.1
8204 if (Hoption.System == kPOLAR) {
8205 r[0] = 1;
8206 r[1] = 0;
8207 r[2] = 0;
8208 view->WCtoNDC(r, x1);
8209 r[0] = 1.1;
8210 r[1] = 0;
8211 r[2] = 0;
8212 view->WCtoNDC(r, x2);
8213 gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
8214 return;
8215 }
8216
8217 if (Hoption.System != kCARTESIAN) return;
8218
8219 rad = TMath::ATan(1.) * 4. /180.;
8220 cosa = TMath::Cos(ang*rad);
8221 sina = TMath::Sin(ang*rad);
8222
8223 view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
8224 for (i = 1; i <= 8; ++i) {
8225 r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
8226 r[i*3 - 2] = av[i*3 - 2]*sina;
8227 r[i*3 - 1] = av[i*3 - 1];
8228 }
8229
8230 view->WCtoNDC(&r[ix1*3 - 3], x1);
8231 view->WCtoNDC(&r[ix2*3 - 3], x2);
8232 view->WCtoNDC(&r[iy1*3 - 3], y1);
8233 view->WCtoNDC(&r[iy2*3 - 3], y2);
8234 view->WCtoNDC(&r[iz1*3 - 3], z1);
8235 view->WCtoNDC(&r[iz2*3 - 3], z2);
8236
8237 view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
8238
8239 Double_t *rmin = view->GetRmin();
8240 Double_t *rmax = view->GetRmax();
8241 if (!rmin || !rmax) return;
8242
8243 // Initialize the axis options
8244 if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
8245 else strlcpy(chopax, "SDH=-",8);
8246 if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
8247 else strlcpy(chopay, "SDH=-",8);
8248 if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
8249 else strlcpy(chopaz, "SDH=-",8);
8250
8251 // Option LOG is required ?
8252 if (Hoption.Logx) strlcat(chopax,"G",8);
8253 if (Hoption.Logy) strlcat(chopay,"G",8);
8254 if (Hoption.Logz) strlcat(chopaz,"G",8);
8255
8256 // Initialize the number of divisions. If the
8257 // number of divisions is negative, option 'N' is required.
8258 ndivx = fXaxis->GetNdivisions();
8259 ndivy = fYaxis->GetNdivisions();
8260 ndivz = fZaxis->GetNdivisions();
8261 if (ndivx < 0) {
8262 ndivx = TMath::Abs(ndivx);
8263 strlcat(chopax, "N",8);
8264 }
8265 if (ndivy < 0) {
8266 ndivy = TMath::Abs(ndivy);
8267 strlcat(chopay, "N",8);
8268 }
8269 if (ndivz < 0) {
8270 ndivz = TMath::Abs(ndivz);
8271 strlcat(chopaz, "N",8);
8272 }
8273
8274 // Set Axis attributes.
8275 // The variable SCALE rescales the VSIZ
8276 // in order to have the same label size for all angles.
8277
8278 axis->SetLineWidth(1);
8279
8280 // X axis drawing
8281 if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
8284 if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
8285 bmin = TMath::Power(10, rmin[0]);
8286 bmax = TMath::Power(10, rmax[0]);
8287 } else {
8288 bmin = rmin[0];
8289 bmax = rmax[0];
8290 }
8291 // Option time display is required ?
8292 if (fXaxis->GetTimeDisplay()) {
8293 strlcat(chopax,"t",8);
8294 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
8295 axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
8296 } else {
8298 }
8299 }
8300 axis->SetOption(chopax);
8301 axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
8302 }
8303
8304 // Y axis drawing
8305 if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
8308 if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
8309
8310 if (fH->GetDimension() < 2) {
8311 strlcpy(chopay, "V=+UN",8);
8312 ndivy = 0;
8313 }
8314 if (TMath::Abs(y1[0] - y2[0]) < epsil) {
8315 y2[0] = y1[0];
8316 }
8317 if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
8318 bmin = TMath::Power(10, rmin[1]);
8319 bmax = TMath::Power(10, rmax[1]);
8320 } else {
8321 bmin = rmin[1];
8322 bmax = rmax[1];
8323 }
8324 // Option time display is required ?
8325 if (fYaxis->GetTimeDisplay()) {
8326 strlcat(chopay,"t",8);
8327 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
8328 axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
8329 } else {
8331 }
8332 }
8333 axis->SetOption(chopay);
8334 axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
8335 }
8336
8337 // Z axis drawing
8338 if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
8340 if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
8341 bmin = TMath::Power(10, rmin[2]);
8342 bmax = TMath::Power(10, rmax[2]);
8343 } else {
8344 bmin = rmin[2];
8345 bmax = rmax[2];
8346 }
8347 // Option time display is required ?
8348 if (fZaxis->GetTimeDisplay()) {
8349 strlcat(chopaz,"t",8);
8350 if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
8351 axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
8352 } else {
8354 }
8355 }
8356 axis->SetOption(chopaz);
8357 axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
8358 }
8359
8360 //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
8361}
8362
8363////////////////////////////////////////////////////////////////////////////////
8364/// [Paint the color palette on the right side of the pad.](\ref HP22)
8365
8367{
8368
8369 TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
8370 TView *view = gPad->GetView();
8371 if (palette) {
8372 if (view) {
8373 if (!palette->TestBit(TPaletteAxis::kHasView)) {
8374 fFunctions->Remove(palette);
8375 delete palette; palette = 0;
8376 }
8377 } else {
8378 if (palette->TestBit(TPaletteAxis::kHasView)) {
8379 fFunctions->Remove(palette);
8380 delete palette; palette = 0;
8381 }
8382 }
8383 // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
8384 if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
8385 }
8386
8387 if (!palette) {
8388 Double_t xup = gPad->GetUxmax();
8389 Double_t x2 = gPad->PadtoX(gPad->GetX2());
8390 Double_t ymin = gPad->PadtoY(gPad->GetUymin());
8391 Double_t ymax = gPad->PadtoY(gPad->GetUymax());
8392 Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
8393 Double_t xmin = gPad->PadtoX(xup +0.1*xr);
8394 Double_t xmax = gPad->PadtoX(xup + xr);
8395 if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
8396 palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
8397 fFunctions->AddFirst(palette);
8398 palette->Paint();
8399 }
8400}
8401
8402////////////////////////////////////////////////////////////////////////////////
8403/// [Control function to draw a 2D histogram as a scatter plot.](\ref HP11)
8404
8406{
8407
8408 fH->TAttMarker::Modify();
8409
8410 Int_t k, marker;
8411 Double_t dz, z, xk,xstep, yk, ystep;
8412 Double_t scale = 1;
8413 Bool_t ltest = kFALSE;
8414 Double_t zmax = fH->GetMaximum();
8415 Double_t zmin = fH->GetMinimum();
8416 if (zmin == 0 && zmax == 0) return;
8417 if (zmin == zmax) {
8418 zmax += 0.1*TMath::Abs(zmax);
8419 zmin -= 0.1*TMath::Abs(zmin);
8420 }
8422 if (Hoption.Logz) {
8423 if (zmin > 0) zmin = TMath::Log10(zmin);
8424 else zmin = 0;
8425 if (zmax > 0) zmax = TMath::Log10(zmax);
8426 else zmax = 0;
8427 if (zmin == 0 && zmax == 0) return;
8428 dz = zmax - zmin;
8429 scale = 100/dz;
8430 if (ncells > 10000) scale /= 5;
8431 ltest = kTRUE;
8432 } else {
8433 dz = zmax - zmin;
8434 if (dz >= kNMAX || zmax < 1) {
8435 scale = (kNMAX-1)/dz;
8436 if (ncells > 10000) scale /= 5;
8437 ltest = kTRUE;
8438 }
8439 }
8440 if (fH->GetMinimumStored() == -1111) {
8441 Double_t yMARGIN = gStyle->GetHistTopMargin();
8442 if (Hoption.MinimumZero) {
8443 if (zmin >= 0) zmin = 0;
8444 else zmin -= yMARGIN*(zmax-zmin);
8445 } else {
8446 Double_t dzmin = yMARGIN*(zmax-zmin);
8447 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
8448 else zmin -= dzmin;
8449 }
8450 }
8451
8452 TString opt = option;
8453 opt.ToLower();
8454 if (opt.Contains("scat=")) {
8455 char optscat[100];
8456 strlcpy(optscat,opt.Data(),100);
8457 char *oscat = strstr(optscat,"scat=");
8458 char *blank = strstr(oscat," "); if (blank) *blank = 0;
8459 sscanf(oscat+5,"%lg",&scale);
8460 }
8461 // use an independent instance of a random generator
8462 // instead of gRandom to avoid conflicts and
8463 // to get same random numbers when drawing the same histogram
8464 TRandom2 random;
8465 marker=0;
8466 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8467 yk = fYaxis->GetBinLowEdge(j);
8468 ystep = fYaxis->GetBinWidth(j);
8469 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8470 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8471 xk = fXaxis->GetBinLowEdge(i);
8472 xstep = fXaxis->GetBinWidth(i);
8473 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
8474 z = fH->GetBinContent(bin);
8475 if (z < zmin) z = zmin;
8476 if (z > zmax) z = zmax;
8477 if (Hoption.Logz) {
8478 if (z > 0) z = TMath::Log10(z) - zmin;
8479 } else {
8480 z -= zmin;
8481 }
8482 if (z <= 0) continue;
8483 k = Int_t(z*scale);
8484 if (ltest) k++;
8485 if (k > 0) {
8486 for (Int_t loop=0; loop<k; loop++) {
8487 if (k+marker >= kNMAX) {
8488 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8489 marker=0;
8490 }
8491 fXbuf[marker] = (random.Rndm()*xstep) + xk;
8492 fYbuf[marker] = (random.Rndm()*ystep) + yk;
8493 if (Hoption.Logx) {
8494 if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
8495 else break;
8496 }
8497 if (Hoption.Logy) {
8498 if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
8499 else break;
8500 }
8501 if (fXbuf[marker] < gPad->GetUxmin()) break;
8502 if (fYbuf[marker] < gPad->GetUymin()) break;
8503 if (fXbuf[marker] > gPad->GetUxmax()) break;
8504 if (fYbuf[marker] > gPad->GetUymax()) break;
8505 marker++;
8506 }
8507 }
8508 }
8509 }
8510 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8511
8513}
8514
8515////////////////////////////////////////////////////////////////////////////////
8516/// Static function to paint special objects like vectors and matrices.
8517/// This function is called via `gROOT->ProcessLine` to paint these objects
8518/// without having a direct dependency of the graphics or histogramming
8519/// system.
8520
8522{
8523
8524 if (!obj) return;
8527
8528 if (obj->InheritsFrom(TMatrixFBase::Class())) {
8529 // case TMatrixF
8530 TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
8531 R__TMatrixFBase->SetBit(kCanDelete);
8532 R__TMatrixFBase->Draw(option);
8533
8534 } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
8535 // case TMatrixD
8536 TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8537 R__TMatrixDBase->SetBit(kCanDelete);
8538 R__TMatrixDBase->Draw(option);
8539
8540 } else if (obj->InheritsFrom(TVectorF::Class())) {
8541 //case TVectorF
8542 TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8543 R__TVectorF->SetBit(kCanDelete);
8544 R__TVectorF->Draw(option);
8545
8546 } else if (obj->InheritsFrom(TVectorD::Class())) {
8547 //case TVectorD
8548 TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8549 R__TVectorD->SetBit(kCanDelete);
8550 R__TVectorD->Draw(option);
8551 }
8552
8553 TH1::AddDirectory(status);
8554}
8555
8556////////////////////////////////////////////////////////////////////////////////
8557/// [Draw the statistics box for 1D and profile histograms.](\ref HP07)
8558
8560{
8561
8562 TString tt, tf;
8563 Int_t dofit;
8564 TPaveStats *stats = 0;
8565 TIter next(fFunctions);
8566 TObject *obj;
8567 while ((obj = next())) {
8568 if (obj->InheritsFrom(TPaveStats::Class())) {
8569 stats = (TPaveStats*)obj;
8570 break;
8571 }
8572 }
8573
8574 if (stats && dostat) {
8575 dofit = stats->GetOptFit();
8576 dostat = stats->GetOptStat();
8577 } else {
8578 dofit = gStyle->GetOptFit();
8579 }
8580 if (!dofit) fit = 0;
8581 if (dofit == 1) dofit = 111;
8582 if (dostat == 1) dostat = 1111;
8583 Int_t print_name = dostat%10;
8584 Int_t print_entries = (dostat/10)%10;
8585 Int_t print_mean = (dostat/100)%10;
8586 Int_t print_stddev = (dostat/1000)%10;
8587 Int_t print_under = (dostat/10000)%10;
8588 Int_t print_over = (dostat/100000)%10;
8589 Int_t print_integral= (dostat/1000000)%10;
8590 Int_t print_skew = (dostat/10000000)%10;
8591 Int_t print_kurt = (dostat/100000000)%10;
8592 Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8593 print_under + print_over + print_integral +
8594 print_skew + print_kurt;
8595 Int_t print_fval = dofit%10;
8596 Int_t print_ferrors = (dofit/10)%10;
8597 Int_t print_fchi2 = (dofit/100)%10;
8598 Int_t print_fprob = (dofit/1000)%10;
8599 Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8600 if (fit) {
8601 if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8602 else nlinesf += fit->GetNpar();
8603 }
8604 if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8605
8606 // Pavetext with statistics
8607 Bool_t done = kFALSE;
8608 if (!dostat && !fit) {
8609 if (stats) { fFunctions->Remove(stats); delete stats;}
8610 return;
8611 }
8612 Double_t statw = gStyle->GetStatW();
8613 if (fit) statw = 1.8*gStyle->GetStatW();
8614 Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8615 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8616 stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8617 }
8618 if (stats) {
8619 stats->Clear();
8620 done = kTRUE;
8621 } else {
8622 stats = new TPaveStats(
8623 gStyle->GetStatX()-statw,
8624 gStyle->GetStatY()-stath,
8625 gStyle->GetStatX(),
8626 gStyle->GetStatY(),"brNDC");
8627
8628 stats->SetParent(fH);
8629 stats->SetOptFit(dofit);
8630 stats->SetOptStat(dostat);
8631 stats->SetFillColor(gStyle->GetStatColor());
8632 stats->SetFillStyle(gStyle->GetStatStyle());
8634 stats->SetTextFont(gStyle->GetStatFont());
8635 if (gStyle->GetStatFont()%10 > 2)
8637 stats->SetFitFormat(gStyle->GetFitFormat());
8639 stats->SetName("stats");
8640
8642 stats->SetTextAlign(12);
8643 stats->SetBit(kCanDelete);
8644 stats->SetBit(kMustCleanup);
8645 }
8646 if (print_name) stats->AddText(fH->GetName());
8647 if (print_entries) {
8648 if (fH->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8649 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8650 stats->AddText(tt.Data());
8651 }
8652 if (print_mean) {
8653 if (print_mean == 1) {
8654 tf.Form("%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8655 tt.Form(tf.Data(),fH->GetMean(1));
8656 } else {
8657 tf.Form("%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8658 ,"%",stats->GetStatFormat());
8659 tt.Form(tf.Data(),fH->GetMean(1),fH->GetMeanError(1));
8660 }
8661 stats->AddText(tt.Data());
8662 if (fH->InheritsFrom(TProfile::Class())) {
8663 if (print_mean == 1) {
8664 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8665 tt.Form(tf.Data(),fH->GetMean(2));
8666 } else {
8667 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8668 ,"%",stats->GetStatFormat());
8669 tt.Form(tf.Data(),fH->GetMean(2),fH->GetMeanError(2));
8670 }
8671 stats->AddText(tt.Data());
8672 }
8673 }
8674 if (print_stddev) {
8675 if (print_stddev == 1) {
8676 tf.Form("%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8677 tt.Form(tf.Data(),fH->GetStdDev(1));
8678 } else {
8679 tf.Form("%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8680 ,"%",stats->GetStatFormat());
8681 tt.Form(tf.Data(),fH->GetStdDev(1),fH->GetStdDevError(1));
8682 }
8683 stats->AddText(tt.Data());
8684 if (fH->InheritsFrom(TProfile::Class())) {
8685 if (print_stddev == 1) {
8686 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8687 tt.Form(tf.Data(),fH->GetStdDev(2));
8688 } else {
8689 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8690 ,"%",stats->GetStatFormat());
8691 tt.Form(tf.Data(),fH->GetStdDev(2),fH->GetStdDevError(2));
8692 }
8693 stats->AddText(tt.Data());
8694 }
8695 }
8696 if (print_under) {
8697 tf.Form("%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8698 tt.Form(tf.Data(),fH->GetBinContent(0));
8699 stats->AddText(tt.Data());
8700 }
8701 if (print_over) {
8702 tf.Form("%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8703 tt.Form(tf.Data(),fH->GetBinContent(fXaxis->GetNbins()+1));
8704 stats->AddText(tt.Data());
8705 }
8706 if (print_integral) {
8707 if (print_integral == 1) {
8708 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8709 tt.Form(tf.Data(),fH->Integral());
8710 } else {
8711 tf.Form("%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8712 tt.Form(tf.Data(),fH->Integral("width"));
8713 }
8714 stats->AddText(tt.Data());
8715 }
8716 if (print_skew) {
8717 if (print_skew == 1) {
8718 tf.Form("%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8719 tt.Form(tf.Data(),fH->GetSkewness(1));
8720 } else {
8721 tf.Form("%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8722 ,"%",stats->GetStatFormat());
8723 tt.Form(tf.Data(),fH->GetSkewness(1),fH->GetSkewness(11));
8724 }
8725 stats->AddText(tt.Data());
8726 }
8727 if (print_kurt) {
8728 if (print_kurt == 1) {
8729 tf.Form("%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8730 tt.Form(tf.Data(),fH->GetKurtosis(1));
8731 } else {
8732 tf.Form("%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8733 ,"%",stats->GetStatFormat());
8734 tt.Form(tf.Data(),fH->GetKurtosis(1),fH->GetKurtosis(11));
8735 }
8736 stats->AddText(tt.Data());
8737 }
8738
8739 // Draw Fit parameters
8740 if (fit) {
8741 Int_t ndf = fit->GetNDF();
8742 tf.Form("#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8743 tt.Form(tf.Data(),(Float_t)fit->GetChisquare());
8744 if (print_fchi2) stats->AddText(tt.Data());
8745 if (print_fprob) {
8746 tf.Form("Prob = %s%s","%",stats->GetFitFormat());
8747 tt.Form(tf.Data(),(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8748 stats->AddText(tt.Data());
8749 }
8750 if (print_fval || print_ferrors) {
8751 Double_t parmin,parmax;
8752 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8753 fit->GetParLimits(ipar,parmin,parmax);
8754 if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8755 if (print_ferrors) {
8756 tf.Form("%-8s = %s%s #pm %s ", fit->GetParName(ipar), "%",stats->GetFitFormat(),
8757 GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8758 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar)
8759 ,(Float_t)fit->GetParError(ipar));
8760 } else {
8761 tf.Form("%-8s = %s%s ",fit->GetParName(ipar), "%",stats->GetFitFormat());
8762 tt.Form(tf.Data(),(Float_t)fit->GetParameter(ipar));
8763 }
8764 stats->AddText(tt.Data());
8765 }
8766 }
8767 }
8768
8769 if (!done) fFunctions->Add(stats);
8770 stats->Paint();
8771}
8772
8773////////////////////////////////////////////////////////////////////////////////
8774/// [Draw the statistics box for 2D histograms.](\ref HP07)
8775
8777{
8778
8779 if (fH->GetDimension() != 2) return;
8780 TH2 *h2 = (TH2*)fH;
8781
8782 TString tt, tf;
8783 Int_t dofit;
8784 TPaveStats *stats = 0;
8785 TIter next(fFunctions);
8786 TObject *obj;
8787 while ((obj = next())) {
8788 if (obj->InheritsFrom(TPaveStats::Class())) {
8789 stats = (TPaveStats*)obj;
8790 break;
8791 }
8792 }
8793 if (stats && dostat) {
8794 dofit = stats->GetOptFit();
8795 dostat = stats->GetOptStat();
8796 } else {
8797 dofit = gStyle->GetOptFit();
8798 }
8799 if (dostat == 1) dostat = 1111;
8800 Int_t print_name = dostat%10;
8801 Int_t print_entries = (dostat/10)%10;
8802 Int_t print_mean = (dostat/100)%10;
8803 Int_t print_stddev = (dostat/1000)%10;
8804 Int_t print_under = (dostat/10000)%10;
8805 Int_t print_over = (dostat/100000)%10;
8806 Int_t print_integral= (dostat/1000000)%10;
8807 Int_t print_skew = (dostat/10000000)%10;
8808 Int_t print_kurt = (dostat/100000000)%10;
8809 Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8810 if (print_under || print_over) nlines += 3;
8811
8812 // Pavetext with statistics
8813 if (!gStyle->GetOptFit()) fit = 0;
8814 Bool_t done = kFALSE;
8815 if (!dostat && !fit) {
8816 if (stats) { fFunctions->Remove(stats); delete stats;}
8817 return;
8818 }
8819 Double_t statw = gStyle->GetStatW();
8820 if (fit) statw = 1.8*gStyle->GetStatW();
8821 Double_t stath = nlines*gStyle->GetStatFontSize();
8822 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8823 stath = 0.25*nlines*gStyle->GetStatH();
8824 }
8825 if (fit) stath += gStyle->GetStatH();
8826 if (stats) {
8827 stats->Clear();
8828 done = kTRUE;
8829 } else {
8830 stats = new TPaveStats(
8831 gStyle->GetStatX()-statw,
8832 gStyle->GetStatY()-stath,
8833 gStyle->GetStatX(),
8834 gStyle->GetStatY(),"brNDC");
8835
8836 stats->SetParent(fH);
8837 stats->SetOptFit(dofit);
8838 stats->SetOptStat(dostat);
8839 stats->SetFillColor(gStyle->GetStatColor());
8840 stats->SetFillStyle(gStyle->GetStatStyle());
8842 stats->SetName("stats");
8843
8845 stats->SetTextAlign(12);
8846 stats->SetTextFont(gStyle->GetStatFont());
8847 if (gStyle->GetStatFont()%10 > 2)
8849 stats->SetFitFormat(gStyle->GetFitFormat());
8851 stats->SetBit(kCanDelete);
8852 stats->SetBit(kMustCleanup);
8853 }
8854 if (print_name) stats->AddText(h2->GetName());
8855 if (print_entries) {
8856 if (h2->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8857 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8858 stats->AddText(tt.Data());
8859 }
8860 if (print_mean) {
8861 if (print_mean == 1) {
8862 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8863 tt.Form(tf.Data(),h2->GetMean(1));
8864 stats->AddText(tt.Data());
8865 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8866 tt.Form(tf.Data(),h2->GetMean(2));
8867 stats->AddText(tt.Data());
8868 } else {
8869 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8870 ,"%",stats->GetStatFormat());
8871 tt.Form(tf.Data(),h2->GetMean(1),h2->GetMeanError(1));
8872 stats->AddText(tt.Data());
8873 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8874 ,"%",stats->GetStatFormat());
8875 tt.Form(tf.Data(),h2->GetMean(2),h2->GetMeanError(2));
8876 stats->AddText(tt.Data());
8877 }
8878 }
8879 if (print_stddev) {
8880 if (print_stddev == 1) {
8881 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8882 tt.Form(tf.Data(),h2->GetStdDev(1));
8883 stats->AddText(tt.Data());
8884 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8885 tt.Form(tf.Data(),h2->GetStdDev(2));
8886 stats->AddText(tt.Data());
8887 } else {
8888 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8889 ,"%",stats->GetStatFormat());
8890 tt.Form(tf.Data(),h2->GetStdDev(1),h2->GetStdDevError(1));
8891 stats->AddText(tt.Data());
8892 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8893 ,"%",stats->GetStatFormat());
8894 tt.Form(tf.Data(),h2->GetStdDev(2),h2->GetStdDevError(2));
8895 stats->AddText(tt.Data());
8896 }
8897 }
8898 if (print_integral) {
8899 tf.Form("%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8900 tt.Form(tf.Data(),fH->Integral());
8901 stats->AddText(tt.Data());
8902 }
8903 if (print_skew) {
8904 if (print_skew == 1) {
8905 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8906 tt.Form(tf.Data(),h2->GetSkewness(1));
8907 stats->AddText(tt.Data());
8908 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8909 tt.Form(tf.Data(),h2->GetSkewness(2));
8910 stats->AddText(tt.Data());
8911 } else {
8912 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8913 ,"%",stats->GetStatFormat());
8914 tt.Form(tf.Data(),h2->GetSkewness(1),h2->GetSkewness(11));
8915 stats->AddText(tt.Data());
8916 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8917 ,"%",stats->GetStatFormat());
8918 tt.Form(tf.Data(),h2->GetSkewness(2),h2->GetSkewness(12));
8919 stats->AddText(tt.Data());
8920 }
8921 }
8922 if (print_kurt) {
8923 if (print_kurt == 1) {
8924 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8925 tt.Form(tf.Data(),h2->GetKurtosis(1));
8926 stats->AddText(tt.Data());
8927 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8928 tt.Form(tf.Data(),h2->GetKurtosis(2));
8929 stats->AddText(tt.Data());
8930 } else {
8931 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8932 ,"%",stats->GetStatFormat());
8933 tt.Form(tf.Data(),h2->GetKurtosis(1),h2->GetKurtosis(11));
8934 stats->AddText(tt.Data());
8935 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8936 ,"%",stats->GetStatFormat());
8937 tt.Form(tf.Data(),h2->GetKurtosis(2),h2->GetKurtosis(12));
8938 stats->AddText(tt.Data());
8939 }
8940 }
8941 if (print_under || print_over) {
8942 //get 3*3 under/overflows for 2d hist
8943 Double_t unov[9];
8944
8945 Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8946 Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8947 Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8948 Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8949 Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8950 Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8951
8952 unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8953 unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8954 unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8955 unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8956 unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8957 unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8958 unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8959 unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8960 unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8961
8962 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8963 stats->AddText(tt.Data());
8964 if (TMath::Abs(unov[4]) < 1.e7)
8965 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8966 else
8967 tt.Form(" %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8968 stats->AddText(tt.Data());
8969 tt.Form(" %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8970 stats->AddText(tt.Data());
8971 }
8972
8973 // Draw Fit parameters
8974 if (fit) {
8975 Int_t ndf = fit->GetNDF();
8976 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8977 stats->AddText(tt.Data());
8978 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8979 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8980 ,(Float_t)fit->GetParameter(ipar)
8981 ,(Float_t)fit->GetParError(ipar));
8982 stats->AddText(tt.Data());
8983 }
8984 }
8985
8986 if (!done) fFunctions->Add(stats);
8987 stats->Paint();
8988}
8989
8990////////////////////////////////////////////////////////////////////////////////
8991/// [Draw the statistics box for 3D histograms.](\ref HP07)
8992
8994{
8995
8996 if (fH->GetDimension() != 3) return;
8997 TH3 *h3 = (TH3*)fH;
8998
8999 TString tt, tf;
9000 Int_t dofit;
9001 TPaveStats *stats = 0;
9002 TIter next(fFunctions);
9003 TObject *obj;
9004 while ((obj = next())) {
9005 if (obj->InheritsFrom(TPaveStats::Class())) {
9006 stats = (TPaveStats*)obj;
9007 break;
9008 }
9009 }
9010 if (stats && dostat) {
9011 dofit = stats->GetOptFit();
9012 dostat = stats->GetOptStat();
9013 } else {
9014 dofit = gStyle->GetOptFit();
9015 }
9016 if (dostat == 1) dostat = 1111;
9017 Int_t print_name = dostat%10;
9018 Int_t print_entries = (dostat/10)%10;
9019 Int_t print_mean = (dostat/100)%10;
9020 Int_t print_stddev = (dostat/1000)%10;
9021 Int_t print_under = (dostat/10000)%10;
9022 Int_t print_over = (dostat/100000)%10;
9023 Int_t print_integral= (dostat/1000000)%10;
9024 Int_t print_skew = (dostat/10000000)%10;
9025 Int_t print_kurt = (dostat/100000000)%10;
9026 Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
9027 if (print_under || print_over) nlines += 3;
9028
9029 // Pavetext with statistics
9030 if (!gStyle->GetOptFit()) fit = 0;
9031 Bool_t done = kFALSE;
9032 if (!dostat && !fit) {
9033 if (stats) { fFunctions->Remove(stats); delete stats;}
9034 return;
9035 }
9036 Double_t statw = gStyle->GetStatW();
9037 if (fit) statw = 1.8*gStyle->GetStatW();
9038 Double_t stath = nlines*gStyle->GetStatFontSize();
9039 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
9040 stath = 0.25*nlines*gStyle->GetStatH();
9041 }
9042 if (fit) stath += gStyle->GetStatH();
9043 if (stats) {
9044 stats->Clear();
9045 done = kTRUE;
9046 } else {
9047 stats = new TPaveStats(
9048 gStyle->GetStatX()-statw,
9049 gStyle->GetStatY()-stath,
9050 gStyle->GetStatX(),
9051 gStyle->GetStatY(),"brNDC");
9052
9053 stats->SetParent(fH);
9054 stats->SetOptFit(dofit);
9055 stats->SetOptStat(dostat);
9056 stats->SetFillColor(gStyle->GetStatColor());
9057 stats->SetFillStyle(gStyle->GetStatStyle());
9059 stats->SetName("stats");
9060
9062 stats->SetTextAlign(12);
9063 stats->SetTextFont(gStyle->GetStatFont());
9064 stats->SetFitFormat(gStyle->GetFitFormat());
9066 stats->SetBit(kCanDelete);
9067 stats->SetBit(kMustCleanup);
9068 }
9069 if (print_name) stats->AddText(h3->GetName());
9070 if (print_entries) {
9071 if (h3->GetEntries() < 1e7) tt.Form("%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
9072 else tt.Form("%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
9073 stats->AddText(tt.Data());
9074 }
9075 if (print_mean) {
9076 if (print_mean == 1) {
9077 tf.Form("%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
9078 tt.Form(tf.Data(),h3->GetMean(1));
9079 stats->AddText(tt.Data());
9080 tf.Form("%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
9081 tt.Form(tf.Data(),h3->GetMean(2));
9082 stats->AddText(tt.Data());
9083 tf.Form("%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
9084 tt.Form(tf.Data(),h3->GetMean(3));
9085 stats->AddText(tt.Data());
9086 } else {
9087 tf.Form("%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
9088 ,"%",stats->GetStatFormat());
9089 tt.Form(tf.Data(),h3->GetMean(1),h3->GetMeanError(1));
9090 stats->AddText(tt.Data());
9091 tf.Form("%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
9092 ,"%",stats->GetStatFormat());
9093 tt.Form(tf.Data(),h3->GetMean(2),h3->GetMeanError(2));
9094 stats->AddText(tt.Data());
9095 tf.Form("%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
9096 ,"%",stats->GetStatFormat());
9097 tt.Form(tf.Data(),h3->GetMean(3),h3->GetMeanError(3));
9098 stats->AddText(tt.Data());
9099 }
9100 }
9101 if (print_stddev) {
9102 if (print_stddev == 1) {
9103 tf.Form("%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
9104 tt.Form(tf.Data(),h3->GetStdDev(1));
9105 stats->AddText(tt.Data());
9106 tf.Form("%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
9107 tt.Form(tf.Data(),h3->GetStdDev(2));
9108 stats->AddText(tt.Data());
9109 tf.Form("%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
9110 tt.Form(tf.Data(),h3->GetStdDev(3));
9111 stats->AddText(tt.Data());
9112 } else {
9113 tf.Form("%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
9114 ,"%",stats->GetStatFormat());
9115 tt.Form(tf.Data(),h3->GetStdDev(1),h3->GetStdDevError(1));
9116 stats->AddText(tt.Data());
9117 tf.Form("%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
9118 ,"%",stats->GetStatFormat());
9119 tt.Form(tf.Data(),h3->GetStdDev(2),h3->GetStdDevError(2));
9120 stats->AddText(tt.Data());
9121 tf.Form("%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
9122 ,"%",stats->GetStatFormat());
9123 tt.Form(tf.Data(),h3->GetStdDev(3),h3->GetStdDevError(3));
9124 stats->AddText(tt.Data());
9125 }
9126 }
9127 if (print_integral) {
9128 tt.Form("%s = %6.4g",gStringIntegral.Data(),h3->Integral());
9129 stats->AddText(tt.Data());
9130 }
9131 if (print_skew) {
9132 if (print_skew == 1) {
9133 tf.Form("%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
9134 tt.Form(tf.Data(),h3->GetSkewness(1));
9135 stats->AddText(tt.Data());
9136 tf.Form("%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
9137 tt.Form(tf.Data(),h3->GetSkewness(2));
9138 stats->AddText(tt.Data());
9139 tf.Form("%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
9140 tt.Form(tf.Data(),h3->GetSkewness(3));
9141 stats->AddText(tt.Data());
9142 } else {
9143 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
9144 ,"%",stats->GetStatFormat());
9145 tt.Form(tf.Data(),h3->GetSkewness(1),h3->GetSkewness(11));
9146 stats->AddText(tt.Data());
9147 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
9148 ,"%",stats->GetStatFormat());
9149 tt.Form(tf.Data(),h3->GetSkewness(2),h3->GetSkewness(12));
9150 stats->AddText(tt.Data());
9151 tf.Form("%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
9152 ,"%",stats->GetStatFormat());
9153 tt.Form(tf.Data(),h3->GetSkewness(3),h3->GetSkewness(13));
9154 stats->AddText(tt.Data());
9155 }
9156 }
9157 if (print_kurt) {
9158 if (print_kurt == 1) {
9159 tf.Form("%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
9160 tt.Form(tf.Data(),h3->GetKurtosis(1));
9161 stats->AddText(tt.Data());
9162 tf.Form("%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
9163 tt.Form(tf.Data(),h3->GetKurtosis(2));
9164 stats->AddText(tt.Data());
9165 tf.Form("%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
9166 tt.Form(tf.Data(),h3->GetKurtosis(3));
9167 stats->AddText(tt.Data());
9168 } else {
9169 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
9170 ,"%",stats->GetStatFormat());
9171 tt.Form(tf.Data(),h3->GetKurtosis(1),h3->GetKurtosis(11));
9172 stats->AddText(tt.Data());
9173 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
9174 ,"%",stats->GetStatFormat());
9175 tt.Form(tf.Data(),h3->GetKurtosis(2),h3->GetKurtosis(12));
9176 stats->AddText(tt.Data());
9177 tf.Form("%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
9178 ,"%",stats->GetStatFormat());
9179 tt.Form(tf.Data(),h3->GetKurtosis(3),h3->GetKurtosis(13));
9180 stats->AddText(tt.Data());
9181 }
9182 }
9183 if (print_under || print_over) {
9184 // no underflow - overflow printing for a 3D histogram
9185 // one would need a 3D table
9186 }
9187
9188 // Draw Fit parameters
9189 if (fit) {
9190 Int_t ndf = fit->GetNDF();
9191 tt.Form("#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
9192 stats->AddText(tt.Data());
9193 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
9194 tt.Form("%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
9195 ,(Float_t)fit->GetParameter(ipar)
9196 ,(Float_t)fit->GetParError(ipar));
9197 stats->AddText(tt.Data());
9198 }
9199 }
9200
9201 if (!done) fFunctions->Add(stats);
9202 stats->Paint();
9203}
9204
9205////////////////////////////////////////////////////////////////////////////////
9206/// [Control function to draw a 2D histogram as a surface plot.](\ref HP18)
9207
9209{
9210
9211 const Double_t ydiff = 1;
9212 const Double_t yligh1 = 10;
9213 const Double_t qa = 0.15;
9214 const Double_t qd = 0.15;
9215 const Double_t qs = 0.8;
9216 Double_t fmin, fmax;
9217 Int_t raster = 0;
9218 Int_t irep = 0;
9219
9220 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9223 Double_t zmin = Hparam.zmin;
9224 Double_t zmax = Hparam.zmax;
9225 Double_t xlab1 = Hparam.xmin;
9226 Double_t xlab2 = Hparam.xmax;
9227 Double_t ylab1 = Hparam.ymin;
9228 Double_t ylab2 = Hparam.ymax;
9229 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
9230 Double_t deltaz = TMath::Abs(zmin);
9231 if (deltaz == 0) deltaz = 1;
9232 if (zmin >= zmax) {
9233 zmin -= 0.5*deltaz;
9234 zmax += 0.5*deltaz;
9235 }
9236 Double_t z1c = zmin;
9237 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
9238 // Compute the lego limits and instantiate a lego object
9239 fXbuf[0] = -1;
9240 fYbuf[0] = 1;
9241 fXbuf[1] = -1;
9242 fYbuf[1] = 1;
9243 if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
9244 if (Hoption.System == kPOLAR) {
9245 fXbuf[2] = z1c;
9246 fYbuf[2] = z2c;
9247 } else if (Hoption.System == kCYLINDRICAL) {
9248 if (Hoption.Logy) {
9249 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
9250 else fXbuf[2] = 0;
9251 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
9252 else fYbuf[2] = 0;
9253 } else {
9254 fXbuf[2] = ylab1;
9255 fYbuf[2] = ylab2;
9256 }
9257 z1c = 0; z2c = 1;
9258 } else if (Hoption.System == kSPHERICAL) {
9259 fXbuf[2] = -1;
9260 fYbuf[2] = 1;
9261 z1c = 0; z2c = 1;
9262 } else if (Hoption.System == kRAPIDITY) {
9263 fXbuf[2] = -1/TMath::Tan(dangle);
9264 fYbuf[2] = 1/TMath::Tan(dangle);
9265 } else {
9266 fXbuf[0] = xlab1;
9267 fYbuf[0] = xlab2;
9268 fXbuf[1] = ylab1;
9269 fYbuf[1] = ylab2;
9270 fXbuf[2] = z1c;
9271 fYbuf[2] = z2c;
9272 }
9273
9277
9278 // Create axis object
9279
9280 TGaxis *axis = new TGaxis();
9281
9282 // Initialize the levels on the Z axis
9283 Int_t ndiv = fH->GetContour();
9284 if (ndiv == 0 ) {
9285 ndiv = gStyle->GetNumberContours();
9286 fH->SetContour(ndiv);
9287 }
9288 Int_t ndivz = TMath::Abs(ndiv);
9289 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9290
9291 if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
9292 if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
9293
9294 // Close the surface in case of non cartesian coordinates.
9295
9296 if (Hoption.System != kCARTESIAN) {nx++; ny++;}
9297
9298 // Now ready to draw the surface plot
9299
9300 TView *view = gPad->GetView();
9301 if (!view) {
9302 Error("PaintSurface", "no TView in current pad");
9303 return;
9304 }
9305
9306 Double_t thedeg = 90 - gPad->GetTheta();
9307 Double_t phideg = -90 - gPad->GetPhi();
9308 Double_t psideg = view->GetPsi();
9309 view->SetView(phideg, thedeg, psideg, irep);
9310
9311 // Set color/style for back box
9312 if (Hoption.Same) {
9313 fLego->SetFillStyle(0);
9314 fLego->SetFillColor(1);
9315 } else {
9316 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9317 fLego->SetFillColor(gPad->GetFrameFillColor());
9318 }
9319 fLego->TAttFill::Modify();
9320
9321 Int_t backcolor = gPad->GetFrameFillColor();
9322 if (Hoption.System != kCARTESIAN) backcolor = 0;
9323 view->PadRange(backcolor);
9324
9327 fLego->TAttFill::Modify();
9328
9329 // Draw the filled contour on top
9330 Int_t icol1 = fH->GetFillColor();
9331
9332 Int_t hoption35 = Hoption.Surf;
9333 if (Hoption.Surf == 13 || Hoption.Surf == 15) {
9334 DefineColorLevels(ndivz);
9335 Hoption.Surf = 23;
9338 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9339 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9340 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9341 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9342 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9343 Hoption.Surf = hoption35;
9344 fLego->SetMesh(1);
9345 }
9346
9347 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
9348 else fLego->InitMoveScreen(-1.1,1.1);
9349
9350 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
9354 fLego->BackBox(90);
9355 }
9356 }
9357
9358 // Gouraud Shading surface
9359 if (Hoption.Surf == 14) {
9360 // Set light sources
9361 fLego->LightSource(0, ydiff, 0,0,0,irep);
9362 fLego->LightSource(1, yligh1 ,1,1,1,irep);
9363 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
9364 fmin = ydiff*qa;
9365 fmax = fmin + (yligh1+0.1)*(qd+qs);
9366 Int_t nbcol = 28;
9367 icol1 = 201;
9368 Double_t dcol = 0.5/Double_t(nbcol);
9369 TColor *colref = gROOT->GetColor(fH->GetFillColor());
9370 if (!colref) return;
9371 Float_t r,g,b,hue,light,satur;
9372 colref->GetRGB(r,g,b);
9373 TColor::RGBtoHLS(r,g,b,hue,light,satur);
9374 TColor *acol;
9375 for (Int_t col=0;col<nbcol;col++) {
9376 acol = gROOT->GetColor(col+icol1);
9377 TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
9378 if (acol) acol->SetRGB(r,g,b);
9379 }
9380 fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
9383 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9384 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9385 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9386 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9387 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9388 } else if (Hoption.Surf == 15) {
9389 // The surface is not drawn in this case.
9390 } else {
9391 // Draw the surface
9392 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
9393 DefineColorLevels(ndivz);
9394 } else {
9396 }
9400 if (Hoption.System == kPOLAR) {
9401 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
9402 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
9403 } else if (Hoption.System == kCYLINDRICAL) {
9404 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9405 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9406 } else if (Hoption.System == kSPHERICAL) {
9407 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9408 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9409 } else if (Hoption.System == kRAPIDITY) {
9410 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9411 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9412 } else {
9415 if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
9416 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
9417 }
9418 }
9419
9420 // Paint the line contour on top for option SURF7
9421 if (Hoption.Surf == 17) {
9422 fLego->InitMoveScreen(-1.1,1.1);
9424 Hoption.Surf = 23;
9427 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
9428 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9429 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9430 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9431 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
9432 }
9433
9434 if ((!Hoption.Same) &&
9435 (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
9438 fLego->BackBox(90);
9439 }
9440 }
9441 if (Hoption.System == kCARTESIAN) {
9442 fLego->InitMoveScreen(-1.1,1.1);
9444 if (Hoption.FrontBox) fLego->FrontBox(90);
9445 }
9446 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9447
9449
9450 delete axis;
9451 delete fLego; fLego = 0;
9452}
9453
9454////////////////////////////////////////////////////////////////////////////////
9455/// Control function to draw a table using Delaunay triangles.
9456
9458{
9459
9460 TGraphDelaunay2D *dt = nullptr;
9461 TGraphDelaunay *dtOld = nullptr;
9462
9463 // Check if fH contains a TGraphDelaunay2D
9464 TList *hl = fH->GetListOfFunctions();
9465 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
9466 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
9467 if (!dt && !dtOld) return;
9468
9469 // If needed, create a TGraph2DPainter
9470 if (!fGraph2DPainter) {
9471 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
9472 else fGraph2DPainter = new TGraph2DPainter(dtOld);
9473 }
9474
9475 // Define the 3D view
9476 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9477 if (Hoption.Same) {
9478 TView *viewsame = gPad->GetView();
9479 if (!viewsame) {
9480 Error("PaintTriangles", "no TView in current pad, do not use option SAME");
9481 return;
9482 }
9483 Double_t *rmin = viewsame->GetRmin();
9484 Double_t *rmax = viewsame->GetRmax();
9485 if (!rmin || !rmax) return;
9486 fXbuf[0] = rmin[0];
9487 fYbuf[0] = rmax[0];
9488 fXbuf[1] = rmin[1];
9489 fYbuf[1] = rmax[1];
9490 fXbuf[2] = rmin[2];
9491 fYbuf[2] = rmax[2];
9492 } else {
9493 fXbuf[0] = Hparam.xmin;
9494 fYbuf[0] = Hparam.xmax;
9495 fXbuf[1] = Hparam.ymin;
9496 fYbuf[1] = Hparam.ymax;
9497 fXbuf[2] = Hparam.zmin;
9498 fYbuf[2] = Hparam.zmax;
9499 }
9500
9502 TView *view = gPad->GetView();
9503 if (!view) {
9504 Error("PaintTriangles", "no TView in current pad");
9505 return;
9506 }
9507 Double_t thedeg = 90 - gPad->GetTheta();
9508 Double_t phideg = -90 - gPad->GetPhi();
9509 Double_t psideg = view->GetPsi();
9510 Int_t irep;
9511 view->SetView(phideg, thedeg, psideg, irep);
9512
9513 // Set color/style for back box
9514 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9515 fLego->SetFillColor(gPad->GetFrameFillColor());
9516 fLego->TAttFill::Modify();
9517 Int_t backcolor = gPad->GetFrameFillColor();
9518 if (Hoption.System != kCARTESIAN) backcolor = 0;
9519 view->PadRange(backcolor);
9522 fLego->TAttFill::Modify();
9523
9524 // Paint the Back Box if needed
9525 if (Hoption.BackBox && !Hoption.Same) {
9526 fLego->InitMoveScreen(-1.1,1.1);
9529 fLego->BackBox(90);
9530 }
9531
9532 // Paint the triangles
9533 fGraph2DPainter->Paint(option);
9534
9535 // Paint the Front Box if needed
9536 if (Hoption.FrontBox) {
9537 fLego->InitMoveScreen(-1.1,1.1);
9539 fLego->FrontBox(90);
9540 }
9541
9542 // Paint the Axis if needed
9543 if (!Hoption.Axis && !Hoption.Same) {
9544 TGaxis *axis = new TGaxis();
9545 PaintLegoAxis(axis, 90);
9546 delete axis;
9547 }
9548
9550
9551 delete fLego; fLego = 0;
9552}
9553
9554////////////////////////////////////////////////////////////////////////////////
9555/// Define the color levels used to paint legos, surfaces etc..
9556
9558{
9559
9560 Int_t i, irep;
9561
9562 // Initialize the color levels
9563 if (ndivz >= 100) {
9564 Warning("PaintSurface", "too many color levels, %d >= 100, reset to 99", ndivz);
9565 ndivz = 99;
9566 }
9567 Double_t *funlevel = new Double_t[ndivz+1];
9568 Int_t *colorlevel = new Int_t[ndivz+1];
9569 Int_t theColor;
9570 Int_t ncolors = gStyle->GetNumberOfColors();
9571 for (i = 0; i < ndivz; ++i) {
9572 funlevel[i] = fH->GetContourLevelPad(i);
9573 theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9574 colorlevel[i] = gStyle->GetColorPalette(theColor);
9575 }
9576 colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9577 fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9578 delete [] colorlevel;
9579 delete [] funlevel;
9580}
9581
9582////////////////////////////////////////////////////////////////////////////////
9583/// [Control function to draw 2D/3D histograms (tables).](\ref HP01c)
9584
9586{
9587
9588 // Fill Hparam structure with histo parameters
9589 if (!TableInit()) return;
9590
9591 // Draw histogram frame
9592 PaintFrame();
9593
9594 // If palette option not specified, delete a possible existing palette
9595 if (!Hoption.Zscale) {
9596 TObject *palette = fFunctions->FindObject("palette");
9597 if (palette) { fFunctions->Remove(palette); delete palette;}
9598 }
9599
9600 // Do not draw the histogram. Only the attached functions will be drawn.
9601 if (Hoption.Func == 2) {
9602 if (Hoption.Zscale) {
9603 Int_t ndiv = fH->GetContour();
9604 if (ndiv == 0 ) {
9605 ndiv = gStyle->GetNumberContours();
9606 fH->SetContour(ndiv);
9607 }
9608 PaintPalette();
9609 }
9610
9611 // Draw the histogram according to the option
9612 } else {
9613 if (fH->InheritsFrom(TH2Poly::Class()) && Hoption.Axis<=0) {
9614 if (Hoption.Fill) PaintTH2PolyBins("f");
9617 if (Hoption.Text) PaintTH2PolyText(option);
9618 if (Hoption.Line) PaintTH2PolyBins("l");
9619 if (Hoption.Mark) PaintTH2PolyBins("P");
9620 } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9621 if (Hoption.Scat) PaintScatterPlot(option);
9622 if (Hoption.Arrow) PaintArrows(option);
9623 if (Hoption.Box) PaintBoxes(option);
9624 if (Hoption.Color) {
9625 if (Hoption.Color == 3) PaintColorLevelsFast(option);
9626 else PaintColorLevels(option);
9627 }
9628 if (Hoption.Contour) PaintContour(option);
9629 if (Hoption.Text) PaintText(option);
9630 if (Hoption.Error >= 100) Paint2DErrors(option);
9631 if (Hoption.Candle) PaintCandlePlot(option);
9632 }
9633 if (Hoption.Lego) PaintLego(option);
9634 if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9635 if (Hoption.Tri) PaintTriangles(option);
9636 }
9637
9638 // Draw histogram title
9639 PaintTitle();
9640
9641 // Draw the axes
9642 if (!Hoption.Lego && !Hoption.Surf &&
9643 !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9644
9645 TF1 *fit = 0;
9646 TIter next(fFunctions);
9647 TObject *obj;
9648 while ((obj = next())) {
9649 if (obj->InheritsFrom(TF1::Class())) {
9650 fit = (TF1*)obj;
9651 break;
9652 }
9653 }
9654 if ((Hoption.Same%10) != 1) {
9655 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9656 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9657 //ALWAYS executed on non-iOS platform.
9658 //On iOS, depends on mode.
9660 }
9661 }
9662 }
9663}
9664
9665////////////////////////////////////////////////////////////////////////////////
9666/// Control function to draw a TH2Poly bins' contours.
9667///
9668/// - option = "F" draw the bins as filled areas.
9669/// - option = "L" draw the bins as line.
9670/// - option = "P" draw the bins as markers.
9671
9673{
9674
9675 //Do not highlight the histogram, if its part was picked.
9676 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9677
9678 TString opt = option;
9679 opt.ToLower();
9680 Bool_t line = kFALSE;
9681 Bool_t fill = kFALSE;
9682 Bool_t mark = kFALSE;
9683 if (opt.Contains("l")) line = kTRUE;
9684 if (opt.Contains("f")) fill = kTRUE;
9685 if (opt.Contains("p")) mark = kTRUE;
9686
9687 TH2PolyBin *b;
9688 Double_t z;
9689
9690 TIter next(((TH2Poly*)fH)->GetBins());
9691 TObject *obj, *poly;
9692
9693 while ((obj=next())) {
9694 b = (TH2PolyBin*)obj;
9695 z = b->GetContent();
9696 if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9697 poly = b->GetPolygon();
9698
9699 // Paint the TGraph bins.
9700 if (poly->IsA() == TGraph::Class()) {
9701 TGraph *g = (TGraph*)poly;
9702 g->TAttLine::Modify();
9703 g->TAttMarker::Modify();
9704 g->TAttFill::Modify();
9705 if (line) {
9706 Int_t fs = g->GetFillStyle();
9707 Int_t fc = g->GetFillColor();
9708 g->SetFillStyle(0);
9709 g->SetFillColor(g->GetLineColor());
9710 g->Paint("F");
9711 g->SetFillStyle(fs);
9712 g->SetFillColor(fc);
9713 }
9714 if (fill) g->Paint("F");
9715 if (mark) g->Paint("P");
9716 }
9717
9718 // Paint the TMultiGraph bins.
9719 if (poly->IsA() == TMultiGraph::Class()) {
9720 TMultiGraph *mg = (TMultiGraph*)poly;
9721 TList *gl = mg->GetListOfGraphs();
9722 if (!gl) return;
9723 TGraph *g;
9724 TIter nextg(gl);
9725 while ((g = (TGraph*) nextg())) {
9726 g->TAttLine::Modify();
9727 g->TAttMarker::Modify();
9728 g->TAttFill::Modify();
9729 if (line) {
9730 Int_t fs = g->GetFillStyle();
9731 Int_t fc = g->GetFillColor();
9732 g->SetFillStyle(0);
9733 g->SetFillColor(g->GetLineColor());
9734 g->Paint("F");
9735 g->SetFillStyle(fs);
9736 g->SetFillColor(fc);
9737 }
9738 if (fill) g->Paint("F");
9739 if (mark) g->Paint("P");
9740 }
9741 }
9742 }
9743}
9744
9745////////////////////////////////////////////////////////////////////////////////
9746/// [Control function to draw a TH2Poly as a color plot.](\ref HP20a)
9747
9749{
9750
9751 //Do not highlight the histogram, if its part was picked.
9752 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9753 return;
9754
9755 Int_t ncolors, color, theColor;
9756 Double_t z, zc;
9757 Double_t zmin = fH->GetMinimum();
9758 Double_t zmax = fH->GetMaximum();
9759 if (Hoption.Logz) {
9760 if (zmax > 0) {
9761 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9762 zmin = TMath::Log10(zmin);
9763 zmax = TMath::Log10(zmax);
9764 } else {
9765 return;
9766 }
9767 }
9768 Double_t dz = zmax - zmin;
9769
9770 // Initialize the levels on the Z axis
9771 ncolors = gStyle->GetNumberOfColors();
9772 Int_t ndiv = fH->GetContour();
9773 if (ndiv == 0 ) {
9774 ndiv = gStyle->GetNumberContours();
9775 fH->SetContour(ndiv);
9776 }
9777 Int_t ndivz = TMath::Abs(ndiv);
9778 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9779 Double_t scale = ndivz/dz;
9780
9781 TH2PolyBin *b;
9782
9783 TIter next(((TH2Poly*)fH)->GetBins());
9784 TObject *obj, *poly;
9785
9786 while ((obj=next())) {
9787 b = (TH2PolyBin*)obj;
9788 poly = b->GetPolygon();
9789
9790 z = b->GetContent();
9791 if (z==0 && Hoption.Zero) continue;
9792 if (Hoption.Logz) {
9793 if (z > 0) z = TMath::Log10(z);
9794 else z = zmin;
9795 }
9796 if (z < zmin) continue;
9797
9798 // Define the bin color.
9800 zc = fH->GetContourLevelPad(0);
9801 if (z < zc) continue;
9802 color = -1;
9803 for (Int_t k=0; k<ndiv; k++) {
9804 zc = fH->GetContourLevelPad(k);
9805 if (z < zc) {
9806 continue;
9807 } else {
9808 color++;
9809 }
9810 }
9811 } else {
9812 color = Int_t(0.01+(z-zmin)*scale);
9813 }
9814 theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9815 if (theColor > ncolors-1) theColor = ncolors-1;
9816
9817 // Paint the TGraph bins.
9818 if (poly->IsA() == TGraph::Class()) {
9819 TGraph *g = (TGraph*)poly;
9820 g->SetFillColor(gStyle->GetColorPalette(theColor));
9821 g->TAttFill::Modify();
9822 g->Paint("F");
9823 }
9824
9825 // Paint the TMultiGraph bins.
9826 if (poly->IsA() == TMultiGraph::Class()) {
9827 TMultiGraph *mg = (TMultiGraph*)poly;
9828 TList *gl = mg->GetListOfGraphs();
9829 if (!gl) return;
9830 TGraph *g;
9831 TIter nextg(gl);
9832 while ((g = (TGraph*) nextg())) {
9833 g->SetFillColor(gStyle->GetColorPalette(theColor));
9834 g->TAttFill::Modify();
9835 g->Paint("F");
9836 }
9837 }
9838 }
9840}
9841
9842////////////////////////////////////////////////////////////////////////////////
9843/// [Control function to draw a TH2Poly as a scatter plot.](\ref HP20a)
9844
9846{
9847
9848 //Do not highlight the histogram, if its part was selected.
9849 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9850 return;
9851
9852 Int_t k, loop, marker=0;
9853 Double_t z, xk,xstep, yk, ystep, xp, yp;
9854 Double_t scale = 1;
9855 Double_t zmin = fH->GetMinimum();
9856 Double_t zmax = fH->GetMaximum();
9857 if (Hoption.Logz) {
9858 if (zmax > 0) {
9859 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9860 zmin = TMath::Log10(zmin);
9861 zmax = TMath::Log10(zmax);
9862 } else {
9863 return;
9864 }
9865 }
9866 Double_t dz = zmax - zmin;
9867 scale = (kNMAX-1)/dz;
9868
9869
9870 // use an independent instance of a random generator
9871 // instead of gRandom to avoid conflicts and
9872 // to get same random numbers when drawing the same histogram
9873 TRandom2 random;
9874
9875 TH2PolyBin *b;
9876
9877 TIter next(((TH2Poly*)fH)->GetBins());
9878 TObject *obj, *poly;
9879
9880 Double_t maxarea = 0, a;
9881 while ((obj=next())) {
9882 b = (TH2PolyBin*)obj;
9883 a = b->GetArea();
9884 if (a>maxarea) maxarea = a;
9885 }
9886
9887 next.Reset();
9888
9889 while ((obj=next())) {
9890 b = (TH2PolyBin*)obj;
9891 poly = b->GetPolygon();
9892 z = b->GetContent();
9893 if (z < zmin) z = zmin;
9894 if (z > zmax) z = zmax;
9895 if (Hoption.Logz) {
9896 if (z > 0) z = TMath::Log10(z) - zmin;
9897 } else {
9898 z -= zmin;
9899 }
9900 k = Int_t((z*scale)*(b->GetArea()/maxarea));
9901 xk = b->GetXMin();
9902 yk = b->GetYMin();
9903 xstep = b->GetXMax()-xk;
9904 ystep = b->GetYMax()-yk;
9905
9906 // Paint the TGraph bins.
9907 if (poly->IsA() == TGraph::Class()) {
9908 TGraph *g = (TGraph*)poly;
9909 if (k <= 0 || z <= 0) continue;
9910 loop = 0;
9911 while (loop<k) {
9912 if (k+marker >= kNMAX) {
9913 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9914 marker=0;
9915 }
9916 xp = (random.Rndm()*xstep) + xk;
9917 yp = (random.Rndm()*ystep) + yk;
9918 if (g->IsInside(xp,yp)) {
9919 fXbuf[marker] = xp;
9920 fYbuf[marker] = yp;
9921 marker++;
9922 loop++;
9923 }
9924 }
9925 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9926 }
9927
9928 // Paint the TMultiGraph bins.
9929 if (poly->IsA() == TMultiGraph::Class()) {
9930 TMultiGraph *mg = (TMultiGraph*)poly;
9931 TList *gl = mg->GetListOfGraphs();
9932 if (!gl) return;
9933 if (k <= 0 || z <= 0) continue;
9934 loop = 0;
9935 while (loop<k) {
9936 if (k+marker >= kNMAX) {
9937 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9938 marker=0;
9939 }
9940 xp = (random.Rndm()*xstep) + xk;
9941 yp = (random.Rndm()*ystep) + yk;
9942 if (mg->IsInside(xp,yp)) {
9943 fXbuf[marker] = xp;
9944 fYbuf[marker] = yp;
9945 marker++;
9946 loop++;
9947 }
9948 }
9949 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9950 }
9951 }
9952 PaintTH2PolyBins("l");
9953}
9954
9955////////////////////////////////////////////////////////////////////////////////
9956/// [Control function to draw a TH2Poly as a text plot.](\ref HP20a)
9957
9959{
9960
9961 TLatex text;
9965
9966 Double_t x, y, z, e, angle = 0;
9967 TString tt, tf;
9968 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
9969 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9970 Int_t opt = (Int_t)Hoption.Text/1000;
9971
9972 text.SetTextAlign(22);
9973 if (Hoption.Text == 1) angle = 0;
9974 text.SetTextAngle(angle);
9975 text.TAttText::Modify();
9976
9977 TH2PolyBin *b;
9978
9979 TIter next(((TH2Poly*)fH)->GetBins());
9980 TObject *obj, *p;
9981
9982 while ((obj=next())) {
9983 b = (TH2PolyBin*)obj;
9984 p = b->GetPolygon();
9985 x = (b->GetXMin()+b->GetXMax())/2;
9986 if (Hoption.Logx) {
9987 if (x > 0) x = TMath::Log10(x);
9988 else continue;
9989 }
9990 y = (b->GetYMin()+b->GetYMax())/2;
9991 if (Hoption.Logy) {
9992 if (y > 0) y = TMath::Log10(y);
9993 else continue;
9994 }
9995 z = b->GetContent();
9996 if (z < fH->GetMinimum() || (z == 0 && !Hoption.MinimumZero)) continue;
9997 if (opt==2) {
9998 e = fH->GetBinError(b->GetBinNumber());
9999 tf.Form("#splitline{%s%s}{#pm %s%s}",
10001 "%",gStyle->GetPaintTextFormat());
10002 tt.Form(tf.Data(),z,e);
10003 } else {
10004 tt.Form(tf.Data(),z);
10005 }
10006 if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
10007 else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),tt.Data());
10008 }
10009
10010 PaintTH2PolyBins("l");
10011}
10012
10013////////////////////////////////////////////////////////////////////////////////
10014/// [Control function to draw a 1D/2D histograms with the bin values.](\ref HP15)
10015
10017{
10018
10019 TLatex text;
10023
10024 Double_t x, y, z, e, angle = 0;
10025 TString tt, tf;
10026 tf.Form("%s%s","%",gStyle->GetPaintTextFormat());
10027 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
10028
10029 // 1D histograms
10030 if (fH->GetDimension() == 1) {
10031 Bool_t getentries = kFALSE;
10032 Double_t yt;
10033 TProfile *hp = (TProfile*)fH;
10034 if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
10035 Hoption.Text = Hoption.Text-2000;
10036 getentries = kTRUE;
10037 }
10038 if (Hoption.Text == 1) angle = 90;
10039 text.SetTextAlign(11);
10040 if (angle == 90) text.SetTextAlign(12);
10041 if (angle == 0) text.SetTextAlign(21);
10042 text.TAttText::Modify();
10043 Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
10044 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10045 if (Hoption.Bar) {
10046 x = fH->GetXaxis()->GetBinLowEdge(i)+
10047 fH->GetXaxis()->GetBinWidth(i)*
10048 (fH->GetBarOffset()+0.5*fH->GetBarWidth());
10049 } else {
10050 x = fH->GetXaxis()->GetBinCenter(i);
10051 }
10052 y = fH->GetBinContent(i);
10053 yt = y;
10054 if (Hoption.MinimumZero && y<0) y = 0;
10055 if (getentries) yt = hp->GetBinEntries(i);
10056 if (yt == 0.) continue;
10057 tt.Form(tf.Data(),yt);
10058 if (Hoption.Logx) {
10059 if (x > 0) x = TMath::Log10(x);
10060 else continue;
10061 }
10062 if (Hoption.Logy) {
10063 if (y > 0) y = TMath::Log10(y);
10064 else continue;
10065 }
10066 if (y >= gPad->GetY2()) continue;
10067 if (y <= gPad->GetY1()) continue;
10068 text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),tt.Data());
10069 }
10070
10071 // 2D histograms
10072 } else {
10073 text.SetTextAlign(22);
10074 if (Hoption.Text == 1) angle = 0;
10075 text.SetTextAngle(angle);
10076 text.TAttText::Modify();
10077 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10078 y = fYaxis->GetBinCenter(j);
10079 if (Hoption.Logy) {
10080 if (y > 0) y = TMath::Log10(y);
10081 else continue;
10082 }
10083 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10084 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
10085 x = fXaxis->GetBinCenter(i);
10086 if (Hoption.Logx) {
10087 if (x > 0) x = TMath::Log10(x);
10088 else continue;
10089 }
10090 if (!IsInside(x,y)) continue;
10091 z = fH->GetBinContent(bin);
10092 if (z < Hparam.zmin || (z == 0 && !Hoption.MinimumZero)) continue;
10093 if (Hoption.Text>2000) {
10094 e = fH->GetBinError(bin);
10095 tf.Form("#splitline{%s%s}{#pm %s%s}",
10097 "%",gStyle->GetPaintTextFormat());
10098 tt.Form(tf.Data(),z,e);
10099 } else {
10100 tt.Form(tf.Data(),z);
10101 }
10102 text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
10103 angle,0.02*fH->GetMarkerSize(),tt.Data());
10104 }
10105 }
10106 }
10107}
10108
10109////////////////////////////////////////////////////////////////////////////////
10110/// [Control function to draw a 3D implicit functions.](\ref HP27)
10111
10113{
10114
10115 Int_t irep;
10116
10117 TGaxis *axis = new TGaxis();
10118 TAxis *xaxis = fH->GetXaxis();
10119 TAxis *yaxis = fH->GetYaxis();
10120 TAxis *zaxis = fH->GetZaxis();
10121
10122 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
10123 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
10124 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
10125 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
10126 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
10127 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
10128
10130
10131 TView *view = gPad->GetView();
10132 if (!view) {
10133 Error("PaintTF3", "no TView in current pad");
10134 return;
10135 }
10136 Double_t thedeg = 90 - gPad->GetTheta();
10137 Double_t phideg = -90 - gPad->GetPhi();
10138 Double_t psideg = view->GetPsi();
10139 view->SetView(phideg, thedeg, psideg, irep);
10140
10141 fLego->InitMoveScreen(-1.1,1.1);
10142
10143 if (Hoption.BackBox) {
10146 fLego->BackBox(90);
10147 }
10148
10150
10152 fH->GetNbinsY(),
10153 fH->GetNbinsZ(), "BF");
10154
10155 if (Hoption.FrontBox) {
10156 fLego->InitMoveScreen(-1.1,1.1);
10158 fLego->FrontBox(90);
10159 }
10160 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
10161
10162 PaintTitle();
10163
10164 delete axis;
10165 delete fLego; fLego = 0;
10166}
10167
10168////////////////////////////////////////////////////////////////////////////////
10169/// Draw the histogram title
10170///
10171/// The title is drawn according to the title alignment returned by
10172/// `GetTitleAlign()`. It is a 2 digits integer): hv
10173///
10174/// where `h` is the horizontal alignment and `v` is the
10175/// vertical alignment.
10176///
10177/// - `h` can get the values 1 2 3 for left, center, and right
10178/// - `v` can get the values 1 2 3 for bottom, middle and top
10179///
10180/// for instance the default alignment is: 13 (left top)
10181
10183{
10184 // probably best place for calls PaintHighlightBin
10185 // calls after paint histo (1D or 2D) and before paint title and stats
10186 if (!gPad->GetView()) PaintHighlightBin();
10187
10188 if (Hoption.Same) return;
10189 if (fH->TestBit(TH1::kNoTitle)) return;
10190 Int_t nt = strlen(fH->GetTitle());
10191 TPaveText *title = 0;
10192 TObject *obj;
10193 TIter next(gPad->GetListOfPrimitives());
10194 while ((obj = next())) {
10195 if (!obj->InheritsFrom(TPaveText::Class())) continue;
10196 title = (TPaveText*)obj;
10197 if (strcmp(title->GetName(),"title")) {title = 0; continue;}
10198 break;
10199 }
10200 if (nt == 0 || gStyle->GetOptTitle() <= 0) {
10201 if (title) delete title;
10202 return;
10203 }
10204 Double_t ht = gStyle->GetTitleH();
10205 Double_t wt = gStyle->GetTitleW();
10206
10207 if (ht <= 0) {
10208 if (gStyle->GetTitleFont("")%10 == 3) {
10209 Double_t hw = TMath::Max((Double_t)gPad->XtoPixel(gPad->GetX2()),
10210 (Double_t)gPad->YtoPixel(gPad->GetY1()));
10211 ht = 1.1*(gStyle->GetTitleSize("")/hw);
10212 } else {
10213 ht = 1.1*gStyle->GetTitleFontSize();
10214 }
10215 }
10216 if (ht <= 0) ht = 0.05;
10217 if (wt <= 0) {
10218 TLatex l;
10219 l.SetTextSize(ht);
10220 l.SetTitle(fH->GetTitle());
10221 // adjustment in case the title has several lines (#splitline)
10222 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
10223 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
10224 wt = TMath::Min(0.7, 0.02+wndc);
10225 }
10226 if (title) {
10227 TText *t0 = (TText*)title->GetLine(0);
10228 if (t0) {
10229 if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
10230 t0->SetTitle(fH->GetTitle());
10231 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
10232 }
10233 return;
10234 }
10235
10236 Int_t talh = gStyle->GetTitleAlign()/10;
10237 if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
10238 Int_t talv = gStyle->GetTitleAlign()%10;
10239 if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
10240 Double_t xpos, ypos;
10241 xpos = gStyle->GetTitleX();
10242 ypos = gStyle->GetTitleY();
10243 if (talh == 2) xpos = xpos-wt/2.;
10244 if (talh == 3) xpos = xpos-wt;
10245 if (talv == 2) ypos = ypos+ht/2.;
10246 if (talv == 1) ypos = ypos+ht;
10247
10248 TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
10249
10250 // box with the histogram title
10252 ptitle->SetFillStyle(gStyle->GetTitleStyle());
10253 ptitle->SetName("title");
10256 ptitle->SetTextFont(gStyle->GetTitleFont(""));
10257 if (gStyle->GetTitleFont("")%10 > 2)
10259 ptitle->AddText(fH->GetTitle());
10260 ptitle->SetBit(kCanDelete);
10261 ptitle->Draw();
10262 ptitle->Paint();
10263
10264 if(!gPad->IsEditable()) delete ptitle;
10265}
10266
10267////////////////////////////////////////////////////////////////////////////////
10268/// Process message `mess`.
10269
10270void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
10271{
10272 if (!strcmp(mess,"SetF3")) {
10273 fCurrentF3 = (TF3 *)obj;
10274 }
10275}
10276
10277////////////////////////////////////////////////////////////////////////////////
10278/// Static function.
10279///
10280/// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
10281/// This procedure can be used to create an all-sky map in Galactic
10282/// coordinates with an equal-area Aitoff projection. Output map
10283/// coordinates are zero longitude centered.
10284/// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
10285///
10286/// source: GMT
10287///
10288/// code from Ernst-Jan Buis
10289
10291{
10292
10293 Double_t x, y;
10294
10295 Double_t alpha2 = (l/2)*TMath::DegToRad();
10296 Double_t delta = b*TMath::DegToRad();
10297 Double_t r2 = TMath::Sqrt(2.);
10298 Double_t f = 2*r2/TMath::Pi();
10299 Double_t cdec = TMath::Cos(delta);
10300 Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
10301 x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
10302 y = TMath::Sin(delta)*r2/denom;
10303 x *= TMath::RadToDeg()/f;
10304 y *= TMath::RadToDeg()/f;
10305 // x *= -1.; // for a skymap swap left<->right
10306 Al = x;
10307 Ab = y;
10308
10309 return 0;
10310}
10311
10312////////////////////////////////////////////////////////////////////////////////
10313/// Static function
10314///
10315/// Probably the most famous of the various map projections, the Mercator projection
10316/// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
10317/// with no distortion along the equator.
10318/// The Mercator projection has been used extensively for world maps in which the distortion towards
10319/// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
10320/// Greenland is larger than South America. In reality, the latter is about eight times the size of
10321/// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
10322/// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
10323/// code from Ernst-Jan Buis
10324
10326{
10327
10328 Al = l;
10330 Ab = TMath::Log(aid);
10331 return 0;
10332}
10333
10334////////////////////////////////////////////////////////////////////////////////
10335/// Static function code from Ernst-Jan Buis
10336
10338{
10339
10340 Al = l*cos(b*TMath::DegToRad());
10341 Ab = b;
10342 return 0;
10343}
10344
10345////////////////////////////////////////////////////////////////////////////////
10346/// Static function code from Ernst-Jan Buis
10347
10349{
10350
10351 Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
10352 Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
10353 return 0;
10354}
10355
10356////////////////////////////////////////////////////////////////////////////////
10357/// Recompute the histogram range following graphics operations.
10358
10360{
10361
10362 if (Hoption.Same) return;
10363
10364 // Compute x,y range
10369
10370 Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
10371 if (Hoption.Proj ==1) {
10372 // TODO : check x range not lower than -180 and not higher than 180
10377
10378 if (xmin > xmin_aid) xmin = xmin_aid;
10379 if (ymin > ymin_aid) ymin = ymin_aid;
10380 if (xmax < xmax_aid) xmax = xmax_aid;
10381 if (ymax < ymax_aid) ymax = ymax_aid;
10382 if (Hparam.ymin<0 && Hparam.ymax>0) {
10383 // there is an 'equator', check its range in the plot..
10384 THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
10385 THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
10386 if (xmin >xmin_aid) xmin = xmin_aid;
10387 if (xmax <xmax_aid) xmax = xmax_aid;
10388 }
10389 if (Hparam.xmin<0 && Hparam.xmax>0) {
10390 THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10391 THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
10392 if (ymin >ymin_aid) ymin = ymin_aid;
10393 if (ymax <ymax_aid) ymax = ymax_aid;
10394 }
10395 } else if ( Hoption.Proj ==2) {
10396 if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
10397 Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
10398 Hoption.Proj = 0;
10399 } else {
10402 }
10403 } else if (Hoption.Proj == 3) {
10408
10409 if (xmin > xmin_aid) xmin = xmin_aid;
10410 if (ymin > ymin_aid) ymin = ymin_aid;
10411 if (xmax < xmax_aid) xmax = xmax_aid;
10412 if (ymax < ymax_aid) ymax = ymax_aid;
10413 if (Hparam.ymin<0 && Hparam.ymax>0) {
10414 THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10415 THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10416 if (xmin >xmin_aid) xmin = xmin_aid;
10417 if (xmax <xmax_aid) xmax = xmax_aid;
10418 }
10419 if (Hparam.xmin<0 && Hparam.xmax>0) {
10420 THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
10421 THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10422 if (ymin >ymin_aid) ymin = ymin_aid;
10423 if (ymax <ymax_aid) ymax = ymax_aid;
10424 }
10425 } else if (Hoption.Proj == 4) {
10430
10431 if (xmin > xmin_aid) xmin = xmin_aid;
10432 if (ymin > ymin_aid) ymin = ymin_aid;
10433 if (xmax < xmax_aid) xmax = xmax_aid;
10434 if (ymax < ymax_aid) ymax = ymax_aid;
10435 if (Hparam.ymin<0 && Hparam.ymax>0) {
10436 THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10437 THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10438 if (xmin >xmin_aid) xmin = xmin_aid;
10439 if (xmax <xmax_aid) xmax = xmax_aid;
10440 }
10441 if (Hparam.xmin<0 && Hparam.xmax>0) {
10442 THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10443 THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10444 if (ymin >ymin_aid) ymin = ymin_aid;
10445 if (ymax <ymax_aid) ymax = ymax_aid;
10446 }
10447 }
10448 Hparam.xmin= xmin;
10449 Hparam.xmax= xmax;
10450 Hparam.ymin= ymin;
10451 Hparam.ymax= ymax;
10452
10453 Double_t dx = xmax-xmin;
10454 Double_t dy = ymax-ymin;
10455 Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
10456 Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
10457
10458 // Range() could change the size of the pad pixmap and therefore should
10459 // be called before the other paint routines
10460 gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
10461 ymin - dyr*gPad->GetBottomMargin(),
10462 xmax + dxr*gPad->GetRightMargin(),
10463 ymax + dyr*gPad->GetTopMargin());
10464 gPad->RangeAxis(xmin, ymin, xmax, ymax);
10465}
10466
10467////////////////////////////////////////////////////////////////////////////////
10468/// Set current histogram to `h`
10469
10471{
10472
10473 if (h == 0) return;
10474 fH = h;
10475 fXaxis = h->GetXaxis();
10476 fYaxis = h->GetYaxis();
10477 fZaxis = h->GetZaxis();
10479}
10480
10481////////////////////////////////////////////////////////////////////////////////
10482/// Initialize various options to draw 2D histograms.
10483
10485{
10486
10487 static const char *where = "TableInit";
10488
10489 Int_t first, last;
10490 Double_t yMARGIN= gStyle->GetHistTopMargin();
10491 Double_t zmin, zmax;
10492 Int_t maximum = 0;
10493 Int_t minimum = 0;
10494 if (fH->GetMaximumStored() != -1111) maximum = 1;
10495 if (fH->GetMinimumStored() != -1111) minimum = 1;
10496
10497 // ----------------- Compute X axis parameters
10498 first = fXaxis->GetFirst();
10499 last = fXaxis->GetLast();
10500 Hparam.xlast = last;
10506
10507 // if log scale in X, replace xmin,max by the log
10508 if (Hoption.Logx) {
10509 // find the first edge of a bin that is > 0
10510 if (Hparam.xlowedge <=0 ) {
10513 }
10514 if (Hparam.xmin <=0 || Hparam.xmax <=0) {
10515 Error(where, "cannot set X axis to log scale");
10516 return 0;
10517 }
10521 if (Hparam.xlast > last) Hparam.xlast = last;
10524 }
10525
10526 // ----------------- Compute Y axis parameters
10527 first = fYaxis->GetFirst();
10528 last = fYaxis->GetLast();
10529 Hparam.ylast = last;
10533 if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10536
10537 // if log scale in Y, replace ymin,max by the log
10538 if (Hoption.Logy) {
10539 if (Hparam.ylowedge <=0 ) {
10542 }
10543 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10544 Error(where, "cannot set Y axis to log scale");
10545 return 0;
10546 }
10550 if (Hparam.ylast > last) Hparam.ylast = last;
10553 }
10554
10555
10556 // ----------------- Compute Z axis parameters
10557 Double_t bigp = TMath::Power(10,32);
10558 zmax = -bigp;
10559 zmin = bigp;
10560 Double_t c1, e1;
10561 Double_t allchan = 0;
10562 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10563 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10564 c1 = fH->GetBinContent(i,j);
10565 zmax = TMath::Max(zmax,c1);
10566 if (Hoption.Error) {
10567 e1 = fH->GetBinError(i,j);
10568 zmax = TMath::Max(zmax,c1+e1);
10569 }
10570 zmin = TMath::Min(zmin,c1);
10571 allchan += c1;
10572 }
10573 }
10574
10575 // Take into account maximum , minimum
10576
10577 if (maximum) zmax = fH->GetMaximumStored();
10578 if (minimum) zmin = fH->GetMinimumStored();
10579 if (Hoption.Logz && zmax < 0) {
10580 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10581 return 0;
10582 } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10583 zmin = 0.01;
10584 zmax = 10.;
10585 }
10586 if (zmin >= zmax) {
10587 if (Hoption.Logz) {
10588 if (zmax > 0) zmin = 0.001*zmax;
10589 else {
10590 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10591 return 0;
10592 }
10593 }
10594 }
10595
10596 // take into account normalization factor
10597 Hparam.allchan = allchan;
10598 Double_t factor = allchan;
10599 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10600 if (allchan) factor /= allchan;
10601 if (factor == 0) factor = 1;
10602 Hparam.factor = factor;
10603 zmax = factor*zmax;
10604 zmin = factor*zmin;
10605 c1 = zmax;
10606 if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10607
10608 // For log scales, histogram coordinates are log10(ymin) and
10609 // log10(ymax). Final adjustment (if not option "Same")
10610 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10611 // Maximum and Minimum are not defined.
10612 if (Hoption.Logz) {
10613 if (zmin <= 0) {
10614 zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10615 fH->SetMinimum(zmin);
10616 }
10617 zmin = TMath::Log10(zmin);
10618 if (!minimum) zmin += TMath::Log10(0.5);
10619 zmax = TMath::Log10(zmax);
10620 if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10621 goto LZMIN;
10622 }
10623
10624 // final adjustment of YMAXI for linear scale (if not option "Same"):
10625 // decrease histogram height to MAX% of allowed height if HMAXIM
10626 // has not been called.
10627 // MAX% is the value in percent which has been set in HPLSET
10628 // (default is 90%).
10629 if (!maximum) {
10630 zmax += yMARGIN*(zmax-zmin);
10631 }
10632
10633 // final adjustment of ymin for linear scale.
10634 // if minimum is not set , then ymin is set to zero if >0
10635 // or to ymin - yMARGIN if <0.
10636 if (!minimum) {
10637 if (Hoption.MinimumZero) {
10638 if (zmin >= 0) zmin = 0;
10639 else zmin -= yMARGIN*(zmax-zmin);
10640 } else {
10641 Double_t dzmin = yMARGIN*(zmax-zmin);
10642 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10643 else zmin -= dzmin;
10644 }
10645 }
10646
10647LZMIN:
10648 Hparam.zmin = zmin;
10649 Hparam.zmax = zmax;
10650
10651 // Set bar offset and width
10654
10655 return 1;
10656}
10657
10658////////////////////////////////////////////////////////////////////////////////
10659/// This function returns the best format to print the error value (e)
10660/// knowing the parameter value (v) and the format (f) used to print it.
10661
10663{
10664
10665 static TString ef;
10666 TString tf, tv;
10667
10668 // print v with the format f in tv.
10669 tf.Form("%s%s","%",f);
10670 tv.Form(tf.Data(),v);
10671
10672 // Analyse tv.
10673 int ie = tv.Index("e");
10674 int iE = tv.Index("E");
10675 int id = tv.Index(".");
10676
10677 // v has been printed with the exponent notation.
10678 // There is 2 cases, the exponent is positive or negative
10679 if (ie >= 0 || iE >= 0) {
10680 if (tv.Index("+") >= 0) {
10681 if (e < 1) {
10682 ef.Form("%s.1f","%");
10683 } else {
10684 if (ie >= 0) {
10685 ef.Form("%s.%de","%",ie-id-1);
10686 } else {
10687 ef.Form("%s.%dE","%",iE-id-1);
10688 }
10689 }
10690 } else {
10691 if (ie >= 0) {
10692 ef.Form("%s.%de","%",ie-id-1);
10693 } else {
10694 ef.Form("%s.%dE","%",iE-id-1);
10695 }
10696 }
10697
10698 // There is not '.' in tv. e will be printed with one decimal digit.
10699 } else if (id < 0) {
10700 ef.Form("%s.1f","%");
10701
10702 // There is a '.' in tv and no exponent notation. e's decimal part will
10703 // have the same number of digits as v's one.
10704 } else {
10705 ef.Form("%s.%df","%",tv.Length()-id-1);
10706 }
10707
10708 return ef.Data();
10709}
10710
10711////////////////////////////////////////////////////////////////////////////////
10712/// Set projection.
10713
10714void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10715{
10716
10717 if (fShowProjection) return;
10718 TString opt = option;
10719 opt.ToLower();
10720 Int_t projection = 0;
10721 if (opt.Contains("x")) projection = 1;
10722 if (opt.Contains("y")) projection = 2;
10723 if (opt.Contains("z")) projection = 3;
10724 if (opt.Contains("xy")) projection = 4;
10725 if (opt.Contains("yx")) projection = 5;
10726 if (opt.Contains("xz")) projection = 6;
10727 if (opt.Contains("zx")) projection = 7;
10728 if (opt.Contains("yz")) projection = 8;
10729 if (opt.Contains("zy")) projection = 9;
10730 if (projection < 4) fShowOption = option+1;
10731 else fShowOption = option+2;
10732 fShowProjection = projection+100*nbins;
10733 gROOT->MakeDefCanvas();
10734 gPad->SetName(Form("c_%zx_projection_%d", (size_t)fH, fShowProjection));
10735 gPad->SetGrid();
10736}
10737
10738////////////////////////////////////////////////////////////////////////////////
10739/// Show projection onto X.
10740
10742{
10743
10744 Int_t nbins = (Int_t)fShowProjection/100;
10745 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10746 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10747
10748 // Erase old position and draw a line at current position
10749 static int pyold1 = 0;
10750 static int pyold2 = 0;
10751 float uxmin = gPad->GetUxmin();
10752 float uxmax = gPad->GetUxmax();
10753 int pxmin = gPad->XtoAbsPixel(uxmin);
10754 int pxmax = gPad->XtoAbsPixel(uxmax);
10755 Float_t upy = gPad->AbsPixeltoY(py);
10756 Float_t y = gPad->PadtoY(upy);
10757 Int_t biny1 = fH->GetYaxis()->FindBin(y);
10758 Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10759 Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10760 Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10761
10762 if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10763 gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10764 pyold1 = py1;
10765 pyold2 = py2;
10766
10767 // Create or set the new canvas proj x
10768 TVirtualPad *padsav = gPad;
10769 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%zx_projection_%d",
10770 (size_t)fH, fShowProjection));
10771 if (c) {
10772 c->Clear();
10773 } else {
10774 fShowProjection = 0;
10775 pyold1 = 0;
10776 pyold2 = 0;
10777 return;
10778 }
10779 c->cd();
10780 c->SetLogy(padsav->GetLogz());
10781 c->SetLogx(padsav->GetLogx());
10782
10783 // Draw slice corresponding to mouse position
10784 TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10785 TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10786 if (hp) {
10787 hp->SetFillColor(38);
10788 // apply a patch from Oliver Freyermuth to set the title in the projection
10789 // using the range of the projected Y values
10790 if (biny1 == biny2) {
10791 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10792 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10793 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10794 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10795 if (fH->GetYaxis()->GetLabels() != NULL) {
10796 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10797 } else {
10798 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10799 }
10800 } else {
10801 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10802 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10803 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10804 // biny1 is used here to get equal precision no matter how large the binrange is,
10805 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10806 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10807 if (fH->GetYaxis()->GetLabels() != NULL) {
10808 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)));
10809 } else {
10810 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10811 }
10812 }
10813 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10814 hp->SetYTitle("Number of Entries");
10815 hp->Draw();
10816 c->Update();
10817 padsav->cd();
10818 }
10819}
10820
10821////////////////////////////////////////////////////////////////////////////////
10822/// Show projection onto Y.
10823
10825{
10826
10827 Int_t nbins = (Int_t)fShowProjection/100;
10828 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10829 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10830
10831 // Erase old position and draw a line at current position
10832 static int pxold1 = 0;
10833 static int pxold2 = 0;
10834 float uymin = gPad->GetUymin();
10835 float uymax = gPad->GetUymax();
10836 int pymin = gPad->YtoAbsPixel(uymin);
10837 int pymax = gPad->YtoAbsPixel(uymax);
10838 Float_t upx = gPad->AbsPixeltoX(px);
10839 Float_t x = gPad->PadtoX(upx);
10840 Int_t binx1 = fH->GetXaxis()->FindBin(x);
10841 Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10842 Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10843 Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10844
10845 if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10846 gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10847 pxold1 = px1;
10848 pxold2 = px2;
10849
10850 // Create or set the new canvas proj y
10851 TVirtualPad *padsav = gPad;
10852 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%zx_projection_%d",
10853 (size_t)fH, fShowProjection));
10854 if (c) {
10855 c->Clear();
10856 } else {
10857 fShowProjection = 0;
10858 pxold1 = 0;
10859 pxold2 = 0;
10860 return;
10861 }
10862 c->cd();
10863 c->SetLogy(padsav->GetLogz());
10864 c->SetLogx(padsav->GetLogy());
10865
10866 // Draw slice corresponding to mouse position
10867 TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10868 TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10869 if (hp) {
10870 hp->SetFillColor(38);
10871 // apply a patch from Oliver Freyermuth to set the title in the projection
10872 // using the range of the projected X values
10873 if (binx1 == binx2) {
10874 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10875 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10876 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10877 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10878 if (fH->GetXaxis()->GetLabels() != NULL) {
10879 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10880 } else {
10881 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10882 }
10883 } else {
10884 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10885 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10886 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10887 // binx1 is used here to get equal precision no matter how large the binrange is,
10888 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10889 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10890 if (fH->GetXaxis()->GetLabels() != NULL) {
10891 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)));
10892 } else {
10893 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10894 }
10895 }
10896 hp->SetXTitle(fH->GetYaxis()->GetTitle());
10897 hp->SetYTitle("Number of Entries");
10898 hp->Draw();
10899 c->Update();
10900 padsav->cd();
10901 }
10902}
10903
10904////////////////////////////////////////////////////////////////////////////////
10905/// Show projection (specified by `fShowProjection`) of a `TH3`.
10906/// The drawing option for the projection is in `fShowOption`.
10907///
10908/// First implementation; R.Brun
10909///
10910/// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10911
10913{
10914
10915 Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10916 if (fH->GetDimension() < 3) {
10917 if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10918 if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10919 }
10920
10921 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10922 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10923
10924 // Erase old position and draw a line at current position
10925 TView *view = gPad->GetView();
10926 if (!view) return;
10927 TH3 *h3 = (TH3*)fH;
10928 TAxis *xaxis = h3->GetXaxis();
10929 TAxis *yaxis = h3->GetYaxis();
10930 TAxis *zaxis = h3->GetZaxis();
10931 Double_t u[3],xx[3];
10932
10933 static TPoint line1[2];//store end points of a line, initialised 0 by default
10934 static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10935 static TPoint line3[2];
10936 static TPoint line4[2];
10937 static TPoint endface1[5];
10938 static TPoint endface2[5];
10939 static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10940 static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10941
10942 Double_t uxmin = gPad->GetUxmin();
10943 Double_t uxmax = gPad->GetUxmax();
10944 Double_t uymin = gPad->GetUymin();
10945 Double_t uymax = gPad->GetUymax();
10946
10947 int pxmin = gPad->XtoAbsPixel(uxmin);
10948 int pxmax = gPad->XtoAbsPixel(uxmax);
10949 if (pxmin==pxmax) return;
10950 int pymin = gPad->YtoAbsPixel(uymin);
10951 int pymax = gPad->YtoAbsPixel(uymax);
10952 if (pymin==pymax) return;
10953 Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10954 Double_t cy = (pymax-pymin)/(uymax-uymin);
10955 TVirtualPad *padsav = gPad;
10956 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%zx_projection_%d",
10957 (size_t)fH, fShowProjection));
10958 if (!c) {
10959 fShowProjection = 0;
10960 return;
10961 }
10962
10963 switch ((Int_t)fShowProjection%100) {
10964 case 1:
10965 // "x"
10966 {
10967 Int_t firstY = yaxis->GetFirst();
10968 Int_t lastY = yaxis->GetLast();
10969 Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10970 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10971 yaxis->SetRange(biny,biny2);
10972 Int_t firstZ = zaxis->GetFirst();
10973 Int_t lastZ = zaxis->GetLast();
10974 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10975 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10976 zaxis->SetRange(binz,binz2);
10977 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10978 if (nbins>1 && line1[0].GetX()) {
10979 gVirtualX->DrawPolyLine(2,line2);
10980 gVirtualX->DrawPolyLine(2,line3);
10981 gVirtualX->DrawPolyLine(2,line4);
10982 gVirtualX->DrawPolyLine(5,endface1);
10983 gVirtualX->DrawPolyLine(5,endface2);
10984 }
10985 xx[0] = xaxis->GetXmin();
10986 xx[2] = zaxis->GetBinCenter(binz);
10987 xx[1] = yaxis->GetBinCenter(biny);
10988 view->WCtoNDC(xx,u);
10989 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10990 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10991 xx[0] = xaxis->GetXmax();
10992 view->WCtoNDC(xx,u);
10993 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10994 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10995 gVirtualX->DrawPolyLine(2,line1);
10996 if (nbins>1) {
10997 xx[0] = xaxis->GetXmin();
10998 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10999 xx[1] = yaxis->GetBinCenter(biny);
11000 view->WCtoNDC(xx,u);
11001 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11002 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11003 xx[0] = xaxis->GetXmax();
11004 view->WCtoNDC(xx,u);
11005 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11006 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11007
11008 xx[0] = xaxis->GetXmin();
11009 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11010 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11011 view->WCtoNDC(xx,u);
11012 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11013 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11014 xx[0] = xaxis->GetXmax();
11015 view->WCtoNDC(xx,u);
11016 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11017 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11018
11019 xx[0] = xaxis->GetXmin();
11020 xx[2] = zaxis->GetBinCenter(binz);
11021 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11022 view->WCtoNDC(xx,u);
11023 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11024 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11025 xx[0] = xaxis->GetXmax();
11026 view->WCtoNDC(xx,u);
11027 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11028 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11029
11030 endface1[0].SetX(line1[0].GetX());
11031 endface1[0].SetY(line1[0].GetY());
11032 endface1[1].SetX(line2[0].GetX());
11033 endface1[1].SetY(line2[0].GetY());
11034 endface1[2].SetX(line3[0].GetX());
11035 endface1[2].SetY(line3[0].GetY());
11036 endface1[3].SetX(line4[0].GetX());
11037 endface1[3].SetY(line4[0].GetY());
11038 endface1[4].SetX(line1[0].GetX());
11039 endface1[4].SetY(line1[0].GetY());
11040
11041 endface2[0].SetX(line1[1].GetX());
11042 endface2[0].SetY(line1[1].GetY());
11043 endface2[1].SetX(line2[1].GetX());
11044 endface2[1].SetY(line2[1].GetY());
11045 endface2[2].SetX(line3[1].GetX());
11046 endface2[2].SetY(line3[1].GetY());
11047 endface2[3].SetX(line4[1].GetX());
11048 endface2[3].SetY(line4[1].GetY());
11049 endface2[4].SetX(line1[1].GetX());
11050 endface2[4].SetY(line1[1].GetY());
11051
11052 gVirtualX->DrawPolyLine(2,line2);
11053 gVirtualX->DrawPolyLine(2,line3);
11054 gVirtualX->DrawPolyLine(2,line4);
11055 gVirtualX->DrawPolyLine(5,endface1);
11056 gVirtualX->DrawPolyLine(5,endface2);
11057 }
11058 c->Clear();
11059 c->cd();
11060 TH1 *hp = h3->Project3D("x");
11061 yaxis->SetRange(firstY,lastY);
11062 zaxis->SetRange(firstZ,lastZ);
11063 if (hp) {
11064 hp->SetFillColor(38);
11065 if (nbins == 1)
11066 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
11067 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
11068 else {
11069 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),
11070 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
11071 }
11072 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11073 hp->SetYTitle("Number of Entries");
11074 hp->Draw(fShowOption.Data());
11075 }
11076 }
11077 break;
11078
11079 case 2:
11080 // "y"
11081 {
11082 Int_t firstX = xaxis->GetFirst();
11083 Int_t lastX = xaxis->GetLast();
11084 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
11085 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11086 xaxis->SetRange(binx,binx2);
11087 Int_t firstZ = zaxis->GetFirst();
11088 Int_t lastZ = zaxis->GetLast();
11089 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
11090 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11091 zaxis->SetRange(binz,binz2);
11092 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
11093 if (nbins>1 && line1[0].GetX()) {
11094 gVirtualX->DrawPolyLine(2,line2);
11095 gVirtualX->DrawPolyLine(2,line3);
11096 gVirtualX->DrawPolyLine(2,line4);
11097 gVirtualX->DrawPolyLine(5,endface1);
11098 gVirtualX->DrawPolyLine(5,endface2);
11099 }
11100 xx[0]=xaxis->GetBinCenter(binx);
11101 xx[2] = zaxis->GetBinCenter(binz);
11102 xx[1] = yaxis->GetXmin();
11103 view->WCtoNDC(xx,u);
11104 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11105 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11106 xx[1] = yaxis->GetXmax();
11107 view->WCtoNDC(xx,u);
11108 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11109 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11110 gVirtualX->DrawPolyLine(2,line1);
11111 if (nbins>1) {
11112 xx[1] = yaxis->GetXmin();
11113 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11114 xx[0] = xaxis->GetBinCenter(binx);
11115 view->WCtoNDC(xx,u);
11116 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11117 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11118 xx[1] = yaxis->GetXmax();
11119 view->WCtoNDC(xx,u);
11120 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11121 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11122
11123 xx[1] = yaxis->GetXmin();
11124 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11125 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11126 view->WCtoNDC(xx,u);
11127 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11128 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11129 xx[1] = yaxis->GetXmax();
11130 view->WCtoNDC(xx,u);
11131 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11132 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11133
11134 xx[1] = yaxis->GetXmin();
11135 xx[2] = zaxis->GetBinCenter(binz);
11136 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11137 view->WCtoNDC(xx,u);
11138 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11139 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11140 xx[1] = yaxis->GetXmax();
11141 view->WCtoNDC(xx,u);
11142 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11143 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11144
11145 endface1[0].SetX(line1[0].GetX());
11146 endface1[0].SetY(line1[0].GetY());
11147 endface1[1].SetX(line2[0].GetX());
11148 endface1[1].SetY(line2[0].GetY());
11149 endface1[2].SetX(line3[0].GetX());
11150 endface1[2].SetY(line3[0].GetY());
11151 endface1[3].SetX(line4[0].GetX());
11152 endface1[3].SetY(line4[0].GetY());
11153 endface1[4].SetX(line1[0].GetX());
11154 endface1[4].SetY(line1[0].GetY());
11155
11156 endface2[0].SetX(line1[1].GetX());
11157 endface2[0].SetY(line1[1].GetY());
11158 endface2[1].SetX(line2[1].GetX());
11159 endface2[1].SetY(line2[1].GetY());
11160 endface2[2].SetX(line3[1].GetX());
11161 endface2[2].SetY(line3[1].GetY());
11162 endface2[3].SetX(line4[1].GetX());
11163 endface2[3].SetY(line4[1].GetY());
11164 endface2[4].SetX(line1[1].GetX());
11165 endface2[4].SetY(line1[1].GetY());
11166
11167 gVirtualX->DrawPolyLine(2,line2);
11168 gVirtualX->DrawPolyLine(2,line3);
11169 gVirtualX->DrawPolyLine(2,line4);
11170 gVirtualX->DrawPolyLine(5,endface1);
11171 gVirtualX->DrawPolyLine(5,endface2);
11172 }
11173 c->Clear();
11174 c->cd();
11175 TH1 *hp = h3->Project3D("y");
11176 xaxis->SetRange(firstX,lastX);
11177 zaxis->SetRange(firstZ,lastZ);
11178 if (hp) {
11179 hp->SetFillColor(38);
11180 if (nbins == 1)
11181 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11182 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
11183 else
11184 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),
11185 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
11186 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11187 hp->SetYTitle("Number of Entries");
11188 hp->Draw(fShowOption.Data());
11189 }
11190 }
11191 break;
11192
11193 case 3:
11194 // "z"
11195 {
11196 Int_t firstX = xaxis->GetFirst();
11197 Int_t lastX = xaxis->GetLast();
11198 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
11199 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11200 xaxis->SetRange(binx,binx2);
11201 Int_t firstY = yaxis->GetFirst();
11202 Int_t lastY = yaxis->GetLast();
11203 Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
11204 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11205 yaxis->SetRange(biny,biny2);
11206 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
11207 if (nbins>1 && line1[0].GetX()) {
11208 gVirtualX->DrawPolyLine(2,line2);
11209 gVirtualX->DrawPolyLine(2,line3);
11210 gVirtualX->DrawPolyLine(2,line4);
11211 gVirtualX->DrawPolyLine(5,endface1);
11212 gVirtualX->DrawPolyLine(5,endface2);
11213 }
11214 xx[0] = xaxis->GetBinCenter(binx);
11215 xx[1] = yaxis->GetBinCenter(biny);
11216 xx[2] = zaxis->GetXmin();
11217 view->WCtoNDC(xx,u);
11218 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11219 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11220 xx[2] = zaxis->GetXmax();
11221 view->WCtoNDC(xx,u);
11222 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11223 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11224 gVirtualX->DrawPolyLine(2,line1);
11225 if (nbins>1) {
11226 xx[2] = zaxis->GetXmin();
11227 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11228 xx[0] = xaxis->GetBinCenter(binx);
11229 view->WCtoNDC(xx,u);
11230 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11231 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11232 xx[2] = zaxis->GetXmax();
11233 view->WCtoNDC(xx,u);
11234 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11235 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11236
11237 xx[2] = zaxis->GetXmin();
11238 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11239 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11240 view->WCtoNDC(xx,u);
11241 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11242 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11243 xx[2] = zaxis->GetXmax();
11244 view->WCtoNDC(xx,u);
11245 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11246 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11247
11248 xx[2] = zaxis->GetXmin();
11249 xx[1] = yaxis->GetBinCenter(biny);
11250 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11251 view->WCtoNDC(xx,u);
11252 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11253 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11254 xx[2] = zaxis->GetXmax();
11255 view->WCtoNDC(xx,u);
11256 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11257 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11258
11259 endface1[0].SetX(line1[0].GetX());
11260 endface1[0].SetY(line1[0].GetY());
11261 endface1[1].SetX(line2[0].GetX());
11262 endface1[1].SetY(line2[0].GetY());
11263 endface1[2].SetX(line3[0].GetX());
11264 endface1[2].SetY(line3[0].GetY());
11265 endface1[3].SetX(line4[0].GetX());
11266 endface1[3].SetY(line4[0].GetY());
11267 endface1[4].SetX(line1[0].GetX());
11268 endface1[4].SetY(line1[0].GetY());
11269
11270 endface2[0].SetX(line1[1].GetX());
11271 endface2[0].SetY(line1[1].GetY());
11272 endface2[1].SetX(line2[1].GetX());
11273 endface2[1].SetY(line2[1].GetY());
11274 endface2[2].SetX(line3[1].GetX());
11275 endface2[2].SetY(line3[1].GetY());
11276 endface2[3].SetX(line4[1].GetX());
11277 endface2[3].SetY(line4[1].GetY());
11278 endface2[4].SetX(line1[1].GetX());
11279 endface2[4].SetY(line1[1].GetY());
11280
11281 gVirtualX->DrawPolyLine(2,line2);
11282 gVirtualX->DrawPolyLine(2,line3);
11283 gVirtualX->DrawPolyLine(2,line4);
11284 gVirtualX->DrawPolyLine(5,endface1);
11285 gVirtualX->DrawPolyLine(5,endface2);
11286 }
11287 c->Clear();
11288 c->cd();
11289 TH1 *hp = h3->Project3D("z");
11290 xaxis->SetRange(firstX,lastX);
11291 yaxis->SetRange(firstY,lastY);
11292 if (hp) {
11293 hp->SetFillColor(38);
11294 if (nbins == 1)
11295 hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11296 biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
11297 else
11298 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),
11299 biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
11300 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11301 hp->SetYTitle("Number of Entries");
11302 hp->Draw(fShowOption.Data());
11303 }
11304 }
11305 break;
11306
11307 case 4:
11308 // "xy"
11309 {
11310 Int_t first = zaxis->GetFirst();
11311 Int_t last = zaxis->GetLast();
11312 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11313 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11314 zaxis->SetRange(binz,binz2);
11315 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11316 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11317 xx[0] = xaxis->GetXmin();
11318 xx[1] = yaxis->GetXmax();
11319 xx[2] = zaxis->GetBinCenter(binz);
11320 view->WCtoNDC(xx,u);
11321 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11322 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11323 rect1[4].SetX(rect1[0].GetX());
11324 rect1[4].SetY(rect1[0].GetY());
11325 xx[0] = xaxis->GetXmax();
11326 view->WCtoNDC(xx,u);
11327 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11328 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11329 xx[1] = yaxis->GetXmin();
11330 view->WCtoNDC(xx,u);
11331 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11332 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11333 xx[0] = xaxis->GetXmin();
11334 view->WCtoNDC(xx,u);
11335 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11336 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11337 gVirtualX->DrawPolyLine(5,rect1);
11338 if (nbins>1) {
11339 xx[0] = xaxis->GetXmin();
11340 xx[1] = yaxis->GetXmax();
11341 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11342 view->WCtoNDC(xx,u);
11343 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11344 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11345 rect2[4].SetX(rect2[0].GetX());
11346 rect2[4].SetY(rect2[0].GetY());
11347 xx[0] = xaxis->GetXmax();
11348 view->WCtoNDC(xx,u);
11349 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11350 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11351 xx[1] = yaxis->GetXmin();
11352 view->WCtoNDC(xx,u);
11353 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11354 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11355 xx[0] = xaxis->GetXmin();
11356 view->WCtoNDC(xx,u);
11357 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11358 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11359 gVirtualX->DrawPolyLine(5,rect2);
11360 }
11361
11362 c->Clear();
11363 c->cd();
11364 TH2 *hp = (TH2*)h3->Project3D("xy");
11365 zaxis->SetRange(first,last);
11366 if (hp) {
11367 hp->SetFillColor(38);
11368 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11369 else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11370 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11371 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11372 hp->SetZTitle("Number of Entries");
11373 hp->Draw(fShowOption.Data());
11374 }
11375 }
11376 break;
11377
11378 case 5:
11379 // "yx"
11380 {
11381 Int_t first = zaxis->GetFirst();
11382 Int_t last = zaxis->GetLast();
11383 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11384 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11385 zaxis->SetRange(binz,binz2);
11386 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11387 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11388 xx[0] = xaxis->GetXmin();
11389 xx[1] = yaxis->GetXmax();
11390 xx[2] = zaxis->GetBinCenter(binz);
11391 view->WCtoNDC(xx,u);
11392 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11393 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11394 rect1[4].SetX(rect1[0].GetX());
11395 rect1[4].SetY(rect1[0].GetY());
11396 xx[0] = xaxis->GetXmax();
11397 view->WCtoNDC(xx,u);
11398 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11399 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11400 xx[1] = yaxis->GetXmin();
11401 view->WCtoNDC(xx,u);
11402 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11403 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11404 xx[0] = xaxis->GetXmin();
11405 view->WCtoNDC(xx,u);
11406 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11407 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11408 gVirtualX->DrawPolyLine(5,rect1);
11409 if (nbins>1) {
11410 xx[0] = xaxis->GetXmin();
11411 xx[1] = yaxis->GetXmax();
11412 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11413 view->WCtoNDC(xx,u);
11414 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11415 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11416 rect2[4].SetX(rect2[0].GetX());
11417 rect2[4].SetY(rect2[0].GetY());
11418 xx[0] = xaxis->GetXmax();
11419 view->WCtoNDC(xx,u);
11420 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11421 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11422 xx[1] = yaxis->GetXmin();
11423 view->WCtoNDC(xx,u);
11424 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11425 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11426 xx[0] = xaxis->GetXmin();
11427 view->WCtoNDC(xx,u);
11428 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11429 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11430 gVirtualX->DrawPolyLine(5,rect2);
11431 }
11432 c->Clear();
11433 c->cd();
11434 TH2 *hp = (TH2*)h3->Project3D("yx");
11435 zaxis->SetRange(first,last);
11436 if (hp) {
11437 hp->SetFillColor(38);
11438 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11439 else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11440 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11441 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11442 hp->SetZTitle("Number of Entries");
11443 hp->Draw(fShowOption.Data());
11444 }
11445 }
11446 break;
11447
11448 case 6:
11449 // "xz"
11450 {
11451 Int_t first = yaxis->GetFirst();
11452 Int_t last = yaxis->GetLast();
11453 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11454 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11455 yaxis->SetRange(biny,biny2);
11456 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11457 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11458 xx[0] = xaxis->GetXmin();
11459 xx[2] = zaxis->GetXmax();
11460 xx[1] = yaxis->GetBinCenter(biny);
11461 view->WCtoNDC(xx,u);
11462 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11463 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11464 rect1[4].SetX(rect1[0].GetX());
11465 rect1[4].SetY(rect1[0].GetY());
11466 xx[0] = xaxis->GetXmax();
11467 view->WCtoNDC(xx,u);
11468 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11469 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11470 xx[2] = zaxis->GetXmin();
11471 view->WCtoNDC(xx,u);
11472 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11473 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11474 xx[0] = xaxis->GetXmin();
11475 view->WCtoNDC(xx,u);
11476 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11477 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11478 gVirtualX->DrawPolyLine(5,rect1);
11479 if (nbins>1) {
11480 xx[0] = xaxis->GetXmin();
11481 xx[2] = zaxis->GetXmax();
11482 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11483 view->WCtoNDC(xx,u);
11484 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11485 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11486 rect2[4].SetX(rect2[0].GetX());
11487 rect2[4].SetY(rect2[0].GetY());
11488 xx[0] = xaxis->GetXmax();
11489 view->WCtoNDC(xx,u);
11490 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11491 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11492 xx[2] = zaxis->GetXmin();
11493 view->WCtoNDC(xx,u);
11494 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11495 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11496 xx[0] = xaxis->GetXmin();
11497 view->WCtoNDC(xx,u);
11498 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11499 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11500 gVirtualX->DrawPolyLine(5,rect2);
11501 }
11502 c->Clear();
11503 c->cd();
11504 TH2 *hp = (TH2*)h3->Project3D("xz");
11505 yaxis->SetRange(first,last);
11506 if (hp) {
11507 hp->SetFillColor(38);
11508 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11509 else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11510 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11511 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11512 hp->SetZTitle("Number of Entries");
11513 hp->Draw(fShowOption.Data());
11514 }
11515 }
11516 break;
11517
11518 case 7:
11519 // "zx"
11520 {
11521 Int_t first = yaxis->GetFirst();
11522 Int_t last = yaxis->GetLast();
11523 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11524 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11525 yaxis->SetRange(biny,biny2);
11526 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11527 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11528 xx[0] = xaxis->GetXmin();
11529 xx[2] = zaxis->GetXmax();
11530 xx[1] = yaxis->GetBinCenter(biny);
11531 view->WCtoNDC(xx,u);
11532 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11533 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11534 rect1[4].SetX(rect1[0].GetX());
11535 rect1[4].SetY(rect1[0].GetY());
11536 xx[0] = xaxis->GetXmax();
11537 view->WCtoNDC(xx,u);
11538 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11539 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11540 xx[2] = zaxis->GetXmin();
11541 view->WCtoNDC(xx,u);
11542 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11543 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11544 xx[0] = xaxis->GetXmin();
11545 view->WCtoNDC(xx,u);
11546 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11547 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11548 gVirtualX->DrawPolyLine(5,rect1);
11549 if (nbins>1) {
11550 xx[0] = xaxis->GetXmin();
11551 xx[2] = zaxis->GetXmax();
11552 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11553 view->WCtoNDC(xx,u);
11554 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11555 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11556 rect2[4].SetX(rect2[0].GetX());
11557 rect2[4].SetY(rect2[0].GetY());
11558 xx[0] = xaxis->GetXmax();
11559 view->WCtoNDC(xx,u);
11560 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11561 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11562 xx[2] = zaxis->GetXmin();
11563 view->WCtoNDC(xx,u);
11564 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11565 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11566 xx[0] = xaxis->GetXmin();
11567 view->WCtoNDC(xx,u);
11568 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11569 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11570 gVirtualX->DrawPolyLine(5,rect2);
11571 }
11572 c->Clear();
11573 c->cd();
11574 TH2 *hp = (TH2*)h3->Project3D("zx");
11575 yaxis->SetRange(first,last);
11576 if (hp) {
11577 hp->SetFillColor(38);
11578 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11579 else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11580 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11581 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11582 hp->SetZTitle("Number of Entries");
11583 hp->Draw(fShowOption.Data());
11584 }
11585 }
11586 break;
11587
11588 case 8:
11589 // "yz"
11590 {
11591 Int_t first = xaxis->GetFirst();
11592 Int_t last = xaxis->GetLast();
11593 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11594 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11595 xaxis->SetRange(binx,binx2);
11596 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11597 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11598 xx[2] = zaxis->GetXmin();
11599 xx[1] = yaxis->GetXmax();
11600 xx[0] = xaxis->GetBinCenter(binx);
11601 view->WCtoNDC(xx,u);
11602 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11603 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11604 rect1[4].SetX(rect1[0].GetX());
11605 rect1[4].SetY(rect1[0].GetY());
11606 xx[2] = zaxis->GetXmax();
11607 view->WCtoNDC(xx,u);
11608 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11609 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11610 xx[1] = yaxis->GetXmin();
11611 view->WCtoNDC(xx,u);
11612 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11613 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11614 xx[2] = zaxis->GetXmin();
11615 view->WCtoNDC(xx,u);
11616 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11617 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11618 gVirtualX->DrawPolyLine(5,rect1);
11619 if (nbins>1) {
11620 xx[2] = zaxis->GetXmin();
11621 xx[1] = yaxis->GetXmax();
11622 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11623 view->WCtoNDC(xx,u);
11624 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11625 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11626 rect2[4].SetX(rect2[0].GetX());
11627 rect2[4].SetY(rect2[0].GetY());
11628 xx[2] = zaxis->GetXmax();
11629 view->WCtoNDC(xx,u);
11630 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11631 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11632 xx[1] = yaxis->GetXmin();
11633 view->WCtoNDC(xx,u);
11634 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11635 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11636 xx[2] = zaxis->GetXmin();
11637 view->WCtoNDC(xx,u);
11638 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11639 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11640 gVirtualX->DrawPolyLine(5,rect2);
11641 }
11642 c->Clear();
11643 c->cd();
11644 TH2 *hp = (TH2*)h3->Project3D("yz");
11645 xaxis->SetRange(first,last);
11646 if (hp) {
11647 hp->SetFillColor(38);
11648 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11649 else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11650 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11651 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11652 hp->SetZTitle("Number of Entries");
11653 hp->Draw(fShowOption.Data());
11654 }
11655 }
11656 break;
11657
11658 case 9:
11659 // "zy"
11660 {
11661 Int_t first = xaxis->GetFirst();
11662 Int_t last = xaxis->GetLast();
11663 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11664 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11665 xaxis->SetRange(binx,binx2);
11666 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11667 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11668 xx[2] = zaxis->GetXmin();
11669 xx[1] = yaxis->GetXmax();
11670 xx[0] = xaxis->GetBinCenter(binx);
11671 view->WCtoNDC(xx,u);
11672 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11673 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11674 rect1[4].SetX(rect1[0].GetX());
11675 rect1[4].SetY(rect1[0].GetY());
11676 xx[2] = zaxis->GetXmax();
11677 view->WCtoNDC(xx,u);
11678 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11679 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11680 xx[1] = yaxis->GetXmin();
11681 view->WCtoNDC(xx,u);
11682 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11683 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11684 xx[2] = zaxis->GetXmin();
11685 view->WCtoNDC(xx,u);
11686 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11687 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11688 gVirtualX->DrawPolyLine(5,rect1);
11689 if (nbins>1) {
11690 xx[2] = zaxis->GetXmin();
11691 xx[1] = yaxis->GetXmax();
11692 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11693 view->WCtoNDC(xx,u);
11694 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11695 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11696 rect2[4].SetX(rect2[0].GetX());
11697 rect2[4].SetY(rect2[0].GetY());
11698 xx[2] = zaxis->GetXmax();
11699 view->WCtoNDC(xx,u);
11700 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11701 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11702 xx[1] = yaxis->GetXmin();
11703 view->WCtoNDC(xx,u);
11704 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11705 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11706 xx[2] = zaxis->GetXmin();
11707 view->WCtoNDC(xx,u);
11708 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11709 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11710 gVirtualX->DrawPolyLine(5,rect2);
11711 }
11712 c->Clear();
11713 c->cd();
11714 TH2 *hp = (TH2*)h3->Project3D("zy");
11715 xaxis->SetRange(first,last);
11716 if (hp) {
11717 hp->SetFillColor(38);
11718 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11719 else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11720 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11721 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11722 hp->SetZTitle("Number of Entries");
11723 hp->Draw(fShowOption.Data());
11724 }
11725 }
11726 break;
11727 }
11728 c->Update();
11729 padsav->cd();
11730}
@ 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
@ kArrowVer
Definition GuiTypes.h:374
@ kPointer
Definition GuiTypes.h:375
Handle_t Window_t
Window handle.
Definition GuiTypes.h:29
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 a(i)
Definition RSha256.hxx:99
#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:45
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
short Width_t
Definition RtypesCore.h:91
short Short_t
Definition RtypesCore.h:39
double Double_t
Definition RtypesCore.h:59
short Color_t
Definition RtypesCore.h:92
short Style_t
Definition RtypesCore.h:89
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define BIT(n)
Definition Rtypes.h:85
#define ClassImp(name)
Definition Rtypes.h:364
@ kBlack
Definition Rtypes.h:65
include TDocParser_001 C image html pict1_TDocParser_001 png width
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
XFontStruct * id
Definition TGX11.cxx:109
R__EXTERN TH1 * gCurrentHist
R__EXTERN Hoption_t Hoption
float xmin
int ncx
float ymin
int ncy
float xmax
float ymax
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
const Int_t kCYLINDRICAL
const Int_t kSPHERICAL
const Int_t kRAPIDITY
#define gROOT
Definition TROOT.h:404
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition TStyle.h:413
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
const Int_t kCARTESIAN
Definition TView3D.cxx:33
const Int_t kPOLAR
Definition TView3D.cxx:34
#define gPad
#define gVirtualX
Definition TVirtualX.h:338
polygon * polys
Definition X3DBuffer.c:24
static struct mg_connection * fc(struct mg_context *ctx)
Definition civetweb.c:3728
Int_t fN
Definition TArray.h:38
Draw all kinds of Arrows.
Definition TArrow.h:29
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:36
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:40
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition TAttAxis.h:45
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:43
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition TAttFill.h:39
virtual void SetImageQuality(EImageQuality lquality)
Definition TAttImage.h:99
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
static Style_t GetMarkerStyleBase(Style_t style)
Internal helper function that returns the corresponding marker style with line width 1 for the given ...
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:42
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:43
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition TAttText.h:44
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition TAttText.h:46
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:47
Class to manage histogram axis.
Definition TAxis.h:30
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:126
Bool_t IsAlphanumeric() const
Definition TAxis.h:84
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
Bool_t CanExtend() const
Definition TAxis.h:82
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:440
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:419
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:126
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:469
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition TAxis.cxx:571
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, that is,...
Definition TAxis.cxx:946
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 using bin numbers.
Definition TAxis.cxx:920
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:540
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:458
THashList * GetLabels() const
Definition TAxis.h:117
Create a Box.
Definition TBox.h:22
Double_t GetX1() const
Definition TBox.h:50
virtual void SetY2(Double_t y2)
Definition TBox.h:64
Double_t GetX2() const
Definition TBox.h:51
Double_t GetY1() const
Definition TBox.h:52
virtual void SetX1(Double_t x1)
Definition TBox.h:61
Double_t GetY2() const
Definition TBox.h:53
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition TBox.cxx:195
virtual void SetX2(Double_t x2)
Definition TBox.h:62
virtual void SetY1(Double_t y1)
Definition TBox.h:63
virtual void Paint(Option_t *option="")
Paint this box with its current attributes.
Definition TBox.cxx:669
The candle plot painter class.
Definition TCandle.h:26
void SetLog(int x, int y, int z)
Definition TCandle.h:123
CandleOption
Definition TCandle.h:29
void SetHistoWidth(const Double_t width)
Definition TCandle.h:127
virtual void Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition TCandle.cxx:670
Bool_t IsViolinScaled()
Definition TCandle.cxx:191
Bool_t IsHorizontal()
Definition TCandle.h:117
int ParseOption(char *optin)
Parsing of the option-string.
Definition TCandle.cxx:245
void SetOption(CandleOption opt)
Definition TCandle.h:122
void SetHistogram(TH1D *proj)
Definition TCandle.h:128
Bool_t IsCandleScaled()
Definition TCandle.cxx:186
void SetCandleWidth(const Double_t width)
Definition TCandle.h:126
void SetAxisPosition(const Double_t candlePos)
Definition TCandle.h:124
static Bool_t SupportAlpha()
Static function returning "true" if transparency is supported.
Definition TCanvas.cxx:2489
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:2966
void SetName(const char *name)
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.
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:1758
static void RGBtoHLS(Float_t r, Float_t g, Float_t b, Float_t &h, Float_t &l, Float_t &s)
Definition TColor.h:79
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition TColor.h:52
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:1822
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:1969
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:2001
static void HLStoRGB(Float_t h, Float_t l, Float_t s, Float_t &r, Float_t &g, Float_t &b)
Definition TColor.h:74
virtual void SetAlpha(Float_t a)
Definition TColor.h:68
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:213
virtual Double_t GetXmax() const
Definition TF1.h:556
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:3414
virtual Double_t GetMaximumStored() const
Definition TF1.h:473
@ kNotDraw
Definition TF1.h:326
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:3427
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:1440
virtual Double_t GetXmin() const
Definition TF1.h:552
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:745
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition TF2.h:148
A 3-Dim function with parameters.
Definition TF3.h:28
The axis painter class.
Definition TGaxis.h:23
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition TGaxis.cxx:2776
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:975
void SetTitleOffset(Float_t titleoffset=1)
Definition TGaxis.h:124
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition TGaxis.cxx:2749
void SetLabelOffset(Float_t labeloffset)
Definition TGaxis.h:106
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition TGaxis.cxx:925
void SetTickSize(Float_t ticksize)
Definition TGaxis.h:118
void SetLabelSize(Float_t labelsize)
Definition TGaxis.h:107
void SetOption(Option_t *option="")
To set axis options.
Definition TGaxis.cxx:2741
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 TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
@ kClipFrame
Clip to the frame boundary.
Definition TGraph.h:71
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:618
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:575
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition TH1.cxx:6667
TAxis * GetZaxis()
Definition TH1.h:322
virtual EBinErrorOpt GetBinErrorOption() const
Definition TH1.h:272
virtual Float_t GetBarWidth() const
Definition TH1.h:256
virtual Double_t GetMinimumStored() const
Definition TH1.h:292
virtual Float_t GetBarOffset() const
Definition TH1.h:255
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7482
virtual Int_t GetNbinsY() const
Definition TH1.h:297
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:8893
virtual Int_t GetNbinsZ() const
Definition TH1.h:298
virtual Double_t GetNormFactor() const
Definition TH1.h:300
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:7410
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7546
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8270
virtual void SetXTitle(const char *title)
Definition TH1.h:413
virtual Int_t GetDimension() const
Definition TH1.h:282
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1283
@ kNoTitle
Don't draw the histogram title.
Definition TH1.h:169
@ kUserContour
User specified contour levels.
Definition TH1.h:165
@ kNoStats
Don't draw stats box.
Definition TH1.h:164
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition TH1.h:320
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:4894
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:8375
virtual Int_t GetNbinsX() const
Definition TH1.h:296
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:398
TAxis * GetYaxis()
Definition TH1.h:321
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:8909
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition TH1.cxx:8313
virtual void SetMinimum(Double_t minimum=-1111)
Definition TH1.h:399
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:7816
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:9052
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:8982
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4387
virtual void SetZTitle(const char *title)
Definition TH1.h:415
TList * GetListOfFunctions() const
Definition TH1.h:243
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7450
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition TH1.cxx:3074
virtual Double_t GetMaximumStored() const
Definition TH1.h:288
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8561
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8407
@ kNormal
Errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:64
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:4994
const Double_t * GetBuffer() const
Definition TH1.h:238
virtual Bool_t IsHighlight() const
Definition TH1.h:334
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:8993
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:8940
virtual void SetYTitle(const char *title)
Definition TH1.h:414
virtual Int_t GetSumw2N() const
Definition TH1.h:314
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7530
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:8465
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7792
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:751
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for the axis passed in the option to the number of bins having a label.
Definition TH1.cxx:5178
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8241
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1403
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7619
2-D histogram with a double per channel (see TH1 documentation)}
Definition TH2.h:292
2-D histogram with a float per channel (see TH1 documentation)}
Definition TH2.h:251
Helper class to represent a bin in the TH2Poly histogram.
Definition TH2Poly.h:25
2D Histogram with Polygonal Bins
Definition TH2Poly.h:66
Service class for 2-D 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:2429
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:2389
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH2.cxx:1279
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH2.h:88
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:31
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH3.cxx:1348
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:2362
The histogram painter class.
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
Pointer to Y axis.
Double_t * fXbuf
X buffer coordinates.
Int_t fXHighlightBin
X highlight bin.
TF3 * fCurrentF3
Current TF3 function.
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
Y highlight bin.
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.
Int_t fNcuts
Number of graphical cuts.
TString fShowOption
Option to draw the projection.
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
True if a projection must be drawn.
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
Pointer to histogram list of functions.
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
Y buffer coordinates.
TAxis * fXaxis
Pointer to X axis.
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
Pointer to a TPainter3dAlgorithms object.
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
Pointer to stack of histograms (if any)
TGraph2DPainter * fGraph2DPainter
Pointer to a TGraph2DPainter object.
TPie * fPie
Pointer to a TPie in case of option PIE.
THistPainter()
Default constructor.
TH1 * fH
Pointer to histogram to paint.
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
Pointer to Z axis.
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]
Pointers to graphical cuts.
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]
Sign of each cut.
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
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.
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:35
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()
To draw Mathematical Formula.
Definition TLatex.h:18
A doubly linked list.
Definition TList.h:38
virtual void Add(TObject *obj)
Definition TList.h:81
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition TList.cxx:822
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition TList.cxx:100
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
virtual TObjLink * FirstLink() const
Definition TList.h:102
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:357
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
TMatrixTBase.
TClass * Class()
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition TMultiGraph.h:36
TList * GetListOfGraphs() const
Definition TMultiGraph.h:70
virtual Int_t IsInside(Double_t x, Double_t y) const
Return 1 if the point (x,y) is inside one of the graphs 0 otherwise.
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:31
void Add(TObject *obj)
Definition TObjArray.h:68
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
TObject * At(Int_t idx) const
Definition TObjArray.h:164
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Clear(Option_t *="")
Definition TObject.h:119
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:429
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition TObject.cxx:413
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:393
virtual void Delete(Option_t *option="")
Delete this object.
Definition TObject.cxx:241
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:515
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition TObject.cxx:591
@ kCannotPick
if object in a pad cannot be picked
Definition TObject.h:67
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
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 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.
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.
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)
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)
void ImplicitFunction(TF3 *f3, 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...
The palette painting class.
void SetHistogram(TH1 *h)
virtual void Paint(Option_t *option="")
Paint the palette.
TH1 * GetHistogram()
The histogram statistics painter class.
Definition TPaveStats.h:18
Int_t GetOptStat() const
Return the stat option.
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
void SetOptStat(Int_t stat=1)
Set the stat option.
virtual void SetParent(TObject *obj)
Definition TPaveStats.h:52
virtual const char * GetFitFormat() const
Definition TPaveStats.h:35
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Int_t GetOptFit() const
Return the fit option.
virtual void Paint(Option_t *option="")
Paint the pave stat.
void SetOptFit(Int_t fit=1)
Set the fit option.
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.
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
virtual TText * GetLine(Int_t number) const
Get Pointer to line number in this pavetext.
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
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:803
virtual void ExecuteEvent(Int_t, Int_t, Int_t)
Execute the mouse events.
Definition TPie.cxx:395
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Evaluate the distance to the chart in gPad.
Definition TPie.cxx:170
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...
Double_t * GetY() const
Definition TPolyLine.h:55
Profile2D histograms are used to display the mean value of Z and its error for each cell in X,...
Definition TProfile2D.h:27
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Profile Histogram.
Definition TProfile.h:32
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition TProfile.cxx:833
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:136
Ssiz_t Length() const
Definition TString.h:410
void ToLower()
Change string to lower-case.
Definition TString.cxx:1150
const char * Data() const
Definition TString.h:369
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:2336
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2314
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
Int_t GetOptStat() const
Definition TStyle.h:236
Color_t GetStatTextColor() const
Definition TStyle.h:249
Float_t GetTitleX() const
Definition TStyle.h:271
Int_t GetOptTitle() const
Definition TStyle.h:237
Float_t GetStatFontSize() const
Definition TStyle.h:252
Float_t GetBarOffset() const
Definition TStyle.h:174
Float_t GetStatX() const
Definition TStyle.h:255
Float_t GetTitleSize(Option_t *axis="X") const
Return title size.
Definition TStyle.cxx:1188
Float_t GetTitleY() const
Definition TStyle.h:272
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition TStyle.cxx:1164
Bool_t GetHistMinimumZero() const
Definition TStyle.h:228
Float_t GetStatY() const
Definition TStyle.h:256
Color_t GetTitleFillColor() const
Definition TStyle.h:262
Style_t GetTitleStyle() const
Definition TStyle.h:264
Color_t GetStatColor() const
Definition TStyle.h:248
Float_t GetBarWidth() const
Definition TStyle.h:175
Float_t GetStatH() const
Definition TStyle.h:258
Width_t GetTitleBorderSize() const
Definition TStyle.h:266
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition TStyle.cxx:1056
Float_t GetErrorX() const
Definition TStyle.h:178
Double_t GetHistTopMargin() const
Definition TStyle.h:229
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:319
Float_t GetEndErrorSize() const
Definition TStyle.h:177
Width_t GetStatBorderSize() const
Definition TStyle.h:250
Int_t GetTitleAlign()
Definition TStyle.h:261
Color_t GetTitleTextColor() const
Definition TStyle.h:263
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:320
Float_t GetTitleH() const
Definition TStyle.h:274
Style_t GetStatStyle() const
Definition TStyle.h:253
Float_t GetStatW() const
Definition TStyle.h:257
const char * GetFitFormat() const
Definition TStyle.h:191
const char * GetStatFormat() const
Definition TStyle.h:254
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition TStyle.cxx:1122
Int_t GetOptFit() const
Definition TStyle.h:235
Int_t GetNumberContours() const
Definition TStyle.h:232
const char * GetPaintTextFormat() const
Definition TStyle.h:241
Style_t GetStatFont() const
Definition TStyle.h:251
Float_t GetTitleFontSize() const
Definition TStyle.h:265
Float_t GetTitleW() const
Definition TStyle.h:273
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1855
Base class for several text objects.
Definition TText.h:22
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:51
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
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
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:663
Short_t Max(Short_t a, Short_t b)
Definition TMathBase.h:208
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:614
Double_t ATan(Double_t)
Definition TMath.h:625
constexpr Double_t PiOver2()
Definition TMath.h:51
Double_t Log(Double_t x)
Definition TMath.h:710
constexpr Double_t DegToRad()
Conversion from degree to radian:
Definition TMath.h:81
Double_t Sqrt(Double_t x)
Definition TMath.h:641
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition TMath.h:685
Short_t Min(Short_t a, Short_t b)
Definition TMathBase.h:176
Double_t Cos(Double_t)
Definition TMath.h:593
constexpr Double_t Pi()
Definition TMath.h:37
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition TMath.h:430
Double_t Sin(Double_t)
Definition TMath.h:589
Double_t Tan(Double_t)
Definition TMath.h:597
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition TMathBase.h:274
constexpr Double_t RadToDeg()
Conversion from radian to degree:
Definition TMath.h:73
Double_t Log10(Double_t x)
Definition TMath.h:714
Short_t Abs(Short_t d)
Definition TMathBase.h:120
Definition first.py:1
Definition graph.py:1
Histograms' drawing options structure.
Definition Hoption.h:24
int Curve
"C" A smooth Curve is drawn.
Definition Hoption.h:32
int Proj
"AITOFF", "MERCATOR", "SINUSOIDAL" and "PARABOLIC" projections for 2d plots.
Definition Hoption.h:59
int Axis
"A" Axis are not drawn around the graph.
Definition Hoption.h:30
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition Hoption.h:41
int Scat
"SCAT" Draw 2D plot a Scatter plot.
Definition Hoption.h:48
int Text
"TEXT" Draw 2D plot with the content of each cell.
Definition Hoption.h:50
int Color
"COL" Draw 2D plot with Colored boxes.
Definition Hoption.h:43
int AxisPos
"X+" and "Y+" Axis position
Definition Hoption.h:60
int List
"LIST" Generate the TObjArray "contours". To be used with option "CONT"
Definition Hoption.h:58
int Logx
log scale in X. Also set by histogram option
Definition Hoption.h:70
int Zscale
"Z" Display the color palette.
Definition Hoption.h:55
int MinimumZero
"MIN0" or gStyle->GetHistMinimumZero()
Definition Hoption.h:63
int Contour
"CONTn" Draw 2D plot as a Contour plot (0 <= n <= 5).
Definition Hoption.h:44
int Off
"][" The first and last vertical lines are not drawn.
Definition Hoption.h:35
int Func
"FUNC" Draw only the function (for example in case of fit).
Definition Hoption.h:45
long Candle
"CANDLE" and "VIOLIN" Draw a 2D histogram as candle/box plot or violin plot.
Definition Hoption.h:53
int Spec
"SPEC" TSpectrum graphics
Definition Hoption.h:61
int FrontBox
"FB" Suppress the front box for the 3D plots.
Definition Hoption.h:56
int Pie
"PIE" Draw 1D plot as a pie chart.
Definition Hoption.h:52
int Star
"*" With option "P", a * is plotted at each point.
Definition Hoption.h:39
int Zero
"0" if selected with any LEGO option the empty bins are not drawn.
Definition Hoption.h:62
int Logz
log scale in Z. Also set by histogram option
Definition Hoption.h:72
int Tri
"TRI" Draw TGraph2D with Delaunay triangles.
Definition Hoption.h:51
int BackBox
"BB" Suppress the back box for the 3D plots.
Definition Hoption.h:57
int Mark
"P" The current Marker is drawn at each point.
Definition Hoption.h:37
int Arrow
"ARR" Draw 2D plot with Arrows.
Definition Hoption.h:40
int Line
"L" A simple polyline through every point is drawn.
Definition Hoption.h:36
int Same
"SAME" Histogram is plotted in the current pad.
Definition Hoption.h:38
int Lego
"LEGO" and "LEGOn" Draw as a Lego plot(1 <= n <= 4).
Definition Hoption.h:47
int Bar
"B", "BAR" and "HBAR" A Bar chart is drawn at each point.
Definition Hoption.h:31
int Fill
"F" A fill area is drawn ("CF" draw a smooth fill area).
Definition Hoption.h:34
int Hist
"HIST" Draw only the histogram.
Definition Hoption.h:46
int Surf
"SURF" and "SURFn" Draw as a Surface ((1 <= n <= 4).
Definition Hoption.h:49
int Logy
log scale in Y. Also set by histogram option
Definition Hoption.h:71
int System
"POL", "CYL", "SPH" and "PSR" Type of coordinate system for 3D plots.
Definition Hoption.h:54
int Error
"En" Draw Errors with current marker type and size (0 <= n <=6).
Definition Hoption.h:33
Histogram parameters structure.
Definition Hparam.h:27
Double_t baroffset
Offset of bin for bars or legos [0,1].
Definition Hparam.h:42
Double_t ylowedge
Low edge of axis.
Definition Hparam.h:33
Double_t xmin
Minimum value along X.
Definition Hparam.h:30
Int_t ylast
Last bin number along Y.
Definition Hparam.h:47
Int_t xfirst
First bin number along X.
Definition Hparam.h:44
Double_t zmin
Minimum value along Z.
Definition Hparam.h:38
Double_t xbinsize
Bin size in case of equidistant bins.
Definition Hparam.h:28
Double_t ymin
Minimum value along y.
Definition Hparam.h:34
Double_t allchan
Integrated sum of contents.
Definition Hparam.h:41
Double_t xlowedge
Low edge of axis.
Definition Hparam.h:29
Double_t ymax
Maximum value along y.
Definition Hparam.h:35
Double_t factor
Multiplication factor (normalization)
Definition Hparam.h:40
Int_t xlast
Last bin number along X.
Definition Hparam.h:45
Double_t ybinsize
Bin size in case of equidistant bins.
Definition Hparam.h:32
Double_t barwidth
Width of bin for bars and legos [0,1].
Definition Hparam.h:43
Double_t zmax
Maximum value along Z.
Definition Hparam.h:39
Double_t xmax
Maximum value along X.
Definition Hparam.h:31
Int_t yfirst
First bin number along Y.
Definition Hparam.h:46
auto * th2
Definition textalign.C:17
auto * m
Definition textangle.C:8
auto * tt
Definition textangle.C:16
auto * l
Definition textangle.C:4
#define mark(osub)
Definition triangle.c:1207