Logo ROOT   6.16/01
Reference Guide
THistPainter.cxx
Go to the documentation of this file.
1// @(#)root/histpainter:$Id$
2// Author: Rene Brun, Olivier Couet
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <stdlib.h>
13#include <string.h>
14#include <stdio.h>
15#include <ctype.h>
16
17#include "Riostream.h"
18#include "TROOT.h"
19#include "TClass.h"
20#include "TSystem.h"
21#include "THistPainter.h"
22#include "TH2.h"
23#include "TH2Poly.h"
24#include "TH3.h"
25#include "TProfile.h"
26#include "TProfile2D.h"
27#include "THStack.h"
28#include "TF2.h"
29#include "TF3.h"
30#include "TCutG.h"
31#include "TMatrixDBase.h"
32#include "TMatrixFBase.h"
33#include "TVectorD.h"
34#include "TVectorF.h"
35#include "TCanvas.h"
36#include "TPad.h"
37#include "TPaveStats.h"
38#include "TFrame.h"
39#include "TLatex.h"
40#include "TLine.h"
41#include "TPolyLine.h"
42#include "TPoints.h"
43#include "TStyle.h"
44#include "TGraph.h"
45#include "TMultiGraph.h"
46#include "TPie.h"
47#include "TGaxis.h"
48#include "TColor.h"
50#include "TGraph2DPainter.h"
51#include "TGraphDelaunay2D.h"
52#include "TView.h"
53#include "TMath.h"
54#include "TRandom2.h"
55#include "TObjArray.h"
56#include "TVectorD.h"
57#include "Hoption.h"
58#include "Hparam.h"
59#include "TPluginManager.h"
60#include "TPaletteAxis.h"
61#include "TCrown.h"
62#include "TVirtualPadEditor.h"
63#include "TEnv.h"
64#include "TPoint.h"
65#include "TImage.h"
66#include "TCandle.h"
67
68/*! \class THistPainter
69\ingroup Histpainter
70\brief The histogram painter class. Implements all histograms' drawing's options.
71
72- [Introduction](#HP00)
73- [Histograms' plotting options](#HP01)
74 - [Options supported for 1D and 2D histograms](#HP01a)
75 - [Options supported for 1D histograms](#HP01b)
76 - [Options supported for 2D histograms](#HP01c)
77 - [Options supported for 3D histograms](#HP01d)
78 - [Options supported for histograms' stacks (THStack)](#HP01e)
79- [Setting the Style](#HP02)
80- [Setting line, fill, marker, and text attributes](#HP03)
81- [Setting Tick marks on the histogram axis](#HP04)
82- [Giving titles to the X, Y and Z axis](#HP05)
83- [The option "SAME"](#HP060)
84 - [Limitations](#HP060a)
85- [Colors automatically picked in palette](#HP061)
86- [Superimposing two histograms with different scales in the same pad](#HP06)
87- [Statistics Display](#HP07)
88- [Fit Statistics](#HP08)
89- [The error bars options](#HP09)
90- [The bar chart option](#HP100)
91- [The "BAR" and "HBAR" options](#HP10)
92- [The SCATter plot option (default for 2D histograms)](#HP11)
93- [The ARRow option](#HP12)
94- [The BOX option](#HP13)
95- [The COLor option](#HP14)
96- [The CANDLE and VIOLIN options](#HP140)
97 - [The CANDLE option](#HP140a)
98 - [The VIOLIN option](#HP140b)
99- [The TEXT and TEXTnn Option](#HP15)
100- [The CONTour options](#HP16)
101 - [The LIST option](#HP16a)
102- [The LEGO options](#HP17)
103- [The "SURFace" options](#HP18)
104- [Cylindrical, Polar, Spherical and PseudoRapidity/Phi options](#HP19)
105- [Base line for bar-charts and lego plots](#HP20)
106- [TH2Poly Drawing](#HP20a)
107- [The SPEC option](#HP21)
108- [Option "Z" : Adding the color palette on the right side of the pad](#HP22)
109- [Setting the color palette](#HP23)
110- [Drawing a sub-range of a 2-D histogram; the [cutg] option](#HP24)
111- [Drawing options for 3D histograms](#HP25)
112- [Drawing option for histograms' stacks](#HP26)
113- [Drawing of 3D implicit functions](#HP27)
114- [Associated functions drawing](#HP28)
115- [Drawing using OpenGL](#HP29)
116 - [General information: plot types and supported options](#HP29a)
117 - [TH3 as color boxes](#HP290)
118 - [TH3 as boxes (spheres)](#HP29b)
119 - [TH3 as iso-surface(s)](#HP29c)
120 - [TF3 (implicit function)](#HP29d)
121 - [Parametric surfaces](#HP29e)
122 - [Interaction with the plots](#HP29f)
123 - [Selectable parts](#HP29g)
124 - [Rotation and zooming](#HP29h)
125 - [Panning](#HP29i)
126 - [Box cut](#HP29j)
127 - [Plot specific interactions (dynamic slicing etc.)](#HP29k)
128 - [Surface with option "GLSURF"](#HP29l)
129 - [TF3](#HP29m)
130 - [Box](#HP29n)
131 - [Iso](#HP29o)
132 - [Parametric plot](#HP29p)
133- [Highlight mode for histogram](#HP30)
134 - [Highlight mode and user function](#HP30a)
135
136
137## <a name="HP00"></a> Introduction
138
139
140Histograms are drawn via the `THistPainter` class. Each histogram has a
141pointer to its own painter (to be usable in a multithreaded program). When the
142canvas has to be redrawn, the `Paint` function of each objects in the
143pad is called. In case of histograms, `TH1::Paint` invokes directly
144`THistPainter::Paint`.
145
146To draw a histogram `h` it is enough to do:
147
148 h->Draw();
149
150`h` can be of any kind: 1D, 2D or 3D. To choose how the histogram will
151be drawn, the `Draw()` method can be invoked with an option. For instance
152to draw a 2D histogram as a lego plot it is enough to do:
153
154 h->Draw("lego");
155
156`THistPainter` offers many options to paint 1D, 2D and 3D histograms.
157
158When the `Draw()` method of a histogram is called for the first time
159(`TH1::Draw`), it creates a `THistPainter` object and saves a
160pointer to this "painter" as a data member of the histogram. The
161`THistPainter` class specializes in the drawing of histograms. It is
162separated from the histogram so that one can have histograms without the
163graphics overhead, for example in a batch program. Each histogram having its own
164painter (rather than a central singleton painter painting all histograms), allows
165two histograms to be drawn in two threads without overwriting the painter's
166values.
167
168When a displayed histogram is filled again, there is no need to call the
169`Draw()` method again; the image will be refreshed the next time the
170pad will be updated.
171
172A pad is updated after one of these three actions:
173
1741. a carriage control on the ROOT command line,
1752. a click inside the pad,
1763. a call to `TPad::Update`.
177
178
179By default a call to `TH1::Draw()` clears the pad of all objects
180before drawing the new image of the histogram. One can use the `SAME`
181option to leave the previous display intact and superimpose the new histogram.
182The same histogram can be drawn with different graphics options in different
183pads.
184
185When a displayed histogram is deleted, its image is automatically removed
186from the pad.
187
188To create a copy of the histogram when drawing it, one can use
189`TH1::DrawClone()`. This will clone the histogram and allow to change
190and delete the original one without affecting the clone.
191
192
193### <a name="HP01"></a> Histograms' plotting options
194
195
196Most options can be concatenated with or without spaces or commas, for example:
197
198 h->Draw("E1 SAME");
199
200The options are not case sensitive:
201
202 h->Draw("e1 same");
203
204
205The default drawing option can be set with `TH1::SetOption` and retrieve
206using `TH1::GetOption`:
207
208 root [0] h->Draw(); // Draw "h" using the standard histogram representation.
209 root [1] h->Draw("E"); // Draw "h" using error bars
210 root [3] h->SetOption("E"); // Change the default drawing option for "h"
211 root [4] h->Draw(); // Draw "h" using error bars
212 root [5] h->GetOption(); // Retrieve the default drawing option for "h"
213 (const Option_t* 0xa3ff948)"E"
214
215
216#### <a name="HP01a"></a> Options supported for 1D and 2D histograms
217
218| Option | Description |
219|----------|-------------------------------------------------------------------|
220| "E" | Draw error bars. |
221| "AXIS" | Draw only axis. |
222| "AXIG" | Draw only grid (if the grid is requested). |
223| <a name="OPTHIST">"HIST"</a> | When an histogram has errors it is visualized by default with error bars. To visualize it without errors use the option "HIST" together with the required option (eg "hist same c"). The "HIST" option can also be used to plot only the histogram and not the associated function(s). |
224| "FUNC" | When an histogram has a fitted function, this option allows to draw the fit result only. |
225| "SAME" | Superimpose on previous picture in the same pad. |
226| "PFC" | Palette Fill Color: histogram's fill color is taken in the current palette. |
227| "PLC" | Palette Line Color: histogram's line color is taken in the current palette. |
228| "PMC" | Palette Marker Color: histogram's marker color is taken in the current palette. |
229| "LEGO" | Draw a lego plot with hidden line removal. |
230| "LEGO1" | Draw a lego plot with hidden surface removal. |
231| "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.|
232| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
233| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
234| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
235| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90). |
236| "X+" | The X-axis is drawn on the top side of the plot. |
237| "Y+" | The Y-axis is drawn on the right side of the plot. |
238
239#### <a name="HP01b"></a> Options supported for 1D histograms
240
241| Option | Description |
242|----------|-------------------------------------------------------------------|
243| " " | Default. |
244| "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.|
245| "][" | When this option is selected the first and last vertical lines of the histogram are not drawn.|
246| "B" | Bar chart option.|
247| "BAR" | Like option "B", but bars can be drawn with a 3D effect.|
248| "HBAR" | Like option "BAR", but bars are drawn horizontally.|
249| "C" | Draw a smooth Curve through the histogram bins.|
250| "E0" | Draw error bars. Markers are drawn for bins with 0 contents.|
251| "E1" | Draw error bars with perpendicular lines at the edges.|
252| "E2" | Draw error bars with rectangles.|
253| "E3" | Draw a fill area through the end points of the vertical error bars.|
254| "E4" | Draw a smoothed filled area through the end points of the error bars.|
255| "E5" | Like E3 but ignore the bins with 0 contents.|
256| "E6" | Like E4 but ignore the bins with 0 contents.|
257| "X0" | When used with one of the "E" option, it suppress the error bar along X as `gStyle->SetErrorX(0)` would do.|
258| "L" | Draw a line through the bin contents.|
259| "P" | Draw current marker at each bin except empty bins.|
260| "P0" | Draw current marker at each bin including empty bins.|
261| "PIE" | Draw histogram as a Pie Chart.|
262| "*H" | Draw histogram with a * at each bin.|
263| "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.|
264
265
266#### <a name="HP01c"></a> Options supported for 2D histograms
267
268| Option | Description |
269|-----------|------------------------------------------------------------------|
270| " " | Default (scatter plot).|
271| "ARR" | Arrow mode. Shows gradient between adjacent cells.|
272| "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.|
273| "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.|
274| "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.|
275| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
276| "COL2" | Alternative rendering algorithm to "COL". Can significantly improve rendering performance for large, non-sparse 2-D histograms.|
277| "COLZ2" | Same as "COL2". In addition the color palette is also drawn.|
278| "CANDLE" | Draw a candle plot along X axis.|
279| "CANDLEX" | Same as "CANDLE".|
280| "CANDLEY" | Draw a candle plot along Y axis.|
281| "CANDLEXn"| Draw a candle plot along X axis. Different candle-styles with n from 1 to 6.|
282| "CANDLEYn"| Draw a candle plot along Y axis. Different candle-styles with n from 1 to 6.|
283| "VIOLIN" | Draw a violin plot along X axis.|
284| "VIOLINX" | Same as "VIOLIN".|
285| "VIOLINY" | Draw a violin plot along Y axis.|
286| "VIOLINXn"| Draw a violin plot along X axis. Different violin-styles with n being 1 or 2.|
287| "VIOLINYn"| Draw a violin plot along Y axis. Different violin-styles with n being 1 or 2.|
288| "CONT" | Draw a contour plot (same as CONT0).|
289| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
290| "CONT1" | Draw a contour plot using line styles to distinguish contours.|
291| "CONT2" | Draw a contour plot using the same line style for all contours.|
292| "CONT3" | Draw a contour plot using fill area colors.|
293| "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).|
294| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.|
295| "LIST" | Generate a list of TGraph objects for each contour.|
296| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
297| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
298| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
299| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
300| "SURF" | Draw a surface plot with hidden line removal.|
301| "SURF1" | Draw a surface plot with hidden surface removal.|
302| "SURF2" | Draw a surface plot using colors to show the cell contents.|
303| "SURF3" | Same as SURF with in addition a contour view drawn on the top.|
304| "SURF4" | Draw a surface using Gouraud shading.|
305| "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.|
306| "LEGO9" | Draw the 3D axis only. Mainly needed for internal use |
307| "FB" | With LEGO or SURFACE, suppress the Front-Box.|
308| "BB" | With LEGO or SURFACE, suppress the Back-Box.|
309| "A" | With LEGO or SURFACE, suppress the axis.|
310| "SCAT" | Draw a scatter-plot (default).|
311| "[cutg]" | Draw only the sub-range selected by the TCutG named "cutg".|
312
313
314#### <a name="HP01d"></a> Options supported for 3D histograms
315
316| Option | Description |
317|----------|-------------------------------------------------------------------|
318| " " | Default (scatter plot).|
319| "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)`.|
320| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
321| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
322| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
323| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
324| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
325| "LEGO" | Same as `BOX`.|
326
327
328#### <a name="HP01e"></a> Options supported for histograms' stacks (`THStack`)
329
330| Option | Description |
331|------------|-----------------------------------------------------------------|
332| " " | Default, the histograms are drawn on top of each other (as lego plots for 2D histograms).|
333| "NOSTACK" | Histograms in the stack are all paint in the same pad as if the option `SAME` had been specified.|
334| "NOSTACKB" | Histograms are drawn next to each other as bar charts.|
335| "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.|
336| "PFC" | Palette Fill Color: stack's fill color is taken in the current palette. |
337| "PLC" | Palette Line Color: stack's line color is taken in the current palette. |
338| "PMC" | Palette Marker Color: stack's marker color is taken in the current palette. |
339
340
341
342### <a name="HP02"></a> Setting the Style
343
344
345Histograms use the current style (`gStyle`). When one changes the current
346style and would like to propagate the changes to the histogram,
347`TH1::UseCurrentStyle` should be called. Call `UseCurrentStyle` on
348each histogram is needed.
349
350To force all the histogram to use the current style use:
351
352 gROOT->ForceStyle();
353
354All the histograms read after this call will use the current style.
355
356
357### <a name="HP03"></a> Setting line, fill, marker, and text attributes
358
359
360The histogram classes inherit from the attribute classes:
361`TAttLine`, `TAttFill` and `TAttMarker`.
362See the description of these classes for the list of options.
363
364
365### <a name="HP04"></a> Setting Tick marks on the histogram axis
366
367
368The `TPad::SetTicks` method specifies the type of tick marks on the axis.
369If ` tx = gPad->GetTickx()` and `ty = gPad->GetTicky()` then:
370
371 tx = 1; tick marks on top side are drawn (inside)
372 tx = 2; tick marks and labels on top side are drawn
373 ty = 1; tick marks on right side are drawn (inside)
374 ty = 2; tick marks and labels on right side are drawn
375
376By default only the left Y axis and X bottom axis are drawn
377(`tx = ty = 0`)
378
379`TPad::SetTicks(tx,ty)` allows to set these options.
380See also The `TAxis` functions to set specific axis attributes.
381
382In case multiple color filled histograms are drawn on the same pad, the fill
383area may hide the axis tick marks. One can force a redraw of the axis over all
384the histograms by calling:
385
386 gPad->RedrawAxis();
387
388
389### <a name="HP05"></a> Giving titles to the X, Y and Z axis
390
391
392 h->GetXaxis()->SetTitle("X axis title");
393 h->GetYaxis()->SetTitle("Y axis title");
394
395The histogram title and the axis titles can be any `TLatex` string.
396The titles are part of the persistent histogram.
397
398
399### <a name="HP060"></a> The option "SAME"
400
401
402By default, when an histogram is drawn, the current pad is cleared before
403drawing. In order to keep the previous drawing and draw on top of it the
404option `SAME` should be use. The histogram drawn with the option
405`SAME` uses the coordinates system available in the current pad.
406
407This option can be used alone or combined with any valid drawing option but
408some combinations must be use with care.
409
410#### <a name="HP060a"></a> Limitations
411
412- It does not work when combined with the `LEGO` and `SURF` options unless the
413 histogram plotted with the option `SAME` has exactly the same
414 ranges on the X, Y and Z axis as the currently drawn histogram. To superimpose
415 lego plots [histograms' stacks](#HP26) should be used.</li>
416
417
418### <a name="HP061"></a> Colors automatically picked in palette
419
420\since **ROOT version 6.09/01**
421
422When several histograms are painted in the same canvas thanks to the option "SAME"
423or via a `THStack` it might be useful to have an easy and automatic way to choose
424their color. The simplest way is to pick colors in the current active color
425palette. Palette coloring for histogram is activated thanks to the options `PFC`
426(Palette Fill Color), `PLC` (Palette Line Color) and `PMC` (Palette Marker Color).
427When one of these options is given to `TH1::Draw` the histogram get its color
428from the current color palette defined by `gStyle->SetPalette(…)`. The color
429is determined according to the number of objects having palette coloring in
430the current pad.
431
432Begin_Macro(source)
433../../../tutorials/hist/histpalettecolor.C
434End_Macro
435
436Begin_Macro(source)
437../../../tutorials/hist/thstackpalettecolor.C
438End_Macro
439
440Begin_Macro(source)
441../../../tutorials/hist/thstack2palettecolor.C
442End_Macro
443
444### <a name="HP06"></a> Superimposing two histograms with different scales in the same pad
445
446
447The following example creates two histograms, the second histogram is the bins
448integral of the first one. It shows a procedure to draw the two histograms in
449the same pad and it draws the scale of the second histogram using a new vertical
450axis on the right side. See also the tutorial `transpad.C` for a variant
451of this example.
452
453Begin_Macro(source)
454{
455 TCanvas *c1 = new TCanvas("c1","c1",600,400);
456 // create/fill draw h1
457 gStyle->SetOptStat(kFALSE);
458 TH1F *h1 = new TH1F("h1","Superimposing two histograms with different scales",100,-3,3);
459 Int_t i;
460 for (i=0;i<10000;i++) h1->Fill(gRandom->Gaus(0,1));
461 h1->Draw();
462 c1->Update();
463
464 // create hint1 filled with the bins integral of h1
465 TH1F *hint1 = new TH1F("hint1","h1 bins integral",100,-3,3);
466 Float_t sum = 0;
467 for (i=1;i<=100;i++) {
468 sum += h1->GetBinContent(i);
469 hint1->SetBinContent(i,sum);
470 }
471
472 // scale hint1 to the pad coordinates
473 Float_t rightmax = 1.1*hint1->GetMaximum();
474 Float_t scale = gPad->GetUymax()/rightmax;
475 hint1->SetLineColor(kRed);
476 hint1->Scale(scale);
477 hint1->Draw("same");
478
479 // draw an axis on the right side
480 TGaxis *axis = new TGaxis(gPad->GetUxmax(),gPad->GetUymin(),
481 gPad->GetUxmax(), gPad->GetUymax(),0,rightmax,510,"+L");
482 axis->SetLineColor(kRed);
483 axis->SetTextColor(kRed);
484 axis->Draw();
485 return c1;
486}
487End_Macro
488
489
490### <a name="HP07"></a> Statistics Display
491
492
493The type of information shown in the histogram statistics box can be selected
494with:
495
496 gStyle->SetOptStat(mode);
497
498The `mode` has up to nine digits that can be set to on (1 or 2), off (0).
499
500 mode = ksiourmen (default = 000001111)
501 k = 1; kurtosis printed
502 k = 2; kurtosis and kurtosis error printed
503 s = 1; skewness printed
504 s = 2; skewness and skewness error printed
505 i = 1; integral of bins printed
506 i = 2; integral of bins with option "width" printed
507 o = 1; number of overflows printed
508 u = 1; number of underflows printed
509 r = 1; standard deviation printed
510 r = 2; standard deviation and standard deviation error printed
511 m = 1; mean value printed
512 m = 2; mean and mean error values printed
513 e = 1; number of entries printed
514 n = 1; name of histogram is printed
515
516For example:
517
518 gStyle->SetOptStat(11);
519
520displays only the name of histogram and the number of entries, whereas:
521
522 gStyle->SetOptStat(1101);
523
524displays the name of histogram, mean value and standard deviation.
525
526<b>WARNING 1:</b> never do:
527
528 gStyle->SetOptStat(0001111);
529
530but instead do:
531
532 gStyle->SetOptStat(1111);
533
534because `0001111` will be taken as an octal number!
535
536<b>WARNING 2:</b> for backward compatibility with older versions
537
538 gStyle->SetOptStat(1);
539
540is taken as:
541
542 gStyle->SetOptStat(1111)
543
544To print only the name of the histogram do:
545
546 gStyle->SetOptStat(1000000001);
547
548<b>NOTE</b> that in case of 2D histograms, when selecting only underflow
549(10000) or overflow (100000), the statistics box will show all combinations
550of underflow/overflows and not just one single number.
551
552The parameter mode can be any combination of the letters `kKsSiIourRmMen`
553
554 k : kurtosis printed
555 K : kurtosis and kurtosis error printed
556 s : skewness printed
557 S : skewness and skewness error printed
558 i : integral of bins printed
559 I : integral of bins with option "width" printed
560 o : number of overflows printed
561 u : number of underflows printed
562 r : standard deviation printed
563 R : standard deviation and standard deviation error printed
564 m : mean value printed
565 M : mean value mean error values printed
566 e : number of entries printed
567 n : name of histogram is printed
568
569For example, to print only name of histogram and number of entries do:
570
571 gStyle->SetOptStat("ne");
572
573To print only the name of the histogram do:
574
575 gStyle->SetOptStat("n");
576
577The default value is:
578
579 gStyle->SetOptStat("nemr");
580
581When a histogram is painted, a `TPaveStats` object is created and added
582to the list of functions of the histogram. If a `TPaveStats` object
583already exists in the histogram list of functions, the existing object is just
584updated with the current histogram parameters.
585
586Once a histogram is painted, the statistics box can be accessed using
587`h->FindObject("stats")`. In the command line it is enough to do:
588
589 Root > h->Draw()
590 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
591
592because after `h->Draw()` the histogram is automatically painted. But
593in a script file the painting should be forced using `gPad->Update()`
594in order to make sure the statistics box is created:
595
596 h->Draw();
597 gPad->Update();
598 TPaveStats *st = (TPaveStats*)h->FindObject("stats");
599
600Without `gPad->Update()` the line `h->FindObject("stats")` returns a null pointer.
601
602When a histogram is drawn with the option `SAME`, the statistics box
603is not drawn. To force the statistics box drawing with the option
604`SAME`, the option `SAMES` must be used.
605If the new statistics box hides the previous statistics box, one can change
606its position with these lines (`h` being the pointer to the histogram):
607
608 Root > TPaveStats *st = (TPaveStats*)h->FindObject("stats")
609 Root > st->SetX1NDC(newx1); //new x start position
610 Root > st->SetX2NDC(newx2); //new x end position
611
612To change the type of information for an histogram with an existing
613`TPaveStats` one should do:
614
615 st->SetOptStat(mode);
616
617Where `mode` has the same meaning than when calling `gStyle->SetOptStat(mode)`
618(see above).
619
620One can delete the statistics box for a histogram `TH1* h` with:
621
622 h->SetStats(0)
623
624and activate it again with:
625
626 h->SetStats(1).
627
628Labels used in the statistics box ("Mean", "Std Dev", ...) can be changed from
629`$ROOTSYS/etc/system.rootrc` or `.rootrc` (look for the string `Hist.Stats.`).
630
631
632### <a name="HP08"></a> Fit Statistics
633
634
635The type of information about fit parameters printed in the histogram statistics
636box can be selected via the parameter mode. The parameter mode can be
637`= pcev` (default `= 0111`)
638
639 p = 1; print Probability
640 c = 1; print Chisquare/Number of degrees of freedom
641 e = 1; print errors (if e=1, v must be 1)
642 v = 1; print name/values of parameters
643
644Example:
645
646 gStyle->SetOptFit(1011);
647
648print fit probability, parameter names/values and errors.
649
6501. When `v" = 1` is specified, only the non-fixed parameters are shown.
6512. When `v" = 2` all parameters are shown.
652
653Note: `gStyle->SetOptFit(1)` means "default value", so it is equivalent
654to `gStyle->SetOptFit(111)`
655
656
657### <a name="HP09"></a> The error bars options
658
659
660| Option | Description |
661|----------|-------------------------------------------------------------------|
662| "E" | Default. Shows only the error bars, not a marker.|
663| "E1" | Small lines are drawn at the end of the error bars.|
664| "E2" | Error rectangles are drawn.|
665| "E3" | A filled area is drawn through the end points of the vertical error bars.|
666| "E4" | A smoothed filled area is drawn through the end points of the vertical error bars.|
667| "E0" | Draw also bins with null contents.|
668
669Begin_Macro(source)
670{
671 TCanvas *c1 = new TCanvas("c1","c1",600,400);
672 TH1F *he = new TH1F("he","Distribution drawn with error bars (option E1) ",100,-3,3);
673 Int_t i;
674 for (i=0;i<10000;i++) he->Fill(gRandom->Gaus(0,1));
675 gStyle->SetEndErrorSize(3);
676 gStyle->SetErrorX(1.);
677 he->SetMarkerStyle(20);
678 he->Draw("E1");
679 return c1;
680}
681End_Macro
682
683The options "E3" and "E4" draw an error band through the end points of the
684vertical error bars. With "E4" the error band is smoothed. Because of the
685smoothing algorithm used some artefacts may appear at the end of the band
686like in the following example. In such cases "E3" should be used instead
687of "E4".
688
689Begin_Macro(source)
690{
691 TCanvas *ce4 = new TCanvas("ce4","ce4",600,400);
692 ce4->Divide(2,1);
693 TH1F *he4 = new TH1F("he4","Distribution drawn with option E4",100,-3,3);
694 Int_t i;
695 for (i=0;i<10000;i++) he4->Fill(gRandom->Gaus(0,1));
696 he4->SetFillColor(kRed);
697 he4->GetXaxis()->SetRange(40,48);
698 ce4->cd(1);
699 he4->Draw("E4");
700 ce4->cd(2);
701 TH1F *he3 = (TH1F*)he4->DrawClone("E3");
702 he3->SetTitle("Distribution drawn option E3");
703 return ce4;
704}
705End_Macro
706
7072D histograms can be drawn with error bars as shown is the following example:
708
709Begin_Macro(source)
710{
711 TCanvas *c2e = new TCanvas("c2e","c2e",600,400);
712 TH2F *h2e = new TH2F("h2e","TH2 drawn with option E",40,-4,4,40,-20,20);
713 Float_t px, py;
714 for (Int_t i = 0; i < 25000; i++) {
715 gRandom->Rannor(px,py);
716 h2e->Fill(px,5*py);
717 }
718 h2e->Draw("E");
719 return c2e;
720}
721End_Macro
722
723
724### <a name="HP100"></a> The bar chart option
725
726
727The option "B" allows to draw simple vertical bar charts.
728The bar width is controlled with `TH1::SetBarWidth()`,
729and the bar offset within the bin, with `TH1::SetBarOffset()`.
730These two settings are useful to draw several histograms on the
731same plot as shown in the following example:
732
733Begin_Macro(source)
734{
735 int i;
736 const Int_t nx = 8;
737 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
738 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
739 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
740
741 TCanvas *cb = new TCanvas("cb","cb",600,400);
742 cb->SetGrid();
743
744 gStyle->SetHistMinimumZero();
745
746 TH1F *h1b = new TH1F("h1b","Option B example",nx,0,nx);
747 h1b->SetFillColor(4);
748 h1b->SetBarWidth(0.4);
749 h1b->SetBarOffset(0.1);
750 h1b->SetStats(0);
751 h1b->SetMinimum(-5);
752 h1b->SetMaximum(5);
753
754 for (i=1; i<=nx; i++) {
755 h1b->SetBinContent(i, d_35_0[i-1]);
756 h1b->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
757 }
758
759 h1b->Draw("b");
760
761 TH1F *h2b = new TH1F("h2b","h2b",nx,0,nx);
762 h2b->SetFillColor(38);
763 h2b->SetBarWidth(0.4);
764 h2b->SetBarOffset(0.5);
765 h2b->SetStats(0);
766 for (i=1;i<=nx;i++) h2b->SetBinContent(i, d_35_1[i-1]);
767
768 h2b->Draw("b same");
769
770 return cb;
771}
772End_Macro
773
774
775### <a name="HP10"></a> The "BAR" and "HBAR" options
776
777
778When the option `bar` or `hbar` is specified, a bar chart is drawn. A vertical
779bar-chart is drawn with the options `bar`, `bar0`, `bar1`, `bar2`, `bar3`, `bar4`.
780An horizontal bar-chart is drawn with the options `hbar`, `hbar0`, `hbar1`,
781`hbar2`, `hbar3`, `hbar4` (hbars.C).
782
783- The bar is filled with the histogram fill color.
784- The left side of the bar is drawn with a light fill color.
785- The right side of the bar is drawn with a dark fill color.
786- The percentage of the bar drawn with either the light or dark color is:
787 - 0% for option "(h)bar" or "(h)bar0"
788 - 10% for option "(h)bar1"
789 - 20% for option "(h)bar2"
790 - 30% for option "(h)bar3"
791 - 40% for option "(h)bar4"
792
793When an histogram has errors the option ["HIST"](#OPTHIST) together with the `(h)bar` option.
794
795Begin_Macro(source)
796../../../tutorials/hist/hbars.C
797End_Macro
798
799To control the bar width (default is the bin width) `TH1::SetBarWidth()`
800should be used.
801
802To control the bar offset (default is 0) `TH1::SetBarOffset()` should
803be used.
804
805These two parameters are useful when several histograms are plotted using
806the option `SAME`. They allow to plot the histograms next to each other.
807
808
809### <a name="HP11"></a> The SCATter plot option (default for 2D histograms)
810
811
812For each cell (i,j) a number of points proportional to the cell content is
813drawn. A maximum of `kNMAX` points per cell is drawn. If the maximum is above
814`kNMAX` contents are normalized to `kNMAX` (`kNMAX=2000`).
815If option is of the form `scat=ff`, (eg `scat=1.8`,
816`scat=1e-3`), then `ff` is used as a scale factor to compute the
817number of dots. `scat=1` is the default.
818
819By default the scatter plot is painted with a "dot marker" which not scalable
820(see the `TAttMarker` documentation). To change the marker size, a scalable marker
821type should be used. For instance a circle (marker style 20).
822
823Begin_Macro(source)
824{
825 TCanvas *c1 = new TCanvas("c1","c1",600,400);
826 TH2F *hscat = new TH2F("hscat","Option SCATter example (default for 2D histograms) ",40,-4,4,40,-20,20);
827 Float_t px, py;
828 for (Int_t i = 0; i < 25000; i++) {
829 gRandom->Rannor(px,py);
830 hscat->Fill(px,5*py);
831 hscat->Fill(3+0.5*px,2*py-10.);
832 }
833 hscat->Draw("scat=0.5");
834 return c1;
835}
836End_Macro
837
838
839### <a name="HP12"></a> The ARRow option
840
841
842Shows gradient between adjacent cells. For each cell (i,j) an arrow is drawn
843The orientation of the arrow follows the cell gradient.
844
845Begin_Macro(source)
846{
847 TCanvas *c1 = new TCanvas("c1","c1",600,400);
848 TH2F *harr = new TH2F("harr","Option ARRow example",20,-4,4,20,-20,20);
849 Float_t px, py;
850 for (Int_t i = 0; i < 25000; i++) {
851 gRandom->Rannor(px,py);
852 harr->Fill(px,5*py);
853 harr->Fill(3+0.5*px,2*py-10.,0.1);
854 }
855 harr->Draw("ARR");
856 return c1;
857}
858End_Macro
859
860
861### <a name="HP13"></a> The BOX option
862
863
864For each cell (i,j) a box is drawn. The size (surface) of the box is
865proportional to the absolute value of the cell content.
866The cells with a negative content are drawn with a `X` on top of the box.
867
868Begin_Macro(source)
869{
870 TCanvas *c1 = new TCanvas("c1","c1",600,400);
871 hbox = new TH2F("hbox","Option BOX example",3,0,3,3,0,3);
872 hbox->SetFillColor(42);
873 hbox->Fill(0.5, 0.5, 1.);
874 hbox->Fill(0.5, 1.5, 4.);
875 hbox->Fill(0.5, 2.5, 3.);
876 hbox->Fill(1.5, 0.5, 2.);
877 hbox->Fill(1.5, 1.5, 12.);
878 hbox->Fill(1.5, 2.5, -6.);
879 hbox->Fill(2.5, 0.5, -4.);
880 hbox->Fill(2.5, 1.5, 6.);
881 hbox->Fill(2.5, 2.5, 0.5);
882 hbox->Draw("BOX");
883 return c1;
884}
885End_Macro
886
887With option `BOX1` a button is drawn for each cell with surface
888proportional to content's absolute value. A sunken button is drawn for
889negative values a raised one for positive.
890
891Begin_Macro(source)
892{
893 TCanvas *c1 = new TCanvas("c1","c1",600,400);
894 hbox1 = new TH2F("hbox1","Option BOX1 example",3,0,3,3,0,3);
895 hbox1->SetFillColor(42);
896 hbox1->Fill(0.5, 0.5, 1.);
897 hbox1->Fill(0.5, 1.5, 4.);
898 hbox1->Fill(0.5, 2.5, 3.);
899 hbox1->Fill(1.5, 0.5, 2.);
900 hbox1->Fill(1.5, 1.5, 12.);
901 hbox1->Fill(1.5, 2.5, -6.);
902 hbox1->Fill(2.5, 0.5, -4.);
903 hbox1->Fill(2.5, 1.5, 6.);
904 hbox1->Fill(2.5, 2.5, 0.5);
905 hbox1->Draw("BOX1");
906 return c1;
907}
908End_Macro
909
910When the option `SAME` (or "SAMES") is used with the option `BOX`,
911the boxes' sizes are computing taking the previous plots into account. The range
912along the Z axis is imposed by the first plot (the one without option
913`SAME`); therefore the order in which the plots are done is relevant.
914
915Begin_Macro(source)
916{
917 TCanvas *c1 = new TCanvas("c1","c1",600,400);
918 TH2F *hb1 = new TH2F("hb1","Example of BOX plots with option SAME ",40,-3,3,40,-3,3);
919 TH2F *hb2 = new TH2F("hb2","hb2",40,-3,3,40,-3,3);
920 TH2F *hb3 = new TH2F("hb3","hb3",40,-3,3,40,-3,3);
921 TH2F *hb4 = new TH2F("hb4","hb4",40,-3,3,40,-3,3);
922 for (Int_t i=0;i<1000;i++) {
923 double x,y;
924 gRandom->Rannor(x,y);
925 if (x>0 && y>0) hb1->Fill(x,y,4);
926 if (x<0 && y<0) hb2->Fill(x,y,3);
927 if (x>0 && y<0) hb3->Fill(x,y,2);
928 if (x<0 && y>0) hb4->Fill(x,y,1);
929 }
930 hb1->SetFillColor(1);
931 hb2->SetFillColor(2);
932 hb3->SetFillColor(3);
933 hb4->SetFillColor(4);
934 hb1->Draw("box");
935 hb2->Draw("box same");
936 hb3->Draw("box same");
937 hb4->Draw("box same");
938 return c1;
939}
940End_Macro
941
942
943### <a name="HP14"></a> The COLor option
944
945
946For each cell (i,j) a box is drawn with a color proportional to the cell
947content.
948
949The color table used is defined in the current style.
950
951If the histogram's minimum and maximum are the same (flat histogram), the
952mapping on colors is not possible, therefore nothing is painted. To paint a
953flat histogram it is enough to set the histogram minimum
954(`TH1::SetMinimum()`) different from the bins' content.
955
956The default number of color levels used to paint the cells is 20.
957It can be changed with `TH1::SetContour()` or
958`TStyle::SetNumberContours()`. The higher this number is, the smoother
959is the color change between cells.
960
961The color palette in TStyle can be modified via `gStyle->SetPalette()`.
962
963All the non-empty bins are painted. Empty bins are not painted unless
964some bins have a negative content because in that case the null bins
965might be not empty.
966
967`TProfile2D` histograms are handled differently because, for this type of 2D
968histograms, it is possible to know if an empty bin has been filled or not. So even
969if all the bins' contents are positive some empty bins might be painted. And vice versa,
970if some bins have a negative content some empty bins might be not painted.
971
972Combined with the option `COL`, the option `Z` allows to
973display the color palette defined by `gStyle->SetPalette()`.
974
975In the following example, the histogram has only positive bins; the empty
976bins (containing 0) are not drawn.
977
978Begin_Macro(source)
979{
980 TCanvas *c1 = new TCanvas("c1","c1",600,400);
981 TH2F *hcol1 = new TH2F("hcol1","Option COLor example ",40,-4,4,40,-20,20);
982 Float_t px, py;
983 for (Int_t i = 0; i < 25000; i++) {
984 gRandom->Rannor(px,py);
985 hcol1->Fill(px,5*py);
986 }
987 hcol1->Draw("COLZ");
988 return c1;
989}
990End_Macro
991
992In the first plot of following example, the histogram has some negative bins;
993the empty bins (containing 0) are drawn. In some cases one wants to not draw
994empty bins (containing 0) of histograms having a negative minimum. The option
995`1`, used to produce the second plot in the following picture, allows to do that.
996
997Begin_Macro(source)
998{
999 TCanvas *c1 = new TCanvas("c1","c1",600,600);
1000 c1->Divide(1,2);
1001 TH2F *hcol23 = new TH2F("hcol2","Option COLZ example ",40,-4,4,40,-20,20);
1002 TH2F *hcol24 = new TH2F("hcol2","Option COLZ1 example ",40,-4,4,40,-20,20);
1003 Float_t px, py;
1004 for (Int_t i = 0; i < 25000; i++) {
1005 gRandom->Rannor(px,py);
1006 hcol23->Fill(px,5*py);
1007 hcol24->Fill(px,5*py);
1008 }
1009 hcol23->Fill(0.,0.,-200.);
1010 hcol24->Fill(0.,0.,-200.);
1011 c1->cd(1); hcol23->Draw("COLZ");
1012 c1->cd(2); hcol24->Draw("COLZ1");
1013 return c1;
1014}
1015End_Macro
1016
1017When the maximum of the histogram is set to a smaller value than the real maximum,
1018 the bins having a content between the new maximum and the real maximum are
1019painted with the color corresponding to the new maximum.
1020
1021When the minimum of the histogram is set to a greater value than the real minimum,
1022 the bins having a value between the real minimum and the new minimum are not drawn
1023 unless the option `0` is set.
1024
1025The following example illustrates the option `0` combined with the option `COL`.
1026
1027Begin_Macro(source)
1028{
1029 TCanvas *c1 = new TCanvas("c1","c1",600,600);
1030 c1->Divide(1,2);
1031 TH2F *hcol21 = new TH2F("hcol21","Option COLZ",40,-4,4,40,-20,20);
1032 TH2F *hcol22 = new TH2F("hcol22","Option COLZ0",40,-4,4,40,-20,20);
1033 Float_t px, py;
1034 for (Int_t i = 0; i < 25000; i++) {
1035 gRandom->Rannor(px,py);
1036 hcol21->Fill(px,5*py);
1037 hcol22->Fill(px,5*py);
1038 }
1039 hcol21->SetBit(TH1::kNoStats);
1040 hcol22->SetBit(TH1::kNoStats);
1041 c1->cd(1); hcol21->Draw("COLZ");
1042 c1->cd(2); hcol22->Draw("COLZ0");
1043 hcol22->SetMaximum(100);
1044 hcol22->SetMinimum(40);
1045 return c1;
1046}
1047End_Macro
1048
1049\since **ROOT version 6.09/01:**
1050
1051When the option SAME (or "SAMES") is used with the option COL, the boxes' color
1052are computing taking the previous plots into account. The range along the Z axis
1053is imposed by the first plot (the one without option SAME); therefore the order
1054in which the plots are done is relevant.
1055
1056Begin_Macro(source)
1057{
1058 c = new TCanvas("c","Example of col plots with option SAME",200,10,700,500);
1059 TH2F *h1 = new TH2F("h1","h1",40,-3,3,40,-3,3);
1060 TH2F *h2 = new TH2F("h2","h2",40,-3,3,40,-3,3);
1061 TH2F *h3 = new TH2F("h3","h3",40,-3,3,40,-3,3);
1062 TH2F *h4 = new TH2F("h4","h4",40,-3,3,40,-3,3);
1063 h1->SetBit(TH1::kNoStats);
1064 for (Int_t i=0;i<5000;i++) {
1065 double x,y;
1066 gRandom->Rannor(x,y);
1067 if(x>0 && y>0) h1->Fill(x,y,4);
1068 if(x<0 && y<0) h2->Fill(x,y,3);
1069 if(x>0 && y<0) h3->Fill(x,y,2);
1070 if(x<0 && y>0) h4->Fill(x,y,1);
1071 }
1072 h1->Draw("colz");
1073 h2->Draw("col same");
1074 h3->Draw("col same");
1075 h4->Draw("col same");
1076}
1077End_Macro
1078
1079The option `COL` can be combined with the option `POL`:
1080
1081Begin_Macro(source)
1082{
1083 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1084 TH2F *hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
1085 Float_t px, py;
1086 for (Int_t i = 0; i < 25000; i++) {
1087 gRandom->Rannor(px,py);
1088 hcol1->Fill(px,py);
1089 }
1090 hcol1->Draw("COLZPOL");
1091 return c1;
1092}
1093End_Macro
1094
1095\since **ROOT version 6.07/03:**
1096
1097A second rendering technique is also available with the COL2 and COLZ2 options.
1098
1099These options provide potential performance improvements compared to the standard
1100COL option. The performance comparison of the COL2 to the COL option depends on
1101the histogram and the size of the rendering region in the current pad. In general,
1102a small (approx. less than 100 bins per axis), sparsely populated TH2 will render
1103faster with the COL option.
1104
1105However, for larger histograms (approx. more than 100 bins per axis)
1106that are not sparse, the COL2 option will provide up to 20 times performance improvements.
1107For example, a 1000x1000 bin TH2 that is not sparse will render an order of magnitude
1108faster with the COL2 option.
1109
1110The COL2 option will also scale its performance based on the size of the
1111pixmap the histogram image is being rendered into. It also is much better optimized for
1112sessions where the user is forwarding X11 windows through an `ssh` connection.
1113
1114For the most part, the COL2 and COLZ2 options are a drop in replacement to the COL
1115and COLZ options. There is one major difference and that concerns the treatment of
1116bins with zero content. The COL2 and COLZ2 options color these bins the color of zero.
1117
1118COL2 option renders the histogram as a bitmap. Therefore it cannot be saved in vector
1119graphics file format like PostScript or PDF (an empty image will be generated). It can
1120be saved only in bitmap files like PNG format for instance.
1121
1122
1123### <a name="HP140"></a> The CANDLE and VIOLIN options
1124
1125The mechanism behind Candle plots and Violin plots is very similar. Because of this they are
1126implemented in the same class TCandle. The keywords CANDLE or VIOLIN will initiate the drawing of
1127the corresponding plots. Followed by the keyword the user can select a plot direction (X or V for
1128vertical projections, or Y or H for horizontal projections) and/or predefined definitions
1129(1-6 for candles, 1-2 for violins). The order doesn't matter. Default is X and 1.
1130
1131Instead of using the predefined representations, the candle and violin parameters can be
1132changed individually. In that case the option have the following form:
1133
1134 CANDLEX(<option-string>)
1135 CANDLEY(<option-string>)
1136 VIOLINX(<option-string>)
1137 VIOLINY(<option-string>).
1138
1139All zeros at the beginning of `option-string` can be omitted.
1140
1141`option-string` consists eight values, defined as follow:
1142
1143 "CANDLEX(zhpawMmb)"
1144
1145Where:
1146
1147 - `b = 0`; no box drawn
1148 - `b = 1`; the box is drawn. As the candle-plot is also called a box-plot it
1149 makes sense in the very most cases to always draw the box
1150 - `b = 2`; draw a filled box with border
1151
1152 - `m = 0`; no median drawn
1153 - `m = 1`; median is drawn as a line
1154 - `m = 2`; median is drawn with errors (notches)
1155 - `m = 3`; median is drawn as a circle
1156
1157 - `M = 0`; no mean drawn
1158 - `M = 1`; mean is drawn as a dashed line
1159 - `M = 3`; mean is drawn as a circle
1160
1161 - `w = 0`; no whisker drawn
1162 - `w = 1`; whisker is drawn to end of distribution.
1163 - `w = 2`; whisker is drawn to max 1.5*iqr
1164
1165 - `a = 0`; no anchor drawn
1166 - `a = 1`; the anchors are drawn
1167
1168 - `p = 0`; no points drawn
1169 - `p = 1`; only outliers are drawn
1170 - `p = 2`; all datapoints are drawn
1171 - `p = 3`: all datapoints are drawn scattered
1172
1173 - `h = 0`; no histogram is drawn
1174 - `h = 1`; histogram at the left or bottom side is drawn
1175 - `h = 2`; histogram at the right or top side is drawn
1176 - `h = 3`; histogram at left and right or top and bottom (violin-style) is drawn
1177
1178 - `z = 0`; no zero indicator line is drawn
1179 - `z = 1`; zero indicator line is drawn.
1180
1181As one can see all individual options for both candle and violin plots can be accessed by this
1182mechanism. In deed the keywords CANDLE(<option-string>) and VIOLIN(<option-string>) have the same
1183meaning. So you can parametrise an option-string for a candle plot and use the keywords VIOLIN and
1184vice versa, if you wish.
1185
1186Using a logarithmic x- or y-axis is possible for candle and violin charts.
1187
1188\since **ROOT version 6.11/01**
1189
1190a logarithmic z-axis is possible, too but will only affect violin charts of course.
1191
1192#### <a name="HP140a"></a> The CANDLE option
1193
1194<a href="http://en.wikipedia.org/wiki/Box_plot">A Candle plot</a> (also known as
1195a "box plot" or "whisker plot") was invented in 1977 by John Tukey. It is a convenient
1196way to describe graphically a data distribution (D) with only five numbers:
1197
1198 1. The minimum value of the distribution D (bottom or left whisker).
1199 2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
1200 3. The median (M): 50% of the data points in D are less than M.
1201 4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
1202 5. The maximum value of the distribution D (top or right whisker).
1203
1204In this implementation a TH2 is considered as a collection of TH1 along
1205X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`).
1206Each TH1 is represented as one candle.
1207
1208Begin_Macro(source)
1209../../../tutorials/hist/candleplotwhiskers.C
1210End_Macro
1211
1212The candle reduces the information coming from a whole distribution into few values.
1213Independently from the number of entries or the significance of the underlying distribution
1214a candle will always look like a candle. So candle plots should be used carefully in
1215particular with unknown distributions. The definition of a candle is based on
1216__unbinned data__. Here, candles are created from binned data. Because of this, the
1217deviation is connected to the bin width used. The calculation of the quantiles
1218normally done on unbinned data also. Because data are binned, this will
1219only work the best possible way within the resolution of one bin
1220
1221Because of all these facts one should take care that:
1222
1223 - there are enough points per candle
1224 - the bin width is small enough (more bins will increase the maximum
1225 available resolution of the quantiles although there will be some
1226 bins with no entries)
1227 - never make a candle-plot if the underlying distribution is double-distributed
1228 - only create candles of distributions that are more-or-less gaussian (the
1229 MPV should be not too far away from the mean).
1230
1231#### What a candle is made of
1232
1233\since **ROOT version 6.07/05**
1234
1235##### The box
1236The box displays the position of the inter-quantile-range of the underlying
1237distribution. The box contains 25% of the distribution below the median
1238and 25% of the distribution above the median. If the underlying distribution is large
1239enough and gaussian shaped the end-points of the box represent \f$ 0.6745\times\sigma \f$
1240(Where \f$ \sigma \f$ is the standard deviation of the gaussian). The width and
1241the position of the box can be modified by SetBarWidth() and SetBarOffset().
1242The +-25% quantiles are calculated by the GetQuantiles() methods.
1243
1244\since **ROOT version 6.11/01**
1245
1246Using the static function TCandle::SetBoxRange(double) the box definition will be
1247overwritten. E.g. using a box range of 0.68 will redefine the area of the lower box edge
1248to the upper box edge in order to cover 68% of the distribution illustrated by that candle.
1249The static function will affect all candle-charts in the running program.
1250Default is 0.5.
1251
1252Using the static function TCandle::SetScaledCandle(bool) the width of the box (and the
1253whole candle) can be influenced. Deactivated, the width is constant (to be set by
1254SetBarWidth() ). Activated, the width of the boxes will be scaled to each other based on the
1255amount of data in the corresponding candle, the maximum width can be influenced by
1256SetBarWidth(). The static function will affect all candle-charts in the running program.
1257Default is false. Scaling between multiple candle-charts (using "same" or THStack) is not
1258supported, yet
1259
1260##### The Median
1261For a sorted list of numbers, the median is the value in the middle of the list.
1262E.g. if a sorted list is made of five numbers "1,2,3,6,7" 3 will be the median
1263because it is in the middle of the list. If the number of entries is even the
1264average of the two values in the middle will be used. As histograms are binned
1265data, the situation is a bit more complex. The following example shows this:
1266
1267~~~ {.cpp}
1268void quantiles() {
1269 TH1I *h = new TH1I("h","h",10,0,10);
1270 //h->Fill(3);
1271 //h->Fill(3);
1272 h->Fill(4);
1273 h->Draw();
1274 Double_t *p = new Double_t[1];
1275 p[0] = 0.5;
1276 Double_t *q = new Double_t[1];
1277 q[0] = 0;
1278 h->GetQuantiles(1,q,p);
1279
1280 cout << "Median is: " << q[0] << std::endl;
1281}
1282~~~
1283
1284Here the bin-width is 1.0. If the two Fill(3) are commented out, as there are currently,
1285the example will return a calculated median of 4.5, because that's the bin center
1286of the bin in which the value 4.0 has been dropped. If the two Fill(3) are not
1287commented out, it will return 3.75, because the algorithm tries to evenly distribute
1288the individual values of a bin with bin content > 0. It means the sorted list
1289would be "3.25, 3.75, 4.5".
1290
1291The consequence is a median of 3.75. This shows how important it is to use a
1292small enough bin-width when using candle-plots on binned data.
1293If the distribution is large enough and gaussian shaped the median will be exactly
1294equal to the mean.
1295The median can be shown as a line or as a circle or not shown at all.
1296
1297In order to show the significance of the median notched candle plots apply a "notch" or
1298narrowing of the box around the median. The significance is defined by
1299\f$ 1.57\times\frac{iqr}{N} \f$ and will be represented as the size of the notch
1300(where iqr is the size of the box and N is the number of entries of the whole
1301distribution). Candle plots like these are usually called "notched candle plots".
1302
1303In case the significance of the median is greater that the size of the box, the
1304box will have an unnatural shape. Usually it means the chart has not enough data,
1305or that representing this uncertainty is not useful
1306
1307##### The Mean
1308The mean can be drawn as a dashed line or as a circle or not drawn at all.
1309The mean is the arithmetic average of the values in the distribution.
1310It is calculated using GetMean(). Because histograms are
1311binned data, the mean value can differ from a calculation on the raw-data.
1312If the distribution is large enough and gaussian shaped the mean will be
1313exactly the median.
1314
1315##### The Whiskers
1316The whiskers represent the part of the distribution not covered by the box.
1317The upper 25% and the lower 25% of the distribution are located within the whiskers.
1318Two representations are available.
1319
1320 - A simple one (using w=1) defining the lower whisker from the lowest data value
1321 to the bottom of the box, and the upper whisker from the top of the box to the
1322 highest data value. In this representation the whisker-lines are dashed.
1323 - A more complex one having a further restriction. The whiskers are still connected
1324 to the box but their length cannot exceed \f$ 1.5\times iqr \f$. So it might
1325 be that the outermost part of the underlying distribution will not be covered
1326 by the whiskers. Usually these missing parts will be represented by the outliers
1327 (see points). Of course the upper and the lower whisker may differ in length.
1328 In this representation the whiskers are drawn as solid lines.
1329
1330\since **ROOT version 6.11/01**
1331
1332Using the static function TCandle::SetWhiskerRange(double) the whisker definition w=1
1333will be overwritten. E.g. using a whisker-range of 0.95 and w=1 will redefine the area of
1334the lower whisker to the upper whisker in order to cover 95% of the distribution inside
1335that candle. The static function will affect all candle-charts in the running program.
1336Default is 1.
1337
1338If the distribution is large enough and gaussian shaped, the maximum length of
1339the whisker will be located at \f$ \pm 2.698 \sigma \f$ (when using the
13401.5*iqr-definition (w=2), where \f$ \sigma \f$ is the standard deviation
1341(see picture above). In that case 99.3% of the total distribution will be covered
1342by the box and the whiskers, whereas 0.7% are represented by the outliers.
1343
1344##### The Anchors
1345The anchors have no special meaning in terms of statistical calculation. They mark
1346the end of the whiskers and they have the width of the box. Both representation
1347with and without anchors are common.
1348
1349##### The Points
1350Depending on the configuration the points can have different meanings:
1351 - If p=1 the points represent the outliers. If they are shown, it means
1352 some parts of the underlying distribution are not covered by the whiskers.
1353 This can only occur when the whiskers are set to option w=2. Here the whiskers
1354 can have a maximum length of \f$ 1.5 \times iqr \f$. So any points outside the
1355 whiskers will be drawn as outliers. The outliers will be represented by crosses.
1356 - If p=2 all points in the distribution will be painted as crosses. This is
1357 useful for small datasets only (up to 10 or 20 points per candle).
1358 The outliers are shown along the candle. Because the underlying distribution
1359 is binned, is frequently occurs that a bin contains more than one value.
1360 Because of this the points will be randomly scattered within their bin along
1361 the candle axis. If the bin content for a bin is exactly 1 (usually
1362 this happens for the outliers) if will be drawn in the middle of the bin along
1363 the candle axis. As the maximum number of points per candle is limited by kNMax/2
1364 on very large datasets scaling will be performed automatically. In that case one
1365 would loose all outliers because they have usually a bin content of 1 (and a
1366 bin content between 0 and 1 after the scaling). Because of this all bin contents
1367 between 0 and 1 - after the scaling - will be forced to be 1.
1368 - As the drawing of all values on large datasets can lead to big amounts of crosses,
1369 one can show all values as a scatter plot instead by choosing p=3. The points will be
1370 drawn as dots and will be scattered within the width of the candle. The color
1371 of the points will be the color of the candle-chart.
1372
1373##### Other Options
1374Is is possible to combine all options of candle and violin plots with each other. E.g. a box-plot
1375with a histogram.
1376
1377#### How to use the candle-plots drawing option
1378
1379There are six predefined candle-plot representations:
1380
1381 - "CANDLEX1": Standard candle (whiskers cover the whole distribution)
1382 - "CANDLEX2": Standard candle with better whisker definition + outliers.
1383 It is a good compromise
1384 - "CANDLEX3": Like candle2 but with a mean as a circle.
1385 It is easier to distinguish mean and median
1386 - "CANDLEX4": Like candle3 but showing the uncertainty of the median as well
1387 (notched candle plots).
1388 For bigger datasets per candle
1389 - "CANDLEX5": Like candle2 but showing all data points.
1390 For very small datasets
1391 - "CANDLEX6": Like candle2 but showing all datapoints scattered.
1392 For huge datasets
1393
1394
1395The following picture shows how the six predefined representations look.
1396
1397Begin_Macro
1398{
1399 TCanvas *c1 = new TCanvas("c1","c1",700,800);
1400 c1->Divide(2,3);
1401 gStyle->SetOptStat(kFALSE);
1402
1403 TH2F *hcandle = new TH2F("hcandle"," ",10,-4,4,40,-20,20);
1404 Float_t px, py;
1405 for (Int_t i = 0; i < 15000; i++) {
1406 gRandom->Rannor(px,py);
1407 hcandle->Fill(px,5*py);
1408 }
1409 hcandle->SetMarkerSize(0.5);
1410
1411 TH2F *h2;
1412 for (Int_t i=1; i<7; i++) {
1413 c1->cd(i);
1414 h2 = (TH2F*)hcandle->DrawClone(Form("CANDLE%d",i));
1415 h2->SetTitle(Form("CANDLE%d",i));
1416 }
1417}
1418End_Macro
1419
1420
1421
1422#### Example 1
1423Box and improved whisker, no mean, no median, no anchor no outliers
1424
1425 h1->Draw("CANDLEX(2001)");
1426
1427#### Example 2
1428A Candle-definition like "CANDLEX2" (New standard candle with better whisker definition + outliers)
1429
1430 h1->Draw("CANDLEX(112111)");
1431
1432#### Example 3
1433The following example shows how several candle plots can be super-imposed using
1434the option SAME. Note that the bar-width and bar-offset are active on candle plots.
1435Also the color, the line width, the size of the points and so on can be changed by the
1436standard attribute setting methods such as SetLineColor() SetLineWidth().
1437
1438Begin_Macro(source)
1439../../../tutorials/hist/candleplot.C
1440End_Macro
1441
1442#### <a name="HP140b"></a> The VIOLIN option
1443
1444<a href="http://en.wikipedia.org/wiki/Violin_plot">A violin plot</a> is a candle plot
1445that also encodes the pdf information at each point.
1446
1447
1448Quartiles and mean are also represented at each point, with a marker
1449and two lines.
1450
1451In this implementation a TH2 is considered as a collection of TH1 along
1452X (option `VIOLIN` or `VIOLINX`) or Y (option `VIOLINY`).
1453
1454#### What a violin is made of
1455
1456\since **ROOT version 6.09/02**
1457
1458##### The histogram
1459The histogram is typically drawn to both directions with respect to the middle-line of the
1460corresponding bin. This can be achieved by using h=3. It is possible to draw a histogram only to
1461one side (h=1, or h=2).
1462The maximum number of bins in the histogram is limited to 500, if the number of bins in the used
1463histogram is higher it will be rebinned automatically. The maximum height of the histogram can
1464be modified by using SetBarWidth() and the position can be changed with SetBarOffset().
1465A solid fill style is recommended.
1466
1467\since **ROOT version 6.11/01**
1468
1469Using the static function TCandle::SetScaledViolin(bool) the height of the histogram or the
1470violin can be influenced. Activated, the height of the bins of the individual violins will be
1471scaled with respect to each other, the maximum height can be influenced by SetBarWidth().
1472Deactivated, the height of the bin with the maximum content of each individual violin is
1473set to a constant value using SetBarWidth(). The static function will affect all violin-charts
1474in the running program. Default is true. Scaling between multiple violin-charts
1475(using "same" or THStack) is not supported, yet.
1476
1477##### The zero indicator line
1478Typical for violin charts is a line in the background over the whole histogram indicating
1479the bins with zero entries. The zero indicator line can be activated with z=1. The line color
1480will always be the same as the fill-color of the histogram.
1481
1482##### The Mean
1483The Mean is illustrated with the same mechanism as used for candle plots. Usually a circle is used.
1484
1485##### Whiskers
1486The whiskers are illustrated by the same mechanism as used for candle plots. There is only one
1487difference. When using the simple whisker definition (w=1) and the zero indicator line (z=1), then
1488the whiskers will be forced to be solid (usually hashed)
1489
1490##### Points
1491The points are illustrated by the same mechanism as used for candle plots. E.g. VIOLIN2 uses
1492better whisker definition (w=2) and outliers (p=1).
1493
1494##### Other options
1495It is possible to combine all options of candle or violin plots with each other. E.g. a violin plot
1496including a box-plot.
1497
1498#### How to use the violin-plots drawing option
1499
1500There are two predefined violin-plot representations:
1501 - "VIOLINX1": Standard violin (histogram, mean, whisker over full distribution,
1502 zero indicator line)
1503 - "VIOLINX2": Line VIOLINX1 both with better whisker definition + outliers.
1504
1505A solid fill style is recommended for this plot (as opposed to a hollow or
1506hashed style).
1507
1508Begin_Macro(source)
1509{
1510 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1511 Int_t nx(6), ny(40);
1512 Double_t xmin(0.0), xmax(+6.0), ymin(0.0), ymax(+4.0);
1513 TH2F* hviolin = new TH2F("hviolin", "Option VIOLIN example", nx, xmin, xmax, ny, ymin, ymax);
1514 TF1 f1("f1", "gaus", +0,0 +4.0);
1515 Double_t x,y;
1516 for (Int_t iBin=1; iBin<hviolin->GetNbinsX(); ++iBin) {
1517 Double_t xc = hviolin->GetXaxis()->GetBinCenter(iBin);
1518 f1.SetParameters(1, 2.0+TMath::Sin(1.0+xc), 0.2+0.1*(xc-xmin)/xmax);
1519 for(Int_t i=0; i<10000; ++i){
1520 x = xc;
1521 y = f1.GetRandom();
1522 hviolin->Fill(x, y);
1523 }
1524 }
1525 hviolin->SetFillColor(kGray);
1526 hviolin->SetMarkerStyle(20);
1527 hviolin->SetMarkerSize(0.5);
1528 hviolin->Draw("VIOLIN");
1529 c1->Update();
1530 return c1;
1531}
1532End_Macro
1533
1534The next example illustrates a time development of a certain value:
1535
1536Begin_Macro(source)
1537../../../tutorials/hist/candledecay.C
1538End_Macro
1539
1540
1541### <a name="HP15"></a> The TEXT and TEXTnn Option
1542
1543
1544For each bin the content is printed. The text attributes are:
1545
1546- text font = current TStyle font (`gStyle->SetTextFont()`).
1547- text size = 0.02*padheight*markersize (if `h` is the histogram drawn
1548 with the option `TEXT` the marker size can be changed with
1549 `h->SetMarkerSize(markersize)`).
1550- text color = marker color.
1551
1552By default the format `g` is used. This format can be redefined
1553by calling `gStyle->SetPaintTextFormat()`.
1554
1555It is also possible to use `TEXTnn` in order to draw the text with
1556the angle `nn` (`0 < nn < 90`).
1557
1558For 2D histograms the text is plotted in the center of each non empty cells.
1559It is possible to plot empty cells by calling `gStyle->SetHistMinimumZero()`.
1560For 1D histogram the text is plotted at a y position equal to the bin content.
1561
1562For 2D histograms when the option "E" (errors) is combined with the option
1563text ("TEXTE"), the error for each bin is also printed.
1564
1565Begin_Macro(source)
1566{
1567 TCanvas *c01 = new TCanvas("c01","c01",700,400);
1568 c01->Divide(2,1);
1569 TH1F *htext1 = new TH1F("htext1","Option TEXT on 1D histograms ",10,-4,4);
1570 TH2F *htext2 = new TH2F("htext2","Option TEXT on 2D histograms ",10,-4,4,10,-20,20);
1571 Float_t px, py;
1572 for (Int_t i = 0; i < 25000; i++) {
1573 gRandom->Rannor(px,py);
1574 htext1->Fill(px,0.1);
1575 htext2->Fill(px,5*py,0.1);
1576 }
1577 gStyle->SetPaintTextFormat("4.1f m");
1578 htext2->SetMarkerSize(1.8);
1579 c01->cd(1);
1580 htext2->Draw("TEXT45");
1581 c01->cd(2);
1582 htext1->Draw();
1583 htext1->Draw("HIST TEXT0 SAME");
1584 return c01;
1585}
1586End_Macro
1587
1588\since **ROOT version 6.07/07:**
1589
1590In case several histograms are drawn on top ot each other (using option `SAME`),
1591the text can be shifted using `SetBarOffset()`. It specifies an offset for the
1592text position in each cell, in percentage of the bin width.
1593
1594Begin_Macro(source)
1595{
1596 TCanvas *c03 = new TCanvas("c03","c03",700,400);
1597 gStyle->SetOptStat(0);
1598 TH2F *htext3 = new TH2F("htext3","Several 2D histograms drawn with option TEXT",10,-4,4,10,-20,20);
1599 TH2F *htext4 = new TH2F("htext4","htext4",10,-4,4,10,-20,20);
1600 TH2F *htext5 = new TH2F("htext5","htext5",10,-4,4,10,-20,20);
1601 Float_t px, py;
1602 for (Int_t i = 0; i < 25000; i++) {
1603 gRandom->Rannor(px,py);
1604 htext3->Fill(4*px,20*py,0.1);
1605 htext4->Fill(4*px,20*py,0.5);
1606 htext5->Fill(4*px,20*py,1.0);
1607 }
1608 //gStyle->SetPaintTextFormat("4.1f m");
1609 htext4->SetMarkerSize(1.8);
1610 htext5->SetMarkerSize(1.8);
1611 htext5->SetMarkerColor(kRed);
1612 htext3->Draw("COL");
1613 htext4->SetBarOffset(0.2);
1614 htext4->Draw("TEXT SAME");
1615 htext5->SetBarOffset(-0.2);
1616 htext5->Draw("TEXT SAME");
1617 return c03;
1618}
1619End_Macro
1620
1621In the case of profile histograms it is possible to print the number
1622of entries instead of the bin content. It is enough to combine the
1623option "E" (for entries) with the option "TEXT".
1624
1625Begin_Macro(source)
1626{
1627 TCanvas *c02 = new TCanvas("c02","c02",700,400);
1628 c02->Divide(2,1);
1629 gStyle->SetPaintTextFormat("g");
1630
1631 TProfile *profile = new TProfile("profile","profile",10,0,10);
1632 profile->SetMarkerSize(2.2);
1633 profile->Fill(0.5,1);
1634 profile->Fill(1.5,2);
1635 profile->Fill(2.5,3);
1636 profile->Fill(3.5,4);
1637 profile->Fill(4.5,5);
1638 profile->Fill(5.5,5);
1639 profile->Fill(6.5,4);
1640 profile->Fill(7.5,3);
1641 profile->Fill(8.5,2);
1642 profile->Fill(9.5,1);
1643 c02->cd(1); profile->Draw("HIST TEXT0");
1644 c02->cd(2); profile->Draw("HIST TEXT0E");
1645
1646 return c02;
1647}
1648End_Macro
1649
1650### <a name="HP16"></a> The CONTour options
1651
1652
1653The following contour options are supported:
1654
1655| Option | Description |
1656|----------|-------------------------------------------------------------------|
1657| "CONT" | Draw a contour plot (same as CONT0).|
1658| "CONT0" | Draw a contour plot using surface colors to distinguish contours.|
1659| "CONT1" | Draw a contour plot using the line colors to distinguish contours.|
1660| "CONT2" | Draw a contour plot using the line styles to distinguish contours.|
1661| "CONT3" | Draw a contour plot solid lines for all contours.|
1662| "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0).|
1663| "CONT5" | Draw a contour plot using Delaunay triangles.|
1664
1665
1666
1667The following example shows a 2D histogram plotted with the option
1668`CONTZ`. The option `CONT` draws a contour plot using surface
1669colors to distinguish contours. Combined with the option `CONT` (or
1670`CONT0`), the option `Z` allows to display the color palette
1671defined by `gStyle->SetPalette()`.
1672
1673Begin_Macro(source)
1674{
1675 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1676 TH2F *hcontz = new TH2F("hcontz","Option CONTZ example ",40,-4,4,40,-20,20);
1677 Float_t px, py;
1678 for (Int_t i = 0; i < 25000; i++) {
1679 gRandom->Rannor(px,py);
1680 hcontz->Fill(px-1,5*py);
1681 hcontz->Fill(2+0.5*px,2*py-10.,0.1);
1682 }
1683 hcontz->Draw("CONTZ");
1684 return c1;
1685}
1686End_Macro
1687
1688The following example shows a 2D histogram plotted with the option
1689`CONT1Z`. The option `CONT1` draws a contour plot using the
1690line colors to distinguish contours. Combined with the option `CONT1`,
1691the option `Z` allows to display the color palette defined by
1692`gStyle->SetPalette()`.
1693
1694Begin_Macro(source)
1695{
1696 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1697 TH2F *hcont1 = new TH2F("hcont1","Option CONT1Z example ",40,-4,4,40,-20,20);
1698 Float_t px, py;
1699 for (Int_t i = 0; i < 25000; i++) {
1700 gRandom->Rannor(px,py);
1701 hcont1->Fill(px-1,5*py);
1702 hcont1->Fill(2+0.5*px,2*py-10.,0.1);
1703 }
1704 hcont1->Draw("CONT1Z");
1705 return c1;
1706}
1707End_Macro
1708
1709The following example shows a 2D histogram plotted with the option
1710`CONT2`. The option `CONT2` draws a contour plot using the
1711line styles to distinguish contours.
1712
1713Begin_Macro(source)
1714{
1715 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1716 TH2F *hcont2 = new TH2F("hcont2","Option CONT2 example ",40,-4,4,40,-20,20);
1717 Float_t px, py;
1718 for (Int_t i = 0; i < 25000; i++) {
1719 gRandom->Rannor(px,py);
1720 hcont2->Fill(px-1,5*py);
1721 hcont2->Fill(2+0.5*px,2*py-10.,0.1);
1722 }
1723 hcont2->Draw("CONT2");
1724 return c1;
1725}
1726End_Macro
1727
1728The following example shows a 2D histogram plotted with the option
1729`CONT3`. The option `CONT3` draws contour plot solid lines for
1730all contours.
1731
1732Begin_Macro(source)
1733{
1734 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1735 TH2F *hcont3 = new TH2F("hcont3","Option CONT3 example ",40,-4,4,40,-20,20);
1736 Float_t px, py;
1737 for (Int_t i = 0; i < 25000; i++) {
1738 gRandom->Rannor(px,py);
1739 hcont3->Fill(px-1,5*py);
1740 hcont3->Fill(2+0.5*px,2*py-10.,0.1);
1741 }
1742 hcont3->Draw("CONT3");
1743 return c1;
1744}
1745End_Macro
1746
1747The following example shows a 2D histogram plotted with the option
1748`CONT4`. The option `CONT4` draws a contour plot using surface
1749colors to distinguish contours (`SURF` option at theta = 0). Combined
1750with the option `CONT` (or `CONT0`), the option `Z`
1751allows to display the color palette defined by `gStyle->SetPalette()`.
1752
1753Begin_Macro(source)
1754{
1755 TCanvas *c1 = new TCanvas("c1","c1",600,400);
1756 TH2F *hcont4 = new TH2F("hcont4","Option CONT4Z example ",40,-4,4,40,-20,20);
1757 Float_t px, py;
1758 for (Int_t i = 0; i < 25000; i++) {
1759 gRandom->Rannor(px,py);
1760 hcont4->Fill(px-1,5*py);
1761 hcont4->Fill(2+0.5*px,2*py-10.,0.1);
1762 }
1763 hcont4->Draw("CONT4Z");
1764 return c1;
1765}
1766End_Macro
1767
1768The default number of contour levels is 20 equidistant levels and can be changed
1769with `TH1::SetContour()` or `TStyle::SetNumberContours()`.
1770
1771#### <a name="HP16a"></a> The LIST option
1772
1773When option `LIST` is specified together with option
1774`CONT`, the points used to draw the contours are saved in
1775`TGraph` objects:
1776
1777 h->Draw("CONT LIST");
1778 gPad->Update();
1779
1780The contour are saved in `TGraph` objects once the pad is painted.
1781Therefore to use this functionality in a macro, `gPad->Update()`
1782should be performed after the histogram drawing. Once the list is
1783built, the contours are accessible in the following way:
1784
1785 TObjArray *contours = gROOT->GetListOfSpecials()->FindObject("contours")
1786 Int_t ncontours = contours->GetSize();
1787 TList *list = (TList*)contours->At(i);
1788
1789Where `i` is a contour number, and list contains a list of
1790`TGraph` objects.
1791For one given contour, more than one disjoint polyline may be generated.
1792The number of TGraphs per contour is given by:
1793
1794 list->GetSize();
1795
1796To access the first graph in the list one should do:
1797
1798 TGraph *gr1 = (TGraph*)list->First();
1799
1800
1801The following example (ContourList.C) shows how to use this functionality.
1802
1803Begin_Macro(source)
1804../../../tutorials/hist/ContourList.C
1805End_Macro
1806
1807The following options select the `CONT4` option and are useful for
1808sky maps or exposure maps (earth.C).
1809
1810| Option | Description |
1811|--------------|---------------------------------------------------------------|
1812| "AITOFF" | Draw a contour via an AITOFF projection.|
1813| "MERCATOR" | Draw a contour via an Mercator projection.|
1814| "SINUSOIDAL" | Draw a contour via an Sinusoidal projection.|
1815| "PARABOLIC" | Draw a contour via an Parabolic projection.|
1816
1817Begin_Macro(source)
1818../../../tutorials/graphics/earth.C
1819End_Macro
1820
1821
1822### <a name="HP17"></a> The LEGO options
1823
1824
1825In a lego plot the cell contents are drawn as 3-d boxes. The height of each box
1826is proportional to the cell content. The lego aspect is control with the
1827following options:
1828
1829| Option | Description |
1830|----------|-------------------------------------------------------------------|
1831| "LEGO" | Draw a lego plot using the hidden lines removal technique.|
1832| "LEGO1" | Draw a lego plot using the hidden surface removal technique.|
1833| "LEGO2" | Draw a lego plot using colors to show the cell contents.|
1834| "LEGO3" | Draw a lego plot with hidden surface removal, like LEGO1 but the border lines of each lego-bar are not drawn.|
1835| "LEGO4" | Draw a lego plot with hidden surface removal, like LEGO1 but without the shadow effect on each lego-bar.|
1836| "0" | When used with any LEGO option, the empty bins are not drawn.|
1837
1838
1839See the limitations with [the option "SAME"](#HP060a).
1840
1841Line attributes can be used in lego plots to change the edges' style.
1842
1843The following example shows a 2D histogram plotted with the option
1844`LEGO`. The option `LEGO` draws a lego plot using the hidden
1845lines removal technique.
1846
1847Begin_Macro(source)
1848{
1849 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1850 TH2F *hlego = new TH2F("hlego","Option LEGO example ",40,-4,4,40,-20,20);
1851 Float_t px, py;
1852 for (Int_t i = 0; i < 25000; i++) {
1853 gRandom->Rannor(px,py);
1854 hlego->Fill(px-1,5*py);
1855 hlego->Fill(2+0.5*px,2*py-10.,0.1);
1856 }
1857 hlego->Draw("LEGO");
1858 return c2;
1859}
1860End_Macro
1861
1862The following example shows a 2D histogram plotted with the option
1863`LEGO1`. The option `LEGO1` draws a lego plot using the
1864hidden surface removal technique. Combined with any `LEGOn` option, the
1865option `0` allows to not drawn the empty bins.
1866
1867Begin_Macro(source)
1868{
1869 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1870 TH2F *hlego1 = new TH2F("hlego1","Option LEGO1 example (with option 0) ",40,-4,4,40,-20,20);
1871 Float_t px, py;
1872 for (Int_t i = 0; i < 25000; i++) {
1873 gRandom->Rannor(px,py);
1874 hlego1->Fill(px-1,5*py);
1875 hlego1->Fill(2+0.5*px,2*py-10.,0.1);
1876 }
1877 hlego1->SetFillColor(kYellow);
1878 hlego1->Draw("LEGO1 0");
1879 return c2;
1880}
1881End_Macro
1882
1883The following example shows a 2D histogram plotted with the option
1884`LEGO3`. Like the option `LEGO1`, the option `LEGO3`
1885draws a lego plot using the hidden surface removal technique but doesn't draw
1886the border lines of each individual lego-bar. This is very useful for histograms
1887having many bins. With such histograms the option `LEGO1` gives a black
1888image because of the border lines. This option also works with stacked legos.
1889
1890Begin_Macro(source)
1891{
1892 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1893 TH2F *hlego3 = new TH2F("hlego3","Option LEGO3 example",40,-4,4,40,-20,20);
1894 Float_t px, py;
1895 for (Int_t i = 0; i < 25000; i++) {
1896 gRandom->Rannor(px,py);
1897 hlego3->Fill(px-1,5*py);
1898 hlego3->Fill(2+0.5*px,2*py-10.,0.1);
1899 }
1900 hlego3->SetFillColor(kRed);
1901 hlego3->Draw("LEGO3");
1902 return c2;
1903}
1904End_Macro
1905
1906The following example shows a 2D histogram plotted with the option
1907`LEGO2`. The option `LEGO2` draws a lego plot using colors to
1908show the cell contents. Combined with the option `LEGO2`, the option
1909`Z` allows to display the color palette defined by
1910`gStyle->SetPalette()`.
1911
1912Begin_Macro(source)
1913{
1914 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1915 TH2F *hlego2 = new TH2F("hlego2","Option LEGO2Z example ",40,-4,4,40,-20,20);
1916 Float_t px, py;
1917 for (Int_t i = 0; i < 25000; i++) {
1918 gRandom->Rannor(px,py);
1919 hlego2->Fill(px-1,5*py);
1920 hlego2->Fill(2+0.5*px,2*py-10.,0.1);
1921 }
1922 hlego2->Draw("LEGO2Z");
1923 return c2;
1924}
1925End_Macro
1926
1927
1928
1929### <a name="HP18"></a> The "SURFace" options
1930
1931
1932In a surface plot, cell contents are represented as a mesh.
1933The height of the mesh is proportional to the cell content.
1934
1935| Option | Description |
1936|----------|-------------------------------------------------------------------|
1937| "SURF" | Draw a surface plot using the hidden line removal technique.|
1938| "SURF1" | Draw a surface plot using the hidden surface removal technique.|
1939| "SURF2" | Draw a surface plot using colors to show the cell contents.|
1940| "SURF3" | Same as `SURF` with an additional filled contour plot on top.|
1941| "SURF4" | Draw a surface using the Gouraud shading technique.|
1942| "SURF5" | Used with one of the options CYL, PSR and CYL this option allows to draw a a filled contour plot.|
1943| "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.|
1944| "SURF7" | Same as `SURF2` with an additional line contour plot on top.|
1945
1946
1947
1948See the limitations with [the option "SAME"](#HP060a).
1949
1950The following example shows a 2D histogram plotted with the option
1951`SURF`. The option `SURF` draws a lego plot using the hidden
1952lines removal technique.
1953
1954Begin_Macro(source)
1955{
1956 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1957 TH2F *hsurf = new TH2F("hsurf","Option SURF example ",30,-4,4,30,-20,20);
1958 Float_t px, py;
1959 for (Int_t i = 0; i < 25000; i++) {
1960 gRandom->Rannor(px,py);
1961 hsurf->Fill(px-1,5*py);
1962 hsurf->Fill(2+0.5*px,2*py-10.,0.1);
1963 }
1964 hsurf->Draw("SURF");
1965 return c2;
1966}
1967End_Macro
1968
1969The following example shows a 2D histogram plotted with the option
1970`SURF1`. The option `SURF1` draws a surface plot using the
1971hidden surface removal technique. Combined with the option `SURF1`,
1972the option `Z` allows to display the color palette defined by
1973`gStyle->SetPalette()`.
1974
1975Begin_Macro(source)
1976{
1977 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1978 TH2F *hsurf1 = new TH2F("hsurf1","Option SURF1 example ",30,-4,4,30,-20,20);
1979 Float_t px, py;
1980 for (Int_t i = 0; i < 25000; i++) {
1981 gRandom->Rannor(px,py);
1982 hsurf1->Fill(px-1,5*py);
1983 hsurf1->Fill(2+0.5*px,2*py-10.,0.1);
1984 }
1985 hsurf1->Draw("SURF1");
1986 return c2;
1987}
1988End_Macro
1989
1990The following example shows a 2D histogram plotted with the option
1991`SURF2`. The option `SURF2` draws a surface plot using colors
1992to show the cell contents. Combined with the option `SURF2`, the option
1993`Z` allows to display the color palette defined by
1994`gStyle->SetPalette()`.
1995
1996Begin_Macro(source)
1997{
1998 TCanvas *c2 = new TCanvas("c2","c2",600,400);
1999 TH2F *hsurf2 = new TH2F("hsurf2","Option SURF2 example ",30,-4,4,30,-20,20);
2000 Float_t px, py;
2001 for (Int_t i = 0; i < 25000; i++) {
2002 gRandom->Rannor(px,py);
2003 hsurf2->Fill(px-1,5*py);
2004 hsurf2->Fill(2+0.5*px,2*py-10.,0.1);
2005 }
2006 hsurf2->Draw("SURF2");
2007 return c2;
2008}
2009End_Macro
2010
2011The following example shows a 2D histogram plotted with the option
2012`SURF3`. The option `SURF3` draws a surface plot using the
2013hidden line removal technique with, in addition, a filled contour view drawn on the
2014top. Combined with the option `SURF3`, the option `Z` allows
2015to display the color palette defined by `gStyle->SetPalette()`.
2016
2017Begin_Macro(source)
2018{
2019 TCanvas *c2 = new TCanvas("c2","c2",600,400);
2020 TH2F *hsurf3 = new TH2F("hsurf3","Option SURF3 example ",30,-4,4,30,-20,20);
2021 Float_t px, py;
2022 for (Int_t i = 0; i < 25000; i++) {
2023 gRandom->Rannor(px,py);
2024 hsurf3->Fill(px-1,5*py);
2025 hsurf3->Fill(2+0.5*px,2*py-10.,0.1);
2026 }
2027 hsurf3->Draw("SURF3");
2028 return c2;
2029}
2030End_Macro
2031
2032The following example shows a 2D histogram plotted with the option
2033`SURF4`. The option `SURF4` draws a surface using the Gouraud
2034shading technique.
2035
2036Begin_Macro(source)
2037{
2038 TCanvas *c2 = new TCanvas("c2","c2",600,400);
2039 TH2F *hsurf4 = new TH2F("hsurf4","Option SURF4 example ",30,-4,4,30,-20,20);
2040 Float_t px, py;
2041 for (Int_t i = 0; i < 25000; i++) {
2042 gRandom->Rannor(px,py);
2043 hsurf4->Fill(px-1,5*py);
2044 hsurf4->Fill(2+0.5*px,2*py-10.,0.1);
2045 }
2046 hsurf4->SetFillColor(kOrange);
2047 hsurf4->Draw("SURF4");
2048 return c2;
2049}
2050End_Macro
2051
2052The following example shows a 2D histogram plotted with the option
2053`SURF5 CYL`. Combined with the option `SURF5`, the option
2054`Z` allows to display the color palette defined by `gStyle->SetPalette()`.
2055
2056Begin_Macro(source)
2057{
2058 TCanvas *c2 = new TCanvas("c2","c2",600,400);
2059 TH2F *hsurf5 = new TH2F("hsurf4","Option SURF5 example ",30,-4,4,30,-20,20);
2060 Float_t px, py;
2061 for (Int_t i = 0; i < 25000; i++) {
2062 gRandom->Rannor(px,py);
2063 hsurf5->Fill(px-1,5*py);
2064 hsurf5->Fill(2+0.5*px,2*py-10.,0.1);
2065 }
2066 hsurf5->Draw("SURF5 CYL");
2067 return c2;
2068}
2069End_Macro
2070
2071The following example shows a 2D histogram plotted with the option
2072`SURF7`. The option `SURF7` draws a surface plot using the
2073hidden surfaces removal technique with, in addition, a line contour view drawn on the
2074top. Combined with the option `SURF7`, the option `Z` allows
2075to display the color palette defined by `gStyle->SetPalette()`.
2076
2077Begin_Macro(source)
2078{
2079 TCanvas *c2 = new TCanvas("c2","c2",600,400);
2080 TH2F *hsurf7 = new TH2F("hsurf3","Option SURF7 example ",30,-4,4,30,-20,20);
2081 Float_t px, py;
2082 for (Int_t i = 0; i < 25000; i++) {
2083 gRandom->Rannor(px,py);
2084 hsurf7->Fill(px-1,5*py);
2085 hsurf7->Fill(2+0.5*px,2*py-10.,0.1);
2086 }
2087 hsurf7->Draw("SURF7");
2088 return c2;
2089}
2090End_Macro
2091
2092As shown in the following example, when a contour plot is painted on top of a
2093surface plot using the option `SAME`, the contours appear in 3D on the
2094surface.
2095
2096Begin_Macro(source)
2097{
2098 TCanvas *c20=new TCanvas("c20","c20",600,400);
2099 int NBins = 50;
2100 double d = 2;
2101 TH2F* hsc = new TH2F("hsc", "Surface and contour with option SAME ", NBins, -d, d, NBins, -d, d);
2102 for (int bx = 1; bx <= NBins; ++bx) {
2103 for (int by = 1; by <= NBins; ++by) {
2104 double x = hsc->GetXaxis()->GetBinCenter(bx);
2105 double y = hsc->GetYaxis()->GetBinCenter(by);
2106 hsc->SetBinContent(bx, by, exp(-x*x)*exp(-y*y));
2107 }
2108 }
2109 hsc->Draw("surf2");
2110 hsc->Draw("CONT1 SAME");
2111 return c20;
2112}
2113End_Macro
2114
2115
2116### <a name="HP19"></a> Cylindrical, Polar, Spherical and PseudoRapidity/Phi options
2117
2118
2119Legos and surfaces plots are represented by default in Cartesian coordinates.
2120Combined with any `LEGOn` or `SURFn` options the following
2121options allow to draw a lego or a surface in other coordinates systems.
2122
2123| Option | Description |
2124|----------|-------------------------------------------------------------------|
2125| "CYL" | Use Cylindrical coordinates. The X coordinate is mapped on the angle and the Y coordinate on the cylinder length.|
2126| "POL" | Use Polar coordinates. The X coordinate is mapped on the angle and the Y coordinate on the radius.|
2127| "SPH" | Use Spherical coordinates. The X coordinate is mapped on the latitude and the Y coordinate on the longitude.|
2128| "PSR" | Use PseudoRapidity/Phi coordinates. The X coordinate is mapped on Phi.|
2129
2130
2131
2132<b>WARNING:</b> Axis are not drawn with these options.
2133
2134The following example shows the same histogram as a lego plot is the four
2135different coordinates systems.
2136
2137Begin_Macro(source)
2138{
2139 TCanvas *c3 = new TCanvas("c3","c3",600,400);
2140 c3->Divide(2,2);
2141 TH2F *hlcc = new TH2F("hlcc","Cylindrical coordinates",20,-4,4,20,-20,20);
2142 Float_t px, py;
2143 for (Int_t i = 0; i < 25000; i++) {
2144 gRandom->Rannor(px,py);
2145 hlcc->Fill(px-1,5*py);
2146 hlcc->Fill(2+0.5*px,2*py-10.,0.1);
2147 }
2148 hlcc->SetFillColor(kYellow);
2149 c3->cd(1); hlcc->Draw("LEGO1 CYL");
2150 c3->cd(2); TH2F *hlpc = (TH2F*) hlcc->DrawClone("LEGO1 POL");
2151 hlpc->SetTitle("Polar coordinates");
2152 c3->cd(3); TH2F *hlsc = (TH2F*) hlcc->DrawClone("LEGO1 SPH");
2153 hlsc->SetTitle("Spherical coordinates");
2154 c3->cd(4); TH2F *hlprpc = (TH2F*) hlcc->DrawClone("LEGO1 PSR");
2155 hlprpc->SetTitle("PseudoRapidity/Phi coordinates");
2156 return c3;
2157}
2158End_Macro
2159
2160The following example shows the same histogram as a surface plot is the four different coordinates systems.
2161
2162Begin_Macro(source)
2163{
2164 TCanvas *c4 = new TCanvas("c4","c4",600,400);
2165 c4->Divide(2,2);
2166 TH2F *hscc = new TH2F("hscc","Cylindrical coordinates",20,-4,4,20,-20,20);
2167 Float_t px, py;
2168 for (Int_t i = 0; i < 25000; i++) {
2169 gRandom->Rannor(px,py);
2170 hscc->Fill(px-1,5*py);
2171 hscc->Fill(2+0.5*px,2*py-10.,0.1);
2172 }
2173 c4->cd(1); hscc->Draw("SURF1 CYL");
2174 c4->cd(2); TH2F *hspc = (TH2F*) hscc->DrawClone("SURF1 POL");
2175 hspc->SetTitle("Polar coordinates");
2176 c4->cd(3); TH2F *hssc = (TH2F*) hscc->DrawClone("SURF1 SPH");
2177 hssc->SetTitle("Spherical coordinates");
2178 c4->cd(4); TH2F *hsprpc = (TH2F*) hscc->DrawClone("SURF1 PSR");
2179 hsprpc->SetTitle("PseudoRapidity/Phi coordinates");
2180 return c4;
2181}
2182End_Macro
2183
2184
2185### <a name="HP20"></a> Base line for bar-charts and lego plots
2186
2187
2188By default the base line used to draw the boxes for bar-charts and lego plots is
2189the histogram minimum. It is possible to force this base line to be 0 with the
2190command:
2191
2192 gStyle->SetHistMinimumZero();
2193
2194Begin_Macro(source)
2195{
2196 TCanvas *c5 = new TCanvas("c5","c5",700,400);
2197 c5->Divide(2,1);
2198 gStyle->SetHistMinimumZero(1);
2199 TH1F *hz1 = new TH1F("hz1","Bar-chart drawn from 0",20,-3,3);
2200 TH2F *hz2 = new TH2F("hz2","Lego plot drawn from 0",20,-3,3,20,-3,3);
2201 Int_t i;
2202 Double_t x,y;
2203 hz1->SetFillColor(kBlue);
2204 hz2->SetFillColor(kBlue);
2205 for (i=0;i<10000;i++) {
2206 x = gRandom->Gaus(0,1);
2207 y = gRandom->Gaus(0,1);
2208 if (x>0) {
2209 hz1->Fill(x,1);
2210 hz2->Fill(x,y,1);
2211 } else {
2212 hz1->Fill(x,-1);
2213 hz2->Fill(x,y,-2);
2214 }
2215 }
2216 c5->cd(1); hz1->Draw("bar2");
2217 c5->cd(2); hz2->Draw("lego1");
2218 return c5;
2219}
2220End_Macro
2221
2222This option also works for horizontal plots. The example given in the section
2223["The bar chart option"](#HP100) appears as follow:
2224
2225Begin_Macro(source)
2226{
2227 int i;
2228 const Int_t nx = 8;
2229 string os_X[nx] = {"8","32","128","512","2048","8192","32768","131072"};
2230 float d_35_0[nx] = {0.75, -3.30, -0.92, 0.10, 0.08, -1.69, -1.29, -2.37};
2231 float d_35_1[nx] = {1.01, -3.02, -0.65, 0.37, 0.34, -1.42, -1.02, -2.10};
2232
2233 TCanvas *cbh = new TCanvas("cbh","cbh",400,600);
2234 cbh->SetGrid();
2235
2236 gStyle->SetHistMinimumZero();
2237
2238 TH1F *h1bh = new TH1F("h1bh","Option HBAR centered on 0",nx,0,nx);
2239 h1bh->SetFillColor(4);
2240 h1bh->SetBarWidth(0.4);
2241 h1bh->SetBarOffset(0.1);
2242 h1bh->SetStats(0);
2243 h1bh->SetMinimum(-5);
2244 h1bh->SetMaximum(5);
2245
2246 for (i=1; i<=nx; i++) {
2247 h1bh->Fill(os_X[i-1].c_str(), d_35_0[i-1]);
2248 h1bh->GetXaxis()->SetBinLabel(i,os_X[i-1].c_str());
2249 }
2250
2251 h1bh->Draw("hbar");
2252
2253 TH1F *h2bh = new TH1F("h2bh","h2bh",nx,0,nx);
2254 h2bh->SetFillColor(38);
2255 h2bh->SetBarWidth(0.4);
2256 h2bh->SetBarOffset(0.5);
2257 h2bh->SetStats(0);
2258 for (i=1;i<=nx;i++) h2bh->Fill(os_X[i-1].c_str(), d_35_1[i-1]);
2259
2260 h2bh->Draw("hbar same");
2261
2262 return cbh;
2263}
2264End_Macro
2265
2266
2267### <a name="HP20a"></a> TH2Poly Drawing
2268
2269
2270The following options are supported:
2271
2272| Option | Description |
2273|----------|-------------------------------------------------------------------|
2274| "SCAT" | Draw a scatter plot (default).|
2275| "COL" | Draw a color plot. All the bins are painted even the empty bins.|
2276| "COLZ" | Same as "COL". In addition the color palette is also drawn.|
2277| "0" | When used with any COL options, the empty bins are not drawn.|
2278| "TEXT" | Draw bin contents as text (format set via `gStyle->SetPaintTextFormat`).|
2279| "TEXTN" | Draw bin names as text.|
2280| "TEXTnn" | Draw bin contents as text at angle nn (0 < nn < 90).|
2281| "L" | Draw the bins boundaries as lines. The lines attributes are the TGraphs ones.|
2282| "P" | Draw the bins boundaries as markers. The markers attributes are the TGraphs ones.|
2283| "F" | Draw the bins boundaries as filled polygons. The filled polygons attributes are the TGraphs ones.|
2284
2285
2286
2287`TH2Poly` can be drawn as a color plot (option COL). `TH2Poly` bins can have any
2288shapes. The bins are defined as graphs. The following macro is a very simple
2289example showing how to book a TH2Poly and draw it.
2290
2291Begin_Macro(source)
2292{
2293 TCanvas *ch2p1 = new TCanvas("ch2p1","ch2p1",600,400);
2294 TH2Poly *h2p = new TH2Poly();
2295 h2p->SetName("h2poly_name");
2296 h2p->SetTitle("h2poly_title");
2297 Double_t px1[] = {0, 5, 6};
2298 Double_t py1[] = {0, 0, 5};
2299 Double_t px2[] = {0, -1, -1, 0};
2300 Double_t py2[] = {0, 0, -1, 3};
2301 Double_t px3[] = {4, 3, 0, 1, 2.4};
2302 Double_t py3[] = {4, 3.7, 1, 3.7, 2.5};
2303 h2p->AddBin(3, px1, py1);
2304 h2p->AddBin(4, px2, py2);
2305 h2p->AddBin(5, px3, py3);
2306 h2p->Fill(0.1, 0.01, 3);
2307 h2p->Fill(-0.5, -0.5, 7);
2308 h2p->Fill(-0.7, -0.5, 1);
2309 h2p->Fill(1, 3, 1.5);
2310 Double_t fx[] = {0.1, -0.5, -0.7, 1};
2311 Double_t fy[] = {0.01, -0.5, -0.5, 3};
2312 Double_t fw[] = {3, 1, 1, 1.5};
2313 h2p->FillN(4, fx, fy, fw);
2314 h2p->Draw("col");
2315}
2316End_Macro
2317
2318Rectangular bins are a frequent case. The special version of
2319the `AddBin` method allows to define them more easily like
2320shown in the following example (th2polyBoxes.C).
2321
2322Begin_Macro(source)
2323../../../tutorials/hist/th2polyBoxes.C
2324End_Macro
2325
2326One `TH2Poly` bin can be a list of polygons. Such bins are defined
2327by calling `AddBin` with a `TMultiGraph`. The following example
2328shows a such case:
2329
2330Begin_Macro(source)
2331{
2332 TCanvas *ch2p2 = new TCanvas("ch2p2","ch2p2",600,400);
2333
2334 Int_t i, bin;
2335 const Int_t nx = 48;
2336 const char *states [nx] = {
2337 "alabama", "arizona", "arkansas", "california",
2338 "colorado", "connecticut", "delaware", "florida",
2339 "georgia", "idaho", "illinois", "indiana",
2340 "iowa", "kansas", "kentucky", "louisiana",
2341 "maine", "maryland", "massachusetts", "michigan",
2342 "minnesota", "mississippi", "missouri", "montana",
2343 "nebraska", "nevada", "new_hampshire", "new_jersey",
2344 "new_mexico", "new_york", "north_carolina", "north_dakota",
2345 "ohio", "oklahoma", "oregon", "pennsylvania",
2346 "rhode_island", "south_carolina", "south_dakota", "tennessee",
2347 "texas", "utah", "vermont", "virginia",
2348 "washington", "west_virginia", "wisconsin", "wyoming"
2349 };
2350 Double_t pop[nx] = {
2351 4708708, 6595778, 2889450, 36961664, 5024748, 3518288, 885122, 18537969,
2352 9829211, 1545801, 12910409, 6423113, 3007856, 2818747, 4314113, 4492076,
2353 1318301, 5699478, 6593587, 9969727, 5266214, 2951996, 5987580, 974989,
2354 1796619, 2643085, 1324575, 8707739, 2009671, 19541453, 9380884, 646844,
2355 11542645, 3687050, 3825657, 12604767, 1053209, 4561242, 812383, 6296254,
2356 24782302, 2784572, 621760, 7882590, 6664195, 1819777, 5654774, 544270
2357 };
2358
2359 Double_t lon1 = -130;
2360 Double_t lon2 = -65;
2361 Double_t lat1 = 24;
2362 Double_t lat2 = 50;
2363 TH2Poly *p = new TH2Poly("USA","USA Population",lon1,lon2,lat1,lat2);
2364
2365 TFile::SetCacheFileDir(".");
2366 TFile *f = TFile::Open("http://root.cern.ch/files/usa.root", "CACHEREAD");
2367
2368 TMultiGraph *mg;
2369 TKey *key;
2370 TIter nextkey(gDirectory->GetListOfKeys());
2371 while ((key = (TKey*)nextkey())) {
2372 TObject *obj = key->ReadObj();
2373 if (obj->InheritsFrom("TMultiGraph")) {
2374 mg = (TMultiGraph*)obj;
2375 bin = p->AddBin(mg);
2376 }
2377 }
2378
2379 for (i=0; i<nx; i++) p->Fill(states[i], pop[i]);
2380
2381 gStyle->SetOptStat(11);
2382 p->Draw("COLZ L");
2383}
2384End_Macro
2385
2386`TH2Poly` histograms can also be plotted using the GL interface using
2387the option "GLLEGO".
2388
2389\since **ROOT version 6.09/01**
2390
2391In some cases it can be useful to not draw the empty bins. the option "0"
2392combined with the option "COL" et COLZ allows to do that.
2393
2394Begin_Macro(source)
2395{
2396 TCanvas *chc = new TCanvas("chc","chc",600,400);
2397
2398 TH2Poly *hc = new TH2Poly();
2399 hc->Honeycomb(0,0,.1,25,25);
2400 hc->SetName("hc");
2401 hc->SetTitle("Option COLZ 0");
2402 TRandom ran;
2403 for (int i = 0; i<300; i++) hc->Fill(ran.Gaus(2.,1), ran.Gaus(2.,1));
2404 hc->Draw("colz 0");
2405}
2406End_Macro
2407
2408### <a name="HP21"></a> The SPEC option
2409
2410
2411This option allows to use the `TSpectrum2Painter` tools. See the full
2412documentation in `TSpectrum2Painter::PaintSpectrum`.
2413
2414
2415### <a name="HP22"></a> Option "Z" : Adding the color palette on the right side of the pad
2416
2417
2418When this option is specified, a color palette with an axis indicating the value
2419of the corresponding color is drawn on the right side of the picture. In case,
2420not enough space is left, one can increase the size of the right margin by
2421calling `TPad::SetRightMargin()`. The attributes used to display the
2422palette axis values are taken from the Z axis of the object. For example, to
2423set the labels size on the palette axis do:
2424
2425 hist->GetZaxis()->SetLabelSize().
2426
2427<b>WARNING:</b> The palette axis is always drawn vertically.
2428
2429
2430### <a name="HP23"></a> Setting the color palette
2431
2432
2433To change the color palette `TStyle::SetPalette` should be used, eg:
2434
2435 gStyle->SetPalette(ncolors,colors);
2436
2437For example the option `COL` draws a 2D histogram with cells
2438represented by a box filled with a color index which is a function
2439of the cell content.
2440If the cell content is N, the color index used will be the color number
2441in `colors[N]`, etc. If the maximum cell content is greater than
2442`ncolors`, all cell contents are scaled to `ncolors`.
2443
2444If ` ncolors <= 0`, a default palette (see below) of 50 colors is
2445defined. This palette is recommended for pads, labels ...
2446
2447`if ncolors == 1 && colors == 0`, then a Pretty Palette with a
2448Spectrum Violet->Red is created with 50 colors. That's the default rain bow
2449palette.
2450
2451Other pre-defined palettes with 255 colors are available when `colors == 0`.
2452The following value of `ncolors` give access to:
2453
2454
2455 if ncolors = 51 and colors=0, a Deep Sea palette is used.
2456 if ncolors = 52 and colors=0, a Grey Scale palette is used.
2457 if ncolors = 53 and colors=0, a Dark Body Radiator palette is used.
2458 if ncolors = 54 and colors=0, a two-color hue palette palette is used.(dark blue through neutral gray to bright yellow)
2459 if ncolors = 55 and colors=0, a Rain Bow palette is used.
2460 if ncolors = 56 and colors=0, an inverted Dark Body Radiator palette is used.
2461
2462
2463If `ncolors > 0 && colors == 0`, the default palette is used with a maximum of ncolors.
2464
2465The default palette defines:
2466
2467- index 0 to 9 : shades of grey
2468- index 10 to 19 : shades of brown
2469- index 20 to 29 : shades of blue
2470- index 30 to 39 : shades of red
2471- index 40 to 49 : basic colors
2472
2473The color numbers specified in the palette can be viewed by selecting
2474the item `colors` in the `VIEW` menu of the canvas tool bar.
2475The red, green, and blue components of a color can be changed thanks to
2476`TColor::SetRGB()`.
2477
2478
2479### <a name="HP24"></a> Drawing a sub-range of a 2D histogram; the [cutg] option
2480
2481
2482Using a `TCutG` object, it is possible to draw a sub-range of a 2D
2483histogram. One must create a graphical cut (mouse or C++) and specify the name
2484of the cut between `[]` in the `Draw()` option.
2485For example (fit2a.C), with a `TCutG` named `cutg`, one can call:
2486
2487 myhist->Draw("surf1 [cutg]");
2488
2489To invert the cut, it is enough to put a `-` in front of its name:
2490
2491 myhist->Draw("surf1 [-cutg]");
2492
2493It is possible to apply several cuts (`,` means logical AND):
2494
2495 myhist->Draw("surf1 [cutg1,cutg2]");
2496
2497Begin_Macro(source)
2498../../../tutorials/fit/fit2a.C
2499End_Macro
2500
2501### <a name="HP25"></a> Drawing options for 3D histograms
2502
2503
2504| Option | Description |
2505|----------|-------------------------------------------------------------------|
2506| "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)`|
2507| "BOX" | Draw a for each cell with volume proportional to the content's absolute value. An hidden line removal algorithm is used|
2508| "BOX1" | Same as BOX but an hidden surface removal algorithm is used|
2509| "BOX2" | The boxes' colors are picked in the current palette according to the bins' contents|
2510| "BOX2Z" | Same as "BOX2". In addition the color palette is also drawn.|
2511| "BOX3" | Same as BOX1, but the border lines of each lego-bar are not drawn.|
2512
2513Note that instead of `BOX` one can also use `LEGO`.
2514
2515By default, like 2D histograms, 3D histograms are drawn as scatter plots.
2516
2517The following example shows a 3D histogram plotted as a scatter plot.
2518
2519Begin_Macro(source)
2520{
2521 auto c06 = new TCanvas("c06","c06",600,400);
2522 gStyle->SetOptStat(kFALSE);
2523 auto h3scat = new TH3F("h3scat","Option SCAT (default) ",15,-2,2,15,-2,2,15,0,4);
2524 Double_t x, y, z;
2525 for (Int_t i=0;i<10000;i++) {
2526 gRandom->Rannor(x, y);
2527 z = x*x + y*y;
2528 h3scat->Fill(x,y,z);
2529 }
2530 h3scat->Draw();
2531}
2532End_Macro
2533
2534The following example shows a 3D histogram plotted with the option `BOX`.
2535
2536Begin_Macro(source)
2537{
2538 auto c16 = new TCanvas("c16","c16",600,400);
2539 gStyle->SetOptStat(kFALSE);
2540 auto h3box = new TH3F("h3box","Option BOX",15,-2,2,15,-2,2,15,0,4);
2541 Double_t x, y, z;
2542 for (Int_t i=0;i<10000;i++) {
2543 gRandom->Rannor(x, y);
2544 z = x*x + y*y;
2545 h3box->Fill(x,y,z);
2546 }
2547 h3box->Draw("BOX");
2548}
2549End_Macro
2550
2551The following example shows a 3D histogram plotted with the option `BOX1`.
2552
2553Begin_Macro(source)
2554{
2555 auto c36 = new TCanvas("c36","c36",600,400);
2556 gStyle->SetOptStat(kFALSE);
2557 auto h3box = new TH3F("h3box","Option BOX1",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2558 Double_t x, y, z;
2559 for (Int_t i=0;i<10000;i++) {
2560 gRandom->Rannor(x, y);
2561 z = abs(sin(x)/x + cos(y)*y);
2562 h3box->Fill(x,y,z);
2563 }
2564 h3box->SetFillColor(9);
2565 h3box->Draw("BOX1");
2566}
2567End_Macro
2568
2569The following example shows a 3D histogram plotted with the option `BOX2`.
2570
2571Begin_Macro(source)
2572{
2573 auto c56 = new TCanvas("c56","c56",600,400);
2574 gStyle->SetOptStat(kFALSE);
2575 auto h3box = new TH3F("h3box","Option BOX2",10,-2.,2.,10,-2.,2.,10,-0.5,2.);
2576 Double_t x, y, z;
2577 for (Int_t i=0;i<10000;i++) {
2578 gRandom->Rannor(x, y);
2579 z = abs(sin(x)/x + cos(y)*y);
2580 h3box->Fill(x,y,z);
2581 }
2582 h3box->Draw("BOX2 Z");
2583}
2584End_Macro
2585
2586The following example shows a 3D histogram plotted with the option `BOX3`.
2587
2588Begin_Macro(source)
2589{
2590 auto c46 = new TCanvas("c46","c46",600,400);
2591 c46->SetFillColor(38);
2592 gStyle->SetOptStat(kFALSE);
2593 auto h3box = new TH3F("h3box","Option BOX3",15,-2,2,15,-2,2,15,0,4);
2594 Double_t x, y, z;
2595 for (Int_t i=0;i<10000;i++) {
2596 gRandom->Rannor(x, y);
2597 z = x*x + y*y;
2598 h3box->Fill(x,y,z);
2599 }
2600 h3box->Draw("BOX3");
2601}
2602End_Macro
2603
2604For all the `BOX` options each bin is drawn as a 3D box with a volume proportional
2605to the absolute value of the bin content. The bins with a negative content are
2606drawn with a X on each face of the box as shown in the following example:
2607
2608Begin_Macro(source)
2609{
2610 auto c = new TCanvas("c","c",600,400);
2611 gStyle->SetOptStat(kFALSE);
2612 auto h3box = new TH3F("h3box","Option BOX1 with negative bins",3, 0., 4., 3, 0.,4., 3, 0., 4.);
2613 h3box->Fill(0., 2., 2., 10.);
2614 h3box->Fill(2., 2., 2., 5.);
2615 h3box->Fill(2., 2., .5, 2.);
2616 h3box->Fill(2., 2., 3., -1.);
2617 h3box->Fill(3., 2., 2., -10.);
2618 h3box->SetFillColor(8);
2619 h3box->Draw("box1");
2620}
2621End_Macro
2622
2623The following example shows a 3D histogram plotted with the option `ISO`.
2624
2625Begin_Macro(source)
2626{
2627 auto c26 = new TCanvas("c26","c26",600,400);
2628 gStyle->SetOptStat(kFALSE);
2629 auto h3iso = new TH3F("h3iso","Option ISO",15,-2,2,15,-2,2,15,0,4);
2630 Double_t x, y, z;
2631 for (Int_t i=0;i<10000;i++) {
2632 gRandom->Rannor(x, y);
2633 z = x*x + y*y;
2634 h3iso->Fill(x,y,z);
2635 }
2636 h3iso->SetFillColor(kCyan);
2637 h3iso->Draw("ISO");
2638}
2639End_Macro
2640
2641
2642### <a name="HP26"></a> Drawing option for histograms' stacks
2643
2644
2645Stacks of histograms are managed with the `THStack`. A `THStack`
2646is a collection of `TH1` (or derived) objects. For painting only the
2647`THStack` containing `TH1` only or
2648`THStack` containing `TH2` only will be considered.
2649
2650By default, histograms are shown stacked:
2651
26521. The first histogram is paint.
26532. The the sum of the first and second, etc...
2654
2655If the option `NOSTACK` is specified, the histograms are all paint in
2656the same pad as if the option `SAME` had been specified. This allows to
2657compute X and Y scales common to all the histograms, like
2658`TMultiGraph` does for graphs.
2659
2660If the option `PADS` is specified, the current pad/canvas is
2661subdivided into a number of pads equal to the number of histograms and each
2662histogram is paint into a separate pad.
2663
2664The following example shows various types of stacks (hstack.C).
2665
2666Begin_Macro(source)
2667../../../tutorials/hist/hstack.C
2668End_Macro
2669
2670The option `nostackb` allows to draw the histograms next to each
2671other as bar charts:
2672
2673Begin_Macro(source)
2674{
2675 TCanvas *cst0 = new TCanvas("cst0","cst0",600,400);
2676 THStack *hs = new THStack("hs","Stacked 1D histograms: option #font[82]{\"nostackb\"}");
2677
2678 TH1F *h1 = new TH1F("h1","h1",10,-4,4);
2679 h1->FillRandom("gaus",20000);
2680 h1->SetFillColor(kRed);
2681 hs->Add(h1);
2682
2683 TH1F *h2 = new TH1F("h2","h2",10,-4,4);
2684 h2->FillRandom("gaus",15000);
2685 h2->SetFillColor(kBlue);
2686 hs->Add(h2);
2687
2688 TH1F *h3 = new TH1F("h3","h3",10,-4,4);
2689 h3->FillRandom("gaus",10000);
2690 h3->SetFillColor(kGreen);
2691 hs->Add(h3);
2692
2693 hs->Draw("nostackb");
2694 hs->GetXaxis()->SetNdivisions(-10);
2695 cst0->SetGridx();
2696 return cst0;
2697}
2698End_Macro
2699
2700If at least one of the histograms in the stack has errors, the whole stack is
2701visualized by default with error bars. To visualize it without errors the
2702option `HIST` should be used.
2703
2704Begin_Macro(source)
2705{
2706 TCanvas *cst1 = new TCanvas("cst1","cst1",700,400);
2707 cst1->Divide(2,1);
2708
2709 TH1F * hst11 = new TH1F("hst11", "", 20, -10, 10);
2710 hst11->Sumw2();
2711 hst11->FillRandom("gaus", 1000);
2712 hst11->SetFillColor(kViolet);
2713 hst11->SetLineColor(kViolet);
2714
2715 TH1F * hst12 = new TH1F("hst12", "", 20, -10, 10);
2716 hst12->FillRandom("gaus", 500);
2717 hst12->SetFillColor(kBlue);
2718 hst12->SetLineColor(kBlue);
2719
2720 THStack st1("st1", "st1");
2721 st1.Add(hst11);
2722 st1.Add(hst12);
2723
2724 cst1->cd(1); st1.Draw();
2725 cst1->cd(2); st1.Draw("hist");
2726
2727 return cst1;
2728}
2729End_Macro
2730
2731### <a name="HP27"></a> Drawing of 3D implicit functions
2732
2733
27343D implicit functions (`TF3`) can be drawn as iso-surfaces.
2735The implicit function f(x,y,z) = 0 is drawn in cartesian coordinates.
2736In the following example the options "FB" and "BB" suppress the
2737"Front Box" and "Back Box" around the plot.
2738
2739Begin_Macro(source)
2740{
2741 TCanvas *c2 = new TCanvas("c2","c2",600,400);
2742 TF3 *f3 = new TF3("f3","sin(x*x+y*y+z*z-36)",-2,2,-2,2,-2,2);
2743 f3->SetClippingBoxOn(0,0,0);
2744 f3->SetFillColor(30);
2745 f3->SetLineColor(15);
2746 f3->Draw("FBBB");
2747 return c2;
2748}
2749End_Macro
2750
2751
2752### <a name="HP28"></a> Associated functions drawing
2753
2754
2755An associated function is created by `TH1::Fit`. More than on fitted
2756function can be associated with one histogram (see `TH1::Fit`).
2757
2758A `TF1` object `f1` can be added to the list of associated
2759functions of an histogram `h` without calling `TH1::Fit`
2760simply doing:
2761
2762 h->GetListOfFunctions()->Add(f1);
2763
2764or
2765
2766 h->GetListOfFunctions()->Add(f1,someoption);
2767
2768To retrieve a function by name from this list, do:
2769
2770 TF1 *f1 = (TF1*)h->GetListOfFunctions()->FindObject(name);
2771
2772or
2773
2774 TF1 *f1 = h->GetFunction(name);
2775
2776Associated functions are automatically painted when an histogram is drawn.
2777To avoid the painting of the associated functions the option `HIST`
2778should be added to the list of the options used to paint the histogram.
2779
2780
2781### <a name="HP29"></a> Drawing using OpenGL
2782
2783
2784The class `TGLHistPainter` allows to paint data set using the OpenGL 3D
2785graphics library. The plotting options start with `GL` keyword.
2786In addition, in order to inform canvases that OpenGL should be used to render
27873D representations, the following option should be set:
2788
2789 gStyle->SetCanvasPreferGL(true);
2790
2791
2792#### <a name="HP29a"></a> General information: plot types and supported options
2793
2794The following types of plots are provided:
2795
2796For lego plots the supported options are:
2797
2798| Option | Description |
2799|----------|-------------------------------------------------------------------|
2800| "GLLEGO" | Draw a lego plot. It works also for `TH2Poly`.|
2801| "GLLEGO2"| Bins with color levels.|
2802| "GLLEGO3"| Cylindrical bars.|
2803
2804
2805
2806Lego painter in cartesian supports logarithmic scales for X, Y, Z.
2807In polar only Z axis can be logarithmic, in cylindrical only Y.
2808
2809For surface plots (`TF2` and `TH2`) the supported options are:
2810
2811| Option | Description |
2812|-----------|------------------------------------------------------------------|
2813| "GLSURF" | Draw a surface.|
2814| "GLSURF1" | Surface with color levels|
2815| "GLSURF2" | The same as "GLSURF1" but without polygon outlines.|
2816| "GLSURF3" | Color level projection on top of plot (works only in cartesian coordinate system).|
2817| "GLSURF4" | Same as "GLSURF" but without polygon outlines.|
2818
2819
2820
2821The surface painting in cartesian coordinates supports logarithmic scales along
2822X, Y, Z axis. In polar coordinates only the Z axis can be logarithmic,
2823in cylindrical coordinates only the Y axis.
2824
2825Additional options to SURF and LEGO - Coordinate systems:
2826
2827| Option | Description |
2828|----------|-------------------------------------------------------------------|
2829| " " | Default, cartesian coordinates system.|
2830| "POL" | Polar coordinates system.|
2831| "CYL" | Cylindrical coordinates system.|
2832| "SPH" | Spherical coordinates system.|
2833
2834
2835
2836#### <a name="HP290"></a> TH3 as color boxes
2837
2838The supported option is:
2839
2840| Option | Description |
2841|----------|-------------------------------------------------------------------|
2842| "GLCOL" | H3 is drawn using semi-transparent colored boxes. See `$ROOTSYS/tutorials/gl/glvox1.C`.|
2843
2844
2845
2846#### <a name="HP29b"></a> TH3 as boxes (spheres)
2847
2848The supported options are:
2849
2850| Option | Description |
2851|----------|-------------------------------------------------------------------|
2852| "GLBOX" | TH3 as a set of boxes, size of box is proportional to bin content.|
2853| "GLBOX1" | The same as "glbox", but spheres are drawn instead of boxes.|
2854
2855
2856
2857#### <a name="HP29c"></a> TH3 as iso-surface(s)
2858
2859The supported option is:
2860
2861| Option | Description |
2862|----------|-------------------------------------------------------------------|
2863| "GLISO" | TH3 is drawn using iso-surfaces.|
2864
2865
2866
2867#### <a name="HP29d"></a> TF3 (implicit function)
2868
2869The supported option is:
2870
2871| Option | Description |
2872|----------|-------------------------------------------------------------------|
2873| "GLTF3" | Draw a TF3.|
2874
2875
2876
2877#### <a name="HP29e"></a> Parametric surfaces
2878
2879`$ROOTSYS/tutorials/gl/glparametric.C` shows how to create parametric
2880equations and visualize the surface.
2881
2882#### <a name="HP29f"></a> Interaction with the plots
2883
2884All the interactions are implemented via standard methods
2885`DistancetoPrimitive()` and `ExecuteEvent()`. That's why all the
2886interactions with the OpenGL plots are possible only when the mouse cursor is
2887in the plot's area (the plot's area is the part of a the pad occupied by
2888gl-produced picture). If the mouse cursor is not above gl-picture, the standard
2889pad interaction is performed.
2890
2891#### <a name="HP29g"></a> Selectable parts
2892
2893Different parts of the plot can be selected:
2894
2895- xoz, yoz, xoy back planes: When such a plane selected, it's highlighted in green
2896 if the dynamic slicing by this plane is supported, and it's highlighted in red,
2897 if the dynamic slicing is not supported.
2898- The plot itself:
2899 On surfaces, the selected surface is outlined in red. (TF3 and
2900 ISO are not outlined). On lego plots, the selected bin is
2901 highlighted. The bin number and content are displayed in pad's
2902 status bar. In box plots, the box or sphere is highlighted and
2903 the bin info is displayed in pad's status bar.
2904
2905
2906#### <a name="HP29h"></a> Rotation and zooming
2907
2908
2909- Rotation:
2910 When the plot is selected, it can be rotated by pressing and
2911 holding the left mouse button and move the cursor.
2912- Zoom/Unzoom:
2913 Mouse wheel or 'j', 'J', 'k', 'K' keys.
2914
2915
2916#### <a name="HP29i"></a> Panning
2917
2918The selected plot can be moved in a pad's area by pressing and
2919holding the left mouse button and the shift key.
2920
2921#### <a name="HP29j"></a> Box cut
2922
2923Surface, iso, box, TF3 and parametric painters support box cut by
2924pressing the 'c' or 'C' key when the mouse cursor is in a plot's
2925area. That will display a transparent box, cutting away part of the
2926surface (or boxes) in order to show internal part of plot. This box
2927can be moved inside the plot's area (the full size of the box is
2928equal to the plot's surrounding box) by selecting one of the box
2929cut axes and pressing the left mouse button to move it.
2930
2931#### <a name="HP29k"></a> Plot specific interactions (dynamic slicing etc.)
2932
2933Currently, all gl-plots support some form of slicing. When back plane
2934is selected (and if it's highlighted in green) you can press and hold
2935left mouse button and shift key and move this back plane inside
2936plot's area, creating the slice. During this "slicing" plot becomes
2937semi-transparent. To remove all slices (and projected curves for
2938surfaces) double click with left mouse button in a plot's area.
2939
2940#### <a name="HP29l"></a> Surface with option "GLSURF"
2941
2942The surface profile is displayed on the slicing plane.
2943The profile projection is drawn on the back plane
2944by pressing `'p'` or `'P'` key.
2945
2946#### <a name="HP29m"></a> TF3
2947
2948The contour plot is drawn on the slicing plane. For TF3 the color
2949scheme can be changed by pressing 's' or 'S'.
2950
2951#### <a name="HP29n"></a> Box
2952
2953The contour plot corresponding to slice plane position is drawn in real time.
2954
2955#### <a name="HP29o"></a> Iso
2956
2957Slicing is similar to "GLBOX" option.
2958
2959#### <a name="HP29p"></a> Parametric plot
2960
2961No slicing. Additional keys: 's' or 'S' to change color scheme -
2962about 20 color schemes supported ('s' for "scheme"); 'l' or 'L' to
2963increase number of polygons ('l' for "level" of details), 'w' or 'W'
2964to show outlines ('w' for "wireframe").
2965
2966#### <a name="HP30"></a> Highlight mode for histogram
2967
2968\since **ROOT version 6.15/01**
2969
2970\image html hlHisto3_top.gif "Highlight mode"
2971
2972Highlight mode is implemented for `TH1` (and for `TGraph`) class. When
2973highlight mode is on, mouse movement over the bin will be represented
2974graphically. Bin will be highlighted as "bin box" (presented by box
2975object). Moreover, any highlight (change of bin) emits signal
2976`TCanvas::Highlighted()` which allows the user to react and call their own
2977function. For a better understanding see also the tutorials
2978`$ROOTSYS/tutorials/hist/hlHisto*.C` files.
2979
2980Highlight mode is switched on/off by `TH1::SetHighlight()` function
2981or interactively from `TH1` context menu. `TH1::IsHighlight()` to verify
2982whether the highlight mode enabled or disabled, default it is disabled.
2983
2984~~~ {.cpp}
2985 root [0] .x $ROOTSYS/tutorials/hsimple.C
2986 root [1] hpx->SetHighlight(kTRUE) // or interactively from TH1 context menu
2987 root [2] hpx->IsHighlight()
2988 (bool) true
2989~~~
2990
2991\image html hlsimple_nofun.gif "Highlight mode for histogram"
2992
2993#### <a name="HP30a"></a> Highlight mode and user function
2994
2995The user can use (connect) `TCanvas::Highlighted()` signal, which is always
2996emitted if there is a highlight bin and call user function via signal
2997and slot communication mechanism. `TCanvas::Highlighted()` is similar
2998`TCanvas::Picked()`
2999
3000- when selected object (histogram as a whole) is different from previous
3001then emit `Picked()` signal
3002- when selected (highlighted) bin from histogram is different from previous
3003then emit `Highlighted()` signal
3004
3005Any user function (or functions) has to be defined
3006`UserFunction(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)`.
3007In example (see below) has name `PrintInfo()`. All parameters of user
3008function are taken from
3009
3010 void TCanvas::Highlighted(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3011
3012- `pad` is pointer to pad with highlighted histogram
3013- `obj` is pointer to highlighted histogram
3014- `x` is highlighted x bin for 1D histogram
3015- `y` is highlighted y bin for 2D histogram (for 1D histogram not in use)
3016
3017Example how to create a connection from any `TCanvas` object to a user
3018`UserFunction()` slot (see also `TQObject::Connect()` for additional info)
3019
3020 TQObject::Connect("TCanvas", "Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
3021 0, 0, "UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3022
3023or use non-static "simplified" function
3024`TCanvas::HighlightConnect(const char *slot)`
3025
3026 c1->HighlightConnect("UserFunction(TVirtualPad*,TObject*,Int_t,Int_t)");
3027
3028NOTE the signal and slot string must have a form
3029"(TVirtualPad*,TObject*,Int_t,Int_t)"
3030
3031 root [0] .x $ROOTSYS/tutorials/hsimple.C
3032 root [1] hpx->SetHighlight(kTRUE)
3033 root [2] .x hlprint.C
3034
3035file `hlprint.C`
3036~~~ {.cpp}
3037void PrintInfo(TVirtualPad *pad, TObject *obj, Int_t x, Int_t y)
3038{
3039 TH1F *h = (TH1F *)obj;
3040 if (!h->IsHighlight()) // after highlight disabled
3041 h->SetTitle("highlight disable");
3042 else
3043 h->SetTitle(TString::Format("bin[%03d] (%5.2f) content %g", x,
3044 h->GetBinCenter(x), h->GetBinContent(x)));
3045 pad->Update();
3046}
3047
3048void hlprint()
3049{
3050 if (!gPad) return;
3051 gPad->GetCanvas()->HighlightConnect("PrintInfo(TVirtualPad*,TObject*,Int_t,Int_t)");
3052}
3053~~~
3054
3055\image html hlsimple.gif "Highlight mode and simple user function"
3056
3057For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperature.C` file.
3058
3059*/
3060
3062
3065
3066const Int_t kNMAX = 2000;
3067
3068const Int_t kMAXCONTOUR = 104;
3070
3071static TBox *gXHighlightBox = 0; // highlight X box
3072static TBox *gYHighlightBox = 0; // highlight Y box
3073
3095
3097
3098////////////////////////////////////////////////////////////////////////////////
3099/// Default constructor.
3100
3102{
3103
3104 fH = 0;
3105 fXaxis = 0;
3106 fYaxis = 0;
3107 fZaxis = 0;
3108 fFunctions = 0;
3109 fXbuf = 0;
3110 fYbuf = 0;
3111 fNcuts = 0;
3112 fStack = 0;
3113 fLego = 0;
3114 fPie = 0;
3115 fGraph2DPainter = 0;
3116 fShowProjection = 0;
3117 fShowOption = "";
3118 for (int i=0; i<kMaxCuts; i++) {
3119 fCuts[i] = 0;
3120 fCutsOpt[i] = 0;
3121 }
3122 fXHighlightBin = -1;
3123 fYHighlightBin = -1;
3124
3125 gStringEntries = gEnv->GetValue("Hist.Stats.Entries", "Entries");
3126 gStringMean = gEnv->GetValue("Hist.Stats.Mean", "Mean");
3127 gStringMeanX = gEnv->GetValue("Hist.Stats.MeanX", "Mean x");
3128 gStringMeanY = gEnv->GetValue("Hist.Stats.MeanY", "Mean y");
3129 gStringMeanZ = gEnv->GetValue("Hist.Stats.MeanZ", "Mean z");
3130 gStringStdDev = gEnv->GetValue("Hist.Stats.StdDev", "Std Dev");
3131 gStringStdDevX = gEnv->GetValue("Hist.Stats.StdDevX", "Std Dev x");
3132 gStringStdDevY = gEnv->GetValue("Hist.Stats.StdDevY", "Std Dev y");
3133 gStringStdDevZ = gEnv->GetValue("Hist.Stats.StdDevZ", "Std Dev z");
3134 gStringUnderflow = gEnv->GetValue("Hist.Stats.Underflow", "Underflow");
3135 gStringOverflow = gEnv->GetValue("Hist.Stats.Overflow", "Overflow");
3136 gStringIntegral = gEnv->GetValue("Hist.Stats.Integral", "Integral");
3137 gStringIntegralBinWidth = gEnv->GetValue("Hist.Stats.IntegralBinWidth", "Integral(w)");
3138 gStringSkewness = gEnv->GetValue("Hist.Stats.Skewness", "Skewness");
3139 gStringSkewnessX = gEnv->GetValue("Hist.Stats.SkewnessX", "Skewness x");
3140 gStringSkewnessY = gEnv->GetValue("Hist.Stats.SkewnessY", "Skewness y");
3141 gStringSkewnessZ = gEnv->GetValue("Hist.Stats.SkewnessZ", "Skewness z");
3142 gStringKurtosis = gEnv->GetValue("Hist.Stats.Kurtosis", "Kurtosis");
3143 gStringKurtosisX = gEnv->GetValue("Hist.Stats.KurtosisX", "Kurtosis x");
3144 gStringKurtosisY = gEnv->GetValue("Hist.Stats.KurtosisY", "Kurtosis y");
3145 gStringKurtosisZ = gEnv->GetValue("Hist.Stats.KurtosisZ", "Kurtosis z");
3146}
3147
3148////////////////////////////////////////////////////////////////////////////////
3149/// Default destructor.
3150
3152{
3153}
3154
3155////////////////////////////////////////////////////////////////////////////////
3156/// Compute the distance from the point px,py to a line.
3157///
3158/// Compute the closest distance of approach from point px,py to elements of
3159/// an histogram. The distance is computed in pixels units.
3160///
3161/// Algorithm: Currently, this simple model computes the distance from the mouse
3162/// to the histogram contour only.
3163
3165{
3166
3167 Double_t defaultLabelSize = 0.04; // See TAttAxis.h for source of this value
3168
3169 const Int_t big = 9999;
3170 const Int_t kMaxDiff = 7;
3171
3172 if (fPie) return fPie->DistancetoPrimitive(px, py);
3173
3174 Double_t x = gPad->AbsPixeltoX(px);
3175 Double_t x1 = gPad->AbsPixeltoX(px+1);
3176
3177 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
3178 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
3179 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
3180 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
3181 Int_t curdist = big;
3182 Int_t yxaxis, dyaxis,xyaxis, dxaxis;
3183 Bool_t dsame;
3184 TObject *PadPointer = gPad->GetPadPointer();
3185 if (!PadPointer) return 0;
3186 TString doption = PadPointer->GetDrawOption();
3187 Double_t factor = 1;
3188 if (fH->GetNormFactor() != 0) {
3189 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3190 }
3191 // return if point is not in the histogram area
3192
3193 // If a 3D view exists, check distance to axis
3194 TView *view = gPad->GetView();
3195 Int_t d1,d2,d3;
3196 if (view && Hoption.Contour != 14) {
3197 Double_t ratio;
3198 d3 = view->GetDistancetoAxis(3, px, py, ratio);
3199 if (d3 <= kMaxDiff) {gPad->SetSelected(fZaxis); return 0;}
3200 d1 = view->GetDistancetoAxis(1, px, py, ratio);
3201 if (d1 <= kMaxDiff) {gPad->SetSelected(fXaxis); return 0;}
3202 d2 = view->GetDistancetoAxis(2, px, py, ratio);
3203 if (d2 <= kMaxDiff) {gPad->SetSelected(fYaxis); return 0;}
3204 if ( px > puxmin && px < puxmax && py > puymax && py < puymin) curdist = 1;
3205 goto FUNCTIONS;
3206 }
3207 // check if point is close to an axis
3208 doption.ToLower();
3209 dsame = kFALSE;
3210 if (doption.Contains("same")) dsame = kTRUE;
3211
3212 dyaxis = Int_t(2*(puymin-puymax)*TMath::Max(Double_t(fYaxis->GetLabelSize()), defaultLabelSize));
3213 if (doption.Contains("y+")) {
3214 xyaxis = puxmax + Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3215 if (px <= xyaxis+dyaxis && px >= xyaxis && py >puymax && py < puymin) {
3216 if (!dsame) {
3217 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3218 else gPad->SetSelected(fXaxis);
3219 return 0;
3220 }
3221 }
3222 } else {
3223 xyaxis = puxmin - Int_t((puxmax-puxmin)*fYaxis->GetLabelOffset());
3224 if (px >= xyaxis-dyaxis && px <= xyaxis && py >puymax && py < puymin) {
3225 if (!dsame) {
3226 if (gPad->IsVertical()) gPad->SetSelected(fYaxis);
3227 else gPad->SetSelected(fXaxis);
3228 return 0;
3229 }
3230 }
3231 }
3232
3233 dxaxis = Int_t((puymin-puymax)*TMath::Max(Double_t(fXaxis->GetLabelSize()), defaultLabelSize));
3234 if (doption.Contains("x+")) {
3235 yxaxis = puymax - Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3236 if (py >= yxaxis-dxaxis && py <= yxaxis && px <puxmax && px > puxmin) {
3237 if (!dsame) {
3238 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3239 else gPad->SetSelected(fYaxis);
3240 return 0;
3241 }
3242 }
3243 } else {
3244 yxaxis = puymin + Int_t((puymin-puymax)*fXaxis->GetLabelOffset());
3245 if (yxaxis < puymin) yxaxis = puymin;
3246 if (py <= yxaxis+dxaxis && py >= yxaxis && px <puxmax && px > puxmin) {
3247 if (!dsame) {
3248 if (gPad->IsVertical()) gPad->SetSelected(fXaxis);
3249 else gPad->SetSelected(fYaxis);
3250 return 0;
3251 }
3252 }
3253 }
3254
3255 if (fH->IsHighlight()) { // only if highlight is enable
3256 if ((px > puxmin) && (py < puymin) && (px < puxmax) && (py > puymax))
3257 HighlightBin(px, py);
3258 }
3259
3260 // if object is 2D or 3D return this object
3261 if (fH->GetDimension() == 2) {
3262 if (fH->InheritsFrom(TH2Poly::Class())) {
3263 TH2Poly *th2 = (TH2Poly*)fH;
3265 gPad->GetRangeAxis(xmin, ymin, xmax, ymax);
3266 Double_t pxu = gPad->AbsPixeltoX(px);
3267 Double_t pyu = gPad->AbsPixeltoY(py);
3268 if ((pxu>xmax) || (pxu < xmin) || (pyu>ymax) || (pyu < ymin)) {
3269 curdist = big;
3270 goto FUNCTIONS;
3271 } else {
3272 Int_t bin = th2->FindBin(pxu, pyu);
3273 if (bin>0) curdist = 1;
3274 else curdist = big;
3275 goto FUNCTIONS;
3276 }
3277 }
3278 Int_t delta2 = 5; //Give a margin of delta2 pixels to be in the 2-d area
3279 if ( px > puxmin + delta2
3280 && px < puxmax - delta2
3281 && py > puymax + delta2
3282 && py < puymin - delta2) {curdist =1; goto FUNCTIONS;}
3283 }
3284
3285 // point is inside histogram area. Find channel number
3286 if (gPad->IsVertical()) {
3287 Int_t bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3288 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoX(x1));
3289 Double_t binval = factor*fH->GetBinContent(bin);
3290 Int_t pybin = gPad->YtoAbsPixel(gPad->YtoPad(binval));
3291 if (binval == 0 && pybin < puymin) pybin = 10000;
3292 // special case if more than one bin for the pixel
3293 if (binsup-bin>1) {
3294 Double_t binvalmin, binvalmax;
3295 binvalmin=binval;
3296 binvalmax=binval;
3297 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3298 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3299 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3300 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3301 }
3302 Int_t pybinmin = gPad->YtoAbsPixel(gPad->YtoPad(binvalmax));
3303 Int_t pybinmax = gPad->YtoAbsPixel(gPad->YtoPad(binvalmin));
3304 if (py<pybinmax+kMaxDiff/2 && py>pybinmin-kMaxDiff/2) pybin = py;
3305 }
3306 if (bin != binsup) { // Mouse on bin border
3307 Double_t binsupval = factor*fH->GetBinContent(binsup);
3308 Int_t pybinsub = gPad->YtoAbsPixel(gPad->YtoPad(binsupval));
3309 if (py <= TMath::Max(pybinsub,pybin) && py >= TMath::Min(pybinsub,pybin) && pybin != 10000) return 0;
3310 }
3311 if (TMath::Abs(py - pybin) <= kMaxDiff) return TMath::Abs(py - pybin);
3312 } else {
3313 Double_t y = gPad->AbsPixeltoY(py);
3314 Double_t y1 = gPad->AbsPixeltoY(py+1);
3315 Int_t bin = fXaxis->FindFixBin(gPad->PadtoY(y));
3316 Int_t binsup = fXaxis->FindFixBin(gPad->PadtoY(y1));
3317 Double_t binval = factor*fH->GetBinContent(bin);
3318 Int_t pxbin = gPad->XtoAbsPixel(gPad->XtoPad(binval));
3319 if (binval == 0 && pxbin > puxmin) pxbin = 10000;
3320 // special case if more than one bin for the pixel
3321 if (binsup-bin>1) {
3322 Double_t binvalmin, binvalmax;
3323 binvalmin=binval;
3324 binvalmax=binval;
3325 for (Int_t ibin=bin+1; ibin<binsup; ibin++) {
3326 Double_t binvaltmp = factor*fH->GetBinContent(ibin);
3327 if (binvalmin>binvaltmp) binvalmin=binvaltmp;
3328 if (binvalmax<binvaltmp) binvalmax=binvaltmp;
3329 }
3330 Int_t pxbinmin = gPad->XtoAbsPixel(gPad->XtoPad(binvalmax));
3331 Int_t pxbinmax = gPad->XtoAbsPixel(gPad->XtoPad(binvalmin));
3332 if (px<pxbinmax+kMaxDiff/2 && px>pxbinmin-kMaxDiff/2) pxbin = px;
3333 }
3334 if (TMath::Abs(px - pxbin) <= kMaxDiff) return TMath::Abs(px - pxbin);
3335 }
3336 // Loop on the list of associated functions and user objects
3337FUNCTIONS:
3338 TObject *f;
3339 TIter next(fFunctions);
3340 while ((f = (TObject*) next())) {
3341 Int_t dist;
3342 if (f->InheritsFrom(TF1::Class())) dist = f->DistancetoPrimitive(-px,py);
3343 else dist = f->DistancetoPrimitive(px,py);
3344 if (dist < kMaxDiff) {gPad->SetSelected(f); return dist;}
3345 }
3346 return curdist;
3347}
3348
3349////////////////////////////////////////////////////////////////////////////////
3350/// Display a panel with all histogram drawing options.
3351
3353{
3354
3355 gCurrentHist = fH;
3356 if (!gPad) {
3357 Error("DrawPanel", "need to draw histogram first");
3358 return;
3359 }
3361 editor->Show();
3362 gROOT->ProcessLine(Form("((TCanvas*)0x%lx)->Selected((TVirtualPad*)0x%lx,(TObject*)0x%lx,1)",
3363 (ULong_t)gPad->GetCanvas(), (ULong_t)gPad, (ULong_t)fH));
3364}
3365
3366////////////////////////////////////////////////////////////////////////////////
3367/// Execute the actions corresponding to `event`.
3368///
3369/// This function is called when a histogram is clicked with the locator at
3370/// the pixel position px,py.
3371
3373{
3374
3375 if (!gPad) return;
3376
3377 static Int_t bin, px1, py1, px2, py2, pyold;
3378 static TBox *zoombox;
3379 Double_t zbx1,zbx2,zby1,zby2;
3380
3381 Int_t bin1, bin2;
3382 Double_t xlow, xup, ylow, binval, x, baroffset, barwidth, binwidth;
3383 Bool_t opaque = gPad->OpaqueMoving();
3384
3385 if (!gPad->IsEditable()) return;
3386
3387 if (fPie) {
3388 fPie->ExecuteEvent(event, px, py);
3389 return;
3390 }
3391 // come here if we have a lego/surface in the pad
3392 TView *view = gPad->GetView();
3393
3394 if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) {
3395 view->ExecuteRotateView(event, px, py);
3396 return;
3397 }
3398
3399 TAxis *xaxis = fH->GetXaxis();
3400 TAxis *yaxis = fH->GetYaxis();
3401 Int_t dimension = fH->GetDimension();
3402
3403 Double_t factor = 1;
3404 if (fH->GetNormFactor() != 0) {
3405 factor = fH->GetNormFactor()/fH->GetSumOfWeights();
3406 }
3407
3408 switch (event) {
3409
3410 case kButton1Down:
3411
3412 if (!opaque) gVirtualX->SetLineColor(-1);
3413 fH->TAttLine::Modify();
3414
3415 if (opaque && dimension ==2) {
3416 zbx1 = gPad->AbsPixeltoX(px);
3417 zbx2 = gPad->AbsPixeltoX(px);
3418 zby1 = gPad->AbsPixeltoY(py);
3419 zby2 = gPad->AbsPixeltoY(py);
3420 px1 = px;
3421 py1 = py;
3422 if (gPad->GetLogx()) {
3423 zbx1 = TMath::Power(10,zbx1);
3424 zbx2 = TMath::Power(10,zbx2);
3425 }
3426 if (gPad->GetLogy()) {
3427 zby1 = TMath::Power(10,zby1);
3428 zby2 = TMath::Power(10,zby2);
3429 }
3430 zoombox = new TBox(zbx1, zby1, zbx2, zby2);
3431 Int_t ci = TColor::GetColor("#7d7dff");
3432 TColor *zoomcolor = gROOT->GetColor(ci);
3433 if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
3434 else zoomcolor->SetAlpha(0.5);
3435 zoombox->SetFillColor(ci);
3436 zoombox->Draw();
3437 gPad->Modified();
3438 gPad->Update();
3439 }
3440 // No break !!!
3441
3442 case kMouseMotion:
3443
3444 if (fShowProjection) {ShowProjection3(px,py); break;}
3445
3446 gPad->SetCursor(kPointer);
3447 if (dimension ==1) {
3448 if (Hoption.Bar) {
3449 baroffset = fH->GetBarOffset();
3450 barwidth = fH->GetBarWidth();
3451 } else {
3452 baroffset = 0;
3453 barwidth = 1;
3454 }
3455 x = gPad->AbsPixeltoX(px);
3456 bin = fXaxis->FindFixBin(gPad->PadtoX(x));
3457 binwidth = fXaxis->GetBinWidth(bin);
3458 xlow = gPad->XtoPad(fXaxis->GetBinLowEdge(bin) + baroffset*binwidth);
3459 xup = gPad->XtoPad(xlow + barwidth*binwidth);
3460 ylow = gPad->GetUymin();
3461 px1 = gPad->XtoAbsPixel(xlow);
3462 px2 = gPad->XtoAbsPixel(xup);
3463 py1 = gPad->YtoAbsPixel(ylow);
3464 py2 = py;
3465 pyold = py;
3466 if (gROOT->GetEditHistograms()) gPad->SetCursor(kArrowVer);
3467 }
3468
3469 break;
3470
3471 case kButton1Motion:
3472
3473 if (dimension ==1) {
3474 if (gROOT->GetEditHistograms()) {
3475 if (!opaque) {
3476 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the old box
3477 py2 += py - pyold;
3478 gVirtualX->DrawBox(px1, py1, px2, py2,TVirtualX::kHollow); // Draw the new box
3479 pyold = py;
3480 } else {
3481 py2 += py - pyold;
3482 pyold = py;
3483 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3484 fH->SetBinContent(bin,binval);
3485 gPad->Modified(kTRUE);
3486 }
3487 }
3488 }
3489
3490 if (opaque && dimension ==2) {
3491 if (TMath::Abs(px1-px)>5 && TMath::Abs(py1-py)>5) {
3492 zbx2 = gPad->AbsPixeltoX(px);
3493 zby2 = gPad->AbsPixeltoY(py);
3494 if (gPad->GetLogx()) zbx2 = TMath::Power(10,zbx2);
3495 if (gPad->GetLogy()) zby2 = TMath::Power(10,zby2);
3496 zoombox->SetX2(zbx2);
3497 zoombox->SetY2(zby2);
3498 gPad->Modified();
3499 gPad->Update();
3500 }
3501 }
3502
3503 break;
3504
3505 case kWheelUp:
3506
3507 if (dimension ==2) {
3508 bin1 = xaxis->GetFirst()+1;
3509 bin2 = xaxis->GetLast()-1;
3510 bin1 = TMath::Max(bin1, 1);
3511 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3512 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3513 bin1 = yaxis->GetFirst()+1;
3514 bin2 = yaxis->GetLast()-1;
3515 bin1 = TMath::Max(bin1, 1);
3516 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3517 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3518 }
3519 gPad->Modified();
3520 gPad->Update();
3521
3522 break;
3523
3524 case kWheelDown:
3525
3526 if (dimension == 2) {
3527 bin1 = xaxis->GetFirst()-1;
3528 bin2 = xaxis->GetLast()+1;
3529 bin1 = TMath::Max(bin1, 1);
3530 bin2 = TMath::Min(bin2, xaxis->GetNbins());
3531 if (bin2>bin1) xaxis->SetRange(bin1,bin2);
3532 bin1 = yaxis->GetFirst()-1;
3533 bin2 = yaxis->GetLast()+1;
3534 bin1 = TMath::Max(bin1, 1);
3535 bin2 = TMath::Min(bin2, yaxis->GetNbins());
3536 if (bin2>bin1) yaxis->SetRange(bin1,bin2);
3537 }
3538 gPad->Modified();
3539 gPad->Update();
3540
3541 break;
3542
3543 case kButton1Up:
3544 if (dimension ==1) {
3545 if (gROOT->GetEditHistograms()) {
3546 binval = gPad->PadtoY(gPad->AbsPixeltoY(py2))/factor;
3547 fH->SetBinContent(bin,binval);
3548 PaintInit(); // recalculate Hparam structure and recalculate range
3549 }
3550
3551 // might resize pad pixmap so should be called before any paint routine
3553 }
3554 if (opaque && dimension ==2) {
3555 if (zoombox) {
3556 Double_t x1 = TMath::Min(zoombox->GetX1(), zoombox->GetX2());
3557 Double_t x2 = TMath::Max(zoombox->GetX1(), zoombox->GetX2());
3558 Double_t y1 = TMath::Min(zoombox->GetY1(), zoombox->GetY2());
3559 Double_t y2 = TMath::Max(zoombox->GetY1(), zoombox->GetY2());
3560 x1 = TMath::Max(x1,xaxis->GetXmin());
3561 x2 = TMath::Min(x2,xaxis->GetXmax());
3562 y1 = TMath::Max(y1,yaxis->GetXmin());
3563 y2 = TMath::Min(y2,yaxis->GetXmax());
3564 if (x1<x2 && y1<y2) {
3565 xaxis->SetRangeUser(x1, x2);
3566 yaxis->SetRangeUser(y1, y2);
3567 }
3568 zoombox->Delete();
3569 zoombox = 0;
3570 }
3571 }
3572 gPad->Modified(kTRUE);
3573 if (opaque) gVirtualX->SetLineColor(-1);
3574
3575 break;
3576
3577 case kButton1Locate:
3578
3579 ExecuteEvent(kButton1Down, px, py);
3580
3581 while (1) {
3582 px = py = 0;
3583 event = gVirtualX->RequestLocator(1, 1, px, py);
3584
3586
3587 if (event != -1) { // button is released
3588 ExecuteEvent(kButton1Up, px, py);
3589 return;
3590 }
3591 }
3592 }
3593}
3594
3595////////////////////////////////////////////////////////////////////////////////
3596/// Get a contour (as a list of TGraphs) using the Delaunay triangulation.
3597
3599{
3600
3601
3602
3603 // Check if fH contains a TGraphDelaunay2D
3604 TList *hl = fH->GetListOfFunctions();
3605 TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
3606 // try with the old painter
3607 TGraphDelaunay *dtOld = nullptr;
3608 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
3609
3610 if (!dt && !dtOld) return nullptr;
3611
3612 gCurrentHist = fH;
3613
3614 if (!fGraph2DPainter) {
3615 if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt);
3616 else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld);
3617 }
3618
3619 return fGraph2DPainter->GetContourList(contour);
3620}
3621
3622////////////////////////////////////////////////////////////////////////////////
3623/// Display the histogram info (bin number, contents, integral up to bin
3624/// corresponding to cursor position px,py.
3625
3627{
3628
3629 if (!gPad) return (char*)"";
3630 static char info[200];
3631 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3632 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3633 Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
3634 TString drawOption = fH->GetDrawOption();
3635 drawOption.ToLower();
3636 Double_t xmin, xmax, uxmin,uxmax;
3637 Double_t ymin, ymax, uymin,uymax;
3638 if (fH->GetDimension() == 2) {
3639 if (gPad->GetView() || drawOption.Index("cont") >= 0) {
3640 uxmin=gPad->GetUxmin();
3641 uxmax=gPad->GetUxmax();
3644 x = xmin +(xmax-xmin)*(x-uxmin)/(uxmax-uxmin);
3645 uymin=gPad->GetUymin();
3646 uymax=gPad->GetUymax();
3649 y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
3650 }
3651 }
3652 Int_t binx,biny,binmin=0,binx1;
3653 if (gPad->IsVertical()) {
3654 binx = fXaxis->FindFixBin(x);
3655 if (drawOption.Index("same") >= 0) {
3656 TH1 *h1;
3657 TIter next(gPad->GetListOfPrimitives());
3658 while ((h1 = (TH1 *)next())) {
3659 if (!h1->InheritsFrom(TH1::Class())) continue;
3660 binmin = h1->GetXaxis()->GetFirst();
3661 break;
3662 }
3663 } else {
3664 binmin = fXaxis->GetFirst();
3665 }
3666 binx1 = fXaxis->FindFixBin(x1);
3667 // special case if more than 1 bin in x per pixel
3668 if (binx1-binx>1 && fH->GetDimension() == 1) {
3669 Double_t binval=fH->GetBinContent(binx);
3670 Int_t binnear=binx;
3671 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3672 Double_t binvaltmp = fH->GetBinContent(ibin);
3673 if (TMath::Abs(y-binvaltmp) < TMath::Abs(y-binval)) {
3674 binval=binvaltmp;
3675 binnear=ibin;
3676 }
3677 }
3678 binx = binnear;
3679 }
3680 } else {
3681 x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
3682 binx = fXaxis->FindFixBin(y);
3683 if (drawOption.Index("same") >= 0) {
3684 TH1 *h1;
3685 TIter next(gPad->GetListOfPrimitives());
3686 while ((h1 = (TH1 *)next())) {
3687 if (!h1->InheritsFrom(TH1::Class())) continue;
3688 binmin = h1->GetXaxis()->GetFirst();
3689 break;
3690 }
3691 } else {
3692 binmin = fXaxis->GetFirst();
3693 }
3694 binx1 = fXaxis->FindFixBin(x1);
3695 // special case if more than 1 bin in x per pixel
3696 if (binx1-binx>1 && fH->GetDimension() == 1) {
3697 Double_t binval=fH->GetBinContent(binx);
3698 Int_t binnear=binx;
3699 for (Int_t ibin=binx+1; ibin<binx1; ibin++) {
3700 Double_t binvaltmp = fH->GetBinContent(ibin);
3701 if (TMath::Abs(x-binvaltmp) < TMath::Abs(x-binval)) {
3702 binval=binvaltmp;
3703 binnear=ibin;
3704 }
3705 }
3706 binx = binnear;
3707 }
3708 }
3709 if (fH->GetDimension() == 1) {
3711 TProfile *tp = (TProfile*)fH;
3712 snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, bine=%g, binn=%d)",
3713 x, y, binx, fH->GetBinContent(binx), fH->GetBinError(binx),
3714 (Int_t) tp->GetBinEntries(binx));
3715 }
3716 else {
3717 Double_t integ = 0;
3718 for (Int_t bin=binmin;bin<=binx;bin++) {integ += fH->GetBinContent(bin);}
3719 snprintf(info,200,"(x=%g, y=%g, binx=%d, binc=%g, Sum=%g)",
3720 x,y,binx,fH->GetBinContent(binx),integ);
3721 }
3722 } else if (fH->GetDimension() == 2) {
3723 if (fH->InheritsFrom(TH2Poly::Class())) {
3724 TH2Poly *th2 = (TH2Poly*)fH;
3725 biny = th2->FindBin(x,y);
3726 snprintf(info,200,"%s (x=%g, y=%g, bin=%d, binc=%g)",
3727 th2->GetBinTitle(biny),x,y,biny,th2->GetBinContent(biny));
3728 }
3729 else if (fH->InheritsFrom(TProfile2D::Class())) {
3730 TProfile2D *tp = (TProfile2D*)fH;
3731 biny = fYaxis->FindFixBin(y);
3732 Int_t bin = fH->GetBin(binx,biny);
3733 snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g, bine=%g, binn=%d)",
3734 x, y, binx, biny, fH->GetBinContent(bin),
3735 fH->GetBinError(bin), (Int_t) tp->GetBinEntries(bin));
3736 } else {
3737 biny = fYaxis->FindFixBin(y);
3738 snprintf(info,200,"(x=%g, y=%g, binx=%d, biny=%d, binc=%g bine=%g)",
3739 x,y,binx,biny,fH->GetBinContent(binx,biny),
3740 fH->GetBinError(binx,biny));
3741 }
3742 } else {
3743 // 3d case: retrieving the x,y,z bin is not yet implemented
3744 // print just the x,y info
3745 snprintf(info,200,"(x=%g, y=%g)",x,y);
3746 }
3747 return info;
3748}
3749
3750////////////////////////////////////////////////////////////////////////////////
3751/// Set highlight (enable/disable) mode for fH
3752
3754{
3755 if (fH->IsHighlight()) return;
3756
3757 fXHighlightBin = -1;
3758 fYHighlightBin = -1;
3759 // delete previous highlight box
3762 // emit Highlighted() signal (user can check on disabled)
3763 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3764}
3765
3766////////////////////////////////////////////////////////////////////////////////
3767/// Check on highlight bin
3768
3770{
3771 // call from DistancetoPrimitive (only if highlight is enable)
3772
3773 Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px));
3774 Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py));
3775 Int_t binx = fXaxis->FindFixBin(x);
3776 Int_t biny = fYaxis->FindFixBin(y);
3777 if (!gPad->IsVertical()) binx = fXaxis->FindFixBin(y);
3778
3779 Bool_t changedBin = kFALSE;
3780 if (binx != fXHighlightBin) {
3781 fXHighlightBin = binx;
3782 changedBin = kTRUE;
3783 } else if (fH->GetDimension() == 1) return;
3784 if (biny != fYHighlightBin) {
3785 fYHighlightBin = biny;
3786 changedBin = kTRUE;
3787 }
3788 if (!changedBin) return;
3789
3790 // Info("HighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3791 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3792
3793 // paint highlight bin as box (recursive calls PaintHighlightBin)
3794 gPad->Modified(kTRUE);
3795 gPad->Update();
3796
3797 // emit Highlighted() signal
3798 if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin);
3799}
3800
3801////////////////////////////////////////////////////////////////////////////////
3802/// Paint highlight bin as TBox object
3803
3805{
3806 // call from PaintTitle
3807
3808 if (!fH->IsHighlight()) return;
3809
3810 Double_t uxmin = gPad->GetUxmin();
3811 Double_t uxmax = gPad->GetUxmax();
3812 Double_t uymin = gPad->GetUymin();
3813 Double_t uymax = gPad->GetUymax();
3814 if (gPad->GetLogx()) {
3815 uxmin = TMath::Power(10.0, uxmin);
3816 uxmax = TMath::Power(10.0, uxmax);
3817 }
3818 if (gPad->GetLogy()) {
3819 uymin = TMath::Power(10.0, uymin);
3820 uymax = TMath::Power(10.0, uymax);
3821 }
3822
3823 // testing specific possibility (after zoom, draw with "same", log, etc.)
3824 Double_t hcenter;
3825 if (gPad->IsVertical()) {
3827 if ((hcenter < uxmin) || (hcenter > uxmax)) return;
3828 } else {
3830 if ((hcenter < uymin) || (hcenter > uymax)) return;
3831 }
3832 if (fH->GetDimension() == 2) {
3834 if ((hcenter < uymin) || (hcenter > uymax)) return;
3835 }
3836
3837 // paint X highlight bin (for 1D or 2D)
3838 Double_t hbx1, hbx2, hby1, hby2;
3839 if (gPad->IsVertical()) {
3842 hby1 = uymin;
3843 hby2 = uymax;
3844 } else {
3845 hbx1 = uxmin;
3846 hbx2 = uxmax;
3849 }
3850
3851 if (!gXHighlightBox) {
3852 gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3856 else gROOT->GetColor(gXHighlightBox->GetFillColor())->SetAlpha(0.5);
3857 }
3858 gXHighlightBox->SetX1(hbx1);
3859 gXHighlightBox->SetX2(hbx2);
3860 gXHighlightBox->SetY1(hby1);
3861 gXHighlightBox->SetY2(hby2);
3863
3864 // Info("PaintHighlightBin", "histo: %p '%s'\txbin: %d, ybin: %d",
3865 // (void *)fH, fH->GetName(), fXHighlightBin, fYHighlightBin);
3866
3867 // paint Y highlight bin (only for 2D)
3868 if (fH->GetDimension() != 2) return;
3869 hbx1 = uxmin;
3870 hbx2 = uxmax;
3873
3874 if (!gYHighlightBox) {
3875 gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2);
3879 }
3880 gYHighlightBox->SetX1(hbx1);
3881 gYHighlightBox->SetX2(hbx2);
3882 gYHighlightBox->SetY1(hby1);
3883 gYHighlightBox->SetY2(hby2);
3885}
3886
3887////////////////////////////////////////////////////////////////////////////////
3888/// Return `kTRUE` if the cell `ix`, `iy` is inside one of the graphical cuts.
3889
3891{
3892
3893 for (Int_t i=0;i<fNcuts;i++) {
3896 if (fCutsOpt[i] > 0) {
3897 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3898 } else {
3899 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3900 }
3901 }
3902 return kTRUE;
3903}
3904
3905////////////////////////////////////////////////////////////////////////////////
3906/// Return `kTRUE` if the point `x`, `y` is inside one of the graphical cuts.
3907
3909{
3910
3911 for (Int_t i=0;i<fNcuts;i++) {
3912 if (fCutsOpt[i] > 0) {
3913 if (!fCuts[i]->IsInside(x,y)) return kFALSE;
3914 } else {
3915 if (fCuts[i]->IsInside(x,y)) return kFALSE;
3916 }
3917 }
3918 return kTRUE;
3919}
3920
3921////////////////////////////////////////////////////////////////////////////////
3922/// Decode string `choptin` and fill Hoption structure.
3923
3925{
3926
3927 char *l;
3928 char chopt[128];
3929 Int_t nch = strlen(choptin);
3930 strlcpy(chopt,choptin,128);
3931 Int_t hdim = fH->GetDimension();
3932
3941
3942 // special 2D options
3943 Hoption.List = 0;
3944 Hoption.Zscale = 0;
3945 Hoption.FrontBox = 1;
3946 Hoption.BackBox = 1;
3948
3949 Hoption.Zero = 0;
3950
3951 //check for graphical cuts
3952 MakeCuts(chopt);
3953
3954 for (Int_t i=0;i<nch;i++) chopt[i] = toupper(chopt[i]);
3955 if (hdim > 1) Hoption.Scat = 1;
3956 if (!nch) Hoption.Hist = 1;
3957 if (fFunctions->First()) Hoption.Func = 1;
3958 if (fH->GetSumw2N() && hdim == 1) Hoption.Error = 2;
3959
3960 char *l1 = strstr(chopt,"PFC"); // Automatic Fill Color
3961 char *l2 = strstr(chopt,"PLC"); // Automatic Line Color
3962 char *l3 = strstr(chopt,"PMC"); // Automatic Marker Color
3963 if (l1 || l2 || l3) {
3964 Int_t i = gPad->NextPaletteColor();
3965 if (l1) {memcpy(l1," ",3); fH->SetFillColor(i);}
3966 if (l2) {memcpy(l2," ",3); fH->SetLineColor(i);}
3967 if (l3) {memcpy(l3," ",3); fH->SetMarkerColor(i);}
3968 Hoption.Hist = 1; // Make sure something is drawn in case there is no drawing option specified.
3969 }
3970
3971 l = strstr(chopt,"SPEC");
3972 if (l) {
3973 Hoption.Scat = 0;
3974 memcpy(l," ",4);
3975 Int_t bs=0;
3976 l = strstr(chopt,"BF(");
3977 if (l) {
3978 if (sscanf(&l[3],"%d",&bs) > 0) {
3979 Int_t i=0;
3980 while (l[i]!=')') {
3981 l[i] = ' ';
3982 i++;
3983 }
3984 l[i] = ' ';
3985 }
3986 }
3987 Hoption.Spec = TMath::Max(1600,bs);
3988 return 1;
3989 }
3990
3991 l = strstr(chopt,"GL");
3992 if (l) {
3993 memcpy(l," ",2);
3994 }
3995 l = strstr(chopt,"X+");
3996 if (l) {
3997 Hoption.AxisPos = 10;
3998 memcpy(l," ",2);
3999 }
4000 l = strstr(chopt,"Y+");
4001 if (l) {
4002 Hoption.AxisPos += 1;
4003 memcpy(l," ",2);
4004 }
4005 if ((Hoption.AxisPos == 10 || Hoption.AxisPos == 1) && (nch == 2)) Hoption.Hist = 1;
4006 if (Hoption.AxisPos == 11 && nch == 4) Hoption.Hist = 1;
4007
4008 l = strstr(chopt,"SAMES");
4009 if (l) {
4010 if (nch == 5) Hoption.Hist = 1;
4011 Hoption.Same = 2;
4012 memcpy(l," ",5);
4013 }
4014 l = strstr(chopt,"SAME");
4015 if (l) {
4016 if (nch == 4) Hoption.Hist = 1;
4017 Hoption.Same = 1;
4018 memcpy(l," ",4);
4019 }
4020
4021 l = strstr(chopt,"PIE");
4022 if (l) {
4023 Hoption.Pie = 1;
4024 memcpy(l," ",3);
4025 }
4026
4027
4028 l = strstr(chopt,"CANDLE");
4029 if (l) {
4030 TCandle candle;
4031 Hoption.Candle = candle.ParseOption(l);
4032 Hoption.Scat = 0;
4033 }
4034
4035 l = strstr(chopt,"VIOLIN");
4036 if (l) {
4037 TCandle candle;
4038 Hoption.Candle = candle.ParseOption(l);
4039 Hoption.Scat = 0;
4040 }
4041
4042 l = strstr(chopt,"LEGO");
4043 if (l) {
4044 Hoption.Scat = 0;
4045 Hoption.Lego = 1; memcpy(l," ",4);
4046 if (l[4] == '1') { Hoption.Lego = 11; l[4] = ' '; }
4047 if (l[4] == '2') { Hoption.Lego = 12; l[4] = ' '; }
4048 if (l[4] == '3') { Hoption.Lego = 13; l[4] = ' '; }
4049 if (l[4] == '4') { Hoption.Lego = 14; l[4] = ' '; }
4050 if (l[4] == '9') { Hoption.Lego = 19; l[4] = ' '; }
4051 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4052 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4053 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4054 }
4055
4056 l = strstr(chopt,"SURF");
4057 if (l) {
4058 Hoption.Scat = 0;
4059 Hoption.Surf = 1; memcpy(l," ",4);
4060 if (l[4] == '1') { Hoption.Surf = 11; l[4] = ' '; }
4061 if (l[4] == '2') { Hoption.Surf = 12; l[4] = ' '; }
4062 if (l[4] == '3') { Hoption.Surf = 13; l[4] = ' '; }
4063 if (l[4] == '4') { Hoption.Surf = 14; l[4] = ' '; }
4064 if (l[4] == '5') { Hoption.Surf = 15; l[4] = ' '; }
4065 if (l[4] == '6') { Hoption.Surf = 16; l[4] = ' '; }
4066 if (l[4] == '7') { Hoption.Surf = 17; l[4] = ' '; }
4067 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4068 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4069 }
4070
4071 l = strstr(chopt,"TF3");
4072 if (l) {
4073 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4074 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4075 }
4076
4077 l = strstr(chopt,"ISO");
4078 if (l) {
4079 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4080 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4081 }
4082
4083 l = strstr(chopt,"LIST"); if (l) { Hoption.List = 1; memcpy(l," ",4);}
4084
4085 l = strstr(chopt,"CONT");
4086 if (l) {
4087 memcpy(l," ",4);
4088 if (hdim>1) {
4089 Hoption.Scat = 0;
4090 Hoption.Contour = 1;
4091 if (l[4] == '1') { Hoption.Contour = 11; l[4] = ' '; }
4092 if (l[4] == '2') { Hoption.Contour = 12; l[4] = ' '; }
4093 if (l[4] == '3') { Hoption.Contour = 13; l[4] = ' '; }
4094 if (l[4] == '4') { Hoption.Contour = 14; l[4] = ' '; }
4095 if (l[4] == '5') { Hoption.Contour = 15; l[4] = ' '; }
4096 } else {
4097 Hoption.Hist = 1;
4098 }
4099 }
4100 l = strstr(chopt,"HBAR");
4101 if (l) {
4102 Hoption.Hist = 0;
4103 Hoption.Bar = 20; memcpy(l," ",4);
4104 if (l[4] == '1') { Hoption.Bar = 21; l[4] = ' '; }
4105 if (l[4] == '2') { Hoption.Bar = 22; l[4] = ' '; }
4106 if (l[4] == '3') { Hoption.Bar = 23; l[4] = ' '; }
4107 if (l[4] == '4') { Hoption.Bar = 24; l[4] = ' '; }
4108 }
4109 l = strstr(chopt,"BAR");
4110 if (l) {
4111 Hoption.Hist = 0;
4112 Hoption.Bar = 10; memcpy(l," ",3);
4113 if (l[3] == '1') { Hoption.Bar = 11; l[3] = ' '; }
4114 if (l[3] == '2') { Hoption.Bar = 12; l[3] = ' '; }
4115 if (l[3] == '3') { Hoption.Bar = 13; l[3] = ' '; }
4116 if (l[3] == '4') { Hoption.Bar = 14; l[3] = ' '; }
4117 }
4118
4119 l = strstr(chopt,"ARR" );
4120 if (l) {
4121 memcpy(l," ", 3);
4122 if (hdim>1) {
4123 Hoption.Arrow = 1;
4124 Hoption.Scat = 0;
4125 } else {
4126 Hoption.Hist = 1;
4127 }
4128 }
4129 l = strstr(chopt,"BOX" );
4130 if (l) {
4131 memcpy(l," ", 3);
4132 if (hdim>1) {
4133 Hoption.Scat = 0;
4134 Hoption.Box = 1;
4135 if (l[3] == '1') { Hoption.Box = 11; l[3] = ' '; }
4136 if (l[3] == '2') { Hoption.Box = 12; l[3] = ' '; }
4137 if (l[3] == '3') { Hoption.Box = 13; l[3] = ' '; }
4138 } else {
4139 Hoption.Hist = 1;
4140 }
4141 }
4142 l = strstr(chopt,"COLZ");
4143 if (l) {
4144 memcpy(l," ",4);
4145 if (hdim>1) {
4146 Hoption.Color = 1;
4147 Hoption.Scat = 0;
4148 Hoption.Zscale = 1;
4149 if (l[4] == '2') { Hoption.Color = 3; l[4] = ' '; }
4150 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4151 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4152 } else {
4153 Hoption.Hist = 1;
4154 }
4155 }
4156 l = strstr(chopt,"COL" );
4157 if (l) {
4158 memcpy(l," ", 3);
4159 if (hdim>1) {
4160 Hoption.Color = 1;
4161 Hoption.Scat = 0;
4162 if (l[3] == '2') { Hoption.Color = 3; l[3] = ' '; }
4163 l = strstr(chopt,"0"); if (l) { Hoption.Zero = 1; memcpy(l," ",1); }
4164 l = strstr(chopt,"1"); if (l) { Hoption.Color = 2; memcpy(l," ",1); }
4165 } else {
4166 Hoption.Hist = 1;
4167 }
4168 }
4169 l = strstr(chopt,"CHAR"); if (l) { Hoption.Char = 1; memcpy(l," ",4); Hoption.Scat = 0; }
4170 l = strstr(chopt,"FUNC"); if (l) { Hoption.Func = 2; memcpy(l," ",4); Hoption.Hist = 0; }
4171 l = strstr(chopt,"HIST"); if (l) { Hoption.Hist = 2; memcpy(l," ",4); Hoption.Func = 0; Hoption.Error = 0;}
4172 l = strstr(chopt,"AXIS"); if (l) { Hoption.Axis = 1; memcpy(l," ",4); }
4173 l = strstr(chopt,"AXIG"); if (l) { Hoption.Axis = 2; memcpy(l," ",4); }
4174 l = strstr(chopt,"SCAT"); if (l) { Hoption.Scat = 1; memcpy(l," ",4); }
4175 l = strstr(chopt,"TEXT");
4176 if (l) {
4177 Int_t angle;
4178 if (sscanf(&l[4],"%d",&angle) > 0) {
4179 if (angle < 0) angle=0;
4180 if (angle > 90) angle=90;
4181 Hoption.Text = 1000+angle;
4182 } else {
4183 Hoption.Text = 1;
4184 }
4185 memcpy(l," ", 4);
4186 l = strstr(chopt,"N");
4187 if (l && fH->InheritsFrom(TH2Poly::Class())) Hoption.Text += 3000;
4188 Hoption.Scat = 0;
4189 }
4190 l = strstr(chopt,"POL"); if (l) { Hoption.System = kPOLAR; memcpy(l," ",3); }
4191 l = strstr(chopt,"CYL"); if (l) { Hoption.System = kCYLINDRICAL; memcpy(l," ",3); }
4192 l = strstr(chopt,"SPH"); if (l) { Hoption.System = kSPHERICAL; memcpy(l," ",3); }
4193 l = strstr(chopt,"PSR"); if (l) { Hoption.System = kRAPIDITY; memcpy(l," ",3); }
4194
4195 l = strstr(chopt,"TRI");
4196 if (l) {
4197 Hoption.Scat = 0;
4198 Hoption.Color = 0;
4199 Hoption.Tri = 1; memcpy(l," ",3);
4200 l = strstr(chopt,"FB"); if (l) { Hoption.FrontBox = 0; memcpy(l," ",2); }
4201 l = strstr(chopt,"BB"); if (l) { Hoption.BackBox = 0; memcpy(l," ",2); }
4202 l = strstr(chopt,"ERR"); if (l) memcpy(l," ",3);
4203 }
4204
4205 l = strstr(chopt,"AITOFF");
4206 if (l) {
4207 Hoption.Proj = 1; memcpy(l," ",6); //Aitoff projection
4208 }
4209 l = strstr(chopt,"MERCATOR");
4210 if (l) {
4211 Hoption.Proj = 2; memcpy(l," ",8); //Mercator projection
4212 }
4213 l = strstr(chopt,"SINUSOIDAL");
4214 if (l) {
4215 Hoption.Proj = 3; memcpy(l," ",10); //Sinusoidal projection
4216 }
4217 l = strstr(chopt,"PARABOLIC");
4218 if (l) {
4219 Hoption.Proj = 4; memcpy(l," ",9); //Parabolic projection
4220 }
4221 if (Hoption.Proj > 0) {
4222 Hoption.Scat = 0;
4223 Hoption.Contour = 14;
4224 }
4225
4226 if (strstr(chopt,"A")) Hoption.Axis = -1;
4227 if (strstr(chopt,"B")) Hoption.Bar = 1;
4228 if (strstr(chopt,"C")) { Hoption.Curve =1; Hoption.Hist = -1;}
4229 if (strstr(chopt,"F")) Hoption.Fill =1;
4230 if (strstr(chopt,"][")) {Hoption.Off =1; Hoption.Hist =1;}
4231 if (strstr(chopt,"F2")) Hoption.Fill =2;
4232 if (strstr(chopt,"L")) { Hoption.Line =1; Hoption.Hist = -1;}
4233 if (strstr(chopt,"P")) { Hoption.Mark =1; Hoption.Hist = -1;}
4234 if (strstr(chopt,"Z")) Hoption.Zscale =1;
4235 if (strstr(chopt,"*")) Hoption.Star =1;
4236 if (strstr(chopt,"H")) Hoption.Hist =2;
4237 if (strstr(chopt,"P0")) Hoption.Mark =10;
4238
4239 if (fH->InheritsFrom(TH2Poly::Class())) {
4241 }
4242
4243 if (strstr(chopt,"E")) {
4244 if (hdim == 1) {
4245 Hoption.Error = 1;
4246 if (strstr(chopt,"E0")) Hoption.Error = 10;
4247 if (strstr(chopt,"E1")) Hoption.Error = 11;
4248 if (strstr(chopt,"E2")) Hoption.Error = 12;
4249 if (strstr(chopt,"E3")) Hoption.Error = 13;
4250 if (strstr(chopt,"E4")) Hoption.Error = 14;
4251 if (strstr(chopt,"E5")) Hoption.Error = 15;
4252 if (strstr(chopt,"E6")) Hoption.Error = 16;
4253 if (strstr(chopt,"X0")) {
4254 if (Hoption.Error == 1) Hoption.Error += 20;
4255 Hoption.Error += 10;
4256 }
4258 Hoption.Text += 2000;
4259 Hoption.Error = 0;
4260 }
4261 } else {
4262 if (Hoption.Error == 0) {
4263 Hoption.Error = 100;
4264 Hoption.Scat = 0;
4265 }
4266 if (Hoption.Text) {
4267 Hoption.Text += 2000;
4268 Hoption.Error = 0;
4269 }
4270 }
4271 }
4272
4273 if (Hoption.Surf == 15) {
4275 Hoption.Surf = 13;
4276 Warning("MakeChopt","option SURF5 is not supported in Cartesian and Polar modes");
4277 }
4278 }
4279
4280 // Copy options from current style
4281 Hoption.Logx = gPad->GetLogx();
4282 Hoption.Logy = gPad->GetLogy();
4283 Hoption.Logz = gPad->GetLogz();
4284
4285 // Check options incompatibilities
4286 if (Hoption.Bar == 1) Hoption.Hist = -1;
4287 return 1;
4288}
4289
4290////////////////////////////////////////////////////////////////////////////////
4291/// Decode string `choptin` and fill Graphical cuts structure.
4292
4294{
4295
4296 fNcuts = 0;
4297 char *left = (char*)strchr(choptin,'[');
4298 if (!left) return 0;
4299 char *right = (char*)strchr(choptin,']');
4300 if (!right) return 0;
4301 Int_t nch = right-left;
4302 if (nch < 2) return 0;
4303 char *cuts = left+1;
4304 *right = 0;
4305 char *comma, *minus;
4306 Int_t i;
4307 while (1) {
4308 comma = strchr(cuts,',');
4309 if (comma) *comma = 0;
4310 minus = strchr(cuts,'-');
4311 if (minus) cuts = minus+1;
4312 while (*cuts == ' ') cuts++;
4313 Int_t nc = strlen(cuts);
4314 while (cuts[nc-1] == ' ') {cuts[nc-1] = 0; nc--;}
4315 TIter next(gROOT->GetListOfSpecials());
4316 TCutG *cut=0;
4317 TObject *obj;
4318 while ((obj = next())) {
4319 if (!obj->InheritsFrom(TCutG::Class())) continue;
4320 if (strcmp(obj->GetName(),cuts)) continue;
4321 cut = (TCutG*)obj;
4322 break;
4323 }
4324 if (cut) {
4325 fCuts[fNcuts] = cut;
4326 fCutsOpt[fNcuts] = 1;
4327 if (minus) fCutsOpt[fNcuts] = -1;
4328 fNcuts++;
4329 }
4330 if (!comma) break;
4331 cuts = comma+1;
4332 }
4333 for (i=0;i<=nch;i++) left[i] = ' ';
4334 return fNcuts;
4335}
4336
4337////////////////////////////////////////////////////////////////////////////////
4338/// [Control routine to paint any kind of histograms](#HP00)
4339
4341{
4342
4343 if (fH->GetBuffer()) fH->BufferEmpty(-1);
4344
4345 //For iOS: put the histogram on the top of stack of pickable objects.
4346 const TPickerStackGuard topPush(fH);
4347
4348 gPad->SetVertical(kTRUE);
4349
4350 TH1 *oldhist = gCurrentHist;
4351 gCurrentHist = fH;
4352 TH1 *hsave = fH;
4353 Double_t minsav = fH->GetMinimumStored();
4354
4355 if (!MakeChopt(option)) return; //check options and fill Hoption structure
4356
4357 // Paint using TSpectrum2Painter
4358 if (Hoption.Spec) {
4359 if (!TableInit()) return;
4360 if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter");
4361 gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%lx,\"%s\",%d)",
4362 (ULong_t)fH, option, Hoption.Spec));
4363 return;
4364 }
4365
4366 if (Hoption.Pie) {
4367 if (fH->GetDimension() == 1) {
4368 if (!fPie) fPie = new TPie(fH);
4369 fPie->Paint(option);
4370 } else {
4371 Error("Paint", "Option PIE is for 1D histograms only");
4372 }
4373 return;
4374 } else {
4375 if (fPie) delete fPie;
4376 fPie = 0;
4377 }
4378
4379 fXbuf = new Double_t[kNMAX];
4380 fYbuf = new Double_t[kNMAX];
4381 if (fH->GetDimension() > 2) {
4382 PaintH3(option);
4383 fH->SetMinimum(minsav);
4384 if (Hoption.Func) {
4385 Hoption_t hoptsave = Hoption;
4386 Hparam_t hparsave = Hparam;
4387 PaintFunction(option);
4388 SetHistogram(hsave);
4389 Hoption = hoptsave;
4390 Hparam = hparsave;
4391 }
4392 gCurrentHist = oldhist;
4393 delete [] fXbuf; delete [] fYbuf;
4394 return;
4395 }
4396 TView *view = gPad->GetView();
4397 if (view) {
4398 if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) {
4399 delete view;
4400 gPad->SetView(0);
4401 }
4402 }
4403 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) {
4404 // In case of 1D histogram, Z axis becomes Y axis.
4405 Int_t logysav=0, logzsav=0;
4406 if (fH->GetDimension() == 1) {
4407 logysav = Hoption.Logy;
4408 logzsav = Hoption.Logz;
4409 Hoption.Logz = 0;
4410 if (Hoption.Logy) {
4411 Hoption.Logz = 1;
4412 Hoption.Logy = 0;
4413 }
4414 }
4415 PaintTable(option);
4416 if (Hoption.Func) {
4417 Hoption_t hoptsave = Hoption;
4418 Hparam_t hparsave = Hparam;
4419 PaintFunction(option);
4420 SetHistogram(hsave);
4421 Hoption = hoptsave;
4422 Hparam = hparsave;
4423 }
4424 fH->SetMinimum(minsav);
4425 gCurrentHist = oldhist;
4426 delete [] fXbuf; delete [] fYbuf;
4427 if (fH->GetDimension() == 1) {
4428 Hoption.Logy = logysav;
4429 Hoption.Logz = logzsav;
4430 }
4431 return;
4432 }
4433
4434 if (Hoption.Bar >= 20) {
4435 PaintBarH(option);
4436 delete [] fXbuf; delete [] fYbuf;
4437 return;
4438 }
4439
4440 // fill Hparam structure with histo parameters
4441 if (!PaintInit()) {
4442 delete [] fXbuf; delete [] fYbuf;
4443 return;
4444 }
4445
4446 // Picture surround (if new page) and page number (if requested).
4447 // Histogram surround (if not option "Same").
4448 PaintFrame();
4449
4450 // Paint histogram axis only
4451 Bool_t gridx = gPad->GetGridx();
4452 Bool_t gridy = gPad->GetGridy();
4453 if (Hoption.Axis > 0) {
4454 if (Hoption.Axis > 1) PaintAxis(kTRUE); //axis with grid
4455 else {
4456 if (gridx) gPad->SetGridx(0);
4457 if (gridy) gPad->SetGridy(0);
4459 if (gridx) gPad->SetGridx(1);
4460 if (gridy) gPad->SetGridy(1);
4461 }
4462 if (Hoption.Same ==1) Hoption.Same = 2;
4463 goto paintstat;
4464 }
4465 if (gridx || gridy) PaintAxis(kTRUE); // Draw the grid only
4466
4467 // test for options BAR or HBAR
4468 if (Hoption.Bar >= 10) {
4469 PaintBar(option);
4470 }
4471
4472 // do not draw histogram if error bars required
4473 if (!Hoption.Error) {
4474 if (Hoption.Hist && Hoption.Bar<10) PaintHist(option);
4475 }
4476
4477 // test for error bars or option E
4478 if (Hoption.Error) {
4479 PaintErrors(option);
4480 if (Hoption.Hist == 2) PaintHist(option);
4481 }
4482
4483 if (Hoption.Text) PaintText(option);
4484
4485 // test for associated function
4486 if (Hoption.Func) {
4487 Hoption_t hoptsave = Hoption;
4488 Hparam_t hparsave = Hparam;
4489 PaintFunction(option);
4490 SetHistogram(hsave);
4491 Hoption = hoptsave;
4492 Hparam = hparsave;
4493 }
4494
4495 if (gridx) gPad->SetGridx(0);
4496 if (gridy) gPad->SetGridy(0);
4498 if (gridx) gPad->SetGridx(1);
4499 if (gridy) gPad->SetGridy(1);
4500
4501 PaintTitle(); // Draw histogram title
4502
4503 // Draw box with histogram statistics and/or fit parameters
4504paintstat:
4505 if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4506 TIter next(fFunctions);
4507 TObject *obj = 0;
4508 while ((obj = next())) {
4509 if (obj->InheritsFrom(TF1::Class())) break;
4510 obj = 0;
4511 }
4512
4513 //Stat is painted twice (first, it will be in canvas' list of primitives),
4514 //second, it will be here, this is not required on iOS.
4515 //Condition is ALWAYS true on a platform different from iOS.
4516 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
4517 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
4518 }
4519 fH->SetMinimum(minsav);
4520 gCurrentHist = oldhist;
4521 delete [] fXbuf; fXbuf = 0;
4522 delete [] fYbuf; fYbuf = 0;
4523
4524}
4525
4526////////////////////////////////////////////////////////////////////////////////
4527/// [Control function to draw a table as an arrow plot](#HP12)
4528
4530{
4531 fH->TAttLine::Modify();
4532
4533 Double_t xk, xstep, yk, ystep;
4534 Double_t dx, dy, si, co, anr, x1, x2, y1, y2, xc, yc, dxn, dyn;
4537 Double_t xrg = gPad->GetUxmin();
4538 Double_t yrg = gPad->GetUymin();
4539 Double_t xln = gPad->GetUxmax() - xrg;
4540 Double_t yln = gPad->GetUymax() - yrg;
4541 Double_t cx = (xln/Double_t(ncx) -0.03)/2;
4542 Double_t cy = (yln/Double_t(ncy) -0.03)/2;
4543 Double_t dn = 1.E-30;
4544
4545 for (Int_t id=1;id<=2;id++) {
4546 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
4547 yk = fYaxis->GetBinLowEdge(j);
4548 ystep = fYaxis->GetBinWidth(j);
4549 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
4550 xk = fXaxis->GetBinLowEdge(i);
4551 xstep = fXaxis->GetBinWidth(i);
4552 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
4553 if (i == Hparam.xfirst) {
4554 dx = fH->GetBinContent(i+1, j) - fH->GetBinContent(i, j);
4555 } else if (i == Hparam.xlast) {
4556 dx = fH->GetBinContent(i, j) - fH->GetBinContent(i-1, j);
4557 } else {
4558 dx = 0.5*(fH->GetBinContent(i+1, j) - fH->GetBinContent(i-1, j));
4559 }
4560 if (j == Hparam.yfirst) {
4561 dy = fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j);
4562 } else if (j == Hparam.ylast) {
4563 dy = fH->GetBinContent(i, j) - fH->GetBinContent(i, j-1);
4564 } else {
4565 dy = 0.5*(fH->GetBinContent(i, j+1) - fH->GetBinContent(i, j-1));
4566 }
4567 if (id == 1) {
4568 dn = TMath::Max(dn, TMath::Abs(dx));
4569 dn = TMath::Max(dn, TMath::Abs(dy));
4570 } else if (id == 2) {
4571 xc = xrg + xln*(Double_t(i - Hparam.xfirst+1)-0.5)/Double_t(ncx);
4572 dxn = cx*dx/dn;
4573 x1 = xc - dxn;
4574 x2 = xc + dxn;
4575 yc = yrg + yln*(Double_t(j - Hparam.yfirst+1)-0.5)/Double_t(ncy);
4576 dyn = cy*dy/dn;
4577 y1 = yc - dyn;
4578 y2 = yc + dyn;
4579 fXbuf[0] = x1;
4580 fXbuf[1] = x2;
4581 fYbuf[0] = y1;
4582 fYbuf[1] = y2;
4583 if (TMath::Abs(x2-x1) > 0.01 || TMath::Abs(y2-y1) > 0.01) {
4584 anr = 0.005*.5*TMath::Sqrt(2/(dxn*dxn + dyn*dyn));
4585 si = anr*(dxn + dyn);
4586 co = anr*(dxn - dyn);
4587 fXbuf[2] = x2 - si;
4588 fYbuf[2] = y2 + co;
4589 gPad->PaintPolyLine(3, fXbuf, fYbuf);
4590 fXbuf[0] = x2;
4591 fXbuf[1] = x2 - co;
4592 fYbuf[0] = y2;
4593 fYbuf[1] = y2 - si;
4594 gPad->PaintPolyLine(2, fXbuf, fYbuf);
4595 }
4596 else {
4597 gPad->PaintPolyLine(2, fXbuf, fYbuf);
4598 }
4599 }
4600 }
4601 }
4602 }
4603
4605}
4606
4607////////////////////////////////////////////////////////////////////////////////
4608/// Draw axis (2D case) of an histogram.
4609///
4610/// If `drawGridOnly` is `TRUE`, only the grid is painted (if needed). This allows
4611/// to draw the grid and the axis separately. In `THistPainter::Paint` this
4612/// feature is used to make sure that the grid is drawn in the background and
4613/// the axis tick marks in the foreground of the pad.
4614
4616{
4617
4618 //On iOS, grid should not be pickable and can not be highlighted.
4619 //Condition is never true on a platform different from iOS.
4620 if (drawGridOnly && (gPad->PadInHighlightMode() || gPad->PadInSelectionMode()))
4621 return;
4622
4623 if (Hoption.Axis == -1) return;
4624 if (Hoption.Same && Hoption.Axis <= 0) return;
4625
4626 // Repainting alphanumeric labels axis on a plot done with
4627 // the option HBAR (horizontal) needs some adjustments.
4628 TAxis *xaxis = 0;
4629 TAxis *yaxis = 0;
4630 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4631 if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels
4632 TIter next(gPad->GetListOfPrimitives());
4633 TObject *obj;
4634 // Check if the first TH1 of THStack in the pad is drawn with the option HBAR
4635 while ((obj = next())) {
4636 if (!obj->InheritsFrom(TH1::Class()) &&
4637 !obj->InheritsFrom(THStack::Class())) continue;
4638 TString opt = obj->GetDrawOption();
4639 opt.ToLower();
4640 // if drawn with HBAR, the axis should be inverted and the pad set to horizontal
4641 if (strstr(opt,"hbar")) {
4642 gPad->SetVertical(kFALSE);
4643 xaxis = fXaxis;
4644 yaxis = fYaxis;
4645 if (!strcmp(xaxis->GetName(),"xaxis")) {
4646 fXaxis = yaxis;
4647 fYaxis = xaxis;
4648 }
4649 }
4650 break;
4651 }
4652 }
4653 }
4654
4655 static char chopt[10] = "";
4656 Double_t gridl = 0;
4657 Int_t ndiv, ndivx, ndivy, nx1, nx2, ndivsave;
4658 Int_t useHparam = 0;
4659 Double_t umin, umax, uminsave, umaxsave;
4660 Short_t xAxisPos = Hoption.AxisPos/10;
4661 Short_t yAxisPos = Hoption.AxisPos - 10*xAxisPos;
4662
4663 Double_t axmin = gPad->GetUxmin();
4664 Double_t axmax = gPad->GetUxmax();
4665 Double_t aymin = gPad->GetUymin();
4666 Double_t aymax = gPad->GetUymax();
4667 char *cw = 0;
4668 TGaxis axis;
4669
4670 // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot'
4671 // Hparam must be use for the axis limits.
4672 if (Hoption.Contour == 14) useHparam = 1;
4673 if (Hoption.Same) {
4674 TObject *obj;
4675 TIter next(gPad->GetListOfPrimitives());
4676 while ((obj=next())) {
4677 if (strstr(obj->GetDrawOption(),"cont4")) {
4678 useHparam = 1;
4679 break;
4680 }
4681 }
4682 }
4683
4684 // Paint X axis
4685
4686 //To make X-axis selectable on iOS device.
4687 if (gPad->PadInSelectionMode())
4688 gPad->PushSelectableObject(fXaxis);
4689
4690 //This condition is ALWAYS true, unless it works on iOS (can be false on iOS).
4691 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fXaxis)) {
4692 ndivx = fXaxis->GetNdivisions();
4693 if (ndivx > 1000) {
4694 nx2 = ndivx/100;
4695 nx1 = TMath::Max(1, ndivx%100);
4696 ndivx = 100*nx2 + Int_t(Float_t(nx1)*gPad->GetAbsWNDC());
4697 }
4698 axis.SetTextAngle(0);
4700
4701 chopt[0] = 0;
4702 strlcat(chopt, "SDH",10);
4703 if (ndivx < 0) strlcat(chopt, "N",10);
4704 if (gPad->GetGridx()) {
4705 gridl = (aymax-aymin)/(gPad->GetY2() - gPad->GetY1());
4706 strlcat(chopt, "W",10);
4707 }
4708
4709 // Define X-Axis limits
4710 if (Hoption.Logx) {
4711 strlcat(chopt, "G",10);
4712 ndiv = TMath::Abs(ndivx);
4713 if (useHparam) {
4714 umin = TMath::Power(10,Hparam.xmin);
4715 umax = TMath::Power(10,Hparam.xmax);
4716 } else {
4717 umin = TMath::Power(10,axmin);
4718 umax = TMath::Power(10,axmax);
4719 }
4720 } else {
4721 ndiv = TMath::Abs(ndivx);
4722 if (useHparam) {
4723 umin = Hparam.xmin;
4724 umax = Hparam.xmax;
4725 } else {
4726 umin = axmin;
4727 umax = axmax;
4728 }
4729 }
4730
4731 // Display axis as time
4732 if (fXaxis->GetTimeDisplay()) {
4733 strlcat(chopt,"t",10);
4734 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
4736 }
4737 }
4738
4739 // The main X axis can be on the bottom or on the top of the pad
4740 Double_t xAxisYPos1, xAxisYPos2;
4741 if (xAxisPos == 1) {
4742 // Main X axis top
4743 xAxisYPos1 = aymax;
4744 xAxisYPos2 = aymin;
4745 } else {
4746 // Main X axis bottom
4747 xAxisYPos1 = aymin;
4748 xAxisYPos2 = aymax;
4749 }
4750
4751 // Paint the main X axis (always)
4752 uminsave = umin;
4753 umaxsave = umax;
4754 ndivsave = ndiv;
4755 axis.SetOption(chopt);
4756 if (xAxisPos) {
4757 strlcat(chopt, "-",10);
4758 gridl = -gridl;
4759 }
4760 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4761 axis.SetLabelSize(0.);
4762 axis.SetTitle("");
4763 }
4764 axis.PaintAxis(axmin, xAxisYPos1,
4765 axmax, xAxisYPos1,
4766 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4767
4768 // Paint additional X axis (if needed)
4769 // On iOS, this additional X axis is neither pickable, nor highlighted.
4770 // Additional checks PadInSelectionMode etc. does not effect non-iOS platform.
4771 if (gPad->GetTickx() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4772 if (xAxisPos) {
4773 cw=strstr(chopt,"-");
4774 *cw='z';
4775 } else {
4776 strlcat(chopt, "-",10);
4777 }
4778 if (gPad->GetTickx() < 2) strlcat(chopt, "U",10);
4779 if ((cw=strstr(chopt,"W"))) *cw='z';
4780 axis.SetTitle("");
4781 axis.PaintAxis(axmin, xAxisYPos2,
4782 axmax, xAxisYPos2,
4783 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4784 }
4785 }//End of "if pad in selection mode etc".
4786
4787 // Paint Y axis
4788 //On iOS, Y axis must pushed into the stack of selectable objects.
4789 if (gPad->PadInSelectionMode())
4790 gPad->PushSelectableObject(fYaxis);
4791
4792 //This conditions is ALWAYS true on a platform, different from iOS (on iOS can be true, can be false).
4793 if (gPad->PadInSelectionMode() || !gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && gPad->GetSelected() == fYaxis)) {
4794 ndivy = fYaxis->GetNdivisions();
4796
4797 chopt[0] = 0;
4798 strlcat(chopt, "SDH",10);
4799 if (ndivy < 0) strlcat(chopt, "N",10);
4800 if (gPad->GetGridy()) {
4801 gridl = (axmax-axmin)/(gPad->GetX2() - gPad->GetX1());
4802 strlcat(chopt, "W",10);
4803 }
4804
4805 // Define Y-Axis limits
4806 if (Hoption.Logy) {
4807 strlcat(chopt, "G",10);
4808 ndiv = TMath::Abs(ndivy);
4809 if (useHparam) {
4810 umin = TMath::Power(10,Hparam.ymin);
4811 umax = TMath::Power(10,Hparam.ymax);
4812 } else {
4813 umin = TMath::Power(10,aymin);
4814 umax = TMath::Power(10,aymax);
4815 }
4816 } else {
4817 ndiv = TMath::Abs(ndivy);
4818 if (useHparam) {
4819 umin = Hparam.ymin;
4820 umax = Hparam.ymax;
4821 } else {
4822 umin = aymin;
4823 umax = aymax;
4824 }
4825 }
4826
4827 // Display axis as time
4828 if (fYaxis->GetTimeDisplay()) {
4829 strlcat(chopt,"t",10);
4830 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
4832 }
4833 }
4834
4835 // The main Y axis can be on the left or on the right of the pad
4836 Double_t yAxisXPos1, yAxisXPos2;
4837 if (yAxisPos == 1) {
4838 // Main Y axis left
4839 yAxisXPos1 = axmax;
4840 yAxisXPos2 = axmin;
4841 } else {
4842 // Main Y axis right
4843 yAxisXPos1 = axmin;
4844 yAxisXPos2 = axmax;
4845 }
4846
4847 // Paint the main Y axis (always)
4848 uminsave = umin;
4849 umaxsave = umax;
4850 ndivsave = ndiv;
4851 axis.SetOption(chopt);
4852 if (yAxisPos) {
4853 strlcat(chopt, "+L",10);
4854 gridl = -gridl;
4855 }
4856 if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis)
4857 axis.SetLabelSize(0.);
4858 axis.SetTitle("");
4859 }
4860 axis.PaintAxis(yAxisXPos1, aymin,
4861 yAxisXPos1, aymax,
4862 umin, umax, ndiv, chopt, gridl, drawGridOnly);
4863
4864 // Paint the additional Y axis (if needed)
4865 // Additional checks for pad mode are required on iOS: this "second" axis is
4866 // neither pickable, nor highlighted. Additional checks have no effect on non-iOS platform.
4867 if (gPad->GetTicky() && !gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
4868 if (gPad->GetTicky() < 2) {
4869 strlcat(chopt, "U",10);
4871 } else {
4872 strlcat(chopt, "+L",10);
4873 }
4874 if ((cw=strstr(chopt,"W"))) *cw='z';
4875 axis.SetTitle("");
4876 axis.PaintAxis(yAxisXPos2, aymin,
4877 yAxisXPos2, aymax,
4878 uminsave, umaxsave, ndivsave, chopt, gridl, drawGridOnly);
4879 }
4880 }//End of "if pad is in selection mode etc."
4881
4882 // Reset the axis if they have been inverted in case of option HBAR
4883 if (xaxis) {
4884 fXaxis = xaxis;
4885 fYaxis = yaxis;
4886 }
4887}
4888
4889////////////////////////////////////////////////////////////////////////////////
4890/// [Draw a bar-chart in a normal pad.](#HP10)
4891
4893{
4894
4895 Int_t bar = Hoption.Bar - 10;
4896 Double_t xmin,xmax,ymin,ymax,umin,umax,w,y;
4897 Double_t offset = fH->GetBarOffset();
4899 TBox box;
4900 Int_t hcolor = fH->GetFillColor();
4901 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4902 Int_t hstyle = fH->GetFillStyle();
4903 box.SetFillColor(hcolor);
4904 box.SetFillStyle(hstyle);
4905 for (Int_t bin=fXaxis->GetFirst();bin<=fXaxis->GetLast();bin++) {
4906 y = fH->GetBinContent(bin);
4907 xmin = gPad->XtoPad(fXaxis->GetBinLowEdge(bin));
4908 xmax = gPad->XtoPad(fXaxis->GetBinUpEdge(bin));
4909 ymin = gPad->GetUymin();
4910 ymax = gPad->YtoPad(y);
4911 if (ymax < gPad->GetUymin()) continue;
4912 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
4913 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
4914 if (gStyle->GetHistMinimumZero() && ymin < 0)
4915 ymin=TMath::Min(0.,gPad->GetUymax());
4916 w = (xmax-xmin)*width;
4917 xmin += offset*(xmax-xmin);
4918 xmax = xmin + w;
4919 if (bar < 1) {
4920 box.PaintBox(xmin,ymin,xmax,ymax);
4921 } else {
4922 umin = xmin + bar*(xmax-xmin)/10.;
4923 umax = xmax - bar*(xmax-xmin)/10.;
4924 //box.SetFillColor(hcolor+150); //bright
4925 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4926 box.PaintBox(xmin,ymin,umin,ymax);
4927 box.SetFillColor(hcolor);
4928 box.PaintBox(umin,ymin,umax,ymax);
4929 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4930 box.PaintBox(umax,ymin,xmax,ymax);
4931 }
4932 }
4933}
4934
4935////////////////////////////////////////////////////////////////////////////////
4936/// [Draw a bar char in a rotated pad (X vertical, Y horizontal)](#HP10)
4937
4939{
4940
4941 gPad->SetVertical(kFALSE);
4942
4943 PaintInitH();
4944
4945 TAxis *xaxis = fXaxis;
4946 TAxis *yaxis = fYaxis;
4947 if (!strcmp(xaxis->GetName(),"xaxis")) {
4948 fXaxis = yaxis;
4949 fYaxis = xaxis;
4950 }
4951
4952 PaintFrame();
4954
4955 Int_t bar = Hoption.Bar - 20;
4956 Double_t xmin,xmax,ymin,ymax,umin,umax,w;
4957 Double_t offset = fH->GetBarOffset();
4959 TBox box;
4960 Int_t hcolor = fH->GetFillColor();
4961 if (hcolor == gPad->GetFrameFillColor()) ++hcolor;
4962 Int_t hstyle = fH->GetFillStyle();
4963 box.SetFillColor(hcolor);
4964 box.SetFillStyle(hstyle);
4965 for (Int_t bin=fYaxis->GetFirst();bin<=fYaxis->GetLast();bin++) {
4966 ymin = gPad->YtoPad(fYaxis->GetBinLowEdge(bin));
4967 ymax = gPad->YtoPad(fYaxis->GetBinUpEdge(bin));
4968 xmin = gPad->GetUxmin();
4969 xmax = gPad->XtoPad(fH->GetBinContent(bin));
4970 if (xmax < gPad->GetUxmin()) continue;
4971 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
4972 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
4973 if (gStyle->GetHistMinimumZero() && xmin < 0)
4974 xmin=TMath::Min(0.,gPad->GetUxmax());
4975 w = (ymax-ymin)*width;
4976 ymin += offset*(ymax-ymin);
4977 ymax = ymin + w;
4978 if (bar < 1) {
4979 box.PaintBox(xmin,ymin,xmax,ymax);
4980 } else {
4981 umin = ymin + bar*(ymax-ymin)/10.;
4982 umax = ymax - bar*(ymax-ymin)/10.;
4983 box.SetFillColor(TColor::GetColorDark(hcolor)); //dark
4984 box.PaintBox(xmin,ymin,xmax,umin);
4985 box.SetFillColor(hcolor);
4986 box.PaintBox(xmin,umin,xmax,umax);
4987 box.SetFillColor(TColor::GetColorBright(hcolor)); //bright
4988 box.PaintBox(xmin,umax,xmax,ymax);
4989 }
4990 }
4991
4992 PaintTitle();
4993
4994 // Draw box with histogram statistics and/or fit parameters
4995 if (Hoption.Same != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
4996 TIter next(fFunctions);
4997 TObject *obj = 0;
4998 while ((obj = next())) {
4999 if (obj->InheritsFrom(TF1::Class())) break;
5000 obj = 0;
5001 }
5002 PaintStat(gStyle->GetOptStat(),(TF1*)obj);
5003 }
5004
5005 fXaxis = xaxis;
5006 fYaxis = yaxis;
5007}
5008
5009////////////////////////////////////////////////////////////////////////////////
5010/// [Control function to draw a 2D histogram as a box plot](#HP13)
5011
5013{
5014
5015 Style_t fillsav = fH->GetFillStyle();
5016 Style_t colsav = fH->GetFillColor();
5017 if (fH->GetFillColor() == 0) fH->SetFillStyle(0);
5018 if (Hoption.Box == 11) fH->SetFillStyle(1001);
5019 fH->TAttLine::Modify();
5020 fH->TAttFill::Modify();
5021
5022 Double_t z, xk,xstep, yk, ystep, xcent, ycent, xlow, xup, ylow, yup;
5023 Double_t ux1 = gPad->PixeltoX(1);
5024 Double_t ux0 = gPad->PixeltoX(0);
5025 Double_t uy1 = gPad->PixeltoY(1);
5026 Double_t uy0 = gPad->PixeltoY(0);
5027 Double_t dxmin = 0.51*(gPad->PadtoX(ux1)-gPad->PadtoX(ux0));
5028 Double_t dymin = 0.51*(gPad->PadtoY(uy0)-gPad->PadtoY(uy1));
5029
5030 Double_t zmin = TMath::Max(fH->GetMinimum(),0.);
5033 Double_t zminlin = zmin, zmaxlin = zmax;
5034
5035 // In case of option SAME, zmin and zmax values are taken from the
5036 // first plotted 2D histogram.
5037 if (Hoption.Same) {
5038 TH2 *h2;
5039 TIter next(gPad->GetListOfPrimitives());
5040 while ((h2 = (TH2 *)next())) {
5041 if (!h2->InheritsFrom(TH2::Class())) continue;
5042 zmin = TMath::Max(h2->GetMinimum(), 0.);
5043 zmax = TMath::Max(TMath::Abs(h2->GetMaximum()),
5044 TMath::Abs(h2->GetMinimum()));
5045 zminlin = zmin;
5046 zmaxlin = zmax;
5047 if (Hoption.Logz) {
5048 if (zmin <= 0) {
5049 zmin = TMath::Log10(zmax*0.001);
5050 } else {
5051 zmin = TMath::Log10(zmin);
5052 }
5053 zmax = TMath::Log10(zmax);
5054 }
5055 break;
5056 }
5057 } else {
5058 if (Hoption.Logz) {
5059 if (zmin > 0) {
5060 zmin = TMath::Log10(zmin);
5061 zmax = TMath::Log10(zmax);
5062 } else {
5063 return;
5064 }
5065 }
5066 }
5067
5068 Double_t zratio, dz = zmax - zmin;
5069 Bool_t kZminNeg = kFALSE;
5070 if (fH->GetMinimum()<0) kZminNeg = kTRUE;
5071 Bool_t kZNeg = kFALSE;
5072
5073 // Define the dark and light colors the "button style" boxes.
5074 Color_t color = fH->GetFillColor();
5075 Color_t light=0, dark=0;
5076 if (Hoption.Box == 11) {
5077 light = TColor::GetColorBright(color);
5078 dark = TColor::GetColorDark(color);
5079 }
5080
5081 // Loop over all the bins and draw the boxes
5082 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5083 yk = fYaxis->GetBinLowEdge(j);
5084 ystep = fYaxis->GetBinWidth(j);
5085 ycent = 0.5*ystep;
5086 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5087 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5088 xk = fXaxis->GetBinLowEdge(i);
5089 xstep = fXaxis->GetBinWidth(i);
5090 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5091 xcent = 0.5*xstep;
5092 z = Hparam.factor*fH->GetBinContent(bin);
5093 kZNeg = kFALSE;
5094
5095 if (TMath::Abs(z) < zminlin) continue; // Can be the case with ...
5096 if (TMath::Abs(z) > zmaxlin) z = zmaxlin; // ... option Same
5097 if (kZminNeg && z==0) continue; // Do not draw empty bins if case of histo with netgative bins.
5098
5099 if (z < 0) {
5100 if (Hoption.Logz) continue;
5101 z = -z;
5102 kZNeg = kTRUE;
5103 }
5104 if (Hoption.Logz) {
5105 if (z != 0) z = TMath::Log10(z);
5106 else z = zmin;
5107 }
5108
5109 if (dz == 0) continue;
5110 zratio = TMath::Sqrt((z-zmin)/dz);
5111 if (zratio == 0) continue;
5112
5113 xup = xcent*zratio + xk + xcent;
5114 xlow = 2*(xk + xcent) - xup;
5115 if (xup-xlow < dxmin) xup = xlow+dxmin;
5116 if (Hoption.Logx) {
5117 if (xup > 0) xup = TMath::Log10(xup);
5118 else continue;
5119 if (xlow > 0) xlow = TMath::Log10(xlow);
5120 else continue;
5121 }
5122
5123 yup = ycent*zratio + yk + ycent;
5124 ylow = 2*(yk + ycent) - yup;
5125 if (yup-ylow < dymin) yup = ylow+dymin;
5126 if (Hoption.Logy) {
5127 if (yup > 0) yup = TMath::Log10(yup);
5128 else continue;
5129 if (ylow > 0) ylow = TMath::Log10(ylow);
5130 else continue;
5131 }
5132
5133 xlow = TMath::Max(xlow, gPad->GetUxmin());
5134 ylow = TMath::Max(ylow, gPad->GetUymin());
5135 xup = TMath::Min(xup , gPad->GetUxmax());
5136 yup = TMath::Min(yup , gPad->GetUymax());
5137
5138 if (xlow >= xup) continue;
5139 if (ylow >= yup) continue;
5140
5141 if (Hoption.Box == 1) {
5142 fH->SetFillColor(color);
5143 fH->TAttFill::Modify();
5144 gPad->PaintBox(xlow, ylow, xup, yup);
5145 if (kZNeg) {
5146 gPad->PaintLine(xlow, ylow, xup, yup);
5147 gPad->PaintLine(xlow, yup, xup, ylow);
5148 }
5149 } else if (Hoption.Box == 11) {
5150 // Draw the center of the box
5151 fH->SetFillColor(color);
5152 fH->TAttFill::Modify();
5153 gPad->PaintBox(xlow, ylow, xup, yup);
5154
5155 // Draw top&left part of the box
5156 Double_t x[7], y[7];
5157 Double_t bwidth = 0.1;
5158 x[0] = xlow; y[0] = ylow;
5159 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5160 x[2] = x[1]; y[2] = yup - bwidth*(yup-ylow);
5161 x[3] = xup - bwidth*(xup-xlow); y[3] = y[2];
5162 x[4] = xup; y[4] = yup;
5163 x[5] = xlow; y[5] = yup;
5164 x[6] = xlow; y[6] = ylow;
5165 if (kZNeg) fH->SetFillColor(dark);
5166 else fH->SetFillColor(light);
5167 fH->TAttFill::Modify();
5168 gPad->PaintFillArea(7, x, y);
5169
5170 // Draw bottom&right part of the box
5171 x[0] = xlow; y[0] = ylow;
5172 x[1] = xlow + bwidth*(xup-xlow); y[1] = ylow + bwidth*(yup-ylow);
5173 x[2] = xup - bwidth*(xup-xlow); y[2] = y[1];
5174 x[3] = x[2]; y[3] = yup - bwidth*(yup-ylow);
5175 x[4] = xup; y[4] = yup;
5176 x[5] = xup; y[5] = ylow;
5177 x[6] = xlow; y[6] = ylow;
5178 if (kZNeg) fH->SetFillColor(light);
5179 else fH->SetFillColor(dark);
5180 fH->TAttFill::Modify();
5181 gPad->PaintFillArea(7, x, y);
5182 }
5183 }
5184 }
5185
5187 fH->SetFillStyle(fillsav);
5188 fH->SetFillColor(colsav);
5189 fH->TAttFill::Modify();
5190}
5191
5192
5193
5194////////////////////////////////////////////////////////////////////////////////
5195/// [Control function to draw a 2D histogram as a candle (box) plot or violin plot](#HP14)
5196
5198{
5199 TH1D *hproj;
5200 TH2D *h2 = (TH2D*)fH;
5201
5202 TCandle myCandle;
5204 myCandle.SetMarkerColor(fH->GetLineColor());
5205 myCandle.SetLineColor(fH->GetLineColor());
5206 myCandle.SetLineWidth(fH->GetLineWidth());
5207 myCandle.SetFillColor(fH->GetFillColor());
5208 myCandle.SetFillStyle(fH->GetFillStyle());
5209 myCandle.SetMarkerSize(fH->GetMarkerSize());
5210 myCandle.SetMarkerStyle(fH->GetMarkerStyle());
5212
5213 Bool_t swapXY = myCandle.IsHorizontal();
5214 const Double_t standardCandleWidth = 0.66;
5215 const Double_t standardHistoWidth = 0.8;
5216
5217 double allMaxContent = h2->GetBinContent(h2->GetMaximumBin());
5218 double allMaxIntegral = 0;
5219
5220 if (!swapXY) { // Vertical candle
5221 //Determining the slice with the maximum content
5222 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5223 hproj = h2->ProjectionY("_px", i, i);
5224 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5225 }
5226 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast; i++) {
5227 Double_t binPosX = fXaxis->GetBinLowEdge(i);
5228 Double_t binWidth = fXaxis->GetBinWidth(i);
5229 hproj = h2->ProjectionY("_px", i, i);
5230 if (hproj->GetEntries() !=0) {
5231 Double_t candleWidth = fH->GetBarWidth();
5232 Double_t offset = fH->GetBarOffset()*binWidth;
5233 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5234 double myIntegral = hproj->Integral();
5235 Double_t histoWidth = candleWidth;
5236 if (candleWidth > 0.999 && candleWidth < 1.001) {
5237 candleWidth = standardCandleWidth;
5238 histoWidth = standardHistoWidth;
5239 }
5240 if (Hoption.Logz && myMaxContent > 0) {
5241 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5242 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5243 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5244 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5245
5246 myCandle.SetAxisPosition(binPosX+binWidth/2. + offset);
5247 myCandle.SetCandleWidth(candleWidth*binWidth);
5248 myCandle.SetHistoWidth(histoWidth*binWidth);
5249 myCandle.SetHistogram(hproj);
5250 myCandle.Paint();
5251 }
5252 }
5253 } else { // Horizontal candle
5254 //Determining the slice with the maximum content
5255 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5256 hproj = h2->ProjectionX("_py", i, i);
5257 if (hproj->Integral() > allMaxIntegral) allMaxIntegral = hproj->Integral();
5258 }
5259 for (Int_t i=Hparam.yfirst; i<=Hparam.ylast; i++) {
5260 Double_t binPosY = fYaxis->GetBinLowEdge(i);
5261 Double_t binWidth = fYaxis->GetBinWidth(i);
5262 hproj = h2->ProjectionX("_py", i, i);
5263 if (hproj->GetEntries() !=0) {
5264 Double_t candleWidth = fH->GetBarWidth();
5265 Double_t offset = fH->GetBarOffset()*binWidth;
5266 double myMaxContent = hproj->GetBinContent(hproj->GetMaximumBin());
5267 double myIntegral = hproj->Integral();
5268 Double_t histoWidth = candleWidth;
5269 if (candleWidth > 0.999 && candleWidth < 1.001) {
5270 candleWidth = standardCandleWidth;
5271 histoWidth = standardHistoWidth;
5272 }
5273 if (Hoption.Logz && myMaxContent > 0) {
5274 histoWidth *= myMaxContent/TMath::Log10(myMaxContent);
5275 if (myCandle.IsViolinScaled() && myMaxContent > 0 && allMaxContent > 0) histoWidth *= TMath::Log10(myMaxContent)/TMath::Log10(allMaxContent);
5276 } else if (myCandle.IsViolinScaled()) histoWidth *= myMaxContent/allMaxContent;
5277 if (myCandle.IsCandleScaled()) candleWidth *= myIntegral/allMaxIntegral;
5278
5279 myCandle.SetAxisPosition(binPosY+binWidth/2. + offset);
5280 myCandle.SetCandleWidth(candleWidth*binWidth);
5281 myCandle.SetHistoWidth(histoWidth*binWidth);
5282 myCandle.SetHistogram(hproj);
5283 myCandle.Paint();
5284 }
5285 }
5286 }
5287}
5288
5289
5290
5291////////////////////////////////////////////////////////////////////////////////
5292/// Returns the rendering regions for an axis to use in the COL2 option
5293///
5294/// The algorithm analyses the size of the axis compared to the size of
5295/// the rendering region. It figures out the boundaries to use for each color
5296/// of the rendering region. Only one axis is computed here.
5297///
5298/// This allows for a single computation of the boundaries before iterating
5299/// through all of the bins.
5300///
5301/// \param pAxis the axis to consider
5302/// \param nPixels the number of pixels to render axis into
5303/// \param isLog whether the axis is log scale
5304
5305std::vector<THistRenderingRegion>
5307{
5308 std::vector<THistRenderingRegion> regions;
5309
5310 enum STRATEGY { Bins, Pixels } strategy;
5311
5312 Int_t nBins = (pAxis->GetLast() - pAxis->GetFirst() + 1);
5313
5314 if (nBins >= nPixels) {
5315 // more bins than pixels... we should loop over pixels and sample
5316 strategy = Pixels;
5317 } else {
5318 // fewer bins than pixels... we should loop over bins
5319 strategy = Bins;
5320 }
5321
5322 if (isLog) {
5323
5324 Double_t xMin = pAxis->GetBinLowEdge(pAxis->GetFirst());
5325 Int_t binOffset=0;
5326 while (xMin <= 0 && ((pAxis->GetFirst()+binOffset) != pAxis->GetLast()) ) {
5327 binOffset++;
5328 xMin = pAxis->GetBinLowEdge(pAxis->GetFirst()+binOffset);
5329 }
5330 if (xMin <= 0) {
5331 // this should cause an error if we have
5332 return regions;
5333 }
5334 Double_t xMax = pAxis->GetBinUpEdge(pAxis->GetLast());
5335
5336 if (strategy == Bins) {
5337 // logarithmic plot. we find the pixel for the bin
5338 // pixel = eta * log10(V) - alpha
5339 // where eta = nPixels/(log10(Vmax)-log10(Vmin))
5340 // and alpha = nPixels*log10(Vmin)/(log10(Vmax)-log10(Vmin))
5341 // and V is axis value
5342 Double_t eta = (nPixels-1.0)/(TMath::Log10(xMax) - TMath::Log10(xMin));
5343 Double_t offset = -1.0 * eta * TMath::Log10(xMin);
5344
5345 for (Int_t bin=pAxis->GetFirst()+binOffset; bin<=pAxis->GetLast(); bin++) {
5346
5347 // linear plot. we simply need to find the appropriate bin
5348 // for the
5349 Double_t xLowValue = pAxis->GetBinLowEdge(bin);
5350 Double_t xUpValue = pAxis->GetBinUpEdge(bin);
5351 Int_t xPx0 = eta*TMath::Log10(xLowValue)+ offset;
5352 Int_t xPx1 = eta*TMath::Log10(xUpValue) + offset;
5353 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5354 std::make_pair(bin, bin+1)};
5355 regions.push_back(region);
5356 }
5357
5358 } else {
5359
5360 // loop over pixels
5361
5362 Double_t beta = (TMath::Log10(xMax) - TMath::Log10(xMin))/(nPixels-1.0);
5363
5364 for (Int_t pixelIndex=0; pixelIndex<(nPixels-1); pixelIndex++) {
5365 // linear plot
5366 Int_t binLow = pAxis->FindBin(xMin*TMath::Power(10.0, beta*pixelIndex));
5367 Int_t binHigh = pAxis->FindBin(xMin*TMath::Power(10.0, beta*(pixelIndex+1)));
5368 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5369 std::make_pair(binLow, binHigh)};
5370 regions.push_back(region);
5371 }
5372 }
5373 } else {
5374 // standard linear plot
5375
5376 if (strategy == Bins) {
5377 // loop over bins
5378 for (Int_t bin=pAxis->GetFirst(); bin<=pAxis->GetLast(); bin++) {
5379
5380 // linear plot. we simply need to find the appropriate bin
5381 // for the
5382 Int_t xPx0 = ((bin - pAxis->GetFirst()) * nPixels)/nBins;
5383 Int_t xPx1 = xPx0 + nPixels/nBins;
5384
5385 // make sure we don't compute beyond our bounds
5386 if (xPx1>= nPixels) xPx1 = nPixels-1;
5387
5388 THistRenderingRegion region = {std::make_pair(xPx0, xPx1),
5389 std::make_pair(bin, bin+1)};
5390 regions.push_back(region);
5391 }
5392 } else {
5393 // loop over pixels
5394 for (Int_t pixelIndex=0; pixelIndex<nPixels-1; pixelIndex++) {
5395 // linear plot
5396 Int_t binLow = (nBins*pixelIndex)/nPixels + pAxis->GetFirst();
5397 Int_t binHigh = binLow + nBins/nPixels;
5398 THistRenderingRegion region = { std::make_pair(pixelIndex, pixelIndex+1),
5399 std::make_pair(binLow, binHigh)};
5400 regions.push_back(region);
5401 }
5402 }
5403 }
5404
5405 return regions;
5406}
5407
5408////////////////////////////////////////////////////////////////////////////////
5409/// [Rendering scheme for the COL2 and COLZ2 options] (#HP14)
5410
5412{
5413
5414 if (Hoption.System != kCARTESIAN) {
5415 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5416 "Only cartesian coordinates supported by 'COL2' option. Using 'COL' option instead.");
5417 PaintColorLevels(nullptr);
5418 return;
5419 }
5420
5421 Double_t z;
5422
5423 // Use existing max or min values. If either is already set
5424 // the appropriate value to use.
5425 Double_t zmin = fH->GetMinimumStored();
5426 Double_t zmax = fH->GetMaximumStored();
5427 Double_t originalZMin = zmin;
5428 Double_t originalZMax = zmax;
5429 if ((zmin == -1111) && (zmax == -1111)) {
5430 fH->GetMinimumAndMaximum(zmin, zmax);
5431 fH->SetMinimum(zmin);
5432 fH->SetMaximum(zmax);
5433 } else if (zmin == -1111) {
5434 zmin = fH->GetMinimum();
5435 fH->SetMinimum(zmin);
5436 } else if (zmax == -1111) {
5437 zmax = fH->GetMaximum();
5438 fH->SetMaximum(zmax);
5439 }
5440
5441 Double_t dz = zmax - zmin;
5442 if (dz <= 0) { // Histogram filled with a constant value
5443 zmax += 0.1*TMath::Abs(zmax);
5444 zmin -= 0.1*TMath::Abs(zmin);
5445 dz = zmax - zmin;
5446 }
5447
5448 if (Hoption.Logz) {
5449 if (zmin > 0) {
5450 zmin = TMath::Log10(zmin);
5451 zmax = TMath::Log10(zmax);
5452 dz = zmax - zmin;
5453 } else {
5454 Error("THistPainter::PaintColorLevelsFast(Option_t*)",
5455 "Cannot plot logz because bin content is less than 0.");
5456 return;
5457 }
5458 }
5459
5460 // Initialize the levels on the Z axis
5461 Int_t ndiv = fH->GetContour();
5462 if (ndiv == 0 ) {
5463 ndiv = gStyle->GetNumberContours();
5464 fH->SetContour(ndiv);
5465 }
5466 std::vector<Double_t> colorBounds(ndiv);
5467 std::vector<Double_t> contours(ndiv, 0);
5468 if (fH->TestBit(TH1::kUserContour) == 0) {
5469 fH->SetContour(ndiv);
5470 } else {
5471 fH->GetContour(contours.data());
5472 }
5473
5474 Double_t step = 1.0/ndiv;
5475 for (Int_t i=0; i<ndiv; ++i) {
5476 colorBounds[i] = step*i;
5477 }
5478
5479 auto pFrame = gPad->GetFrame();
5480 Int_t px0 = gPad->XtoPixel(pFrame->GetX1());
5481 Int_t px1 = gPad->XtoPixel(pFrame->GetX2());
5482 Int_t py0 = gPad->YtoPixel(pFrame->GetY1());
5483 Int_t py1 = gPad->YtoPixel(pFrame->GetY2());
5484 Int_t nXPixels = px1-px0;
5485 Int_t nYPixels = py0-py1; // y=0 is at the top of the screen
5486
5487 std::vector<Double_t> buffer(nXPixels*nYPixels, 0);
5488
5489 auto xRegions = ComputeRenderingRegions(fXaxis, nXPixels, Hoption.Logx);
5490 auto yRegions = ComputeRenderingRegions(fYaxis, nYPixels, Hoption.Logy);
5491 if (xRegions.size() == 0 || yRegions.size() == 0) {
5492 Error("THistPainter::PaintColorLevelFast(Option_t*)",
5493 "Encountered error while computing rendering regions.");
5494 return;
5495 }
5496
5497 Bool_t minExists = kFALSE;
5498 Bool_t maxExists = kFALSE;
5499 Double_t minValue = 1.;
5500 Double_t maxValue = 0.;
5501 for (auto& yRegion : yRegions) {
5502 for (auto& xRegion : xRegions ) {
5503
5504 const auto& xBinRange = xRegion.fBinRange;
5505 const auto& yBinRange = yRegion.fBinRange;
5506
5507 // sample the range
5508 z = fH->GetBinContent(xBinRange.second-1, yBinRange.second-1);
5509
5510 if (Hoption.Logz) {
5511 if (z > 0) z = TMath::Log10(z);
5512 else z = zmin;
5513 }
5514
5515 // obey the user's max and min values if they were set
5516 if (z > zmax) z = zmax;
5517 if (z < zmin) z = zmin;
5518
5519 if (fH->TestBit(TH1::kUserContour) == 1) {
5520 // contours are absolute values
5521 auto index = TMath::BinarySearch(contours.size(), contours.data(), z);
5522 z = colorBounds[index];
5523 } else {
5524 Int_t index = 0;
5525 if (dz != 0) {
5526 index = 0.001 + ((z - zmin)/dz)*ndiv;
5527 }
5528
5529 if (index == static_cast<Int_t>(colorBounds.size())) {
5530 index--;
5531 }
5532
5533 // Do a little bookkeeping to use later for getting libAfterImage to produce
5534 // the correct colors
5535 if (index == 0) {
5536 minExists = kTRUE;
5537 } else if (index == static_cast<Int_t>(colorBounds.size()-1)) {
5538 maxExists = kTRUE;
5539 }
5540
5541 z = colorBounds[index];
5542
5543 if (z < minValue) {
5544 minValue = z;
5545 }
5546 if (z > maxValue) {
5547 maxValue = z;
5548 }
5549 }
5550
5551 // fill in the actual pixels
5552 const auto& xPixelRange = xRegion.fPixelRange;
5553 const auto& yPixelRange = yRegion.fPixelRange;
5554 for (Int_t xPx = xPixelRange.first; xPx <= xPixelRange.second; ++xPx) {
5555 for (Int_t yPx = yPixelRange.first; yPx <= yPixelRange.second; ++yPx) {
5556 Int_t pixel = yPx*nXPixels + xPx;
5557 buffer[pixel] = z;
5558 }
5559 }
5560 } // end px loop
5561 } // end py loop
5562
5563 // This is a bit of a hack to ensure that we span the entire color range and
5564 // don't screw up the colors for a sparse histogram. No one will notice that I set a
5565 // single pixel on the edge of the image to a different color. This is even more
5566 // true because the chosen pixels will be covered by the axis.
5567 if (minValue != maxValue) {
5568 if ( !minExists) {
5569 buffer.front() = 0;
5570 }
5571
5572 if ( !maxExists) {
5573 buffer[buffer.size()-nXPixels] = 0.95;
5574 }
5575 }
5576
5577 // Generate the TImage
5579 TImage* pImage = TImage::Create();
5581 pImage->SetImage(buffer.data(), nXPixels, nYPixels, pPalette);
5582 delete pPalette;
5583
5584 Window_t wid = static_cast<Window_t>(gVirtualX->GetWindowID(gPad->GetPixmapID()));
5585 pImage->PaintImage(wid, px0, py1, 0, 0, nXPixels, nYPixels);
5586 delete pImage;
5587
5589
5590 // Reset the maximum and minimum values to their original values
5591 // when this function was called. If we don't do this, an initial
5592 // value of -1111 will be replaced with the true max or min values.
5593 fH->SetMinimum(originalZMin);
5594 fH->SetMaximum(originalZMax);
5595}
5596
5597////////////////////////////////////////////////////////////////////////////////
5598/// [Control function to draw a 2D histogram as a color plot.](#HP14)
5599
5601{
5602 Double_t z, zc, xk, xstep, yk, ystep, xlow, xup, ylow, yup;
5603
5604 Double_t zmin = fH->GetMinimum();
5605 Double_t zmax = fH->GetMaximum();
5606
5607 Double_t dz = zmax - zmin;
5608 if (dz <= 0) { // Histogram filled with a constant value
5609 zmax += 0.1*TMath::Abs(zmax);
5610 zmin -= 0.1*TMath::Abs(zmin);
5611 dz = zmax - zmin;
5612 }
5613
5614 // In case of option SAME, zmin and zmax values are taken from the
5615 // first plotted 2D histogram.
5616 if (Hoption.Same) {
5617 TH2 *h2;
5618 TIter next(gPad->GetListOfPrimitives());
5619 while ((h2 = (TH2 *)next())) {
5620 if (!h2->InheritsFrom(TH2::Class())) continue;
5621 zmin = h2->GetMinimum();
5622 zmax = h2->GetMaximum();
5623 if (Hoption.Logz) {
5624 if (zmin <= 0) {
5625 zmin = TMath::Log10(zmax*0.001);
5626 } else {
5627 zmin = TMath::Log10(zmin);
5628 }
5629 zmax = TMath::Log10(zmax);
5630 }
5631 dz = zmax - zmin;
5632 break;
5633 }
5634 } else {
5635 if (Hoption.Logz) {
5636 if (zmin > 0) {
5637 zmin = TMath::Log10(zmin);
5638 zmax = TMath::Log10(zmax);
5639 dz = zmax - zmin;
5640 } else {
5641 return;
5642 }
5643 }
5644 }
5645
5646 Style_t fillsav = fH->GetFillStyle();
5647 Style_t colsav = fH->GetFillColor();
5648 fH->SetFillStyle(1001);
5649 fH->TAttFill::Modify();
5650
5651 // Initialize the levels on the Z axis
5652 Int_t ncolors = gStyle->GetNumberOfColors();
5653 Int_t ndiv = fH->GetContour();
5654 if (ndiv == 0 ) {
5655 ndiv = gStyle->GetNumberContours();
5656 fH->SetContour(ndiv);
5657 }
5658 Int_t ndivz = TMath::Abs(ndiv);
5659 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
5660 Double_t scale = ndivz/dz;
5661
5662 Int_t color;
5663 TProfile2D* prof2d = dynamic_cast<TProfile2D*>(fH);
5664 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
5665 yk = fYaxis->GetBinLowEdge(j);
5666 ystep = fYaxis->GetBinWidth(j);
5667 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
5668 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
5669 xk = fXaxis->GetBinLowEdge(i);
5670 xstep = fXaxis->GetBinWidth(i);
5671 if (Hoption.System == kPOLAR && xk<0) xk= 2*TMath::Pi()+xk;
5672 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
5673 z = fH->GetBinContent(bin);
5674 // if fH is a profile histogram do not draw empty bins
5675 if (prof2d) {
5676 const Double_t binEntries = prof2d->GetBinEntries(bin);
5677 if (binEntries == 0)
5678 continue;
5679 } else {
5680 // don't draw the empty bins for non-profile histograms
5681 // with positive content
5682 if (z == 0) {
5683 if (zmin >= 0 || Hoption.Logz) continue;
5684 if (Hoption.Color == 2) continue;
5685 }
5686 }
5687
5688 if (Hoption.Logz) {
5689 if (z > 0) z = TMath::Log10(z);
5690 else z = zmin;
5691 }
5692 if (z < zmin && !Hoption.Zero) continue;
5693 xup = xk + xstep;
5694 xlow = xk;
5695 if (Hoption.Logx) {
5696 if (xup > 0) xup = TMath::Log10(xup);
5697 else continue;
5698 if (xlow > 0) xlow = TMath::Log10(xlow);
5699 else continue;
5700 }
5701 yup = yk + ystep;
5702 ylow = yk;
5703 if (Hoption.System != kPOLAR) {
5704 if (Hoption.Logy) {
5705 if (yup > 0) yup = TMath::Log10(yup);
5706 else continue;
5707 if (ylow > 0) ylow = TMath::Log10(ylow);
5708 else continue;
5709 }
5710 if (xup < gPad->GetUxmin()) continue;
5711 if (yup < gPad->GetUymin()) continue;
5712 if (xlow > gPad->GetUxmax()) continue;
5713 if (ylow > gPad->GetUymax()) continue;
5714 if (xlow < gPad->GetUxmin()) xlow = gPad->GetUxmin();
5715 if (ylow < gPad->GetUymin()) ylow = gPad->GetUymin();
5716 if (xup > gPad->GetUxmax()) xup = gPad->GetUxmax();
5717 if (yup > gPad->GetUymax()) yup = gPad->GetUymax();
5718 }
5719
5721 zc = fH->GetContourLevelPad(0);
5722 if (z < zc) continue;
5723 color = -1;
5724 for (Int_t k=0; k<ndiv; k++) {
5725 zc = fH->GetContourLevelPad(k);
5726 if (z < zc) {
5727 continue;
5728 } else {
5729 color++;
5730 }
5731 }
5732 } else {
5733 color = Int_t(0.01+(z-zmin)*scale);
5734 }
5735
5736 Int_t theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
5737 if (theColor > ncolors-1) theColor = ncolors-1;
5739 fH->TAttFill::Modify();
5740 if (Hoption.System != kPOLAR) {
5741 gPad->PaintBox(xlow, ylow, xup, yup);
5742 } else {
5743 TCrown crown(0,0,ylow,yup,xlow*TMath::RadToDeg(),xup*TMath::RadToDeg());
5744 crown.SetFillColor(gStyle->GetColorPalette(theColor));
5745 crown.Paint();
5746 }
5747 }
5748 }
5749
5751
5752 fH->SetFillStyle(fillsav);
5753 fH->SetFillColor(colsav);
5754 fH->TAttFill::Modify();
5755
5756}
5757
5758////////////////////////////////////////////////////////////////////////////////
5759/// [Control function to draw a 2D histogram as a contour plot.](#HP16)
5760
5762{
5763
5764 Int_t i, j, count, ncontour, icol, n, lj, m, ix, jx, ljfill;
5765 Int_t itars, mode, ir[4];
5766 Double_t xsave, ysave, thesave,phisave,x[4], y[4], zc[4];
5767
5768 if (Hoption.Contour == 14) {
5769 Hoption.Surf = 12;
5770 Hoption.Axis = 1;
5771 thesave = gPad->GetTheta();
5772 phisave = gPad->GetPhi();
5773 gPad->SetPhi(0.);
5774 gPad->SetTheta(90.);
5775 PaintSurface(option);
5776 gPad->SetPhi(phisave);
5777 gPad->SetTheta(thesave);
5778 TView *view = gPad->GetView();
5779 if (view) view->SetBit(kCannotRotate); //tested in ExecuteEvent
5780 PaintAxis();
5781 return;
5782 }
5783
5784 if (Hoption.Same) {
5785 // If the contour is painted on a 3d plot, the contour lines are
5786 // paint in 3d too.
5787 TObject *obj;
5788 TIter next(gPad->GetListOfPrimitives());
5789 while ((obj=next())) {
5790 if (strstr(obj->GetDrawOption(),"surf") ||
5791 strstr(obj->GetDrawOption(),"lego") ||
5792 strstr(obj->GetDrawOption(),"tri")) {
5793 Hoption.Surf = 16;
5794 PaintSurface(option);
5795 return;
5796 }
5797 }
5798 }
5799
5800 if (Hoption.Contour == 15) {
5801 TGraphDelaunay2D *dt = nullptr;
5802 TGraphDelaunay *dtOld = nullptr;
5803 TList *hl = fH->GetListOfFunctions();
5804 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
5805 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
5806 if (!dt && !dtOld) return;
5807 if (!fGraph2DPainter) {
5808 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
5809 else fGraph2DPainter = new TGraph2DPainter(dtOld);
5810 }
5811 fGraph2DPainter->Paint(option);
5812 return;
5813 }
5814
5815 gPad->SetBit(TGraph::kClipFrame);
5816
5817 Double_t *levels = new Double_t[2*kMAXCONTOUR];
5818 Double_t *xarr = new Double_t[2*kMAXCONTOUR];
5819 Double_t *yarr = new Double_t[2*kMAXCONTOUR];
5820 Int_t *itarr = new Int_t[2*kMAXCONTOUR];
5821
5822 Int_t npmax = 0;
5823 for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0;
5824
5825 ncontour = fH->GetContour();
5826 if (ncontour == 0) {
5827 ncontour = gStyle->GetNumberContours();
5828 fH->SetContour(ncontour);
5829 }
5830 if (ncontour > kMAXCONTOUR) {
5831 Warning("PaintContour", "maximum number of contours is %d, asked for %d",
5832 kMAXCONTOUR, ncontour);
5833 ncontour = kMAXCONTOUR-1;
5834 }
5835 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour);
5836
5837 for (i=0;i<ncontour;i++) levels[i] = fH->GetContourLevelPad(i);
5838 Int_t linesav = fH->GetLineStyle();
5839 Int_t colorsav = fH->GetLineColor();
5840 Int_t fillsav = fH->GetFillColor();
5841 if (Hoption.Contour == 13) {
5842 fH->TAttLine::Modify();
5843 }
5844
5845 TPolyLine **polys = 0;
5846 TPolyLine *poly=0;
5847 TObjArray *contours = 0;
5848 TList *list = 0;
5849 TGraph *graph = 0;
5850 Int_t *np = 0;
5851 if (Hoption.Contour == 1) {
5852 np = new Int_t[ncontour];
5853 for (i=0;i<ncontour;i++) np[i] = 0;
5854 polys = new TPolyLine*[ncontour];
5855 for (i=0;i<ncontour;i++) {
5856 polys[i] = new TPolyLine(100);
5857 }
5858 if (Hoption.List == 1) {
5859 contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
5860 if (contours) {
5861 gROOT->GetListOfSpecials()->Remove(contours);
5862 count = contours->GetSize();
5863 for (i=0;i<count;i++) {
5864 list = (TList*)contours->At(i);
5865 if (list) list->Delete();
5866 }
5867 }
5868 contours = new TObjArray(ncontour);
5869 contours->SetName("contours");
5870 gROOT->GetListOfSpecials()->Add(contours);
5871 for (i=0;i<ncontour;i++) {
5872 list = new TList();
5873 contours->Add(list);
5874 }
5875 }
5876 }
5877 Int_t theColor;
5878 Int_t ncolors = gStyle->GetNumberOfColors();
5879 Int_t ndivz = TMath::Abs(ncontour);
5880
5881 Int_t k,ipoly;
5882 for (j=Hparam.yfirst; j<Hparam.ylast; j++) {
5883 y[0] = fYaxis->GetBinCenter(j);
5884 y[1] = y[0];
5885 y[2] = fYaxis->GetBinCenter(j+1);
5886 y[3] = y[2];
5887 for (i=Hparam.xfirst; i<Hparam.xlast; i++) {
5888 zc[0] = fH->GetBinContent(i, j);
5889 zc[1] = fH->GetBinContent(i+1, j);
5890 zc[2] = fH->GetBinContent(i+1, j+1);
5891 zc[3] = fH->GetBinContent(i, j+1);
5892 if (!IsInside(fXaxis->GetBinCenter(i),fYaxis->GetBinCenter(j))) continue;
5893 if (Hoption.Logz) {
5894 if (zc[0] > 0) zc[0] = TMath::Log10(zc[0]);
5895 else zc[0] = Hparam.zmin;
5896 if (zc[1] > 0) zc[1] = TMath::Log10(zc[1]);
5897 else zc[1] = Hparam.zmin;
5898 if (zc[2] > 0) zc[2] = TMath::Log10(zc[2]);
5899 else zc[2] = Hparam.zmin;
5900 if (zc[3] > 0) zc[3] = TMath::Log10(zc[3]);
5901 else zc[3] = Hparam.zmin;
5902 }
5903 for (k=0;k<4;k++) {
5904 ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]);
5905 }
5906 if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) {
5907 x[0] = fXaxis->GetBinCenter(i);
5908 x[3] = x[0];
5909 x[1] = fXaxis->GetBinCenter(i+1);
5910 x[2] = x[1];
5911 if (zc[0] <= zc[1]) n = 0; else n = 1;
5912 if (zc[2] <= zc[3]) m = 2; else m = 3;
5913 if (zc[n] > zc[m]) n = m;
5914 n++;
5915 lj=1;
5916 for (ix=1;ix<=4;ix++) {
5917 m = n%4 + 1;
5918 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5919 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5920 lj += 2*ljfill;
5921 n = m;
5922 }
5923
5924 if (zc[0] <= zc[1]) n = 0; else n = 1;
5925 if (zc[2] <= zc[3]) m = 2; else m = 3;
5926 if (zc[n] > zc[m]) n = m;
5927 n++;
5928 lj=2;
5929 for (ix=1;ix<=4;ix++) {
5930 if (n == 1) m = 4;
5931 else m = n-1;
5932 ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1],
5933 ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels);
5934 lj += 2*ljfill;
5935 n = m;
5936 }
5937
5938 // Re-order endpoints
5939
5940 count = 0;
5941 for (ix=1; ix<=lj-5; ix +=2) {
5942 //count = 0;
5943 while (itarr[ix-1] != itarr[ix]) {
5944 xsave = xarr[ix];
5945 ysave = yarr[ix];
5946 itars = itarr[ix];
5947 for (jx=ix; jx<=lj-5; jx +=2) {
5948 xarr[jx] = xarr[jx+2];
5949 yarr[jx] = yarr[jx+2];
5950 itarr[jx] = itarr[jx+2];
5951 }
5952 xarr[lj-3] = xsave;
5953 yarr[lj-3] = ysave;
5954 itarr[lj-3] = itars;
5955 if (count > 100) break;
5956 count++;
5957 }
5958 }
5959
5960 if (count > 100) continue;
5961 for (ix=1; ix<=lj-2; ix +=2) {
5962 theColor = Int_t((itarr[ix-1]+0.99)*Float_t(ncolors)/Float_t(ndivz));
5963 icol = gStyle->GetColorPalette(theColor);
5964 if (Hoption.Contour == 11) {
5965 fH->SetLineColor(icol);
5966 }
5967 if (Hoption.Contour == 12) {
5968 mode = icol%5;
5969 if (mode == 0) mode = 5;
5970 fH->SetLineStyle(mode);
5971 }
5972 if (Hoption.Contour != 1) {
5973 fH->TAttLine::Modify();
5974 gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]);
5975 continue;
5976 }
5977
5978 ipoly = itarr[ix-1];
5979 if (ipoly >=0 && ipoly <ncontour) {
5980 poly = polys[ipoly];
5981 poly->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]);
5982 poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]);
5983 np[ipoly] += 2;
5984 if (npmax < np[ipoly]) npmax = np[ipoly];
5985 }
5986 }
5987 } // end of if (ir[0]
5988 } //end of for (i
5989 } //end of for (j
5990
5992 Double_t *xp, *yp;
5993 Int_t nadd,iminus,iplus;
5994 Double_t *xx, *yy;
5995 Int_t istart;
5996 Int_t first = ncontour;
5997 Int_t *polysort = 0;
5998 Int_t contListNb;
5999 if (Hoption.Contour != 1) goto theEND;
6000
6001 //The 2 points line generated above are now sorted/merged to generate
6002 //a list of consecutive points.
6003 // If the option "List" has been specified, the list of points is saved
6004 // in the form of TGraph objects in the ROOT list of special objects.
6005 xmin = gPad->GetUxmin();
6006 ymin = gPad->GetUymin();
6007 xp = new Double_t[2*npmax];
6008 yp = new Double_t[2*npmax];
6009 polysort = new Int_t[ncontour];
6010 //find first positive contour
6011 for (ipoly=0;ipoly<ncontour;ipoly++) {
6012 if (levels[ipoly] >= 0) {first = ipoly; break;}
6013 }
6014 //store negative contours from 0 to minimum, then all positive contours
6015 k = 0;
6016 for (ipoly=first-1;ipoly>=0;ipoly--) {polysort[k] = ipoly; k++;}
6017 for (ipoly=first;ipoly<ncontour;ipoly++) {polysort[k] = ipoly; k++;}
6018 // we can now draw sorted contours
6019 contListNb = 0;
6020 fH->SetFillStyle(1001);
6021 for (k=0;k<ncontour;k++) {
6022 ipoly = polysort[k];
6023 if (np[ipoly] == 0) continue;
6024 if (Hoption.List) list = (TList*)contours->At(contListNb);
6025 contListNb++;
6026 poly = polys[ipoly];
6027 xx = poly->GetX();
6028 yy = poly->GetY();
6029 istart = 0;
6030 while (1) {
6031 iminus = npmax;
6032 iplus = iminus+1;
6033 xp[iminus]= xx[istart]; yp[iminus] = yy[istart];
6034 xp[iplus] = xx[istart+1]; yp[iplus] = yy[istart+1];
6035 xx[istart] = xmin; yy[istart] = ymin;
6036 xx[istart+1] = xmin; yy[istart+1] = ymin;
6037 while (1) {
6038 nadd = 0;
6039 for (i=2;i<np[ipoly];i+=2) {
6040 if ((iplus < 2*npmax-1) && (xx[i] == xp[iplus]) && (yy[i] == yp[iplus])) {
6041 iplus++;
6042 xp[iplus] = xx[i+1]; yp[iplus] = yy[i+1];
6043 xx[i] = xmin; yy[i] = ymin;
6044 xx[i+1] = xmin; yy[i+1] = ymin;
6045 nadd++;
6046 }
6047 if ((iminus > 0) && (xx[i+1] == xp[iminus]) && (yy[i+1] == yp[iminus])) {
6048 iminus--;
6049 xp[iminus] = xx[i]; yp[iminus] = yy[i];
6050 xx[i] = xmin; yy[i] = ymin;
6051 xx[i+1] = xmin; yy[i+1] = ymin;
6052 nadd++;
6053 }
6054 }
6055 if (nadd == 0) break;
6056 }
6057 theColor = Int_t((ipoly+0.99)*Float_t(ncolors)/Float_t(ndivz));
6058 icol = gStyle->GetColorPalette(theColor);
6059 if (ndivz > 1) fH->SetFillColor(icol);
6060 fH->TAttFill::Modify();
6061 gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6062 if (Hoption.List) {
6063 graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]);
6064 graph->SetFillColor(icol);
6065 graph->SetLineWidth(fH->GetLineWidth());
6066 list->Add(graph);
6067 }
6068 //check if more points are left
6069 istart = 0;
6070 for (i=2;i<np[ipoly];i+=2) {
6071 if (xx[i] != xmin && yy[i] != ymin) {
6072 istart = i;
6073 break;
6074 }
6075 }
6076 if (istart == 0) break;
6077 }
6078 }
6079
6080 for (i=0;i<ncontour;i++) delete polys[i];
6081 delete [] polys;
6082 delete [] xp;
6083 delete [] yp;
6084 delete [] polysort;
6085
6086theEND:
6087 gPad->ResetBit(TGraph::kClipFrame);
6089 fH->SetLineStyle(linesav);
6090 fH->SetLineColor(colorsav);
6091 fH->SetFillColor(fillsav);
6092 if (np) delete [] np;
6093 delete [] xarr;
6094 delete [] yarr;
6095 delete [] itarr;
6096 delete [] levels;
6097}
6098
6099////////////////////////////////////////////////////////////////////////////////
6100/// Fill the matrix `xarr` and `yarr` for Contour Plot.
6101
6103 Double_t elev2, Int_t icont2, Double_t x2, Double_t y2,
6104 Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
6105{
6106
6107 Bool_t vert;
6108 Double_t tlen, tdif, elev, diff, pdif, xlen;
6109 Int_t n, i, icount;
6110
6111 if (x1 == x2) {
6112 vert = kTRUE;
6113 tlen = y2 - y1;
6114 } else {
6115 vert = kFALSE;
6116 tlen = x2 - x1;
6117 }
6118
6119 n = icont1 +1;
6120 tdif = elev2 - elev1;
6121 i = 0;
6122 icount = 0;
6123 while (n <= icont2 && i <= kMAXCONTOUR/2 -3) {
6124 //elev = fH->GetContourLevel(n);
6125 elev = levels[n];
6126 diff = elev - elev1;
6127 pdif = diff/tdif;
6128 xlen = tlen*pdif;
6129 if (vert) {
6130 if (Hoption.Logx)
6131 xarr[i] = TMath::Log10(x1);
6132 else
6133 xarr[i] = x1;
6134 if (Hoption.Logy)
6135 yarr[i] = TMath::Log10(y1 + xlen);
6136 else
6137 yarr[i] = y1 + xlen;
6138 } else {
6139 if (Hoption.Logx)
6140 xarr[i] = TMath::Log10(x1 + xlen);
6141 else
6142 xarr[i] = x1 + xlen;
6143 if (Hoption.Logy)
6144 yarr[i] = TMath::Log10(y1);
6145 else
6146 yarr[i] = y1;
6147 }
6148 itarr[i] = n;
6149 icount++;
6150 i +=2;
6151 n++;
6152 }
6153 return icount;
6154}
6155
6156////////////////////////////////////////////////////////////////////////////////
6157/// [Draw 1D histograms error bars.](#HP09)
6158
6160{
6161
6162 // On iOS, we do not highlight histogram, if it's not picked at the moment
6163 // (but part of histogram (axis or pavestat) was picked, that's why this code
6164 // is called at all. This conditional statement never executes on non-iOS platform.
6165 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
6166
6167 const Int_t kBASEMARKER=8;
6168 Double_t xp, yp, ex1, ex2, ey1, ey2;
6169 Double_t delta;
6170 Double_t s2x, s2y, bxsize, bysize, symbolsize, xerror, sbase;
6171 Double_t xi1, xi2, xi3, xi4, yi1, yi2, yi3, yi4;
6173 Double_t logxmin = 0;
6174 Double_t logymin = 0;
6175 Int_t i, k, npoints, first, last, fixbin;
6176 Int_t if1 = 0;
6177 Int_t if2 = 0;
6178 Int_t drawmarker, errormarker;
6179 Int_t option0, option1, option2, option3, option4, optionE, optionEX0, optionI0;
6180
6181 Double_t *xline = 0;
6182 Double_t *yline = 0;
6183 option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0;
6184 if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;}
6185 if (Hoption.Error == 31) {optionEX0 = 1; Hoption.Error = 1;}
6186 if (Hoption.Error == 10) option0 = 1;
6187 if (Hoption.Error == 11) option1 = 1;
6188 if (Hoption.Error == 12) option2 = 1;
6189 if (Hoption.Error == 13) option3 = 1;
6190 if (Hoption.Error == 14) {option4 = 1; option3 = 1;}
6191 if (Hoption.Error == 15) {optionI0 = 1; option3 = 1;}
6192 if (Hoption.Error == 16) {optionI0 = 1; option4 = 1; option3 = 1;}
6193 if (option2+option3 == 0) optionE = 1;
6194 if (Hoption.Error == 0) optionE = 0;
6195 if (fXaxis->GetXbins()->fN) fixbin = 0;
6196 else fixbin = 1;
6197
6198 errormarker = fH->GetMarkerStyle();
6199 if (optionEX0) {
6200 xerror = 0;
6201 } else {
6202 xerror = gStyle->GetErrorX();
6203 }
6204 symbolsize = fH->GetMarkerSize();
6205 if (errormarker == 1) symbolsize = 0.01;
6206 sbase = symbolsize*kBASEMARKER;
6207 // set the graphics attributes
6208
6209 fH->TAttLine::Modify();
6210 fH->TAttFill::Modify();
6211 fH->TAttMarker::Modify();
6212
6213 // set the first and last bin
6214
6215 Double_t factor = Hparam.factor;
6217 last = Hparam.xlast;
6218 npoints = last - first +1;
6219 xmin = gPad->GetUxmin();
6220 xmax = gPad->GetUxmax();
6221 ymin = gPad->GetUymin();
6222 ymax = gPad->GetUymax();
6223
6224
6225 if (option3) {
6226 xline = new Double_t[2*npoints];
6227 yline = new Double_t[2*npoints];
6228 if (!xline || !yline) {
6229 Error("PaintErrors", "too many points, out of memory");
6230 return;
6231 }
6232 if1 = 1;
6233 if2 = 2*npoints;
6234 }
6235
6236 // compute the offset of the error bars due to the symbol size
6237 s2x = gPad->PixeltoX(Int_t(0.5*sbase)) - gPad->PixeltoX(0);
6238 s2y =-gPad->PixeltoY(Int_t(0.5*sbase)) + gPad->PixeltoY(0);
6239
6240 // compute size of the lines at the end of the error bars
6241 Int_t dxend = Int_t(gStyle->GetEndErrorSize());
6242 bxsize = gPad->PixeltoX(dxend) - gPad->PixeltoX(0);
6243 bysize =-gPad->PixeltoY(dxend) + gPad->PixeltoY(0);
6244
6245
6246 if (fixbin) {
6247 if (Hoption.Logx) xp = TMath::Power(10,Hparam.xmin) + 0.5*Hparam.xbinsize;
6248 else xp = Hparam.xmin + 0.5*Hparam.xbinsize;
6249 } else {
6250 delta = fH->GetBinWidth(first);
6251 xp = fH->GetBinLowEdge(first) + 0.5*delta;
6252 }
6253
6254 // if errormarker = 0 or symbolsize = 0. no symbol is drawn
6255 if (Hoption.Logx) logxmin = TMath::Power(10,Hparam.xmin);
6256 if (Hoption.Logy) logymin = TMath::Power(10,Hparam.ymin);
6257
6258 // ---------------------- Loop over the points---------------------
6259 for (k=first; k<=last; k++) {
6260
6261 // get the data
6262 // xp = X position of the current point
6263 // yp = Y position of the current point
6264 // ex1 = Low X error
6265 // ex2 = Up X error
6266 // ey1 = Low Y error
6267 // ey2 = Up Y error
6268 // (xi,yi) = Error bars coordinates
6269
6270 if (Hoption.Logx) {
6271 if (xp <= 0) goto L30;
6272 if (xp < logxmin) goto L30;
6273 if (xp > TMath::Power(10,xmax)) break;
6274 } else {
6275 if (xp < xmin) goto L30;
6276 if (xp > xmax) break;
6277 }
6278 yp = factor*fH->GetBinContent(k);
6279 if (optionI0 && yp==0) goto L30;
6280 if (fixbin) {
6281 ex1 = xerror*Hparam.xbinsize;
6282 } else {
6283 delta = fH->GetBinWidth(k);
6284 ex1 = xerror*delta;
6285 }
6286 if (fH->GetBinErrorOption() == TH1::kNormal) {
6287 ey1 = factor*fH->GetBinError(k);
6288 ey2 = ey1;
6289 } else {
6290 ey1 = factor*fH->GetBinErrorLow(k);
6291 ey2 = factor*fH->GetBinErrorUp(k);
6292 }
6293 ex2 = ex1;
6294
6295 xi4 = xp;
6296 xi3 = xp;
6297 xi2 = xp + ex2;
6298 xi1 = xp - ex1;
6299
6300 yi1 = yp;
6301 yi2 = yp;
6302 yi3 = yp - ey1;
6303 yi4 = yp + ey2;
6304
6305 // take the LOG if necessary
6306 if (Hoption.Logx) {
6307 xi1 = TMath::Log10(TMath::Max(xi1,logxmin));
6308 xi2 = TMath::Log10(TMath::Max(xi2,logxmin));
6309 xi3 = TMath::Log10(TMath::Max(xi3,logxmin));
6310 xi4 = TMath::Log10(TMath::Max(xi4,logxmin));
6311 }
6312 if (Hoption.Logy) {
6313 yi1 = TMath::Log10(TMath::Max(yi1,logymin));
6314 yi2 = TMath::Log10(TMath::Max(yi2,logymin));
6315 yi3 = TMath::Log10(TMath::Max(yi3,logymin));
6316 yi4 = TMath::Log10(TMath::Max(yi4,logymin));
6317 }
6318
6319 // test if error bars are not outside the limits
6320 // otherwise they are truncated
6321
6322 xi1 = TMath::Max(xi1,xmin);
6323 xi2 = TMath::Min(xi2,xmax);
6324 yi3 = TMath::Max(yi3,ymin);
6325 yi4 = TMath::Min(yi4,ymax);
6326
6327 // test if the marker is on the frame limits. If "Yes", the
6328 // marker will not be drawn and the error bars will be readjusted.
6329
6330 drawmarker = kTRUE;
6331 if (!option0 && !option3) {
6332 if (Hoption.Logy && yp < logymin) goto L30;
6333 if (yi1 < ymin || yi1 > ymax) goto L30;
6334 if (Hoption.Error != 0 && yp == 0 && ey1 <= 0) drawmarker = kFALSE;
6335 }
6336 if (!symbolsize || !errormarker) drawmarker = kFALSE;
6337
6338 // draw the error rectangles
6339 if (option2) gPad->PaintBox(xi1,yi3,xi2,yi4);
6340
6341 // keep points for fill area drawing
6342 if (option3) {
6343 xline[if1-1] = xi3;
6344 xline[if2-1] = xi3;
6345 yline[if1-1] = yi4;
6346 yline[if2-1] = yi3;
6347 if1++;
6348 if2--;
6349 }
6350
6351 // draw the error bars
6352 if (Hoption.Logy && yp < logymin) drawmarker = kFALSE;
6353 if (optionE && drawmarker) {
6354 if ((yi3 < yi1 - s2y) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1 - s2y,ymax));
6355 if ((yi1 + s2y < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1 + s2y, ymin),xi4,yi4);
6356 // don't duplicate the horizontal line
6357 if (Hoption.Hist != 2) {
6358 if (yi1<ymax && yi1>ymin) {
6359 if (xi1 < xi3 - s2x) gPad->PaintLine(xi1,yi1,xi3 - s2x,yi2);
6360 if (xi3 + s2x < xi2) gPad->PaintLine(xi3 + s2x,yi1,xi2,yi2);
6361 }
6362 }
6363 }
6364 if (optionE && !drawmarker && (ey1 != 0 || ey2 !=0)) {
6365 if ((yi3 < yi1) && (yi3 < ymax)) gPad->PaintLine(xi3,yi3,xi4,TMath::Min(yi1,ymax));
6366 if ((yi1 < yi4) && (yi4 > ymin)) gPad->PaintLine(xi3,TMath::Max(yi1,ymin),xi4,yi4);
6367 // don't duplicate the horizontal line
6368 if (Hoption.Hist != 2) {
6369 if (yi1<ymax && yi1>ymin) {
6370 if (xi1 < xi3) gPad->PaintLine(xi1,yi1,xi3,yi2);
6371 if (xi3 < xi2) gPad->PaintLine(xi3,yi1,xi2,yi2);
6372 }
6373 }
6374 }
6375
6376 // draw line at the end of the error bars
6377
6378 if (option1 && drawmarker) {
6379 if (yi3 < yi1-s2y) gPad->PaintLine(xi3 - bxsize,yi3,xi3 + bxsize,yi3);
6380 if (yi4 > yi1+s2y) gPad->PaintLine(xi3 - bxsize,yi4,xi3 + bxsize,yi4);
6381 if (xi1 < xi3-s2x) gPad->PaintLine(xi1,yi1 - bysize,xi1,yi1 + bysize);
6382 if (xi2 > xi3+s2x) gPad->PaintLine(xi2,yi1 - bysize,xi2,yi1 + bysize);
6383 }
6384
6385 // draw the marker
6386
6387 if (drawmarker) gPad->PaintPolyMarker(1, &xi3, &yi1);
6388
6389L30:
6390 if (fixbin) xp += Hparam.xbinsize;
6391 else {
6392 if (k < last) {
6393 delta = fH->GetBinWidth(k+1);
6394 xp = fH->GetBinLowEdge(k+1) + 0.5*delta;
6395 }
6396 }
6397 } //end of for loop
6398
6399 // draw the filled area
6400
6401 if (option3) {
6402 TGraph graph;
6403 graph.SetLineStyle(fH->GetLineStyle());
6404 graph.SetLineColor(fH->GetLineColor());
6405 graph.SetLineWidth(fH->GetLineWidth());
6406 graph.SetFillStyle(fH->GetFillStyle());
6407 graph.SetFillColor(fH->GetFillColor());
6408 Int_t logx = gPad->GetLogx();
6409 Int_t logy = gPad->GetLogy();
6410 gPad->SetLogx(0);
6411 gPad->SetLogy(0);
6412
6413 // In some cases the number of points in the fill area is smaller than
6414 // 2*npoints. In such cases the array xline and yline must be arranged
6415 // before being plotted. The next loop does that.
6416 if (if2 > npoints) {
6417 for (i=1; i<if1; i++) {
6418 xline[if1-2+i] = xline[if2-1+i];
6419 yline[if1-2+i] = yline[if2-1+i];
6420 }
6421 npoints = if1-1;
6422 }
6423 if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC");
6424 else graph.PaintGraph(2*npoints,xline,yline,"F");
6425 gPad->SetLogx(logx);
6426 gPad->SetLogy(logy);
6427 delete [] xline;
6428 delete [] yline;
6429 }
6430}
6431
6432////////////////////////////////////////////////////////////////////////////////
6433/// Draw 2D histograms errors.
6434
6436{
6437
6438 fH->TAttMarker::Modify();
6439 fH->TAttLine::Modify();
6440
6441 // Define the 3D view
6442 fXbuf[0] = Hparam.xmin;
6443 fYbuf[0] = Hparam.xmax;
6444 fXbuf[1] = Hparam.ymin;
6445 fYbuf[1] = Hparam.ymax;
6446 fXbuf[2] = Hparam.zmin;
6447 fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin());
6449 TView *view = gPad->GetView();
6450 if (!view) {
6451 Error("Paint2DErrors", "no TView in current pad");
6452 return;
6453 }
6454 Double_t thedeg = 90 - gPad->GetTheta();
6455 Double_t phideg = -90 - gPad->GetPhi();
6456 Double_t psideg = view->GetPsi();
6457 Int_t irep;
6458 view->SetView(phideg, thedeg, psideg, irep);
6459
6460 // Set color/style for back box
6461 fLego->SetFillStyle(gPad->GetFrameFillStyle());
6462 fLego->SetFillColor(gPad->GetFrameFillColor());
6463 fLego->TAttFill::Modify();
6464 Int_t backcolor = gPad->GetFrameFillColor();
6465 if (Hoption.System != kCARTESIAN) backcolor = 0;
6466 view->PadRange(backcolor);
6469 fLego->TAttFill::Modify();
6470
6471 // Paint the Back Box if needed
6472 if (Hoption.BackBox && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6473 fLego->InitMoveScreen(-1.1,1.1);
6476 fLego->BackBox(90);
6477 }
6478
6479 // Paint the Errors
6480 Double_t x, ex, x1, x2;
6481 Double_t y, ey, y1, y2;
6482 Double_t z, ez1, ez2, z1, z2;
6483 Double_t temp1[3],temp2[3];
6484 Double_t xyerror;
6485 if (Hoption.Error == 110) {
6486 xyerror = 0;
6487 } else {
6488 xyerror = gStyle->GetErrorX();
6489 }
6490
6491 Double_t xk, xstep, yk, ystep;
6492 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
6493 y = fYaxis->GetBinCenter(j);
6494 ey = fYaxis->GetBinWidth(j)*xyerror;
6495 y1 = y-ey;
6496 y2 = y+ey;
6497 if (Hoption.Logy) {
6498 if (y > 0) y = TMath::Log10(y);
6499 else continue;
6500 if (y1 > 0) y1 = TMath::Log10(y1);
6501 else y1 = Hparam.ymin;
6502 if (y2 > 0) y2 = TMath::Log10(y2);
6503 else y2 = Hparam.ymin;
6504 }
6505 yk = fYaxis->GetBinLowEdge(j);
6506 ystep = fYaxis->GetBinWidth(j);
6507 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
6508 xk = fXaxis->GetBinLowEdge(i);
6509 xstep = fXaxis->GetBinWidth(i);
6510 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
6511 Int_t bin = fH->GetBin(i,j);
6512 x = fXaxis->GetBinCenter(i);
6513 ex = fXaxis->GetBinWidth(i)*xyerror;
6514 x1 = x-ex;
6515 x2 = x+ex;
6516 if (Hoption.Logx) {
6517 if (x > 0) x = TMath::Log10(x);
6518 else continue;
6519 if (x1 > 0) x1 = TMath::Log10(x1);
6520 else x1 = Hparam.xmin;
6521 if (x2 > 0) x2 = TMath::Log10(x2);
6522 else x2 = Hparam.xmin;
6523 }
6524 z = fH->GetBinContent(bin);
6525 if (fH->GetBinErrorOption() == TH1::kNormal) {
6526 ez1 = fH->GetBinError(bin);
6527 ez2 = ez1;
6528 }
6529 else {
6530 ez1 = fH->GetBinErrorLow(bin);
6531 ez2 = fH->GetBinErrorUp(bin);
6532 }
6533 z1 = z - ez1;
6534 z2 = z + ez2;
6535 if (Hoption.Logz) {
6536 if (z > 0) z = TMath::Log10(z);
6537 else z = Hparam.zmin;
6538 if (z1 > 0) z1 = TMath::Log10(z1);
6539 else z1 = Hparam.zmin;
6540 if (z2 > 0) z2 = TMath::Log10(z2);
6541 else z2 = Hparam.zmin;
6542
6543 }
6544 if (z <= Hparam.zmin) continue;
6545 if (z > Hparam.zmax) z = Hparam.zmax;
6546
6547 temp1[0] = x1;
6548 temp1[1] = y;
6549 temp1[2] = z;
6550 temp2[0] = x2;
6551 temp2[1] = y;
6552 temp2[2] = z;
6553 gPad->PaintLine3D(temp1, temp2);
6554 temp1[0] = x;
6555 temp1[1] = y1;
6556 temp1[2] = z;
6557 temp2[0] = x;
6558 temp2[1] = y2;
6559 temp2[2] = z;
6560 gPad->PaintLine3D(temp1, temp2);
6561 temp1[0] = x;
6562 temp1[1] = y;
6563 temp1[2] = z1;
6564 temp2[0] = x;
6565 temp2[1] = y;
6566 temp2[2] = z2;
6567 gPad->PaintLine3D(temp1, temp2);
6568 temp1[0] = x;
6569 temp1[1] = y;
6570 temp1[2] = z;
6571 view->WCtoNDC(temp1, &temp2[0]);
6572 gPad->PaintPolyMarker(1, &temp2[0], &temp2[1]);
6573 }
6574 }
6575
6576 // Paint the Front Box if needed
6577 if (Hoption.FrontBox) {
6578 fLego->InitMoveScreen(-1.1,1.1);
6580 fLego->FrontBox(90);
6581 }
6582
6583 // Paint the Axis if needed
6584 if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) {
6585 TGaxis *axis = new TGaxis();
6586 PaintLegoAxis(axis, 90);
6587 delete axis;
6588 }
6589
6590 delete fLego; fLego = 0;
6591}
6592
6593////////////////////////////////////////////////////////////////////////////////
6594/// Calculate range and clear pad (canvas).
6595
6597{
6598
6599 if (Hoption.Same) return;
6600
6602
6603 if (Hoption.Lego || Hoption.Surf || Hoption.Tri ||
6604 Hoption.Contour == 14 || Hoption.Error >= 100) {
6605 TObject *frame = gPad->FindObject("TFrame");
6606 if (frame) gPad->GetListOfPrimitives()->Remove(frame);
6607 return;
6608 }
6609
6610 //The next statement is always executed on non-iOS platform,
6611 //on iOS depends on pad mode.
6612 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode())
6613 gPad->PaintPadFrame(Hparam.xmin,Hparam.ymin,Hparam.xmax,Hparam.ymax);
6614}
6615
6616////////////////////////////////////////////////////////////////////////////////
6617/// [Paint functions associated to an histogram.](#HP28")
6618
6620{
6621
6623 TObject *obj;
6624
6625 while (lnk) {
6626 obj = lnk->GetObject();
6627 TVirtualPad *padsave = gPad;
6628 if (obj->InheritsFrom(TF2::Class())) {
6629 if (obj->TestBit(TF2::kNotDraw) == 0) {
6630 if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) {
6631 TF2 *f2 = (TF2*)obj;
6632 f2->SetMinimum(fH->GetMinimum());
6633 f2->SetMaximum(fH->GetMaximum());
6634 f2->SetRange(fH->GetXaxis()->GetXmin(), fH->GetYaxis()->GetXmin(), fH->GetXaxis()->GetXmax(), fH->GetYaxis()->GetXmax() );
6635 f2->Paint("surf same");
6636 } else {
6637 obj->Paint("cont3 same");
6638 }
6639 }
6640 } else if (obj->InheritsFrom(TF1::Class())) {
6641 if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame");
6642 } else {
6643 //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat).
6644 gPad->PushSelectableObject(obj);
6645
6646 //The next statement is ALWAYS executed on non-iOS platform, on iOS it depends on pad's mode
6647 //and picked object.
6648 if (!gPad->PadInHighlightMode() || (gPad->PadInHighlightMode() && obj == gPad->GetSelected()))
6649 obj->Paint(lnk->GetOption());
6650 }
6651 lnk = (TObjOptLink*)lnk->Next();
6652 padsave->cd();
6653 }
6654}
6655
6656////////////////////////////////////////////////////////////////////////////////
6657/// [Control routine to draw 1D histograms](#HP01b)
6658
6660{
6661
6662 //On iOS: do not highlight hist, if part of it was selected.
6663 //Never executes on non-iOS platform.
6664 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
6665 return;
6666
6667 static char chopth[17];
6668
6669 Int_t htype, oldhtype;
6670 Int_t i, j, first, last, nbins, fixbin;
6671 Double_t c1, yb;
6672 yb = 0;
6673
6674 strlcpy(chopth, " ",17);
6675
6678 Double_t baroffset = fH->GetBarOffset();
6679 Double_t barwidth = fH->GetBarWidth();
6680 Double_t baroffsetsave = gStyle->GetBarOffset();
6681 Double_t barwidthsave = gStyle->GetBarWidth();
6682 gStyle->SetBarOffset(baroffset);
6683 gStyle->SetBarWidth(barwidth);
6684
6685 // Create "LIFE" structure to keep current histogram status
6686
6688 last = Hparam.xlast;
6689 nbins = last - first + 1;
6690
6691 Double_t *keepx = 0;
6692 Double_t *keepy = 0;
6693 if (fXaxis->GetXbins()->fN) fixbin = 0;
6694 else fixbin = 1;
6695 if (fixbin) keepx = new Double_t[2];
6696 else keepx = new Double_t[nbins+1];
6697 keepy = new Double_t[nbins];
6698 Double_t logymin = 0;
6699 if (Hoption.Logy) logymin = TMath::Power(10,ymin);
6700
6701 // Loop on histogram bins
6702
6703 for (j=first; j<=last;j++) {
6705 if (TMath::Abs(ymax-ymin) > 0) {
6706 if (Hoption.Logy) yb = TMath::Log10(TMath::Max(c1,.1*logymin));
6707 else yb = c1;
6708 }
6709 if (!Hoption.Line) {
6710 yb = TMath::Max(yb, ymin);
6711 yb = TMath::Min(yb, ymax);
6712 }
6713 keepy[j-first] = yb;
6714 }
6715
6716 // Draw histogram according to value of FillStyle and FillColor
6717
6718 if (fixbin) { keepx[0] = Hparam.xmin; keepx[1] = Hparam.xmax; }
6719 else {
6720 for (i=0; i<nbins; i++) keepx[i] = fXaxis->GetBinLowEdge(i+first);
6721 keepx[nbins] = fXaxis->GetBinUpEdge(nbins-1+first);
6722 }
6723
6724 // Prepare Fill area (systematic with option "Bar").
6725
6726 oldhtype = fH->GetFillStyle();
6727 htype = oldhtype;
6728 if (Hoption.Bar) {
6729 if (htype == 0 || htype == 1000) htype = 1001;
6730 }
6731
6732 Width_t lw = (Width_t)fH->GetLineWidth();
6733
6734 // Code option for GrapHist
6735
6736 if (Hoption.Line) chopth[0] = 'L';
6737 if (Hoption.Star) chopth[1] = '*';
6738 if (Hoption.Mark) chopth[2] = 'P';
6739 if (Hoption.Mark == 10) chopth[3] = '0';
6741 if (Hoption.Curve) chopth[3] = 'C';
6742 if (Hoption.Hist > 0) chopth[4] = 'H';
6743 else if (Hoption.Bar) chopth[5] = 'B';
6744 if (fH->GetFillColor() && htype) {
6745 if (Hoption.Logy) {
6746 chopth[6] = '1';
6747 }
6748 if (Hoption.Hist > 0 || Hoption.Curve || Hoption.Line) {
6749 chopth[7] = 'F';
6750 }
6751 }
6752 }
6753 if (!fixbin && strlen(chopth)) {
6754 chopth[8] = 'N';
6755 }
6756
6757 if (Hoption.Fill == 2) chopth[13] = '2';
6758
6759 // Option LOGX
6760
6761 if (Hoption.Logx) {
6762 chopth[9] = 'G';
6763 chopth[10] = 'X';
6764 if (fixbin) {
6765 keepx[0] = TMath::Power(10,keepx[0]);
6766 keepx[1] = TMath::Power(10,keepx[1]);
6767 }
6768 }
6769
6770 if (Hoption.Off) {
6771 chopth[11] = ']';
6772 chopth[12] = '[';
6773 }
6774
6775 // Draw the histogram
6776
6777 TGraph graph;
6778 graph.SetLineWidth(lw);
6779 graph.SetLineStyle(fH->GetLineStyle());
6780 graph.SetLineColor(fH->GetLineColor());
6781 graph.SetFillStyle(htype);
6782 graph.SetFillColor(fH->GetFillColor());
6783 graph.SetMarkerStyle(fH->GetMarkerStyle());
6784 graph.SetMarkerSize(fH->GetMarkerSize());
6785 graph.SetMarkerColor(fH->GetMarkerColor());
6786 if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame);
6787
6788 graph.PaintGrapHist(nbins, keepx, keepy ,chopth);
6789
6790 delete [] keepx;
6791 delete [] keepy;
6792 gStyle->SetBarOffset(baroffsetsave);
6793 gStyle->SetBarWidth(barwidthsave);
6794
6795 htype=oldhtype;
6796}
6797
6798////////////////////////////////////////////////////////////////////////////////
6799/// [Control function to draw a 3D histograms.](#HP01d)
6800
6802{
6803
6804 char *cmd;
6805 TString opt = option;
6806 opt.ToLower();
6807 Int_t irep;
6808
6809 if (Hoption.Box || Hoption.Lego) {
6810 if (Hoption.Box == 11 || Hoption.Lego == 11) {
6811 PaintH3Box(1);
6812 } else if (Hoption.Box == 12 || Hoption.Lego == 12) {
6813 PaintH3Box(2);
6814 } else if (Hoption.Box == 13 || Hoption.Lego == 13) {
6815 PaintH3Box(3);
6816 } else {
6818 }
6819 return;
6820 } else if (strstr(opt,"iso")) {
6821 PaintH3Iso();
6822 return;
6823 } else if (strstr(opt,"tf3")) {
6824 PaintTF3();
6825 return;
6826 } else {
6827 cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%lx,\"%s\");",(Long_t)fH,option);
6828 }
6829
6830 if (strstr(opt,"fb")) Hoption.FrontBox = 0;
6831 if (strstr(opt,"bb")) Hoption.BackBox = 0;
6832
6833 TView *view = gPad->GetView();
6834 if (!view) return;
6835 Double_t thedeg = 90 - gPad->GetTheta();
6836 Double_t phideg = -90 - gPad->GetPhi();
6837 Double_t psideg = view->GetPsi();
6838 view->SetView(phideg, thedeg, psideg, irep);
6839
6840 // Paint the data
6841 gROOT->ProcessLine(cmd);
6842
6843 if (Hoption.Same) return;
6844
6845 // Draw axis
6846 view->SetOutlineToCube();
6847 TSeqCollection *ol = view->GetOutline();
6848 if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option);
6850 TGaxis *axis = new TGaxis();
6851 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
6852 delete axis;
6853
6854 // Draw palette. In case of 4D plot with TTree::Draw() the palette should
6855 // be painted with the option colz.
6856 if (fH->GetDrawOption() && strstr(opt,"colz")) {
6857 Int_t ndiv = fH->GetContour();
6858 if (ndiv == 0 ) {
6859 ndiv = gStyle->GetNumberContours();
6860 fH->SetContour(ndiv);
6861 }
6862 PaintPalette();
6863 }
6864
6865 // Draw title
6866 PaintTitle();
6867
6868 //Draw stats and fit results
6869 TF1 *fit = 0;
6870 TIter next(fFunctions);
6871 TObject *obj;
6872 while ((obj = next())) {
6873 if (obj->InheritsFrom(TF1::Class())) {
6874 fit = (TF1*)obj;
6875 break;
6876 }
6877 }
6878 if (Hoption.Same != 1) {
6879 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
6881 }
6882 }
6883
6884}
6885
6886////////////////////////////////////////////////////////////////////////////////
6887/// Compute histogram parameters used by the drawing routines.
6888
6890{
6891
6892 if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) return 1;
6893
6894 Int_t i;
6895 static const char *where = "PaintInit";
6896 Double_t yMARGIN = gStyle->GetHistTopMargin();
6897 Int_t maximum = 0;
6898 Int_t minimum = 0;
6899 if (fH->GetMaximumStored() != -1111) maximum = 1;
6900 if (fH->GetMinimumStored() != -1111) minimum = 1;
6901
6902 // Compute X axis parameters
6903
6904 Int_t last = fXaxis->GetLast();
6908 Hparam.xlast = last;
6912
6913 // if log scale in X, replace xmin,max by the log
6914 if (Hoption.Logx) {
6915 if (Hparam.xmax<=0) {
6916 Error(where, "cannot set X axis to log scale");
6917 return 0;
6918 }
6919 if (Hparam.xlowedge <=0 ) {
6920 if (Hoption.Same) {
6921 Hparam.xlowedge = TMath::Power(10, gPad->GetUxmin());
6922 } else {
6923 for (i=first; i<=last; i++) {
6924 Double_t binLow = fXaxis->GetBinLowEdge(i);
6925 if (binLow>0) {
6926 Hparam.xlowedge = binLow;
6927 break;
6928 }
6929 if (binLow == 0 && fH->GetBinContent(i) !=0) {
6930 Hparam.xlowedge = fXaxis->GetBinUpEdge(i)*0.001;
6931 break;
6932 }
6933 }
6934 if (Hparam.xlowedge<=0) {
6935 Error(where, "cannot set X axis to log scale");
6936 return 0;
6937 }
6938 }
6940 }
6945 if (Hparam.xlast > last) Hparam.xlast = last;
6947 }
6948
6949 // Compute Y axis parameters
6950 Double_t bigp = TMath::Power(10,32);
6951 Double_t ymax = -bigp;
6952 Double_t ymin = bigp;
6953 Double_t c1, e1;
6954 Double_t xv[1];
6955 Double_t fval;
6956 TObject *f;
6957 TF1 *f1;
6958 Double_t allchan = 0;
6959 Int_t nonNullErrors = 0;
6960 TIter next(fFunctions);
6961 for (i=first; i<=last;i++) {
6962 c1 = fH->GetBinContent(i);
6964 if (Hoption.Logy) {
6965 if (c1 > 0) ymin = TMath::Min(ymin,c1);
6966 } else {
6968 }
6969 if (Hoption.Error) {
6971 e1 = fH->GetBinError(i);
6972 else
6973 e1 = fH->GetBinErrorUp(i);
6974 if (e1 > 0) nonNullErrors++;
6975 ymax = TMath::Max(ymax,c1+e1);
6977 e1 = fH->GetBinErrorLow(i);
6978
6979 if (Hoption.Logy) {
6980 if (c1-e1>0.01*TMath::Abs(c1)) ymin = TMath::Min(ymin,c1-e1);
6981 } else {
6982 ymin = TMath::Min(ymin,c1-e1);
6983 }
6984 }
6985 if (Hoption.Func) {
6986 xv[0] = fXaxis->GetBinCenter(i);
6987 while ((f = (TObject*) next())) {
6988 if (f->IsA() == TF1::Class()) {
6989 f1 = (TF1*)f;
6990 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
6991 fval = f1->Eval(xv[0],0,0);
6992 if (f1->GetMaximumStored() != -1111) fval = TMath::Min(f1->GetMaximumStored(), fval);
6993 ymax = TMath::Max(ymax,fval);
6994 if (Hoption.Logy) {
6995 if (c1 > 0 && fval > 0.3*c1) ymin = TMath::Min(ymin,fval);
6996 }
6997 }
6998 }
6999 next.Reset();
7000 }
7001 allchan += c1;
7002 }
7003 if (!nonNullErrors) {
7004 if (Hoption.Error) {
7005 if (!Hoption.Mark && !Hoption.Line && !Hoption.Star && !Hoption.Curve) Hoption.Hist = 2;
7006 Hoption.Error=0;
7007 }
7008 }
7009
7010
7011 // Take into account maximum , minimum
7012
7013 if (Hoption.Logy && ymin <= 0) {
7014 if (ymax >= 1) ymin = TMath::Max(.005,ymax*1e-10);
7015 else ymin = 0.001*ymax;
7016 }
7017
7018 Double_t xm = ymin;
7019 if (maximum) ymax = fH->GetMaximumStored();
7020 if (minimum) xm = fH->GetMinimumStored();
7021 if (Hoption.Logy && xm < 0) {
7022 Error(where, "log scale requested with a negative argument (%f)", xm);
7023 return 0;
7024 } else if (Hoption.Logy && xm>=0 && ymax==0) { // empty histogram in log scale
7025 ymin = 0.01;
7026 ymax = 10.;
7027 } else {
7028 ymin = xm;
7029 }
7030
7031 if (ymin >= ymax) {
7032 if (Hoption.Logy) {
7033 if (ymax > 0) ymin = 0.001*ymax;
7034 else {
7035 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", ymax);
7036 return 0;
7037 }
7038 }
7039 else {
7040 if (ymin > 0) {
7041 ymin = 0;
7042 ymax *= 2;
7043 } else if (ymin < 0) {
7044 ymax = 0;
7045 ymin *= 2;
7046 } else {
7047 ymin = 0;
7048 ymax = 1;
7049 }
7050 }
7051 }
7052
7053 // In some cases, mainly because of precision issues, ymin and ymax could almost equal.
7054 if (TMath::AreEqualRel(ymin,ymax,1E-15)) {
7055 ymin = ymin*(1-1E-14);
7056 ymax = ymax*(1+1E-14);
7057 }
7058
7059 // take into account normalization factor
7060 Hparam.allchan = allchan;
7061 Double_t factor = allchan;
7062 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7063 if (allchan) factor /= allchan;
7064 if (factor == 0) factor = 1;
7065 Hparam.factor = factor;
7066 ymax = factor*ymax;
7067 ymin = factor*ymin;
7068 //just in case the norm factor is negative
7069 // this may happen with a positive norm factor and a negative integral !
7070 if (ymax < ymin) {
7071 Double_t temp = ymax;
7072 ymax = ymin;
7073 ymin = temp;
7074 }
7075
7076 // For log scales, histogram coordinates are LOG10(ymin) and
7077 // LOG10(ymax). Final adjustment (if not option "Same"
7078 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7079 // Maximum and Minimum are not defined.
7080 if (Hoption.Logy) {
7081 if (ymin <=0 || ymax <=0) {
7082 Error(where, "Cannot set Y axis to log scale");
7083 return 0;
7084 }
7086 if (!minimum) ymin += TMath::Log10(0.5);
7088 if (!maximum) ymax += TMath::Log10(2*(0.9/0.95));
7089 if (!Hoption.Same) {
7090 Hparam.ymin = ymin;
7091 Hparam.ymax = ymax;
7092 }
7093 return 1;
7094 }
7095
7096 // final adjustment of ymin for linear scale.
7097 // if minimum is not set , then ymin is set to zero if >0
7098 // or to ymin - margin if <0.
7099 if (!minimum) {
7100 if (gStyle->GetHistMinimumZero()) {
7101 if (ymin >= 0) ymin = 0;
7102 else ymin -= yMARGIN*(ymax-ymin);
7103 } else {
7104 Double_t dymin = yMARGIN*(ymax-ymin);
7105 if (ymin >= 0 && (ymin-dymin <= 0)) ymin = 0;
7106 else ymin -= dymin;
7107 }
7108 }
7109
7110 // final adjustment of YMAXI for linear scale (if not option "Same"):
7111 // decrease histogram height to MAX% of allowed height if HMAXIM
7112 // has not been called.
7113 if (!maximum) {
7114 ymax += yMARGIN*(ymax-ymin);
7115 }
7116
7117 Hparam.ymin = ymin;
7118 Hparam.ymax = ymax;
7119 return 1;
7120}
7121
7122////////////////////////////////////////////////////////////////////////////////
7123/// Compute histogram parameters used by the drawing routines for a rotated pad.
7124
7126{
7127
7128 static const char *where = "PaintInitH";
7129 Double_t yMARGIN = gStyle->GetHistTopMargin();
7130 Int_t maximum = 0;
7131 Int_t minimum = 0;
7132 if (fH->GetMaximumStored() != -1111) maximum = 1;
7133 if (fH->GetMinimumStored() != -1111) minimum = 1;
7134
7135 // Compute X axis parameters
7136
7137 Int_t last = fXaxis->GetLast();
7141 Hparam.xlast = last;
7145
7146 // if log scale in Y, replace ymin,max by the log
7147 if (Hoption.Logy) {
7148 if (Hparam.xlowedge <=0 ) {
7151 }
7152 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
7153 Error(where, "cannot set Y axis to log scale");
7154 return 0;
7155 }
7160 if (Hparam.xlast > last) Hparam.xlast = last;
7161 }
7162
7163 // Compute Y axis parameters
7164 Double_t bigp = TMath::Power(10,32);
7165 Double_t xmax = -bigp;
7166 Double_t xmin = bigp;
7167 Double_t c1, e1;
7168 Double_t xv[1];
7169 Double_t fval;
7170 Int_t i;
7171 TObject *f;
7172 TF1 *f1;
7173 Double_t allchan = 0;
7174 TIter next(fFunctions);
7175 for (i=first; i<=last;i++) {
7176 c1 = fH->GetBinContent(i);
7179 if (Hoption.Error) {
7180 e1 = fH->GetBinError(i);
7181 xmax = TMath::Max(xmax,c1+e1);
7182 xmin = TMath::Min(xmin,c1-e1);
7183 }
7184 if (Hoption.Func) {
7185 xv[0] = fXaxis->GetBinCenter(i);
7186 while ((f = (TObject*) next())) {
7187 if (f->IsA() == TF1::Class()) {
7188 f1 = (TF1*)f;
7189 if (xv[0] < f1->GetXmin() || xv[0] > f1->GetXmax()) continue;
7190 fval = f1->Eval(xv[0],0,0);
7191 xmax = TMath::Max(xmax,fval);
7192 if (Hoption.Logy) {
7193 if (fval > 0.3*c1) xmin = TMath::Min(xmin,fval);
7194 }
7195 }
7196 }
7197 next.Reset();
7198 }
7199 allchan += c1;
7200 }
7201
7202 // Take into account maximum , minimum
7203
7204 if (Hoption.Logx && xmin <= 0) {
7205 if (xmax >= 1) xmin = TMath::Max(.5,xmax*1e-10);
7206 else xmin = 0.001*xmax;
7207 }
7208 Double_t xm = xmin;
7209 if (maximum) xmax = fH->GetMaximumStored();
7210 if (minimum) xm = fH->GetMinimumStored();
7211 if (Hoption.Logx && xm <= 0) {
7212 Error(where, "log scale requested with zero or negative argument (%f)", xm);
7213 return 0;
7214 }
7215 else xmin = xm;
7216 if (xmin >= xmax) {
7217 if (Hoption.Logx) {
7218 if (xmax > 0) xmin = 0.001*xmax;
7219 else {
7220 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", xmax);
7221 return 0;
7222 }
7223 }
7224 else {
7225 if (xmin > 0) {
7226 xmin = 0;
7227 xmax *= 2;
7228 } else if (xmin < 0) {
7229 xmax = 0;
7230 xmin *= 2;
7231 } else {
7232 xmin = -1;
7233 xmax = 1;
7234 }
7235 }
7236 }
7237
7238 // take into account normalization factor
7239 Hparam.allchan = allchan;
7240 Double_t factor = allchan;
7241 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
7242 if (allchan) factor /= allchan;
7243 if (factor == 0) factor = 1;
7244 Hparam.factor = factor;
7245 xmax = factor*xmax;
7246 xmin = factor*xmin;
7247
7248 // For log scales, histogram coordinates are LOG10(ymin) and
7249 // LOG10(ymax). Final adjustment (if not option "Same"
7250 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
7251 // Maximum and Minimum are not defined.
7252 if (Hoption.Logx) {
7253 if (xmin <=0 || xmax <=0) {
7254 Error(where, "Cannot set Y axis to log scale");
7255 return 0;
7256 }
7258 if (!minimum) xmin += TMath::Log10(0.5);
7260 if (!maximum) xmax += TMath::Log10(2*(0.9/0.95));
7261 if (!Hoption.Same) {
7262 Hparam.xmin = xmin;
7263 Hparam.xmax = xmax;
7264 }
7265 return 1;
7266 }
7267
7268 // final adjustment of ymin for linear scale.
7269 // if minimum is not set , then ymin is set to zero if >0
7270 // or to ymin - margin if <0.
7271 if (!minimum) {
7272 if (xmin >= 0) xmin = 0;
7273 else xmin -= yMARGIN*(xmax-xmin);
7274 }
7275
7276 // final adjustment of YMAXI for linear scale (if not option "Same"):
7277 // decrease histogram height to MAX% of allowed height if HMAXIM
7278 // has not been called.
7279 if (!maximum) {
7280 xmax += yMARGIN*(xmax-xmin);
7281 }
7282 Hparam.xmin = xmin;
7283 Hparam.xmax = xmax;
7284 return 1;
7285}
7286
7287////////////////////////////////////////////////////////////////////////////////
7288/// [Control function to draw a 3D histogram with boxes.](#HP25)
7289
7291{
7292 // Predefined box structure
7293 Double_t wxyz[8][3] = { {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
7294 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} };
7295 Int_t iface[6][4] = { {0,3,2,1}, {4,5,6,7},
7296 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} };
7297
7298 // Define dimensions of world space
7299 TGaxis *axis = new TGaxis();
7300 TAxis *xaxis = fH->GetXaxis();
7301 TAxis *yaxis = fH->GetYaxis();
7302 TAxis *zaxis = fH->GetZaxis();
7303
7304 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7305 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7306 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7307 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7308 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7309 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7310
7312
7313 // Set view
7314 TView *view = gPad->GetView();
7315 if (!view) {
7316 Error("PaintH3", "no TView in current pad");
7317 return;
7318 }
7319 Double_t thedeg = 90 - gPad->GetTheta();
7320 Double_t phideg = -90 - gPad->GetPhi();
7321 Double_t psideg = view->GetPsi();
7322 Int_t irep;
7323 view->SetView(phideg, thedeg, psideg, irep);
7324
7325 Int_t backcolor = gPad->GetFrameFillColor();
7326 view->PadRange(backcolor);
7327
7328 // Draw back surfaces of frame box
7329 fLego->InitMoveScreen(-1.1,1.1);
7330 if (Hoption.BackBox) {
7333 fLego->BackBox(90);
7334 }
7335
7337
7338 // Define order of drawing
7339 Double_t *tnorm = view->GetTnorm();
7340 if (!tnorm) return;
7341 Int_t incrx = (tnorm[ 8] < 0.) ? -1 : +1;
7342 Int_t incry = (tnorm[ 9] < 0.) ? -1 : +1;
7343 Int_t incrz = (tnorm[10] < 0.) ? -1 : +1;
7344 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7345 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7346 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7347 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7348 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7349 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7350
7351 // Set graphic attributes (colour, style, etc.)
7352 Style_t fillsav = fH->GetFillStyle();
7353 Style_t colsav = fH->GetFillColor();
7354 Style_t coldark = TColor::GetColorDark(colsav);
7355 Style_t colbright = TColor::GetColorBright(colsav);
7356
7357 fH->SetFillStyle(1001);
7358 fH->TAttFill::Modify();
7359 fH->TAttLine::Modify();
7360 Int_t ncolors = gStyle->GetNumberOfColors();
7361 Int_t theColor;
7362
7363 // Create bin boxes and draw
7364 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7367
7368 Double_t pmin[3], pmax[3], sxyz[8][3];
7369 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7370 pmin[0] = xaxis->GetBinLowEdge(ix);
7371 pmax[0] = xaxis->GetBinUpEdge(ix);
7372 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7373 pmin[1] = yaxis->GetBinLowEdge(iy);
7374 pmax[1] = yaxis->GetBinUpEdge(iy);
7375 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7376 pmin[2] = zaxis->GetBinLowEdge(iz);
7377 pmax[2] = zaxis->GetBinUpEdge(iz);
7378 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7379 Bool_t neg = kFALSE;
7380 Int_t n = 5;
7381 if (w<0) {
7382 w = -w;
7383 neg = kTRUE;
7384 }
7385 if (w < wmin) continue;
7386 if (w > wmax) w = wmax;
7387 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7388 if (scale == 0) continue;
7389 for (Int_t i=0; i<3; ++i) {
7390 Double_t c = (pmax[i] + pmin[i])*0.5;
7391 Double_t d = (pmax[i] - pmin[i])*scale;
7392 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7393 sxyz[k][i] = wxyz[k][i]*d + c;
7394 }
7395 }
7396 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7397 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7398 }
7399 Double_t x[8], y[8]; // draw bin box faces
7400 for (Int_t k=0; k<6; ++k) {
7401 for (Int_t i=0; i<4; ++i) {
7402 Int_t iv = iface[k][i];
7403 x[i] = sxyz[iv][0];
7404 y[i] = sxyz[iv][1];
7405 }
7406 x[4] = x[0] ; y[4] = y[0];
7407 if (neg) {
7408 x[5] = x[2] ; y[5] = y[2];
7409 x[6] = x[3] ; y[6] = y[3];
7410 x[7] = x[1] ; y[7] = y[1];
7411 n = 8;
7412 } else {
7413 n = 5;
7414 }
7415 Double_t z = (x[2]-x[0])*(y[3]-y[1]) - (y[2]-y[0])*(x[3]-x[1]);
7416 if (z <= 0.) continue;
7417 if (iopt == 2) {
7418 theColor = ncolors*((w-wmin)/(wmax-wmin)) -1;
7420 } else {
7421 if (k == 3 || k == 5) {
7422 fH->SetFillColor(coldark);
7423 } else if (k == 0 || k == 1) {
7424 fH->SetFillColor(colbright);
7425 } else {
7426 fH->SetFillColor(colsav);
7427 }
7428 }
7429 fH->TAttFill::Modify();
7430 gPad->PaintFillArea(4, x, y);
7431 if (iopt != 3)gPad->PaintPolyLine(n, x, y);
7432 }
7433 }
7434 }
7435 }
7436
7437 // Draw front surfaces of frame box
7438 if (Hoption.FrontBox) fLego->FrontBox(90);
7439
7440 // Draw axis and title
7441 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7442 PaintTitle();
7443
7444 // Draw palette. if needed.
7445 if (Hoption.Zscale) {
7446 Int_t ndiv = fH->GetContour();
7447 if (ndiv == 0 ) {
7448 ndiv = gStyle->GetNumberContours();
7449 fH->SetContour(ndiv);
7450 }
7451 PaintPalette();
7452 }
7453
7454 delete axis;
7455 delete fLego; fLego = 0;
7456
7457 fH->SetFillStyle(fillsav);
7458 fH->SetFillColor(colsav);
7459 fH->TAttFill::Modify();
7460}
7461
7462////////////////////////////////////////////////////////////////////////////////
7463/// [Control function to draw a 3D histogram with boxes.](#HP25)
7464
7466{
7467 // Predefined box structure
7468 Double_t wxyz[8][3] = {
7469 {-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1}, // bottom vertices
7470 {-1,-1, 1}, {1,-1, 1}, {1,1, 1}, {-1,1, 1} // top vertices
7471 };
7472 Int_t iface[6][4] = {
7473 {0,3,2,1}, {4,5,6,7}, // bottom and top faces
7474 {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} // side faces
7475 };
7476 Double_t normal[6][3] = {
7477 {0,0,-1}, {0,0,1}, // Z-, Z+
7478 {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0} // Y-, X+, Y+, X-
7479 };
7480
7481 // Define dimensions of world space
7482 TGaxis *axis = new TGaxis();
7483 TAxis *xaxis = fH->GetXaxis();
7484 TAxis *yaxis = fH->GetYaxis();
7485 TAxis *zaxis = fH->GetZaxis();
7486
7487 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7488 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7489 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7490 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7491 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7492 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7493
7495
7496 // Set view
7497 TView *view = gPad->GetView();
7498 if (!view) {
7499 Error("PaintH3", "no TView in current pad");
7500 return;
7501 }
7502 Double_t thedeg = 90 - gPad->GetTheta();
7503 Double_t phideg = -90 - gPad->GetPhi();
7504 Double_t psideg = view->GetPsi();
7505 Int_t irep;
7506 view->SetView(phideg, thedeg, psideg, irep);
7507
7508 Int_t backcolor = gPad->GetFrameFillColor();
7509 view->PadRange(backcolor);
7510
7511 // Draw front surfaces of frame box
7512 if (Hoption.FrontBox) {
7513 fLego->InitMoveScreen(-1.1,1.1);
7515 }
7516
7517 // Initialize hidden line removal algorithm "raster screen"
7518 fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7519
7520 // Define order of drawing
7521 Double_t *tnorm = view->GetTnorm();
7522 if (!tnorm) return;
7523 Int_t incrx = (tnorm[ 8] < 0.) ? +1 : -1;
7524 Int_t incry = (tnorm[ 9] < 0.) ? +1 : -1;
7525 Int_t incrz = (tnorm[10] < 0.) ? +1 : -1;
7526 Int_t ix1 = (incrx == +1) ? xaxis->GetFirst() : xaxis->GetLast();
7527 Int_t iy1 = (incry == +1) ? yaxis->GetFirst() : yaxis->GetLast();
7528 Int_t iz1 = (incrz == +1) ? zaxis->GetFirst() : zaxis->GetLast();
7529 Int_t ix2 = (incrx == +1) ? xaxis->GetLast() : xaxis->GetFirst();
7530 Int_t iy2 = (incry == +1) ? yaxis->GetLast() : yaxis->GetFirst();
7531 Int_t iz2 = (incrz == +1) ? zaxis->GetLast() : zaxis->GetFirst();
7532
7533 // Set line attributes (colour, style, etc.)
7534 fH->TAttLine::Modify();
7535
7536 // Create bin boxes and draw
7537 const Int_t NTMAX = 100;
7538 Double_t tt[NTMAX][2];
7539 Double_t wmin = TMath::Max(fH->GetMinimum(),0.);
7542 Double_t pmin[3], pmax[3], sxyz[8][3], pp[4][2];
7543 for (Int_t ix = ix1; ix !=ix2+incrx; ix += incrx) {
7544 pmin[0] = xaxis->GetBinLowEdge(ix);
7545 pmax[0] = xaxis->GetBinUpEdge(ix);
7546 for (Int_t iy = iy1; iy != iy2+incry; iy += incry) {
7547 pmin[1] = yaxis->GetBinLowEdge(iy);
7548 pmax[1] = yaxis->GetBinUpEdge(iy);
7549 for (Int_t iz = iz1; iz != iz2+incrz; iz += incrz) {
7550 pmin[2] = zaxis->GetBinLowEdge(iz);
7551 pmax[2] = zaxis->GetBinUpEdge(iz);
7552 Double_t w = fH->GetBinContent(fH->GetBin(ix,iy,iz));
7553 Bool_t neg = kFALSE;
7554 if (w<0) {
7555 w = -w;
7556 neg = kTRUE;
7557 }
7558 if (w < wmin) continue;
7559 if (w > wmax) w = wmax;
7560 Double_t scale = (TMath::Power((w-wmin)/(wmax-wmin),1./3.))/2.;
7561 if (scale == 0) continue;
7562 for (Int_t i=0; i<3; ++i) {
7563 Double_t c = (pmax[i] + pmin[i])*0.5;
7564 Double_t d = (pmax[i] - pmin[i])*scale;
7565 for (Int_t k=0; k<8; ++k) { // set bin box vertices
7566 sxyz[k][i] = wxyz[k][i]*d + c;
7567 }
7568 }
7569 for (Int_t k=0; k<8; ++k) { // transform to normalized space
7570 view->WCtoNDC(&sxyz[k][0],&sxyz[k][0]);
7571 }
7572 for (Int_t k=0; k<6; ++k) { // draw box faces
7573 Double_t zn;
7574 view->FindNormal(normal[k][0], normal[k][1], normal[k][2], zn);
7575 if (zn <= 0) continue;
7576 for (Int_t i=0; i<4; ++i) {
7577 Int_t ip = iface[k][i];
7578 pp[i][0] = sxyz[ip][0];
7579 pp[i][1] = sxyz[ip][1];
7580 }
7581 for (Int_t i=0; i<4; ++i) {
7582 Int_t i1 = i;
7583 Int_t i2 = (i == 3) ? 0 : i + 1;
7584 Int_t nt;
7585 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7586 Double_t xdel = pp[i2][0] - pp[i1][0];
7587 Double_t ydel = pp[i2][1] - pp[i1][1];
7588 Double_t x[2], y[2];
7589 for (Int_t it = 0; it < nt; ++it) {
7590 x[0] = pp[i1][0] + xdel*tt[it][0];
7591 y[0] = pp[i1][1] + ydel*tt[it][0];
7592 x[1] = pp[i1][0] + xdel*tt[it][1];
7593 y[1] = pp[i1][1] + ydel*tt[it][1];
7594 gPad->PaintPolyLine(2, x, y);
7595 }
7596 }
7597 if (neg) {
7598 Int_t i1 = 0;
7599 Int_t i2 = 2;
7600 Int_t nt;
7601 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7602 Double_t xdel = pp[i2][0] - pp[i1][0];
7603 Double_t ydel = pp[i2][1] - pp[i1][1];
7604 Double_t x[2], y[2];
7605 for (Int_t it = 0; it < nt; ++it) {
7606 x[0] = pp[i1][0] + xdel*tt[it][0];
7607 y[0] = pp[i1][1] + ydel*tt[it][0];
7608 x[1] = pp[i1][0] + xdel*tt[it][1];
7609 y[1] = pp[i1][1] + ydel*tt[it][1];
7610 gPad->PaintPolyLine(2, x, y);
7611 }
7612 i1 = 1;
7613 i2 = 3;
7614 fLego->FindVisibleLine(&pp[i1][0], &pp[i2][0], NTMAX, nt, &tt[0][0]);
7615 xdel = pp[i2][0] - pp[i1][0];
7616 ydel = pp[i2][1] - pp[i1][1];
7617 for (Int_t it = 0; it < nt; ++it) {
7618 x[0] = pp[i1][0] + xdel*tt[it][0];
7619 y[0] = pp[i1][1] + ydel*tt[it][0];
7620 x[1] = pp[i1][0] + xdel*tt[it][1];
7621 y[1] = pp[i1][1] + ydel*tt[it][1];
7622 gPad->PaintPolyLine(2, x, y);
7623 }
7624 }
7625 fLego->FillPolygonBorder(4, &pp[0][0]); // update raster screen
7626 }
7627 }
7628 }
7629 }
7630
7631 // Draw frame box
7632 if (Hoption.BackBox) {
7635 fLego->BackBox(90);
7636 }
7637
7638 if (Hoption.FrontBox) fLego->FrontBox(90);
7639
7640 // Draw axis and title
7641 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7642 PaintTitle();
7643
7644 delete axis;
7645 delete fLego; fLego = 0;
7646}
7647
7648////////////////////////////////////////////////////////////////////////////////
7649/// [Control function to draw a 3D histogram with Iso Surfaces.](#HP25)
7650
7652{
7653
7654 const Double_t ydiff = 1;
7655 const Double_t yligh1 = 10;
7656 const Double_t qa = 0.15;
7657 const Double_t qd = 0.15;
7658 const Double_t qs = 0.8;
7659 Double_t fmin, fmax;
7660 Int_t i, irep;
7661 Int_t nbcol = 28;
7662 Int_t icol1 = 201;
7663 Int_t ic1 = icol1;
7664 Int_t ic2 = ic1+nbcol;
7665 Int_t ic3 = ic2+nbcol;
7666
7667 TGaxis *axis = new TGaxis();
7668 TAxis *xaxis = fH->GetXaxis();
7669 TAxis *yaxis = fH->GetYaxis();
7670 TAxis *zaxis = fH->GetZaxis();
7671
7672 Int_t nx = fH->GetNbinsX();
7673 Int_t ny = fH->GetNbinsY();
7674 Int_t nz = fH->GetNbinsZ();
7675
7676 Double_t *x = new Double_t[nx];
7677 Double_t *y = new Double_t[ny];
7678 Double_t *z = new Double_t[nz];
7679
7680 for (i=0; i<nx; i++) x[i] = xaxis->GetBinCenter(i+1);
7681 for (i=0; i<ny; i++) y[i] = yaxis->GetBinCenter(i+1);
7682 for (i=0; i<nz; i++) z[i] = zaxis->GetBinCenter(i+1);
7683
7684 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
7685 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
7686 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
7687 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
7688 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
7689 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
7690
7691 Double_t s[3];
7692 s[0] = fH->GetSumOfWeights()/(fH->GetNbinsX()*fH->GetNbinsY()*fH->GetNbinsZ());
7693 s[1] = 0.5*s[0];
7694 s[2] = 1.5*s[0];
7695
7697
7698 TView *view = gPad->GetView();
7699 if (!view) {
7700 Error("PaintH3Iso", "no TView in current pad");
7701 delete [] x;
7702 delete [] y;
7703 delete [] z;
7704 return;
7705 }
7706 Double_t thedeg = 90 - gPad->GetTheta();
7707 Double_t phideg = -90 - gPad->GetPhi();
7708 Double_t psideg = view->GetPsi();
7709 view->SetView(phideg, thedeg, psideg, irep);
7710
7711 Int_t backcolor = gPad->GetFrameFillColor();
7712 if (Hoption.System != kCARTESIAN) backcolor = 0;
7713 view->PadRange(backcolor);
7714
7715 Double_t dcol = 0.5/Double_t(nbcol);
7716 TColor *colref = gROOT->GetColor(fH->GetFillColor());
7717 if (!colref) {
7718 delete [] x;
7719 delete [] y;
7720 delete [] z;
7721 return;
7722 }
7723 Float_t r, g, b, hue, light, satur;
7724 colref->GetRGB(r,g,b);
7725 TColor::RGBtoHLS(r,g,b,hue,light,satur);
7726 TColor *acol;
7727 for (Int_t col=0;col<nbcol;col++) {
7728 acol = gROOT->GetColor(col+icol1);
7729 TColor::HLStoRGB(hue, .4+col*dcol, satur, r, g, b);
7730 if (acol) acol->SetRGB(r, g, b);
7731 }
7732
7733 fLego->InitMoveScreen(-1.1,1.1);
7734
7735 if (Hoption.BackBox) {
7738 fLego->BackBox(90);
7739 }
7740
7741 fLego->LightSource(0, ydiff, 0, 0, 0, irep);
7742 fLego->LightSource(1, yligh1, 1, 1, 1, irep);
7743 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
7744 fmin = ydiff*qa;
7745 fmax = ydiff*qa + (yligh1+0.1)*(qd+qs);
7746 fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3);
7747
7748 fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF");
7749
7750 if (Hoption.FrontBox) {
7751 fLego->InitMoveScreen(-1.1,1.1);
7753 fLego->FrontBox(90);
7754 }
7755 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7756
7757 PaintTitle();
7758
7759 delete axis;
7760 delete fLego; fLego = 0;
7761 delete [] x;
7762 delete [] y;
7763 delete [] z;
7764}
7765
7766////////////////////////////////////////////////////////////////////////////////
7767/// [Control function to draw a 2D histogram as a lego plot.](#HP17)
7768
7770{
7771
7772 Int_t raster = 1;
7773 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
7774 Int_t nx = Hparam.xlast - Hparam.xfirst + 1;
7775 Int_t ny = Hparam.ylast - Hparam.yfirst + 1;
7776 Double_t zmin = Hparam.zmin;
7777 Double_t zmax = Hparam.zmax;
7778 Double_t xlab1 = Hparam.xmin;
7779 Double_t xlab2 = Hparam.xmax;
7780 Double_t ylab1 = Hparam.ymin;
7781 Double_t ylab2 = Hparam.ymax;
7782 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
7783 Double_t deltaz = TMath::Abs(zmin);
7784 if (deltaz == 0) deltaz = 1;
7785 if (zmin >= zmax) {
7786 zmin -= 0.5*deltaz;
7787 zmax += 0.5*deltaz;
7788 }
7789 Double_t z1c = zmin;
7790 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
7791
7792 // Compute the lego limits and instantiate a lego object
7793 fXbuf[0] = -1;
7794 fYbuf[0] = 1;
7795 fXbuf[1] = -1;
7796 fYbuf[1] = 1;
7797 if (Hoption.System == kPOLAR) {
7798 fXbuf[2] = z1c;
7799 fYbuf[2] = z2c;
7800 } else if (Hoption.System == kCYLINDRICAL) {
7801 if (Hoption.Logy) {
7802 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
7803 else fXbuf[2] = 0;
7804 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
7805 else fYbuf[2] = 0;
7806 } else {
7807 fXbuf[2] = ylab1;
7808 fYbuf[2] = ylab2;
7809 }
7810 z1c = 0; z2c = 1;
7811 } else if (Hoption.System == kSPHERICAL) {
7812 fXbuf[2] = -1;
7813 fYbuf[2] = 1;
7814 z1c = 0; z2c = 1;
7815 } else if (Hoption.System == kRAPIDITY) {
7816 fXbuf[2] = -1/TMath::Tan(dangle);
7817 fYbuf[2] = 1/TMath::Tan(dangle);
7818 } else {
7819 fXbuf[0] = xlab1;
7820 fYbuf[0] = xlab2;
7821 fXbuf[1] = ylab1;
7822 fYbuf[1] = ylab2;
7823 fXbuf[2] = z1c;
7824 fYbuf[2] = z2c;
7825 raster = 0;
7826 }
7827
7829
7830 Int_t nids = -1;
7831 TH1 * hid = NULL;
7832 Color_t colormain = -1, colordark = -1;
7833 Bool_t drawShadowsInLego1 = kTRUE;
7834
7835 // LEGO3 is like LEGO1 except that the black lines around each lego are not drawn.
7836 if (Hoption.Lego == 13) {
7837 Hoption.Lego = 11;
7838 fLego->SetMesh(0);
7839 }
7840 // LEGO4 is like LEGO1 except no shadows are drawn.
7841 if (Hoption.Lego == 14) {
7842 Hoption.Lego = 11;
7843 drawShadowsInLego1 = kFALSE;
7844 }
7845
7846 // Create axis object
7847
7848 TGaxis *axis = new TGaxis();
7849
7850 // Initialize the levels on the Z axis
7851 Int_t ndiv = fH->GetContour();
7852 if (ndiv == 0 ) {
7853 ndiv = gStyle->GetNumberContours();
7854 fH->SetContour(ndiv);
7855 }
7856 Int_t ndivz = TMath::Abs(ndiv);
7857 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
7858
7859 // Initialize colors
7860 if (!fStack) {
7862 } else {
7863 for (Int_t id=0;id<=fStack->GetSize();id++) {
7864 hid = (TH1*)fStack->At((id==0)?id:id-1);
7865 fLego->SetEdgeAtt(hid->GetLineColor(),hid->GetLineStyle(),hid->GetLineWidth(),id);
7866 }
7867 }
7868
7869 if (Hoption.Lego == 11) {
7870 nids = 1;
7871 if (fStack) nids = fStack->GetSize();
7872 hid = fH;
7873 for (Int_t id=0;id<=nids;id++) {
7874 if (id > 0 && fStack) hid = (TH1*)fStack->At(id-1);
7875 colormain = hid->GetFillColor();
7876 if (colormain == 1) colormain = 17; //avoid drawing with black
7877 if (drawShadowsInLego1) colordark = TColor::GetColorDark(colormain);
7878 else colordark = colormain;
7879 fLego->SetColorMain(colormain,id);
7880 fLego->SetColorDark(colordark,id);
7881 if (id <= 1) fLego->SetColorMain(colormain,-1); // Set Bottom color
7882 if (id == nids) fLego->SetColorMain(colormain,99); // Set Top color
7883 }
7884 }
7885
7886 // Now ready to draw the lego plot
7887 Int_t irep = 0;
7888
7889 TView *view = gPad->GetView();
7890 if (!view) {
7891 Error("PaintLego", "no TView in current pad");
7892 return;
7893 }
7894
7895 Double_t thedeg = 90 - gPad->GetTheta();
7896 Double_t phideg = -90 - gPad->GetPhi();
7897 Double_t psideg = view->GetPsi();
7898 view->SetView(phideg, thedeg, psideg, irep);
7899
7900 fLego->SetLineColor(kBlack); // zgrid color for lego1 & lego2
7902
7903 // Set color/style for back box
7904 fLego->SetFillStyle(gPad->GetFrameFillStyle());
7905 fLego->SetFillColor(gPad->GetFrameFillColor());
7906 fLego->TAttFill::Modify();
7907
7908 Int_t backcolor = gPad->GetFrameFillColor();
7909 if (Hoption.System != kCARTESIAN) backcolor = 0;
7910 view->PadRange(backcolor);
7911
7914 fLego->TAttFill::Modify();
7915
7917
7918 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
7919 else fLego->InitMoveScreen(-1.1,1.1);
7920
7921 if (Hoption.Lego == 19) {
7923 if (Hoption.BackBox) fLego->BackBox(90);
7924 if (Hoption.FrontBox) fLego->FrontBox(90);
7925 if (!Hoption.Axis) PaintLegoAxis(axis, 90);
7926 return;
7927 }
7928
7929 if (Hoption.Lego == 11 || Hoption.Lego == 12) {
7932 fLego->BackBox(90);
7933 }
7934 }
7935
7936 if (Hoption.Lego == 12) DefineColorLevels(ndivz);
7937
7942 if (Hoption.System == kPOLAR) {
7943 if (Hoption.Lego == 1) fLego->LegoPolar(1,nx,ny,"FB");
7944 if (Hoption.Lego == 11) fLego->LegoPolar(1,nx,ny,"BF");
7945 if (Hoption.Lego == 12) fLego->LegoPolar(1,nx,ny,"BF");
7946 } else if (Hoption.System == kCYLINDRICAL) {
7947 if (Hoption.Lego == 1) fLego->LegoCylindrical(1,nx,ny,"FB");
7948 if (Hoption.Lego == 11) fLego->LegoCylindrical(1,nx,ny,"BF");
7949 if (Hoption.Lego == 12) fLego->LegoCylindrical(1,nx,ny,"BF");
7950 } else if (Hoption.System == kSPHERICAL) {
7951 if (Hoption.Lego == 1) fLego->LegoSpherical(0,1,nx,ny,"FB");
7952 if (Hoption.Lego == 11) fLego->LegoSpherical(0,1,nx,ny,"BF");
7953 if (Hoption.Lego == 12) fLego->LegoSpherical(0,1,nx,ny,"BF");
7954 } else if (Hoption.System == kRAPIDITY) {
7955 if (Hoption.Lego == 1) fLego->LegoSpherical(1,1,nx,ny,"FB");
7956 if (Hoption.Lego == 11) fLego->LegoSpherical(1,1,nx,ny,"BF");
7957 if (Hoption.Lego == 12) fLego->LegoSpherical(1,1,nx,ny,"BF");
7958 } else {
7959 if (Hoption.Lego == 1) {
7961 fLego->LegoCartesian(90,nx,ny,"FB");}
7962 if (Hoption.Lego == 11) fLego->LegoCartesian(90,nx,ny,"BF");
7963 if (Hoption.Lego == 12) fLego->LegoCartesian(90,nx,ny,"BF");
7964 }
7965
7966 if (Hoption.Lego == 1 || Hoption.Lego == 11) {
7969 fLego->BackBox(90);
7970 }
7971 }
7972 if (Hoption.System == kCARTESIAN) {
7973 fLego->InitMoveScreen(-1.1,1.1);
7975 if (Hoption.FrontBox) fLego->FrontBox(90);
7976 }
7977 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
7979 delete axis;
7980 delete fLego; fLego = 0;
7981}
7982
7983////////////////////////////////////////////////////////////////////////////////
7984/// Draw the axis for legos and surface plots.
7985
7987{
7988
7989 static Double_t epsil = 0.001;
7990
7991 Double_t cosa, sina;
7992 Double_t bmin, bmax;
7993 Double_t r[24] /* was [3][8] */;
7994 Int_t ndivx, ndivy, ndivz, i;
7995 Double_t x1[3], x2[3], y1[3], y2[3], z1[3], z2[3], av[24] /* was [3][8] */;
7996 static char chopax[8], chopay[8], chopaz[8];
7997 Int_t ix1, ix2, iy1, iy2, iz1, iz2;
7998 Double_t rad;
7999
8000 TView *view = gPad->GetView();
8001 if (!view) {
8002 Error("PaintLegoAxis", "no TView in current pad");
8003 return;
8004 }
8005
8006 // In polar coordinates, draw a short line going from the external circle
8007 // corresponding to r = 1 up to r = 1.1
8008 if (Hoption.System == kPOLAR) {
8009 r[0] = 1;
8010 r[1] = 0;
8011 r[2] = 0;
8012 view->WCtoNDC(r, x1);
8013 r[0] = 1.1;
8014 r[1] = 0;
8015 r[2] = 0;
8016 view->WCtoNDC(r, x2);
8017 gPad->PaintLine(x1[0],x1[1],x2[0],x2[1]);
8018 return;
8019 }
8020
8021 if (Hoption.System != kCARTESIAN) return;
8022
8023 rad = TMath::ATan(1.) * 4. /180.;
8024 cosa = TMath::Cos(ang*rad);
8025 sina = TMath::Sin(ang*rad);
8026
8027 view->AxisVertex(ang, av, ix1, ix2, iy1, iy2, iz1, iz2);
8028 for (i = 1; i <= 8; ++i) {
8029 r[i*3 - 3] = av[i*3 - 3] + av[i*3 - 2]*cosa;
8030 r[i*3 - 2] = av[i*3 - 2]*sina;
8031 r[i*3 - 1] = av[i*3 - 1];
8032 }
8033
8034 view->WCtoNDC(&r[ix1*3 - 3], x1);
8035 view->WCtoNDC(&r[ix2*3 - 3], x2);
8036 view->WCtoNDC(&r[iy1*3 - 3], y1);
8037 view->WCtoNDC(&r[iy2*3 - 3], y2);
8038 view->WCtoNDC(&r[iz1*3 - 3], z1);
8039 view->WCtoNDC(&r[iz2*3 - 3], z2);
8040
8041 view->SetAxisNDC(x1, x2, y1, y2, z1, z2);
8042
8043 Double_t *rmin = view->GetRmin();
8044 Double_t *rmax = view->GetRmax();
8045 if (!rmin || !rmax) return;
8046
8047 // Initialize the axis options
8048 if (x1[0] > x2[0]) strlcpy(chopax, "SDH=+",8);
8049 else strlcpy(chopax, "SDH=-",8);
8050 if (y1[0] > y2[0]) strlcpy(chopay, "SDH=+",8);
8051 else strlcpy(chopay, "SDH=-",8);
8052 if (z2[1] > z1[1]) strlcpy(chopaz, "SDH=+",8);
8053 else strlcpy(chopaz, "SDH=-",8);
8054
8055 // Option LOG is required ?
8056 if (Hoption.Logx) strlcat(chopax,"G",8);
8057 if (Hoption.Logy) strlcat(chopay,"G",8);
8058 if (Hoption.Logz) strlcat(chopaz,"G",8);
8059
8060 // Initialize the number of divisions. If the
8061 // number of divisions is negative, option 'N' is required.
8062 ndivx = fXaxis->GetNdivisions();
8063 ndivy = fYaxis->GetNdivisions();
8064 ndivz = fZaxis->GetNdivisions();
8065 if (ndivx < 0) {
8066 ndivx = TMath::Abs(ndivx);
8067 strlcat(chopax, "N",8);
8068 }
8069 if (ndivy < 0) {
8070 ndivy = TMath::Abs(ndivy);
8071 strlcat(chopay, "N",8);
8072 }
8073 if (ndivz < 0) {
8074 ndivz = TMath::Abs(ndivz);
8075 strlcat(chopaz, "N",8);
8076 }
8077
8078 // Set Axis attributes.
8079 // The variable SCALE rescales the VSIZ
8080 // in order to have the same label size for all angles.
8081
8082 axis->SetLineWidth(1);
8083
8084 // X axis drawing
8085 if (TMath::Abs(x1[0] - x2[0]) >= epsil || TMath::Abs(x1[1] - x2[1]) > epsil) {
8088 if (Hoption.Logx && !fH->InheritsFrom(TH3::Class())) {
8089 bmin = TMath::Power(10, rmin[0]);
8090 bmax = TMath::Power(10, rmax[0]);
8091 } else {
8092 bmin = rmin[0];
8093 bmax = rmax[0];
8094 }
8095 // Option time display is required ?
8096 if (fXaxis->GetTimeDisplay()) {
8097 strlcat(chopax,"t",8);
8098 if (strlen(fXaxis->GetTimeFormatOnly()) == 0) {
8099 axis->SetTimeFormat(fXaxis->ChooseTimeFormat(bmax-bmin));
8100 } else {
8102 }
8103 }
8104 axis->SetOption(chopax);
8105 axis->PaintAxis(x1[0], x1[1], x2[0], x2[1], bmin, bmax, ndivx, chopax);
8106 }
8107
8108 // Y axis drawing
8109 if (TMath::Abs(y1[0] - y2[0]) >= epsil || TMath::Abs(y1[1] - y2[1]) > epsil) {
8112 if (fYaxis->GetTitleOffset() == 0) axis->SetTitleOffset(1.5);
8113
8114 if (fH->GetDimension() < 2) {
8115 strlcpy(chopay, "V=+UN",8);
8116 ndivy = 0;
8117 }
8118 if (TMath::Abs(y1[0] - y2[0]) < epsil) {
8119 y2[0] = y1[0];
8120 }
8121 if (Hoption.Logy && !fH->InheritsFrom(TH3::Class())) {
8122 bmin = TMath::Power(10, rmin[1]);
8123 bmax = TMath::Power(10, rmax[1]);
8124 } else {
8125 bmin = rmin[1];
8126 bmax = rmax[1];
8127 }
8128 // Option time display is required ?
8129 if (fYaxis->GetTimeDisplay()) {
8130 strlcat(chopay,"t",8);
8131 if (strlen(fYaxis->GetTimeFormatOnly()) == 0) {
8132 axis->SetTimeFormat(fYaxis->ChooseTimeFormat(bmax-bmin));
8133 } else {
8135 }
8136 }
8137 axis->SetOption(chopay);
8138 axis->PaintAxis(y1[0], y1[1], y2[0], y2[1], bmin, bmax, ndivy, chopay);
8139 }
8140
8141 // Z axis drawing
8142 if (TMath::Abs(z1[0] - z2[0]) >= 100*epsil || TMath::Abs(z1[1] - z2[1]) > 100*epsil) {
8144 if (Hoption.Logz && !fH->InheritsFrom(TH3::Class())) {
8145 bmin = TMath::Power(10, rmin[2]);
8146 bmax = TMath::Power(10, rmax[2]);
8147 } else {
8148 bmin = rmin[2];
8149 bmax = rmax[2];
8150 }
8151 // Option time display is required ?
8152 if (fZaxis->GetTimeDisplay()) {
8153 strlcat(chopaz,"t",8);
8154 if (strlen(fZaxis->GetTimeFormatOnly()) == 0) {
8155 axis->SetTimeFormat(fZaxis->ChooseTimeFormat(bmax-bmin));
8156 } else {
8158 }
8159 }
8160 axis->SetOption(chopaz);
8161 axis->PaintAxis(z1[0], z1[1], z2[0], z2[1], bmin, bmax, ndivz, chopaz);
8162 }
8163
8164 //fH->SetLineStyle(1); /// otherwise fEdgeStyle[i] gets overwritten!
8165}
8166
8167////////////////////////////////////////////////////////////////////////////////
8168/// [Paint the color palette on the right side of the pad.](#HP22)
8169
8171{
8172
8173 TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette");
8174 TView *view = gPad->GetView();
8175 if (palette) {
8176 if (view) {
8177 if (!palette->TestBit(TPaletteAxis::kHasView)) {
8178 fFunctions->Remove(palette);
8179 delete palette; palette = 0;
8180 }
8181 } else {
8182 if (palette->TestBit(TPaletteAxis::kHasView)) {
8183 fFunctions->Remove(palette);
8184 delete palette; palette = 0;
8185 }
8186 }
8187 // make sure the histogram member of the palette is setup correctly. It may not be after a Clone()
8188 if (palette && !palette->GetHistogram()) palette->SetHistogram(fH);
8189 }
8190
8191 if (!palette) {
8192 Double_t xup = gPad->GetUxmax();
8193 Double_t x2 = gPad->PadtoX(gPad->GetX2());
8194 Double_t ymin = gPad->PadtoY(gPad->GetUymin());
8195 Double_t ymax = gPad->PadtoY(gPad->GetUymax());
8196 Double_t xr = 0.05*(gPad->GetX2() - gPad->GetX1());
8197 Double_t xmin = gPad->PadtoX(xup +0.1*xr);
8198 Double_t xmax = gPad->PadtoX(xup + xr);
8199 if (xmax > x2) xmax = gPad->PadtoX(gPad->GetX2()-0.01*xr);
8200 palette = new TPaletteAxis(xmin,ymin,xmax,ymax,fH);
8201 fFunctions->AddFirst(palette);
8202 palette->Paint();
8203 }
8204}
8205
8206////////////////////////////////////////////////////////////////////////////////
8207/// [Control function to draw a 2D histogram as a scatter plot.](#HP11)
8208
8210{
8211
8212 fH->TAttMarker::Modify();
8213
8214 Int_t k, marker;
8215 Double_t dz, z, xk,xstep, yk, ystep;
8216 Double_t scale = 1;
8217 Bool_t ltest = kFALSE;
8218 Double_t zmax = fH->GetMaximum();
8219 Double_t zmin = fH->GetMinimum();
8220 if (zmin == 0 && zmax == 0) return;
8221 if (zmin == zmax) {
8222 zmax += 0.1*TMath::Abs(zmax);
8223 zmin -= 0.1*TMath::Abs(zmin);
8224 }
8226 if (Hoption.Logz) {
8227 if (zmin > 0) zmin = TMath::Log10(zmin);
8228 else zmin = 0;
8229 if (zmax > 0) zmax = TMath::Log10(zmax);
8230 else zmax = 0;
8231 if (zmin == 0 && zmax == 0) return;
8232 dz = zmax - zmin;
8233 scale = 100/dz;
8234 if (ncells > 10000) scale /= 5;
8235 ltest = kTRUE;
8236 } else {
8237 dz = zmax - zmin;
8238 if (dz >= kNMAX || zmax < 1) {
8239 scale = (kNMAX-1)/dz;
8240 if (ncells > 10000) scale /= 5;
8241 ltest = kTRUE;
8242 }
8243 }
8244 if (fH->GetMinimumStored() == -1111) {
8245 Double_t yMARGIN = gStyle->GetHistTopMargin();
8246 if (gStyle->GetHistMinimumZero()) {
8247 if (zmin >= 0) zmin = 0;
8248 else zmin -= yMARGIN*(zmax-zmin);
8249 } else {
8250 Double_t dzmin = yMARGIN*(zmax-zmin);
8251 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
8252 else zmin -= dzmin;
8253 }
8254 }
8255
8256 TString opt = option;
8257 opt.ToLower();
8258 if (opt.Contains("scat=")) {
8259 char optscat[100];
8260 strlcpy(optscat,opt.Data(),100);
8261 char *oscat = strstr(optscat,"scat=");
8262 char *blank = strstr(oscat," "); if (blank) *blank = 0;
8263 sscanf(oscat+5,"%lg",&scale);
8264 }
8265 // use an independent instance of a random generator
8266 // instead of gRandom to avoid conflicts and
8267 // to get same random numbers when drawing the same histogram
8268 TRandom2 random;
8269 marker=0;
8270 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
8271 yk = fYaxis->GetBinLowEdge(j);
8272 ystep = fYaxis->GetBinWidth(j);
8273 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
8274 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
8275 xk = fXaxis->GetBinLowEdge(i);
8276 xstep = fXaxis->GetBinWidth(i);
8277 if (!IsInside(xk+0.5*xstep,yk+0.5*ystep)) continue;
8278 z = fH->GetBinContent(bin);
8279 if (z < zmin) z = zmin;
8280 if (z > zmax) z = zmax;
8281 if (Hoption.Logz) {
8282 if (z > 0) z = TMath::Log10(z) - zmin;
8283 } else {
8284 z -= zmin;
8285 }
8286 if (z <= 0) continue;
8287 k = Int_t(z*scale);
8288 if (ltest) k++;
8289 if (k > 0) {
8290 for (Int_t loop=0; loop<k; loop++) {
8291 if (k+marker >= kNMAX) {
8292 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8293 marker=0;
8294 }
8295 fXbuf[marker] = (random.Rndm()*xstep) + xk;
8296 fYbuf[marker] = (random.Rndm()*ystep) + yk;
8297 if (Hoption.Logx) {
8298 if (fXbuf[marker] > 0) fXbuf[marker] = TMath::Log10(fXbuf[marker]);
8299 else break;
8300 }
8301 if (Hoption.Logy) {
8302 if (fYbuf[marker] > 0) fYbuf[marker] = TMath::Log10(fYbuf[marker]);
8303 else break;
8304 }
8305 if (fXbuf[marker] < gPad->GetUxmin()) break;
8306 if (fYbuf[marker] < gPad->GetUymin()) break;
8307 if (fXbuf[marker] > gPad->GetUxmax()) break;
8308 if (fYbuf[marker] > gPad->GetUymax()) break;
8309 marker++;
8310 }
8311 }
8312 }
8313 }
8314 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
8315
8317}
8318
8319////////////////////////////////////////////////////////////////////////////////
8320/// Static function to paint special objects like vectors and matrices.
8321/// This function is called via `gROOT->ProcessLine` to paint these objects
8322/// without having a direct dependency of the graphics or histogramming
8323/// system.
8324
8326{
8327
8328 if (!obj) return;
8331
8332 if (obj->InheritsFrom(TMatrixFBase::Class())) {
8333 // case TMatrixF
8334 TH2F *R__TMatrixFBase = new TH2F((TMatrixFBase &)*obj);
8335 R__TMatrixFBase->SetBit(kCanDelete);
8336 R__TMatrixFBase->Draw(option);
8337
8338 } else if (obj->InheritsFrom(TMatrixDBase::Class())) {
8339 // case TMatrixD
8340 TH2D *R__TMatrixDBase = new TH2D((TMatrixDBase &)*obj);
8341 R__TMatrixDBase->SetBit(kCanDelete);
8342 R__TMatrixDBase->Draw(option);
8343
8344 } else if (obj->InheritsFrom(TVectorF::Class())) {
8345 //case TVectorF
8346 TH1F *R__TVectorF = new TH1F((TVectorF &)*obj);
8347 R__TVectorF->SetBit(kCanDelete);
8348 R__TVectorF->Draw(option);
8349
8350 } else if (obj->InheritsFrom(TVectorD::Class())) {
8351 //case TVectorD
8352 TH1D *R__TVectorD = new TH1D((TVectorD &)*obj);
8353 R__TVectorD->SetBit(kCanDelete);
8354 R__TVectorD->Draw(option);
8355 }
8356
8357 TH1::AddDirectory(status);
8358}
8359
8360////////////////////////////////////////////////////////////////////////////////
8361/// [Draw the statistics box for 1D and profile histograms.](#HP07)
8362
8364{
8365
8366 static char t[100];
8367 Int_t dofit;
8368 TPaveStats *stats = 0;
8369 TIter next(fFunctions);
8370 TObject *obj;
8371 while ((obj = next())) {
8372 if (obj->InheritsFrom(TPaveStats::Class())) {
8373 stats = (TPaveStats*)obj;
8374 break;
8375 }
8376 }
8377
8378 if (stats && dostat) {
8379 dofit = stats->GetOptFit();
8380 dostat = stats->GetOptStat();
8381 } else {
8382 dofit = gStyle->GetOptFit();
8383 }
8384 if (!dofit) fit = 0;
8385 if (dofit == 1) dofit = 111;
8386 if (dostat == 1) dostat = 1111;
8387 Int_t print_name = dostat%10;
8388 Int_t print_entries = (dostat/10)%10;
8389 Int_t print_mean = (dostat/100)%10;
8390 Int_t print_stddev = (dostat/1000)%10;
8391 Int_t print_under = (dostat/10000)%10;
8392 Int_t print_over = (dostat/100000)%10;
8393 Int_t print_integral= (dostat/1000000)%10;
8394 Int_t print_skew = (dostat/10000000)%10;
8395 Int_t print_kurt = (dostat/100000000)%10;
8396 Int_t nlines = print_name + print_entries + print_mean + print_stddev +
8397 print_under + print_over + print_integral +
8398 print_skew + print_kurt;
8399 Int_t print_fval = dofit%10;
8400 Int_t print_ferrors = (dofit/10)%10;
8401 Int_t print_fchi2 = (dofit/100)%10;
8402 Int_t print_fprob = (dofit/1000)%10;
8403 Int_t nlinesf = print_fval + print_fchi2 + print_fprob;
8404 if (fit) {
8405 if (print_fval < 2) nlinesf += fit->GetNumberFreeParameters();
8406 else nlinesf += fit->GetNpar();
8407 }
8408 if (fH->InheritsFrom(TProfile::Class())) nlinesf += print_mean + print_stddev;
8409
8410 // Pavetext with statistics
8411 Bool_t done = kFALSE;
8412 if (!dostat && !fit) {
8413 if (stats) { fFunctions->Remove(stats); delete stats;}
8414 return;
8415 }
8416 Double_t statw = gStyle->GetStatW();
8417 if (fit) statw = 1.8*gStyle->GetStatW();
8418 Double_t stath = (nlines+nlinesf)*gStyle->GetStatFontSize();
8419 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8420 stath = 0.25*(nlines+nlinesf)*gStyle->GetStatH();
8421 }
8422 if (stats) {
8423 stats->Clear();
8424 done = kTRUE;
8425 } else {
8426 stats = new TPaveStats(
8427 gStyle->GetStatX()-statw,
8428 gStyle->GetStatY()-stath,
8429 gStyle->GetStatX(),
8430 gStyle->GetStatY(),"brNDC");
8431
8432 stats->SetParent(fH);
8433 stats->SetOptFit(dofit);
8434 stats->SetOptStat(dostat);
8435 stats->SetFillColor(gStyle->GetStatColor());
8436 stats->SetFillStyle(gStyle->GetStatStyle());
8438 stats->SetTextFont(gStyle->GetStatFont());
8439 if (gStyle->GetStatFont()%10 > 2)
8441 stats->SetFitFormat(gStyle->GetFitFormat());
8443 stats->SetName("stats");
8444
8446 stats->SetTextAlign(12);
8447 stats->SetBit(kCanDelete);
8448 stats->SetBit(kMustCleanup);
8449 }
8450 if (print_name) stats->AddText(fH->GetName());
8451 if (print_entries) {
8452 if (fH->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(fH->GetEntries()+0.5));
8453 else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(fH->GetEntries()));
8454 stats->AddText(t);
8455 }
8456 char textstats[50];
8457 if (print_mean) {
8458 if (print_mean == 1) {
8459 snprintf(textstats,50,"%s = %s%s",gStringMean.Data(),"%",stats->GetStatFormat());
8460 snprintf(t,100,textstats,fH->GetMean(1));
8461 } else {
8462 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMean.Data(),"%",stats->GetStatFormat()
8463 ,"%",stats->GetStatFormat());
8464 snprintf(t,100,textstats,fH->GetMean(1),fH->GetMeanError(1));
8465 }
8466 stats->AddText(t);
8468 if (print_mean == 1) {
8469 snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8470 snprintf(t,100,textstats,fH->GetMean(2));
8471 } else {
8472 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8473 ,"%",stats->GetStatFormat());
8474 snprintf(t,100,textstats,fH->GetMean(2),fH->GetMeanError(2));
8475 }
8476 stats->AddText(t);
8477 }
8478 }
8479 if (print_stddev) {
8480 if (print_stddev == 1) {
8481 snprintf(textstats,50,"%s = %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat());
8482 snprintf(t,100,textstats,fH->GetStdDev(1));
8483 } else {
8484 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDev.Data(),"%",stats->GetStatFormat()
8485 ,"%",stats->GetStatFormat());
8486 snprintf(t,100,textstats,fH->GetStdDev(1),fH->GetStdDevError(1));
8487 }
8488 stats->AddText(t);
8490 if (print_stddev == 1) {
8491 snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8492 snprintf(t,100,textstats,fH->GetStdDev(2));
8493 } else {
8494 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8495 ,"%",stats->GetStatFormat());
8496 snprintf(t,100,textstats,fH->GetStdDev(2),fH->GetStdDevError(2));
8497 }
8498 stats->AddText(t);
8499 }
8500 }
8501 if (print_under) {
8502 snprintf(textstats,50,"%s = %s%s",gStringUnderflow.Data(),"%",stats->GetStatFormat());
8503 snprintf(t,100,textstats,fH->GetBinContent(0));
8504 stats->AddText(t);
8505 }
8506 if (print_over) {
8507 snprintf(textstats,50,"%s = %s%s",gStringOverflow.Data(),"%",stats->GetStatFormat());
8508 snprintf(t,100,textstats,fH->GetBinContent(fXaxis->GetNbins()+1));
8509 stats->AddText(t);
8510 }
8511 if (print_integral) {
8512 if (print_integral == 1) {
8513 snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8514 snprintf(t,100,textstats,fH->Integral());
8515 } else {
8516 snprintf(textstats,50,"%s = %s%s",gStringIntegralBinWidth.Data(),"%",stats->GetStatFormat());
8517 snprintf(t,100,textstats,fH->Integral("width"));
8518 }
8519 stats->AddText(t);
8520 }
8521 if (print_skew) {
8522 if (print_skew == 1) {
8523 snprintf(textstats,50,"%s = %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat());
8524 snprintf(t,100,textstats,fH->GetSkewness(1));
8525 } else {
8526 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewness.Data(),"%",stats->GetStatFormat()
8527 ,"%",stats->GetStatFormat());
8528 snprintf(t,100,textstats,fH->GetSkewness(1),fH->GetSkewness(11));
8529 }
8530 stats->AddText(t);
8531 }
8532 if (print_kurt) {
8533 if (print_kurt == 1) {
8534 snprintf(textstats,50,"%s = %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat());
8535 snprintf(t,100,textstats,fH->GetKurtosis(1));
8536 } else {
8537 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosis.Data(),"%",stats->GetStatFormat()
8538 ,"%",stats->GetStatFormat());
8539 snprintf(t,100,textstats,fH->GetKurtosis(1),fH->GetKurtosis(11));
8540 }
8541 stats->AddText(t);
8542 }
8543
8544 // Draw Fit parameters
8545 if (fit) {
8546 Int_t ndf = fit->GetNDF();
8547 snprintf(textstats,50,"#chi^{2} / ndf = %s%s / %d","%",stats->GetFitFormat(),ndf);
8548 snprintf(t,100,textstats,(Float_t)fit->GetChisquare());
8549 if (print_fchi2) stats->AddText(t);
8550 if (print_fprob) {
8551 snprintf(textstats,50,"Prob = %s%s","%",stats->GetFitFormat());
8552 snprintf(t,100,textstats,(Float_t)TMath::Prob(fit->GetChisquare(),ndf));
8553 stats->AddText(t);
8554 }
8555 if (print_fval || print_ferrors) {
8556 Double_t parmin,parmax;
8557 Int_t a;
8558 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8559 fit->GetParLimits(ipar,parmin,parmax);
8560 if (print_fval < 2 && parmin*parmax != 0 && parmin >= parmax) continue;
8561 snprintf(t,100,"%-8s ",fit->GetParName(ipar));
8562 a = strlen(t);
8563 if (a>50) a = 50;
8564 if (print_ferrors) {
8565 snprintf(textstats,50,"= %s%s #pm %s ", "%",stats->GetFitFormat(),
8566 GetBestFormat(fit->GetParameter(ipar), fit->GetParError(ipar), stats->GetFitFormat()));
8567 snprintf(&t[a],100-a,textstats,(Float_t)fit->GetParameter(ipar)
8568 ,(Float_t)fit->GetParError(ipar));
8569 } else {
8570 snprintf(textstats,50,"= %s%s ","%",stats->GetFitFormat());
8571 snprintf(&t[a],100-a,textstats,(Float_t)fit->GetParameter(ipar));
8572 }
8573 t[63] = 0;
8574 stats->AddText(t);
8575 }
8576 }
8577 }
8578
8579 if (!done) fFunctions->Add(stats);
8580 stats->Paint();
8581}
8582
8583////////////////////////////////////////////////////////////////////////////////
8584/// [Draw the statistics box for 2D histograms.](#HP07)
8585
8587{
8588
8589 if (fH->GetDimension() != 2) return;
8590 TH2 *h2 = (TH2*)fH;
8591
8592 static char t[100];
8593 Int_t dofit;
8594 TPaveStats *stats = 0;
8595 TIter next(fFunctions);
8596 TObject *obj;
8597 while ((obj = next())) {
8598 if (obj->InheritsFrom(TPaveStats::Class())) {
8599 stats = (TPaveStats*)obj;
8600 break;
8601 }
8602 }
8603 if (stats && dostat) {
8604 dofit = stats->GetOptFit();
8605 dostat = stats->GetOptStat();
8606 } else {
8607 dofit = gStyle->GetOptFit();
8608 }
8609 if (dostat == 1) dostat = 1111;
8610 Int_t print_name = dostat%10;
8611 Int_t print_entries = (dostat/10)%10;
8612 Int_t print_mean = (dostat/100)%10;
8613 Int_t print_stddev = (dostat/1000)%10;
8614 Int_t print_under = (dostat/10000)%10;
8615 Int_t print_over = (dostat/100000)%10;
8616 Int_t print_integral= (dostat/1000000)%10;
8617 Int_t print_skew = (dostat/10000000)%10;
8618 Int_t print_kurt = (dostat/100000000)%10;
8619 Int_t nlines = print_name + print_entries + 2*print_mean + 2*print_stddev + print_integral;
8620 if (print_under || print_over) nlines += 3;
8621
8622 // Pavetext with statistics
8623 if (!gStyle->GetOptFit()) fit = 0;
8624 Bool_t done = kFALSE;
8625 if (!dostat && !fit) {
8626 if (stats) { fFunctions->Remove(stats); delete stats;}
8627 return;
8628 }
8629 Double_t statw = gStyle->GetStatW();
8630 if (fit) statw = 1.8*gStyle->GetStatW();
8631 Double_t stath = nlines*gStyle->GetStatFontSize();
8632 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8633 stath = 0.25*nlines*gStyle->GetStatH();
8634 }
8635 if (fit) stath += gStyle->GetStatH();
8636 if (stats) {
8637 stats->Clear();
8638 done = kTRUE;
8639 } else {
8640 stats = new TPaveStats(
8641 gStyle->GetStatX()-statw,
8642 gStyle->GetStatY()-stath,
8643 gStyle->GetStatX(),
8644 gStyle->GetStatY(),"brNDC");
8645
8646 stats->SetParent(fH);
8647 stats->SetOptFit(dofit);
8648 stats->SetOptStat(dostat);
8649 stats->SetFillColor(gStyle->GetStatColor());
8650 stats->SetFillStyle(gStyle->GetStatStyle());
8652 stats->SetName("stats");
8653
8655 stats->SetTextAlign(12);
8656 stats->SetTextFont(gStyle->GetStatFont());
8657 if (gStyle->GetStatFont()%10 > 2)
8659 stats->SetFitFormat(gStyle->GetFitFormat());
8661 stats->SetBit(kCanDelete);
8662 stats->SetBit(kMustCleanup);
8663 }
8664 if (print_name) stats->AddText(h2->GetName());
8665 if (print_entries) {
8666 if (h2->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h2->GetEntries()+0.5));
8667 else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h2->GetEntries()));
8668 stats->AddText(t);
8669 }
8670 char textstats[50];
8671 if (print_mean) {
8672 if (print_mean == 1) {
8673 snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8674 snprintf(t,50,textstats,h2->GetMean(1));
8675 stats->AddText(t);
8676 snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8677 snprintf(t,100,textstats,h2->GetMean(2));
8678 stats->AddText(t);
8679 } else {
8680 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8681 ,"%",stats->GetStatFormat());
8682 snprintf(t,100,textstats,h2->GetMean(1),h2->GetMeanError(1));
8683 stats->AddText(t);
8684 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8685 ,"%",stats->GetStatFormat());
8686 snprintf(t,100,textstats,h2->GetMean(2),h2->GetMeanError(2));
8687 stats->AddText(t);
8688 }
8689 }
8690 if (print_stddev) {
8691 if (print_stddev == 1) {
8692 snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8693 snprintf(t,100,textstats,h2->GetStdDev(1));
8694 stats->AddText(t);
8695 snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8696 snprintf(t,100,textstats,h2->GetStdDev(2));
8697 stats->AddText(t);
8698 } else {
8699 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8700 ,"%",stats->GetStatFormat());
8701 snprintf(t,100,textstats,h2->GetStdDev(1),h2->GetStdDevError(1));
8702 stats->AddText(t);
8703 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8704 ,"%",stats->GetStatFormat());
8705 snprintf(t,100,textstats,h2->GetStdDev(2),h2->GetStdDevError(2));
8706 stats->AddText(t);
8707 }
8708 }
8709 if (print_integral) {
8710 snprintf(textstats,50,"%s = %s%s",gStringIntegral.Data(),"%",stats->GetStatFormat());
8711 snprintf(t,100,textstats,fH->Integral());
8712 stats->AddText(t);
8713 }
8714 if (print_skew) {
8715 if (print_skew == 1) {
8716 snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8717 snprintf(t,100,textstats,h2->GetSkewness(1));
8718 stats->AddText(t);
8719 snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8720 snprintf(t,100,textstats,h2->GetSkewness(2));
8721 stats->AddText(t);
8722 } else {
8723 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8724 ,"%",stats->GetStatFormat());
8725 snprintf(t,100,textstats,h2->GetSkewness(1),h2->GetSkewness(11));
8726 stats->AddText(t);
8727 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8728 ,"%",stats->GetStatFormat());
8729 snprintf(t,100,textstats,h2->GetSkewness(2),h2->GetSkewness(12));
8730 stats->AddText(t);
8731 }
8732 }
8733 if (print_kurt) {
8734 if (print_kurt == 1) {
8735 snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8736 snprintf(t,100,textstats,h2->GetKurtosis(1));
8737 stats->AddText(t);
8738 snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8739 snprintf(t,100,textstats,h2->GetKurtosis(2));
8740 stats->AddText(t);
8741 } else {
8742 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8743 ,"%",stats->GetStatFormat());
8744 snprintf(t,100,textstats,h2->GetKurtosis(1),h2->GetKurtosis(11));
8745 stats->AddText(t);
8746 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8747 ,"%",stats->GetStatFormat());
8748 snprintf(t,100,textstats,h2->GetKurtosis(2),h2->GetKurtosis(12));
8749 stats->AddText(t);
8750 }
8751 }
8752 if (print_under || print_over) {
8753 //get 3*3 under/overflows for 2d hist
8754 Double_t unov[9];
8755
8756 Int_t cellsX = h2->GetXaxis()->GetNbins() + 1;
8757 Int_t cellsY = h2->GetYaxis()->GetNbins() + 1;
8758 Int_t firstX = std::max(1, h2->GetXaxis()->GetFirst());
8759 Int_t firstY = std::max(1, h2->GetYaxis()->GetFirst());
8760 Int_t lastX = std::min(h2->GetXaxis()->GetLast(), h2->GetXaxis()->GetNbins());
8761 Int_t lastY = std::min(h2->GetYaxis()->GetLast(), h2->GetYaxis()->GetNbins());
8762
8763 unov[0] = h2->Integral( 0, firstX-1, lastY+1, cellsY );
8764 unov[1] = h2->Integral(firstX , lastX , lastY+1, cellsY );
8765 unov[2] = h2->Integral(lastX+1, cellsX , lastY+1, cellsY );
8766 unov[3] = h2->Integral( 0, firstX-1, firstY , lastY );
8767 unov[4] = h2->Integral(firstX , lastX , firstY , lastY );
8768 unov[5] = h2->Integral(lastX+1, cellsX , firstY , lastY );
8769 unov[6] = h2->Integral( 0, firstX-1, 0, firstY-1);
8770 unov[7] = h2->Integral(firstX, lastX, 0, firstY-1);
8771 unov[8] = h2->Integral(lastX+1, cellsX , 0, firstY-1);
8772
8773 snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[0], (Int_t)unov[1], (Int_t)unov[2]);
8774 stats->AddText(t);
8775 if (TMath::Abs(unov[4]) < 1.e7)
8776 snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[3], (Int_t)unov[4], (Int_t)unov[5]);
8777 else
8778 snprintf(t, 100," %7d|%14.7g|%7d\n", (Int_t)unov[3], (Float_t)unov[4], (Int_t)unov[5]);
8779 stats->AddText(t);
8780 snprintf(t, 100," %7d|%7d|%7d\n", (Int_t)unov[6], (Int_t)unov[7], (Int_t)unov[8]);
8781 stats->AddText(t);
8782 }
8783
8784 // Draw Fit parameters
8785 if (fit) {
8786 Int_t ndf = fit->GetNDF();
8787 snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
8788 stats->AddText(t);
8789 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
8790 snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
8791 ,(Float_t)fit->GetParameter(ipar)
8792 ,(Float_t)fit->GetParError(ipar));
8793 t[63] = 0;
8794 stats->AddText(t);
8795 }
8796 }
8797
8798 if (!done) fFunctions->Add(stats);
8799 stats->Paint();
8800}
8801
8802////////////////////////////////////////////////////////////////////////////////
8803/// [Draw the statistics box for 3D histograms.](#HP07)
8804
8806{
8807
8808 if (fH->GetDimension() != 3) return;
8809 TH3 *h3 = (TH3*)fH;
8810
8811 static char t[100];
8812 Int_t dofit;
8813 TPaveStats *stats = 0;
8814 TIter next(fFunctions);
8815 TObject *obj;
8816 while ((obj = next())) {
8817 if (obj->InheritsFrom(TPaveStats::Class())) {
8818 stats = (TPaveStats*)obj;
8819 break;
8820 }
8821 }
8822 if (stats && dostat) {
8823 dofit = stats->GetOptFit();
8824 dostat = stats->GetOptStat();
8825 } else {
8826 dofit = gStyle->GetOptFit();
8827 }
8828 if (dostat == 1) dostat = 1111;
8829 Int_t print_name = dostat%10;
8830 Int_t print_entries = (dostat/10)%10;
8831 Int_t print_mean = (dostat/100)%10;
8832 Int_t print_stddev = (dostat/1000)%10;
8833 Int_t print_under = (dostat/10000)%10;
8834 Int_t print_over = (dostat/100000)%10;
8835 Int_t print_integral= (dostat/1000000)%10;
8836 Int_t print_skew = (dostat/10000000)%10;
8837 Int_t print_kurt = (dostat/100000000)%10;
8838 Int_t nlines = print_name + print_entries + 3*print_mean + 3*print_stddev + print_integral;
8839 if (print_under || print_over) nlines += 3;
8840
8841 // Pavetext with statistics
8842 if (!gStyle->GetOptFit()) fit = 0;
8843 Bool_t done = kFALSE;
8844 if (!dostat && !fit) {
8845 if (stats) { fFunctions->Remove(stats); delete stats;}
8846 return;
8847 }
8848 Double_t statw = gStyle->GetStatW();
8849 if (fit) statw = 1.8*gStyle->GetStatW();
8850 Double_t stath = nlines*gStyle->GetStatFontSize();
8851 if (stath <= 0 || 3 == (gStyle->GetStatFont()%10)) {
8852 stath = 0.25*nlines*gStyle->GetStatH();
8853 }
8854 if (fit) stath += gStyle->GetStatH();
8855 if (stats) {
8856 stats->Clear();
8857 done = kTRUE;
8858 } else {
8859 stats = new TPaveStats(
8860 gStyle->GetStatX()-statw,
8861 gStyle->GetStatY()-stath,
8862 gStyle->GetStatX(),
8863 gStyle->GetStatY(),"brNDC");
8864
8865 stats->SetParent(fH);
8866 stats->SetOptFit(dofit);
8867 stats->SetOptStat(dostat);
8868 stats->SetFillColor(gStyle->GetStatColor());
8869 stats->SetFillStyle(gStyle->GetStatStyle());
8871 stats->SetName("stats");
8872
8874 stats->SetTextAlign(12);
8875 stats->SetTextFont(gStyle->GetStatFont());
8876 stats->SetFitFormat(gStyle->GetFitFormat());
8878 stats->SetBit(kCanDelete);
8879 stats->SetBit(kMustCleanup);
8880 }
8881 if (print_name) stats->AddText(h3->GetName());
8882 if (print_entries) {
8883 if (h3->GetEntries() < 1e7) snprintf(t,100,"%s = %-7d",gStringEntries.Data(),Int_t(h3->GetEntries()+0.5));
8884 else snprintf(t,100,"%s = %14.7g",gStringEntries.Data(),Float_t(h3->GetEntries()+0.5));
8885 stats->AddText(t);
8886 }
8887 char textstats[50];
8888 if (print_mean) {
8889 if (print_mean == 1) {
8890 snprintf(textstats,50,"%s = %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat());
8891 snprintf(t,100,textstats,h3->GetMean(1));
8892 stats->AddText(t);
8893 snprintf(textstats,50,"%s = %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat());
8894 snprintf(t,100,textstats,h3->GetMean(2));
8895 stats->AddText(t);
8896 snprintf(textstats,50,"%s = %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat());
8897 snprintf(t,100,textstats,h3->GetMean(3));
8898 stats->AddText(t);
8899 } else {
8900 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanX.Data(),"%",stats->GetStatFormat()
8901 ,"%",stats->GetStatFormat());
8902 snprintf(t,100,textstats,h3->GetMean(1),h3->GetMeanError(1));
8903 stats->AddText(t);
8904 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanY.Data(),"%",stats->GetStatFormat()
8905 ,"%",stats->GetStatFormat());
8906 snprintf(t,100,textstats,h3->GetMean(2),h3->GetMeanError(2));
8907 stats->AddText(t);
8908 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringMeanZ.Data(),"%",stats->GetStatFormat()
8909 ,"%",stats->GetStatFormat());
8910 snprintf(t,100,textstats,h3->GetMean(3),h3->GetMeanError(3));
8911 stats->AddText(t);
8912 }
8913 }
8914 if (print_stddev) {
8915 if (print_stddev == 1) {
8916 snprintf(textstats,50,"%s = %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat());
8917 snprintf(t,100,textstats,h3->GetStdDev(1));
8918 stats->AddText(t);
8919 snprintf(textstats,50,"%s = %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat());
8920 snprintf(t,100,textstats,h3->GetStdDev(2));
8921 stats->AddText(t);
8922 snprintf(textstats,50,"%s = %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat());
8923 snprintf(t,100,textstats,h3->GetStdDev(3));
8924 stats->AddText(t);
8925 } else {
8926 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevX.Data(),"%",stats->GetStatFormat()
8927 ,"%",stats->GetStatFormat());
8928 snprintf(t,100,textstats,h3->GetStdDev(1),h3->GetStdDevError(1));
8929 stats->AddText(t);
8930 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevY.Data(),"%",stats->GetStatFormat()
8931 ,"%",stats->GetStatFormat());
8932 snprintf(t,100,textstats,h3->GetStdDev(2),h3->GetStdDevError(2));
8933 stats->AddText(t);
8934 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringStdDevZ.Data(),"%",stats->GetStatFormat()
8935 ,"%",stats->GetStatFormat());
8936 snprintf(t,100,textstats,h3->GetStdDev(3),h3->GetStdDevError(3));
8937 stats->AddText(t);
8938 }
8939 }
8940 if (print_integral) {
8941 snprintf(t,100,"%s = %6.4g",gStringIntegral.Data(),h3->Integral());
8942 stats->AddText(t);
8943 }
8944 if (print_skew) {
8945 if (print_skew == 1) {
8946 snprintf(textstats,50,"%s = %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat());
8947 snprintf(t,100,textstats,h3->GetSkewness(1));
8948 stats->AddText(t);
8949 snprintf(textstats,50,"%s = %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat());
8950 snprintf(t,100,textstats,h3->GetSkewness(2));
8951 stats->AddText(t);
8952 snprintf(textstats,50,"%s = %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat());
8953 snprintf(t,100,textstats,h3->GetSkewness(3));
8954 stats->AddText(t);
8955 } else {
8956 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessX.Data(),"%",stats->GetStatFormat()
8957 ,"%",stats->GetStatFormat());
8958 snprintf(t,100,textstats,h3->GetSkewness(1),h3->GetSkewness(11));
8959 stats->AddText(t);
8960 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessY.Data(),"%",stats->GetStatFormat()
8961 ,"%",stats->GetStatFormat());
8962 snprintf(t,100,textstats,h3->GetSkewness(2),h3->GetSkewness(12));
8963 stats->AddText(t);
8964 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringSkewnessZ.Data(),"%",stats->GetStatFormat()
8965 ,"%",stats->GetStatFormat());
8966 snprintf(t,100,textstats,h3->GetSkewness(3),h3->GetSkewness(13));
8967 stats->AddText(t);
8968 }
8969 }
8970 if (print_kurt) {
8971 if (print_kurt == 1) {
8972 snprintf(textstats,50,"%s = %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat());
8973 snprintf(t,100,textstats,h3->GetKurtosis(1));
8974 stats->AddText(t);
8975 snprintf(textstats,50,"%s = %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat());
8976 snprintf(t,100,textstats,h3->GetKurtosis(2));
8977 stats->AddText(t);
8978 snprintf(textstats,50,"%s = %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat());
8979 snprintf(t,100,textstats,h3->GetKurtosis(3));
8980 stats->AddText(t);
8981 } else {
8982 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisX.Data(),"%",stats->GetStatFormat()
8983 ,"%",stats->GetStatFormat());
8984 snprintf(t,100,textstats,h3->GetKurtosis(1),h3->GetKurtosis(11));
8985 stats->AddText(t);
8986 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisY.Data(),"%",stats->GetStatFormat()
8987 ,"%",stats->GetStatFormat());
8988 snprintf(t,100,textstats,h3->GetKurtosis(2),h3->GetKurtosis(12));
8989 stats->AddText(t);
8990 snprintf(textstats,50,"%s = %s%s #pm %s%s",gStringKurtosisZ.Data(),"%",stats->GetStatFormat()
8991 ,"%",stats->GetStatFormat());
8992 snprintf(t,100,textstats,h3->GetKurtosis(3),h3->GetKurtosis(13));
8993 stats->AddText(t);
8994 }
8995 }
8996 if (print_under || print_over) {
8997 // no underflow - overflow printing for a 3D histogram
8998 // one would need a 3D table
8999 }
9000
9001 // Draw Fit parameters
9002 if (fit) {
9003 Int_t ndf = fit->GetNDF();
9004 snprintf(t,100,"#chi^{2} / ndf = %6.4g / %d",(Float_t)fit->GetChisquare(),ndf);
9005 stats->AddText(t);
9006 for (Int_t ipar=0;ipar<fit->GetNpar();ipar++) {
9007 snprintf(t,100,"%-8s = %5.4g #pm %5.4g ",fit->GetParName(ipar)
9008 ,(Float_t)fit->GetParameter(ipar)
9009 ,(Float_t)fit->GetParError(ipar));
9010 t[32] = 0;
9011 stats->AddText(t);
9012 }
9013 }
9014
9015 if (!done) fFunctions->Add(stats);
9016 stats->Paint();
9017}
9018
9019////////////////////////////////////////////////////////////////////////////////
9020/// [Control function to draw a 2D histogram as a surface plot.](#HP18)
9021
9023{
9024
9025 const Double_t ydiff = 1;
9026 const Double_t yligh1 = 10;
9027 const Double_t qa = 0.15;
9028 const Double_t qd = 0.15;
9029 const Double_t qs = 0.8;
9030 Double_t fmin, fmax;
9031 Int_t raster = 0;
9032 Int_t irep = 0;
9033
9034 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9037 Double_t zmin = Hparam.zmin;
9038 Double_t zmax = Hparam.zmax;
9039 Double_t xlab1 = Hparam.xmin;
9040 Double_t xlab2 = Hparam.xmax;
9041 Double_t ylab1 = Hparam.ymin;
9042 Double_t ylab2 = Hparam.ymax;
9043 Double_t dangle = 10*3.141592/180; //Delta angle for Rapidity option
9044 Double_t deltaz = TMath::Abs(zmin);
9045 if (deltaz == 0) deltaz = 1;
9046 if (zmin >= zmax) {
9047 zmin -= 0.5*deltaz;
9048 zmax += 0.5*deltaz;
9049 }
9050 Double_t z1c = zmin;
9051 Double_t z2c = zmin + (zmax-zmin)*(1+gStyle->GetHistTopMargin());
9052 // Compute the lego limits and instantiate a lego object
9053 fXbuf[0] = -1;
9054 fYbuf[0] = 1;
9055 fXbuf[1] = -1;
9056 fYbuf[1] = 1;
9057 if (Hoption.System >= kPOLAR && (Hoption.Surf == 1 || Hoption.Surf == 13)) raster = 1;
9058 if (Hoption.System == kPOLAR) {
9059 fXbuf[2] = z1c;
9060 fYbuf[2] = z2c;
9061 } else if (Hoption.System == kCYLINDRICAL) {
9062 if (Hoption.Logy) {
9063 if (ylab1 > 0) fXbuf[2] = TMath::Log10(ylab1);
9064 else fXbuf[2] = 0;
9065 if (ylab2 > 0) fYbuf[2] = TMath::Log10(ylab2);
9066 else fYbuf[2] = 0;
9067 } else {
9068 fXbuf[2] = ylab1;
9069 fYbuf[2] = ylab2;
9070 }
9071 z1c = 0; z2c = 1;
9072 } else if (Hoption.System == kSPHERICAL) {
9073 fXbuf[2] = -1;
9074 fYbuf[2] = 1;
9075 z1c = 0; z2c = 1;
9076 } else if (Hoption.System == kRAPIDITY) {
9077 fXbuf[2] = -1/TMath::Tan(dangle);
9078 fYbuf[2] = 1/TMath::Tan(dangle);
9079 } else {
9080 fXbuf[0] = xlab1;
9081 fYbuf[0] = xlab2;
9082 fXbuf[1] = ylab1;
9083 fYbuf[1] = ylab2;
9084 fXbuf[2] = z1c;
9085 fYbuf[2] = z2c;
9086 }
9087
9091
9092 // Create axis object
9093
9094 TGaxis *axis = new TGaxis();
9095
9096 // Initialize the levels on the Z axis
9097 Int_t ndiv = fH->GetContour();
9098 if (ndiv == 0 ) {
9099 ndiv = gStyle->GetNumberContours();
9100 fH->SetContour(ndiv);
9101 }
9102 Int_t ndivz = TMath::Abs(ndiv);
9103 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9104
9105 if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3);
9106 if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0);
9107
9108 // Close the surface in case of non cartesian coordinates.
9109
9110 if (Hoption.System != kCARTESIAN) {nx++; ny++;}
9111
9112 // Now ready to draw the surface plot
9113
9114 TView *view = gPad->GetView();
9115 if (!view) {
9116 Error("PaintSurface", "no TView in current pad");
9117 return;
9118 }
9119
9120 Double_t thedeg = 90 - gPad->GetTheta();
9121 Double_t phideg = -90 - gPad->GetPhi();
9122 Double_t psideg = view->GetPsi();
9123 view->SetView(phideg, thedeg, psideg, irep);
9124
9125 // Set color/style for back box
9126 if (Hoption.Same) {
9127 fLego->SetFillStyle(0);
9128 fLego->SetFillColor(1);
9129 } else {
9130 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9131 fLego->SetFillColor(gPad->GetFrameFillColor());
9132 }
9133 fLego->TAttFill::Modify();
9134
9135 Int_t backcolor = gPad->GetFrameFillColor();
9136 if (Hoption.System != kCARTESIAN) backcolor = 0;
9137 view->PadRange(backcolor);
9138
9141 fLego->TAttFill::Modify();
9142
9143 // Draw the filled contour on top
9144 Int_t icol1 = fH->GetFillColor();
9145
9146 Int_t hoption35 = Hoption.Surf;
9147 if (Hoption.Surf == 13 || Hoption.Surf == 15) {
9148 DefineColorLevels(ndivz);
9149 Hoption.Surf = 23;
9152 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9153 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9154 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9155 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9156 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9157 Hoption.Surf = hoption35;
9158 fLego->SetMesh(1);
9159 }
9160
9161 if (raster) fLego->InitRaster(-1.1,-1.1,1.1,1.1,1000,800);
9162 else fLego->InitMoveScreen(-1.1,1.1);
9163
9164 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) {
9168 fLego->BackBox(90);
9169 }
9170 }
9171
9172 // Gouraud Shading surface
9173 if (Hoption.Surf == 14) {
9174 // Set light sources
9175 fLego->LightSource(0, ydiff, 0,0,0,irep);
9176 fLego->LightSource(1, yligh1 ,1,1,1,irep);
9177 fLego->SurfaceProperty(qa, qd, qs, 1, irep);
9178 fmin = ydiff*qa;
9179 fmax = fmin + (yligh1+0.1)*(qd+qs);
9180 Int_t nbcol = 28;
9181 icol1 = 201;
9182 Double_t dcol = 0.5/Double_t(nbcol);
9183 TColor *colref = gROOT->GetColor(fH->GetFillColor());
9184 if (!colref) return;
9185 Float_t r,g,b,hue,light,satur;
9186 colref->GetRGB(r,g,b);
9187 TColor::RGBtoHLS(r,g,b,hue,light,satur);
9188 TColor *acol;
9189 for (Int_t col=0;col<nbcol;col++) {
9190 acol = gROOT->GetColor(col+icol1);
9191 TColor::HLStoRGB(hue,.4+col*dcol,satur,r,g,b);
9192 if (acol) acol->SetRGB(r,g,b);
9193 }
9194 fLego->Spectrum(nbcol, fmin, fmax, icol1, 1, irep);
9197 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"BF");
9198 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9199 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9200 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9201 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"BF");
9202 } else if (Hoption.Surf == 15) {
9203 // The surface is not drawn in this case.
9204 } else {
9205 // Draw the surface
9206 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 16 || Hoption.Surf == 17) {
9207 DefineColorLevels(ndivz);
9208 } else {
9210 }
9214 if (Hoption.System == kPOLAR) {
9215 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfacePolar(1,nx,ny,"FB");
9216 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfacePolar(1,nx,ny,"BF");
9217 } else if (Hoption.System == kCYLINDRICAL) {
9218 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9219 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCylindrical(1,nx,ny,"BF");
9220 } else if (Hoption.System == kSPHERICAL) {
9221 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9222 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(0,1,nx,ny,"BF");
9223 } else if (Hoption.System == kRAPIDITY) {
9224 if (Hoption.Surf == 1 || Hoption.Surf == 13) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9225 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceSpherical(1,1,nx,ny,"BF");
9226 } else {
9229 if (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16) fLego->SurfaceCartesian(90,nx,ny,"FB");
9230 if (Hoption.Surf == 11 || Hoption.Surf == 12 || Hoption.Surf == 17) fLego->SurfaceCartesian(90,nx,ny,"BF");
9231 }
9232 }
9233
9234 // Paint the line contour on top for option SURF7
9235 if (Hoption.Surf == 17) {
9236 fLego->InitMoveScreen(-1.1,1.1);
9238 Hoption.Surf = 23;
9241 if (Hoption.System == kPOLAR) fLego->SurfacePolar(1,nx,ny,"FB");
9242 if (Hoption.System == kCYLINDRICAL) fLego->SurfaceCylindrical(1,nx,ny,"FB");
9243 if (Hoption.System == kSPHERICAL) fLego->SurfaceSpherical(0,1,nx,ny,"FB");
9244 if (Hoption.System == kRAPIDITY ) fLego->SurfaceSpherical(1,1,nx,ny,"FB");
9245 if (Hoption.System == kCARTESIAN) fLego->SurfaceCartesian(90,nx,ny,"FB");
9246 }
9247
9248 if ((!Hoption.Same) &&
9249 (Hoption.Surf == 1 || Hoption.Surf == 13 || Hoption.Surf == 16)) {
9252 fLego->BackBox(90);
9253 }
9254 }
9255 if (Hoption.System == kCARTESIAN) {
9256 fLego->InitMoveScreen(-1.1,1.1);
9258 if (Hoption.FrontBox) fLego->FrontBox(90);
9259 }
9260 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9261
9263
9264 delete axis;
9265 delete fLego; fLego = 0;
9266}
9267
9268////////////////////////////////////////////////////////////////////////////////
9269/// Control function to draw a table using Delaunay triangles.
9270
9272{
9273
9274 TGraphDelaunay2D *dt = nullptr;
9275 TGraphDelaunay *dtOld = nullptr;
9276
9277 // Check if fH contains a TGraphDelaunay2D
9278 TList *hl = fH->GetListOfFunctions();
9279 dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D");
9280 if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
9281 if (!dt && !dtOld) return;
9282
9283 // If needed, create a TGraph2DPainter
9284 if (!fGraph2DPainter) {
9285 if (dt) fGraph2DPainter = new TGraph2DPainter(dt);
9286 else fGraph2DPainter = new TGraph2DPainter(dtOld);
9287 }
9288
9289 // Define the 3D view
9290 if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;}
9291 if (Hoption.Same) {
9292 TView *viewsame = gPad->GetView();
9293 if (!viewsame) {
9294 Error("PaintTriangles", "no TView in current pad, do not use option SAME");
9295 return;
9296 }
9297 Double_t *rmin = viewsame->GetRmin();
9298 Double_t *rmax = viewsame->GetRmax();
9299 if (!rmin || !rmax) return;
9300 fXbuf[0] = rmin[0];
9301 fYbuf[0] = rmax[0];
9302 fXbuf[1] = rmin[1];
9303 fYbuf[1] = rmax[1];
9304 fXbuf[2] = rmin[2];
9305 fYbuf[2] = rmax[2];
9306 } else {
9307 fXbuf[0] = Hparam.xmin;
9308 fYbuf[0] = Hparam.xmax;
9309 fXbuf[1] = Hparam.ymin;
9310 fYbuf[1] = Hparam.ymax;
9311 fXbuf[2] = Hparam.zmin;
9312 fYbuf[2] = Hparam.zmax;
9313 }
9314
9316 TView *view = gPad->GetView();
9317 if (!view) {
9318 Error("PaintTriangles", "no TView in current pad");
9319 return;
9320 }
9321 Double_t thedeg = 90 - gPad->GetTheta();
9322 Double_t phideg = -90 - gPad->GetPhi();
9323 Double_t psideg = view->GetPsi();
9324 Int_t irep;
9325 view->SetView(phideg, thedeg, psideg, irep);
9326
9327 // Set color/style for back box
9328 fLego->SetFillStyle(gPad->GetFrameFillStyle());
9329 fLego->SetFillColor(gPad->GetFrameFillColor());
9330 fLego->TAttFill::Modify();
9331 Int_t backcolor = gPad->GetFrameFillColor();
9332 if (Hoption.System != kCARTESIAN) backcolor = 0;
9333 view->PadRange(backcolor);
9336 fLego->TAttFill::Modify();
9337
9338 // Paint the Back Box if needed
9339 if (Hoption.BackBox && !Hoption.Same) {
9340 fLego->InitMoveScreen(-1.1,1.1);
9343 fLego->BackBox(90);
9344 }
9345
9346 // Paint the triangles
9347 fGraph2DPainter->Paint(option);
9348
9349 // Paint the Front Box if needed
9350 if (Hoption.FrontBox) {
9351 fLego->InitMoveScreen(-1.1,1.1);
9353 fLego->FrontBox(90);
9354 }
9355
9356 // Paint the Axis if needed
9357 if (!Hoption.Axis && !Hoption.Same) {
9358 TGaxis *axis = new TGaxis();
9359 PaintLegoAxis(axis, 90);
9360 delete axis;
9361 }
9362
9364
9365 delete fLego; fLego = 0;
9366}
9367
9368////////////////////////////////////////////////////////////////////////////////
9369/// Define the color levels used to paint legos, surfaces etc..
9370
9372{
9373
9374 Int_t i, irep;
9375
9376 // Initialize the color levels
9377 if (ndivz >= 100) {
9378 Warning("PaintSurface", "too many color levels, %d, reset to 8", ndivz);
9379 ndivz = 8;
9380 }
9381 Double_t *funlevel = new Double_t[ndivz+1];
9382 Int_t *colorlevel = new Int_t[ndivz+1];
9383 Int_t theColor;
9384 Int_t ncolors = gStyle->GetNumberOfColors();
9385 for (i = 0; i < ndivz; ++i) {
9386 funlevel[i] = fH->GetContourLevelPad(i);
9387 theColor = Int_t((i+0.99)*Float_t(ncolors)/Float_t(ndivz));
9388 colorlevel[i] = gStyle->GetColorPalette(theColor);
9389 }
9390 colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1);
9391 fLego->ColorFunction(ndivz, funlevel, colorlevel, irep);
9392 delete [] colorlevel;
9393 delete [] funlevel;
9394}
9395
9396////////////////////////////////////////////////////////////////////////////////
9397/// [Control function to draw 2D/3D histograms (tables).](#HP01c)
9398
9400{
9401
9402 // Fill Hparam structure with histo parameters
9403 if (!TableInit()) return;
9404
9405 // Draw histogram frame
9406 PaintFrame();
9407
9408 // If palette option not specified, delete a possible existing palette
9409 if (!Hoption.Zscale) {
9410 TObject *palette = fFunctions->FindObject("palette");
9411 if (palette) { fFunctions->Remove(palette); delete palette;}
9412 }
9413
9414 // Do not draw the histogram. Only the attached functions will be drawn.
9415 if (Hoption.Func == 2) {
9416 if (Hoption.Zscale) {
9417 Int_t ndiv = fH->GetContour();
9418 if (ndiv == 0 ) {
9419 ndiv = gStyle->GetNumberContours();
9420 fH->SetContour(ndiv);
9421 }
9422 PaintPalette();
9423 }
9424
9425 // Draw the histogram according to the option
9426 } else {
9427 if (fH->InheritsFrom(TH2Poly::Class())) {
9428 if (Hoption.Fill) PaintTH2PolyBins("f");
9431 if (Hoption.Text) PaintTH2PolyText(option);
9432 if (Hoption.Line) PaintTH2PolyBins("l");
9433 if (Hoption.Mark) PaintTH2PolyBins("P");
9434 } else if (fH->GetEntries() != 0 && Hoption.Axis<=0) {
9435 if (Hoption.Scat) PaintScatterPlot(option);
9436 if (Hoption.Arrow) PaintArrows(option);
9437 if (Hoption.Box) PaintBoxes(option);
9438 if (Hoption.Color) {
9439 if (Hoption.Color == 3) PaintColorLevelsFast(option);
9440 else PaintColorLevels(option);
9441 }
9442 if (Hoption.Contour) PaintContour(option);
9443 if (Hoption.Text) PaintText(option);
9444 if (Hoption.Error >= 100) Paint2DErrors(option);
9445 if (Hoption.Candle) PaintCandlePlot(option);
9446 }
9447 if (Hoption.Lego) PaintLego(option);
9448 if (Hoption.Surf && !Hoption.Contour) PaintSurface(option);
9449 if (Hoption.Tri) PaintTriangles(option);
9450 }
9451
9452 // Draw histogram title
9453 PaintTitle();
9454
9455 // Draw the axes
9456 if (!Hoption.Lego && !Hoption.Surf &&
9457 !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE);
9458
9459 TF1 *fit = 0;
9460 TIter next(fFunctions);
9461 TObject *obj;
9462 while ((obj = next())) {
9463 if (obj->InheritsFrom(TF1::Class())) {
9464 fit = (TF1*)obj;
9465 break;
9466 }
9467 }
9468 if (Hoption.Same != 1) {
9469 if (!fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats
9470 if (!gPad->PadInSelectionMode() && !gPad->PadInHighlightMode()) {
9471 //ALWAYS executed on non-iOS platform.
9472 //On iOS, depends on mode.
9474 }
9475 }
9476 }
9477}
9478
9479////////////////////////////////////////////////////////////////////////////////
9480/// Control function to draw a TH2Poly bins' contours.
9481///
9482/// - option = "F" draw the bins as filled areas.
9483/// - option = "L" draw the bins as line.
9484/// - option = "P" draw the bins as markers.
9485
9487{
9488
9489 //Do not highlight the histogram, if its part was picked.
9490 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH) return;
9491
9492 TString opt = option;
9493 opt.ToLower();
9494 Bool_t line = kFALSE;
9495 Bool_t fill = kFALSE;
9496 Bool_t mark = kFALSE;
9497 if (opt.Contains("l")) line = kTRUE;
9498 if (opt.Contains("f")) fill = kTRUE;
9499 if (opt.Contains("p")) mark = kTRUE;
9500
9501 TH2PolyBin *b;
9502 Double_t z;
9503
9504 TIter next(((TH2Poly*)fH)->GetBins());
9505 TObject *obj, *poly;
9506
9507 while ((obj=next())) {
9508 b = (TH2PolyBin*)obj;
9509 z = b->GetContent();
9510 if (z==0 && Hoption.Zero) continue; // Do not draw empty bins in case of option "COL0 L"
9511 poly = b->GetPolygon();
9512
9513 // Paint the TGraph bins.
9514 if (poly->IsA() == TGraph::Class()) {
9515 TGraph *g = (TGraph*)poly;
9516 g->TAttLine::Modify();
9517 g->TAttMarker::Modify();
9518 g->TAttFill::Modify();
9519 if (line) {
9520 Int_t fs = g->GetFillStyle();
9521 Int_t fc = g->GetFillColor();
9522 g->SetFillStyle(0);
9523 g->SetFillColor(g->GetLineColor());
9524 g->Paint("F");
9525 g->SetFillStyle(fs);
9526 g->SetFillColor(fc);
9527 }
9528 if (fill) g->Paint("F");
9529 if (mark) g->Paint("P");
9530 }
9531
9532 // Paint the TMultiGraph bins.
9533 if (poly->IsA() == TMultiGraph::Class()) {
9534 TMultiGraph *mg = (TMultiGraph*)poly;
9535 TList *gl = mg->GetListOfGraphs();
9536 if (!gl) return;
9537 TGraph *g;
9538 TIter nextg(gl);
9539 while ((g = (TGraph*) nextg())) {
9540 g->TAttLine::Modify();
9541 g->TAttMarker::Modify();
9542 g->TAttFill::Modify();
9543 if (line) {
9544 Int_t fs = g->GetFillStyle();
9545 Int_t fc = g->GetFillColor();
9546 g->SetFillStyle(0);
9547 g->SetFillColor(g->GetLineColor());
9548 g->Paint("F");
9549 g->SetFillStyle(fs);
9550 g->SetFillColor(fc);
9551 }
9552 if (fill) g->Paint("F");
9553 if (mark) g->Paint("P");
9554 }
9555 }
9556 }
9557}
9558
9559////////////////////////////////////////////////////////////////////////////////
9560/// [Control function to draw a TH2Poly as a color plot.](#HP20a)
9561
9563{
9564
9565 //Do not highlight the histogram, if its part was picked.
9566 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9567 return;
9568
9569 Int_t ncolors, color, theColor;
9570 Double_t z, zc;
9571 Double_t zmin = fH->GetMinimum();
9572 Double_t zmax = fH->GetMaximum();
9573 if (Hoption.Logz) {
9574 if (zmax > 0) {
9575 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9576 zmin = TMath::Log10(zmin);
9577 zmax = TMath::Log10(zmax);
9578 } else {
9579 return;
9580 }
9581 }
9582 Double_t dz = zmax - zmin;
9583
9584 // Initialize the levels on the Z axis
9585 ncolors = gStyle->GetNumberOfColors();
9586 Int_t ndiv = fH->GetContour();
9587 if (ndiv == 0 ) {
9588 ndiv = gStyle->GetNumberContours();
9589 fH->SetContour(ndiv);
9590 }
9591 Int_t ndivz = TMath::Abs(ndiv);
9592 if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv);
9593 Double_t scale = ndivz/dz;
9594
9595 TH2PolyBin *b;
9596
9597 TIter next(((TH2Poly*)fH)->GetBins());
9598 TObject *obj, *poly;
9599
9600 while ((obj=next())) {
9601 b = (TH2PolyBin*)obj;
9602 poly = b->GetPolygon();
9603
9604 z = b->GetContent();
9605 if (z==0 && Hoption.Zero) continue;
9606 if (Hoption.Logz) {
9607 if (z > 0) z = TMath::Log10(z);
9608 else z = zmin;
9609 }
9610 if (z < zmin) continue;
9611
9612 // Define the bin color.
9614 zc = fH->GetContourLevelPad(0);
9615 if (z < zc) continue;
9616 color = -1;
9617 for (Int_t k=0; k<ndiv; k++) {
9618 zc = fH->GetContourLevelPad(k);
9619 if (z < zc) {
9620 continue;
9621 } else {
9622 color++;
9623 }
9624 }
9625 } else {
9626 color = Int_t(0.01+(z-zmin)*scale);
9627 }
9628 theColor = Int_t((color+0.99)*Float_t(ncolors)/Float_t(ndivz));
9629 if (theColor > ncolors-1) theColor = ncolors-1;
9630
9631 // Paint the TGraph bins.
9632 if (poly->IsA() == TGraph::Class()) {
9633 TGraph *g = (TGraph*)poly;
9634 g->SetFillColor(gStyle->GetColorPalette(theColor));
9635 g->TAttFill::Modify();
9636 g->Paint("F");
9637 }
9638
9639 // Paint the TMultiGraph bins.
9640 if (poly->IsA() == TMultiGraph::Class()) {
9641 TMultiGraph *mg = (TMultiGraph*)poly;
9642 TList *gl = mg->GetListOfGraphs();
9643 if (!gl) return;
9644 TGraph *g;
9645 TIter nextg(gl);
9646 while ((g = (TGraph*) nextg())) {
9647 g->SetFillColor(gStyle->GetColorPalette(theColor));
9648 g->TAttFill::Modify();
9649 g->Paint("F");
9650 }
9651 }
9652 }
9654}
9655
9656////////////////////////////////////////////////////////////////////////////////
9657/// [Control function to draw a TH2Poly as a scatter plot.](#HP20a)
9658
9660{
9661
9662 //Do not highlight the histogram, if its part was selected.
9663 if (gPad->PadInHighlightMode() && gPad->GetSelected() != fH)
9664 return;
9665
9666 Int_t k, loop, marker=0;
9667 Double_t z, xk,xstep, yk, ystep, xp, yp;
9668 Double_t scale = 1;
9669 Double_t zmin = fH->GetMinimum();
9670 Double_t zmax = fH->GetMaximum();
9671 if (Hoption.Logz) {
9672 if (zmax > 0) {
9673 if (zmin <= 0) zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
9674 zmin = TMath::Log10(zmin);
9675 zmax = TMath::Log10(zmax);
9676 } else {
9677 return;
9678 }
9679 }
9680 Double_t dz = zmax - zmin;
9681 scale = (kNMAX-1)/dz;
9682
9683
9684 // use an independent instance of a random generator
9685 // instead of gRandom to avoid conflicts and
9686 // to get same random numbers when drawing the same histogram
9687 TRandom2 random;
9688
9689 TH2PolyBin *b;
9690
9691 TIter next(((TH2Poly*)fH)->GetBins());
9692 TObject *obj, *poly;
9693
9694 Double_t maxarea = 0, a;
9695 while ((obj=next())) {
9696 b = (TH2PolyBin*)obj;
9697 a = b->GetArea();
9698 if (a>maxarea) maxarea = a;
9699 }
9700
9701 next.Reset();
9702
9703 while ((obj=next())) {
9704 b = (TH2PolyBin*)obj;
9705 poly = b->GetPolygon();
9706 z = b->GetContent();
9707 if (z < zmin) z = zmin;
9708 if (z > zmax) z = zmax;
9709 if (Hoption.Logz) {
9710 if (z > 0) z = TMath::Log10(z) - zmin;
9711 } else {
9712 z -= zmin;
9713 }
9714 k = Int_t((z*scale)*(b->GetArea()/maxarea));
9715 xk = b->GetXMin();
9716 yk = b->GetYMin();
9717 xstep = b->GetXMax()-xk;
9718 ystep = b->GetYMax()-yk;
9719
9720 // Paint the TGraph bins.
9721 if (poly->IsA() == TGraph::Class()) {
9722 TGraph *g = (TGraph*)poly;
9723 if (k <= 0 || z <= 0) continue;
9724 loop = 0;
9725 while (loop<k) {
9726 if (k+marker >= kNMAX) {
9727 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9728 marker=0;
9729 }
9730 xp = (random.Rndm()*xstep) + xk;
9731 yp = (random.Rndm()*ystep) + yk;
9732 if (g->IsInside(xp,yp)) {
9733 fXbuf[marker] = xp;
9734 fYbuf[marker] = yp;
9735 marker++;
9736 loop++;
9737 }
9738 }
9739 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9740 }
9741
9742 // Paint the TMultiGraph bins.
9743 if (poly->IsA() == TMultiGraph::Class()) {
9744 TMultiGraph *mg = (TMultiGraph*)poly;
9745 TList *gl = mg->GetListOfGraphs();
9746 if (!gl) return;
9747 if (k <= 0 || z <= 0) continue;
9748 loop = 0;
9749 while (loop<k) {
9750 if (k+marker >= kNMAX) {
9751 gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9752 marker=0;
9753 }
9754 xp = (random.Rndm()*xstep) + xk;
9755 yp = (random.Rndm()*ystep) + yk;
9756 if (mg->IsInside(xp,yp)) {
9757 fXbuf[marker] = xp;
9758 fYbuf[marker] = yp;
9759 marker++;
9760 loop++;
9761 }
9762 }
9763 if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf);
9764 }
9765 }
9766 PaintTH2PolyBins("l");
9767}
9768
9769////////////////////////////////////////////////////////////////////////////////
9770/// [Control function to draw a TH2Poly as a text plot.](#HP20a)
9771
9773{
9774
9775 TLatex text;
9779
9780 Double_t x, y, z, e, angle = 0;
9781 char value[50];
9782 char format[32];
9783 snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
9784 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9785 Int_t opt = (Int_t)Hoption.Text/1000;
9786
9787 text.SetTextAlign(22);
9788 if (Hoption.Text == 1) angle = 0;
9789 text.SetTextAngle(angle);
9790 text.TAttText::Modify();
9791
9792 TH2PolyBin *b;
9793
9794 TIter next(((TH2Poly*)fH)->GetBins());
9795 TObject *obj, *p;
9796
9797 while ((obj=next())) {
9798 b = (TH2PolyBin*)obj;
9799 p = b->GetPolygon();
9800 x = (b->GetXMin()+b->GetXMax())/2;
9801 if (Hoption.Logx) {
9802 if (x > 0) x = TMath::Log10(x);
9803 else continue;
9804 }
9805 y = (b->GetYMin()+b->GetYMax())/2;
9806 if (Hoption.Logy) {
9807 if (y > 0) y = TMath::Log10(y);
9808 else continue;
9809 }
9810 z = b->GetContent();
9811 if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9812 if (opt==2) {
9813 e = fH->GetBinError(b->GetBinNumber());
9814 snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
9816 "%",gStyle->GetPaintTextFormat());
9817 snprintf(value,50,format,z,e);
9818 } else {
9819 snprintf(value,50,format,z);
9820 }
9821 if (opt==3) text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),p->GetName());
9822 else text.PaintLatex(x,y,angle,0.02*fH->GetMarkerSize(),value);
9823 }
9824
9825 PaintTH2PolyBins("l");
9826}
9827
9828////////////////////////////////////////////////////////////////////////////////
9829/// [Control function to draw a 1D/2D histograms with the bin values.](#HP15)
9830
9832{
9833
9834 TLatex text;
9838
9839 Double_t x, y, z, e, angle = 0;
9840 char value[50];
9841 char format[32];
9842 snprintf(format,32,"%s%s","%",gStyle->GetPaintTextFormat());
9843 if (Hoption.Text >= 1000) angle = Hoption.Text%1000;
9844
9845 // 1D histograms
9846 if (fH->GetDimension() == 1) {
9847 Bool_t getentries = kFALSE;
9848 Double_t yt;
9849 TProfile *hp = (TProfile*)fH;
9850 if (Hoption.Text>2000 && fH->InheritsFrom(TProfile::Class())) {
9851 Hoption.Text = Hoption.Text-2000;
9852 getentries = kTRUE;
9853 }
9854 if (Hoption.Text == 1) angle = 90;
9855 text.SetTextAlign(11);
9856 if (angle == 90) text.SetTextAlign(12);
9857 if (angle == 0) text.SetTextAlign(21);
9858 text.TAttText::Modify();
9859 Double_t dt = 0.02*(gPad->GetY2()-gPad->GetY1());
9860 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9861 if (Hoption.Bar) {
9862 x = fH->GetXaxis()->GetBinLowEdge(i)+
9863 fH->GetXaxis()->GetBinWidth(i)*
9864 (fH->GetBarOffset()+0.5*fH->GetBarWidth());
9865 } else {
9866 x = fH->GetXaxis()->GetBinCenter(i);
9867 }
9868 y = fH->GetBinContent(i);
9869 yt = y;
9870 if (gStyle->GetHistMinimumZero() && y<0) y = 0;
9871 if (getentries) yt = hp->GetBinEntries(i);
9872 if (yt == 0.) continue;
9873 snprintf(value,50,format,yt);
9874 if (Hoption.Logx) {
9875 if (x > 0) x = TMath::Log10(x);
9876 else continue;
9877 }
9878 if (Hoption.Logy) {
9879 if (y > 0) y = TMath::Log10(y);
9880 else continue;
9881 }
9882 if (y >= gPad->GetY2()) continue;
9883 if (y <= gPad->GetY1()) continue;
9884 text.PaintLatex(x,y+0.2*dt,angle,0.02*fH->GetMarkerSize(),value);
9885 }
9886
9887 // 2D histograms
9888 } else {
9889 text.SetTextAlign(22);
9890 if (Hoption.Text == 1) angle = 0;
9891 text.SetTextAngle(angle);
9892 text.TAttText::Modify();
9893 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
9894 y = fYaxis->GetBinCenter(j);
9895 if (Hoption.Logy) {
9896 if (y > 0) y = TMath::Log10(y);
9897 else continue;
9898 }
9899 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
9900 Int_t bin = j*(fXaxis->GetNbins()+2) + i;
9901 x = fXaxis->GetBinCenter(i);
9902 if (Hoption.Logx) {
9903 if (x > 0) x = TMath::Log10(x);
9904 else continue;
9905 }
9906 if (!IsInside(x,y)) continue;
9907 z = fH->GetBinContent(bin);
9908 if (z < Hparam.zmin || (z == 0 && !gStyle->GetHistMinimumZero()) ) continue;
9909 if (Hoption.Text>2000) {
9910 e = fH->GetBinError(bin);
9911 snprintf(format,32,"#splitline{%s%s}{#pm %s%s}",
9913 "%",gStyle->GetPaintTextFormat());
9914 snprintf(value,50,format,z,e);
9915 } else {
9916 snprintf(value,50,format,z);
9917 }
9918 text.PaintLatex(x,y+fH->GetBarOffset()*fYaxis->GetBinWidth(j),
9919 angle,0.02*fH->GetMarkerSize(),value);
9920 }
9921 }
9922 }
9923}
9924
9925////////////////////////////////////////////////////////////////////////////////
9926/// [Control function to draw a 3D implicit functions.](#HP27)
9927
9929{
9930
9931 Int_t irep;
9932
9933 TGaxis *axis = new TGaxis();
9934 TAxis *xaxis = fH->GetXaxis();
9935 TAxis *yaxis = fH->GetYaxis();
9936 TAxis *zaxis = fH->GetZaxis();
9937
9938 fXbuf[0] = xaxis->GetBinLowEdge(xaxis->GetFirst());
9939 fYbuf[0] = xaxis->GetBinUpEdge(xaxis->GetLast());
9940 fXbuf[1] = yaxis->GetBinLowEdge(yaxis->GetFirst());
9941 fYbuf[1] = yaxis->GetBinUpEdge(yaxis->GetLast());
9942 fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst());
9943 fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast());
9944
9946
9947 TView *view = gPad->GetView();
9948 if (!view) {
9949 Error("PaintTF3", "no TView in current pad");
9950 return;
9951 }
9952 Double_t thedeg = 90 - gPad->GetTheta();
9953 Double_t phideg = -90 - gPad->GetPhi();
9954 Double_t psideg = view->GetPsi();
9955 view->SetView(phideg, thedeg, psideg, irep);
9956
9957 fLego->InitMoveScreen(-1.1,1.1);
9958
9959 if (Hoption.BackBox) {
9962 fLego->BackBox(90);
9963 }
9964
9966
9968 fH->GetNbinsY(),
9969 fH->GetNbinsZ(), "BF");
9970
9971 if (Hoption.FrontBox) {
9972 fLego->InitMoveScreen(-1.1,1.1);
9974 fLego->FrontBox(90);
9975 }
9976 if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90);
9977
9978 PaintTitle();
9979
9980 delete axis;
9981 delete fLego; fLego = 0;
9982}
9983
9984////////////////////////////////////////////////////////////////////////////////
9985/// Draw the histogram title
9986///
9987/// The title is drawn according to the title alignment returned by
9988/// `GetTitleAlign()`. It is a 2 digits integer): hv
9989///
9990/// where `h` is the horizontal alignment and `v` is the
9991/// vertical alignment.
9992///
9993/// - `h` can get the values 1 2 3 for left, center, and right
9994/// - `v` can get the values 1 2 3 for bottom, middle and top
9995///
9996/// for instance the default alignment is: 13 (left top)
9997
9999{
10000 // probably best place for calls PaintHighlightBin
10001 // calls after paint histo (1D or 2D) and before paint title and stats
10002 if (!gPad->GetView()) PaintHighlightBin();
10003
10004 if (Hoption.Same) return;
10005 if (fH->TestBit(TH1::kNoTitle)) return;
10006 Int_t nt = strlen(fH->GetTitle());
10007 TPaveText *title = 0;
10008 TObject *obj;
10009 TIter next(gPad->GetListOfPrimitives());
10010 while ((obj = next())) {
10011 if (!obj->InheritsFrom(TPaveText::Class())) continue;
10012 title = (TPaveText*)obj;
10013 if (strcmp(title->GetName(),"title")) {title = 0; continue;}
10014 break;
10015 }
10016 if (nt == 0 || gStyle->GetOptTitle() <= 0) {
10017 if (title) delete title;
10018 return;
10019 }
10020 Double_t ht = gStyle->GetTitleH();
10021 Double_t wt = gStyle->GetTitleW();
10022
10023 if (ht <= 0) {
10024 if (gStyle->GetTitleFont("")%10 == 3) {
10025 Double_t hw = TMath::Max((Double_t)gPad->XtoPixel(gPad->GetX2()),
10026 (Double_t)gPad->YtoPixel(gPad->GetY1()));
10027 ht = 1.1*(gStyle->GetTitleSize("")/hw);
10028 } else {
10029 ht = 1.1*gStyle->GetTitleFontSize();
10030 }
10031 }
10032 if (ht <= 0) ht = 0.05;
10033 if (wt <= 0) {
10034 TLatex l;
10035 l.SetTextSize(ht);
10036 l.SetTitle(fH->GetTitle());
10037 // adjustment in case the title has several lines (#splitline)
10038 ht = TMath::Max(ht, 1.2*l.GetYsize()/(gPad->GetY2() - gPad->GetY1()));
10039 Double_t wndc = l.GetXsize()/(gPad->GetX2() - gPad->GetX1());
10040 wt = TMath::Min(0.7, 0.02+wndc);
10041 }
10042 if (title) {
10043 TText *t0 = (TText*)title->GetLine(0);
10044 if (t0) {
10045 if (!strcmp(t0->GetTitle(),fH->GetTitle())) return;
10046 t0->SetTitle(fH->GetTitle());
10047 if (wt > 0) title->SetX2NDC(title->GetX1NDC()+wt);
10048 }
10049 return;
10050 }
10051
10052 Int_t talh = gStyle->GetTitleAlign()/10;
10053 if (talh < 1) talh = 1; else if (talh > 3) talh = 3;
10054 Int_t talv = gStyle->GetTitleAlign()%10;
10055 if (talv < 1) talv = 1; else if (talv > 3) talv = 3;
10056 Double_t xpos, ypos;
10057 xpos = gStyle->GetTitleX();
10058 ypos = gStyle->GetTitleY();
10059 if (talh == 2) xpos = xpos-wt/2.;
10060 if (talh == 3) xpos = xpos-wt;
10061 if (talv == 2) ypos = ypos+ht/2.;
10062 if (talv == 1) ypos = ypos+ht;
10063
10064 TPaveText *ptitle = new TPaveText(xpos, ypos-ht, xpos+wt, ypos,"blNDC");
10065
10066 // box with the histogram title
10068 ptitle->SetFillStyle(gStyle->GetTitleStyle());
10069 ptitle->SetName("title");
10072 ptitle->SetTextFont(gStyle->GetTitleFont(""));
10073 if (gStyle->GetTitleFont("")%10 > 2)
10075 ptitle->AddText(fH->GetTitle());
10076 ptitle->SetBit(kCanDelete);
10077 ptitle->Draw();
10078 ptitle->Paint();
10079
10080 if(!gPad->IsEditable()) delete ptitle;
10081}
10082
10083////////////////////////////////////////////////////////////////////////////////
10084/// Process message `mess`.
10085
10086void THistPainter::ProcessMessage(const char *mess, const TObject *obj)
10087{
10088
10089 if (!strcmp(mess,"SetF3")) {
10091 } else if (!strcmp(mess,"SetF3ClippingBoxOff")) {
10093 } else if (!strcmp(mess,"SetF3ClippingBoxOn")) {
10094 TVectorD &v = (TVectorD&)(*obj);
10095 Double_t xclip = v(0);
10096 Double_t yclip = v(1);
10097 Double_t zclip = v(2);
10099 }
10100}
10101
10102////////////////////////////////////////////////////////////////////////////////
10103/// Static function.
10104///
10105/// Convert Right Ascension, Declination to X,Y using an AITOFF projection.
10106/// This procedure can be used to create an all-sky map in Galactic
10107/// coordinates with an equal-area Aitoff projection. Output map
10108/// coordinates are zero longitude centered.
10109/// Also called Hammer-Aitoff projection (first presented by Ernst von Hammer in 1892)
10110///
10111/// source: GMT
10112///
10113/// code from Ernst-Jan Buis
10114
10116{
10117
10118 Double_t x, y;
10119
10120 Double_t alpha2 = (l/2)*TMath::DegToRad();
10121 Double_t delta = b*TMath::DegToRad();
10122 Double_t r2 = TMath::Sqrt(2.);
10123 Double_t f = 2*r2/TMath::Pi();
10124 Double_t cdec = TMath::Cos(delta);
10125 Double_t denom = TMath::Sqrt(1. + cdec*TMath::Cos(alpha2));
10126 x = cdec*TMath::Sin(alpha2)*2.*r2/denom;
10127 y = TMath::Sin(delta)*r2/denom;
10128 x *= TMath::RadToDeg()/f;
10129 y *= TMath::RadToDeg()/f;
10130 // x *= -1.; // for a skymap swap left<->right
10131 Al = x;
10132 Ab = y;
10133
10134 return 0;
10135}
10136
10137////////////////////////////////////////////////////////////////////////////////
10138/// Static function
10139///
10140/// Probably the most famous of the various map projections, the Mercator projection
10141/// takes its name from Mercator who presented it in 1569. It is a cylindrical, conformal projection
10142/// with no distortion along the equator.
10143/// The Mercator projection has been used extensively for world maps in which the distortion towards
10144/// the polar regions grows rather large, thus incorrectly giving the impression that, for example,
10145/// Greenland is larger than South America. In reality, the latter is about eight times the size of
10146/// Greenland. Also, the Former Soviet Union looks much bigger than Africa or South America. One may wonder
10147/// whether this illusion has had any influence on U.S. foreign policy.' (Source: GMT)
10148/// code from Ernst-Jan Buis
10149
10151{
10152
10153 Al = l;
10155 Ab = TMath::Log(aid);
10156 return 0;
10157}
10158
10159////////////////////////////////////////////////////////////////////////////////
10160/// Static function code from Ernst-Jan Buis
10161
10163{
10164
10165 Al = l*cos(b*TMath::DegToRad());
10166 Ab = b;
10167 return 0;
10168}
10169
10170////////////////////////////////////////////////////////////////////////////////
10171/// Static function code from Ernst-Jan Buis
10172
10174{
10175
10176 Al = l*(2.*TMath::Cos(2*b*TMath::DegToRad()/3) - 1);
10177 Ab = 180*TMath::Sin(b*TMath::DegToRad()/3);
10178 return 0;
10179}
10180
10181////////////////////////////////////////////////////////////////////////////////
10182/// Recompute the histogram range following graphics operations.
10183
10185{
10186
10187 if (Hoption.Same) return;
10188
10189 // Compute x,y range
10194
10195 Double_t xmin_aid, ymin_aid, xmax_aid, ymax_aid;
10196 if (Hoption.Proj ==1) {
10197 // TODO : check x range not lower than -180 and not higher than 180
10202
10203 if (xmin > xmin_aid) xmin = xmin_aid;
10204 if (ymin > ymin_aid) ymin = ymin_aid;
10205 if (xmax < xmax_aid) xmax = xmax_aid;
10206 if (ymax < ymax_aid) ymax = ymax_aid;
10207 if (Hparam.ymin<0 && Hparam.ymax>0) {
10208 // there is an 'equator', check its range in the plot..
10209 THistPainter::ProjectAitoff2xy(Hparam.xmin*0.9999, 0, xmin_aid, ymin_aid);
10210 THistPainter::ProjectAitoff2xy(Hparam.xmax*0.9999, 0, xmax_aid, ymin_aid);
10211 if (xmin >xmin_aid) xmin = xmin_aid;
10212 if (xmax <xmax_aid) xmax = xmax_aid;
10213 }
10214 if (Hparam.xmin<0 && Hparam.xmax>0) {
10215 THistPainter::ProjectAitoff2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10216 THistPainter::ProjectAitoff2xy(0, Hparam.ymax, xmax_aid, ymax_aid);
10217 if (ymin >ymin_aid) ymin = ymin_aid;
10218 if (ymax <ymax_aid) ymax = ymax_aid;
10219 }
10220 } else if ( Hoption.Proj ==2) {
10221 if (Hparam.ymin <= -90 || Hparam.ymax >=90) {
10222 Warning("Mercator Projection", "Latitude out of range %f or %f", Hparam.ymin, Hparam.ymax);
10223 Hoption.Proj = 0;
10224 } else {
10227 }
10228 } else if (Hoption.Proj == 3) {
10233
10234 if (xmin > xmin_aid) xmin = xmin_aid;
10235 if (ymin > ymin_aid) ymin = ymin_aid;
10236 if (xmax < xmax_aid) xmax = xmax_aid;
10237 if (ymax < ymax_aid) ymax = ymax_aid;
10238 if (Hparam.ymin<0 && Hparam.ymax>0) {
10239 THistPainter::ProjectSinusoidal2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10240 THistPainter::ProjectSinusoidal2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10241 if (xmin >xmin_aid) xmin = xmin_aid;
10242 if (xmax <xmax_aid) xmax = xmax_aid;
10243 }
10244 if (Hparam.xmin<0 && Hparam.xmax>0) {
10245 THistPainter::ProjectSinusoidal2xy(0,Hparam.ymin, xmin_aid, ymin_aid);
10246 THistPainter::ProjectSinusoidal2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10247 if (ymin >ymin_aid) ymin = ymin_aid;
10248 if (ymax <ymax_aid) ymax = ymax_aid;
10249 }
10250 } else if (Hoption.Proj == 4) {
10255
10256 if (xmin > xmin_aid) xmin = xmin_aid;
10257 if (ymin > ymin_aid) ymin = ymin_aid;
10258 if (xmax < xmax_aid) xmax = xmax_aid;
10259 if (ymax < ymax_aid) ymax = ymax_aid;
10260 if (Hparam.ymin<0 && Hparam.ymax>0) {
10261 THistPainter::ProjectParabolic2xy(Hparam.xmin, 0, xmin_aid, ymin_aid);
10262 THistPainter::ProjectParabolic2xy(Hparam.xmax, 0, xmax_aid, ymin_aid);
10263 if (xmin >xmin_aid) xmin = xmin_aid;
10264 if (xmax <xmax_aid) xmax = xmax_aid;
10265 }
10266 if (Hparam.xmin<0 && Hparam.xmax>0) {
10267 THistPainter::ProjectParabolic2xy(0, Hparam.ymin, xmin_aid, ymin_aid);
10268 THistPainter::ProjectParabolic2xy(0, Hparam.ymax, xmax_aid, ymin_aid);
10269 if (ymin >ymin_aid) ymin = ymin_aid;
10270 if (ymax <ymax_aid) ymax = ymax_aid;
10271 }
10272 }
10273 Hparam.xmin= xmin;
10274 Hparam.xmax= xmax;
10275 Hparam.ymin= ymin;
10276 Hparam.ymax= ymax;
10277
10278 Double_t dx = xmax-xmin;
10279 Double_t dy = ymax-ymin;
10280 Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
10281 Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
10282
10283 // Range() could change the size of the pad pixmap and therefore should
10284 // be called before the other paint routines
10285 gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
10286 ymin - dyr*gPad->GetBottomMargin(),
10287 xmax + dxr*gPad->GetRightMargin(),
10288 ymax + dyr*gPad->GetTopMargin());
10289 gPad->RangeAxis(xmin, ymin, xmax, ymax);
10290}
10291
10292////////////////////////////////////////////////////////////////////////////////
10293/// Set current histogram to `h`
10294
10296{
10297
10298 if (h == 0) return;
10299 fH = h;
10300 fXaxis = h->GetXaxis();
10301 fYaxis = h->GetYaxis();
10302 fZaxis = h->GetZaxis();
10304}
10305
10306////////////////////////////////////////////////////////////////////////////////
10307/// Initialize various options to draw 2D histograms.
10308
10310{
10311
10312 static const char *where = "TableInit";
10313
10314 Int_t first, last;
10315 Double_t yMARGIN= gStyle->GetHistTopMargin();
10316 Double_t zmin, zmax;
10317 Int_t maximum = 0;
10318 Int_t minimum = 0;
10319 if (fH->GetMaximumStored() != -1111) maximum = 1;
10320 if (fH->GetMinimumStored() != -1111) minimum = 1;
10321
10322 // ----------------- Compute X axis parameters
10323 first = fXaxis->GetFirst();
10324 last = fXaxis->GetLast();
10325 Hparam.xlast = last;
10331
10332 // if log scale in X, replace xmin,max by the log
10333 if (Hoption.Logx) {
10334 // find the first edge of a bin that is > 0
10335 if (Hparam.xlowedge <=0 ) {
10338 }
10339 if (Hparam.xmin <=0 || Hparam.xmax <=0) {
10340 Error(where, "cannot set X axis to log scale");
10341 return 0;
10342 }
10346 if (Hparam.xlast > last) Hparam.xlast = last;
10349 }
10350
10351 // ----------------- Compute Y axis parameters
10352 first = fYaxis->GetFirst();
10353 last = fYaxis->GetLast();
10354 Hparam.ylast = last;
10358 if (!Hparam.ybinsize) Hparam.ybinsize = 1;
10361
10362 // if log scale in Y, replace ymin,max by the log
10363 if (Hoption.Logy) {
10364 if (Hparam.ylowedge <=0 ) {
10367 }
10368 if (Hparam.ymin <=0 || Hparam.ymax <=0) {
10369 Error(where, "cannot set Y axis to log scale");
10370 return 0;
10371 }
10375 if (Hparam.ylast > last) Hparam.ylast = last;
10378 }
10379
10380
10381 // ----------------- Compute Z axis parameters
10382 Double_t bigp = TMath::Power(10,32);
10383 zmax = -bigp;
10384 zmin = bigp;
10385 Double_t c1, e1;
10386 Double_t allchan = 0;
10387 for (Int_t j=Hparam.yfirst; j<=Hparam.ylast;j++) {
10388 for (Int_t i=Hparam.xfirst; i<=Hparam.xlast;i++) {
10389 c1 = fH->GetBinContent(i,j);
10390 zmax = TMath::Max(zmax,c1);
10391 if (Hoption.Error) {
10392 e1 = fH->GetBinError(i,j);
10393 zmax = TMath::Max(zmax,c1+e1);
10394 }
10395 zmin = TMath::Min(zmin,c1);
10396 allchan += c1;
10397 }
10398 }
10399
10400 // Take into account maximum , minimum
10401
10402 if (maximum) zmax = fH->GetMaximumStored();
10403 if (minimum) zmin = fH->GetMinimumStored();
10404 if (Hoption.Logz && zmax < 0) {
10405 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10406 return 0;
10407 } else if (Hoption.Logz && zmin>=0 && zmax==0) { // empty histogram in log scale
10408 zmin = 0.01;
10409 zmax = 10.;
10410 }
10411 if (zmin >= zmax) {
10412 if (Hoption.Logz) {
10413 if (zmax > 0) zmin = 0.001*zmax;
10414 else {
10415 if (!Hoption.Same) Error(where, "log scale is requested but maximum is less or equal 0 (%f)", zmax);
10416 return 0;
10417 }
10418 }
10419 }
10420
10421 // take into account normalization factor
10422 Hparam.allchan = allchan;
10423 Double_t factor = allchan;
10424 if (fH->GetNormFactor() > 0) factor = fH->GetNormFactor();
10425 if (allchan) factor /= allchan;
10426 if (factor == 0) factor = 1;
10427 Hparam.factor = factor;
10428 zmax = factor*zmax;
10429 zmin = factor*zmin;
10430 c1 = zmax;
10431 if (TMath::Abs(zmin) > TMath::Abs(c1)) c1 = zmin;
10432
10433 // For log scales, histogram coordinates are log10(ymin) and
10434 // log10(ymax). Final adjustment (if not option "Same")
10435 // or "+" for ymax) of ymax and ymin for logarithmic scale, if
10436 // Maximum and Minimum are not defined.
10437 if (Hoption.Logz) {
10438 if (zmin <= 0) {
10439 zmin = TMath::Min((Double_t)1, (Double_t)0.001*zmax);
10440 fH->SetMinimum(zmin);
10441 }
10442 zmin = TMath::Log10(zmin);
10443 if (!minimum) zmin += TMath::Log10(0.5);
10444 zmax = TMath::Log10(zmax);
10445 if (!maximum) zmax += TMath::Log10(2*(0.9/0.95));
10446 goto LZMIN;
10447 }
10448
10449 // final adjustment of YMAXI for linear scale (if not option "Same"):
10450 // decrease histogram height to MAX% of allowed height if HMAXIM
10451 // has not been called.
10452 // MAX% is the value in percent which has been set in HPLSET
10453 // (default is 90%).
10454 if (!maximum) {
10455 zmax += yMARGIN*(zmax-zmin);
10456 }
10457
10458 // final adjustment of ymin for linear scale.
10459 // if minimum is not set , then ymin is set to zero if >0
10460 // or to ymin - yMARGIN if <0.
10461 if (!minimum) {
10462 if (gStyle->GetHistMinimumZero()) {
10463 if (zmin >= 0) zmin = 0;
10464 else zmin -= yMARGIN*(zmax-zmin);
10465 } else {
10466 Double_t dzmin = yMARGIN*(zmax-zmin);
10467 if (zmin >= 0 && (zmin-dzmin <= 0)) zmin = 0;
10468 else zmin -= dzmin;
10469 }
10470 }
10471
10472LZMIN:
10473 Hparam.zmin = zmin;
10474 Hparam.zmax = zmax;
10475
10476 // Set bar offset and width
10479
10480 return 1;
10481}
10482
10483////////////////////////////////////////////////////////////////////////////////
10484/// This function returns the best format to print the error value (e)
10485/// knowing the parameter value (v) and the format (f) used to print it.
10486
10488{
10489
10490 static char ef[20];
10491 char tf[20], tv[64];
10492
10493 // print v with the format f in tv.
10494 snprintf(tf,20,"%s%s","%",f);
10495 snprintf(tv,64,tf,v);
10496
10497 // Analyse tv.
10498 TString sv = tv;
10499 int ie = sv.Index("e");
10500 int iE = sv.Index("E");
10501 int id = sv.Index(".");
10502
10503 // v has been printed with the exponent notation.
10504 // There is 2 cases, the exponent is positive or negative
10505 if (ie >= 0 || iE >= 0) {
10506 if (sv.Index("+") >= 0) {
10507 if (e < 1) {
10508 snprintf(ef,20,"%s.1f","%");
10509 } else {
10510 if (ie >= 0) {
10511 snprintf(ef,20,"%s.%de","%",ie-id-1);
10512 } else {
10513 snprintf(ef,20,"%s.%dE","%",iE-id-1);
10514 }
10515 }
10516 } else {
10517 if (ie >= 0) {
10518 snprintf(ef,20,"%s.%de","%",ie-id-1);
10519 } else {
10520 snprintf(ef,20,"%s.%dE","%",iE-id-1);
10521 }
10522 }
10523
10524 // There is not '.' in tv. e will be printed with one decimal digit.
10525 } else if (id < 0) {
10526 snprintf(ef,20,"%s.1f","%");
10527
10528 // There is a '.' in tv and no exponent notation. e's decimal part will
10529 // have the same number of digits as v's one.
10530 } else {
10531 snprintf(ef,20,"%s.%df","%",sv.Length()-id-1);
10532 }
10533
10534 return ef;
10535}
10536
10537////////////////////////////////////////////////////////////////////////////////
10538/// Set projection.
10539
10540void THistPainter::SetShowProjection(const char *option,Int_t nbins)
10541{
10542
10543 if (fShowProjection) return;
10544 TString opt = option;
10545 opt.ToLower();
10546 Int_t projection = 0;
10547 if (opt.Contains("x")) projection = 1;
10548 if (opt.Contains("y")) projection = 2;
10549 if (opt.Contains("z")) projection = 3;
10550 if (opt.Contains("xy")) projection = 4;
10551 if (opt.Contains("yx")) projection = 5;
10552 if (opt.Contains("xz")) projection = 6;
10553 if (opt.Contains("zx")) projection = 7;
10554 if (opt.Contains("yz")) projection = 8;
10555 if (opt.Contains("zy")) projection = 9;
10556 if (projection < 4) fShowOption = option+1;
10557 else fShowOption = option+2;
10558 fShowProjection = projection+100*nbins;
10559 gROOT->MakeDefCanvas();
10560 gPad->SetName(Form("c_%lx_projection_%d", (ULong_t)fH, fShowProjection));
10561 gPad->SetGrid();
10562}
10563
10564////////////////////////////////////////////////////////////////////////////////
10565/// Show projection onto X.
10566
10568{
10569
10570 Int_t nbins = (Int_t)fShowProjection/100;
10571 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10572 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10573
10574 // Erase old position and draw a line at current position
10575 static int pyold1 = 0;
10576 static int pyold2 = 0;
10577 float uxmin = gPad->GetUxmin();
10578 float uxmax = gPad->GetUxmax();
10579 int pxmin = gPad->XtoAbsPixel(uxmin);
10580 int pxmax = gPad->XtoAbsPixel(uxmax);
10581 Float_t upy = gPad->AbsPixeltoY(py);
10582 Float_t y = gPad->PadtoY(upy);
10583 Int_t biny1 = fH->GetYaxis()->FindBin(y);
10584 Int_t biny2 = TMath::Min(biny1+nbins-1, fH->GetYaxis()->GetNbins());
10585 Int_t py1 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinLowEdge(biny1));
10586 Int_t py2 = gPad->YtoAbsPixel(fH->GetYaxis()->GetBinUpEdge(biny2));
10587
10588 if (pyold1 || pyold2) gVirtualX->DrawBox(pxmin,pyold1,pxmax,pyold2,TVirtualX::kFilled);
10589 gVirtualX->DrawBox(pxmin,py1,pxmax,py2,TVirtualX::kFilled);
10590 pyold1 = py1;
10591 pyold2 = py2;
10592
10593 // Create or set the new canvas proj x
10594 TVirtualPad *padsav = gPad;
10595 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10597 if (c) {
10598 c->Clear();
10599 } else {
10600 fShowProjection = 0;
10601 pyold1 = 0;
10602 pyold2 = 0;
10603 return;
10604 }
10605 c->cd();
10606 c->SetLogy(padsav->GetLogz());
10607 c->SetLogx(padsav->GetLogx());
10608
10609 // Draw slice corresponding to mouse position
10610 TString prjName = TString::Format("slice_px_of_%s",fH->GetName());
10611 TH1D *hp = ((TH2*)fH)->ProjectionX(prjName, biny1, biny2);
10612 if (hp) {
10613 hp->SetFillColor(38);
10614 // apply a patch from Oliver Freyermuth to set the title in the projection
10615 // using the range of the projected Y values
10616 if (biny1 == biny2) {
10617 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10618 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny1);
10619 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10620 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10621 if (fH->GetYaxis()->GetLabels() != NULL) {
10622 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf] %s", biny1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetYaxis()->GetBinLabel(biny1)));
10623 } else {
10624 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.*lf..%.*lf]", biny1, valuePrecision, valueFrom, valuePrecision, valueTo));
10625 }
10626 } else {
10627 Double_t valueFrom = fH->GetYaxis()->GetBinLowEdge(biny1);
10628 Double_t valueTo = fH->GetYaxis()->GetBinUpEdge(biny2);
10629 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10630 // biny1 is used here to get equal precision no matter how large the binrange is,
10631 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10632 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetYaxis()->GetBinUpEdge(biny1)-valueFrom))+1;
10633 if (fH->GetYaxis()->GetLabels() != NULL) {
10634 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)));
10635 } else {
10636 hp->SetTitle(TString::Format("ProjectionX of biny=[%d,%d] [y=%.*lf..%.*lf]", biny1, biny2, valuePrecision, valueFrom, valuePrecision, valueTo));
10637 }
10638 }
10639 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10640 hp->SetYTitle("Number of Entries");
10641 hp->Draw();
10642 c->Update();
10643 padsav->cd();
10644 }
10645}
10646
10647////////////////////////////////////////////////////////////////////////////////
10648/// Show projection onto Y.
10649
10651{
10652
10653 Int_t nbins = (Int_t)fShowProjection/100;
10654 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10655 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10656
10657 // Erase old position and draw a line at current position
10658 static int pxold1 = 0;
10659 static int pxold2 = 0;
10660 float uymin = gPad->GetUymin();
10661 float uymax = gPad->GetUymax();
10662 int pymin = gPad->YtoAbsPixel(uymin);
10663 int pymax = gPad->YtoAbsPixel(uymax);
10664 Float_t upx = gPad->AbsPixeltoX(px);
10665 Float_t x = gPad->PadtoX(upx);
10666 Int_t binx1 = fH->GetXaxis()->FindBin(x);
10667 Int_t binx2 = TMath::Min(binx1+nbins-1, fH->GetXaxis()->GetNbins());
10668 Int_t px1 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinLowEdge(binx1));
10669 Int_t px2 = gPad->XtoAbsPixel(fH->GetXaxis()->GetBinUpEdge(binx2));
10670
10671 if (pxold1 || pxold2) gVirtualX->DrawBox(pxold1,pymin,pxold2,pymax,TVirtualX::kFilled);
10672 gVirtualX->DrawBox(px1,pymin,px2,pymax,TVirtualX::kFilled);
10673 pxold1 = px1;
10674 pxold2 = px2;
10675
10676 // Create or set the new canvas proj y
10677 TVirtualPad *padsav = gPad;
10678 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10680 if (c) {
10681 c->Clear();
10682 } else {
10683 fShowProjection = 0;
10684 pxold1 = 0;
10685 pxold2 = 0;
10686 return;
10687 }
10688 c->cd();
10689 c->SetLogy(padsav->GetLogz());
10690 c->SetLogx(padsav->GetLogy());
10691
10692 // Draw slice corresponding to mouse position
10693 TString prjName = TString::Format("slice_py_of_%s",fH->GetName());
10694 TH1D *hp = ((TH2*)fH)->ProjectionY(prjName, binx1, binx2);
10695 if (hp) {
10696 hp->SetFillColor(38);
10697 // apply a patch from Oliver Freyermuth to set the title in the projection
10698 // using the range of the projected X values
10699 if (binx1 == binx2) {
10700 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10701 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx1);
10702 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10703 Int_t valuePrecision = -TMath::Nint(TMath::Log10(valueTo-valueFrom))+1;
10704 if (fH->GetXaxis()->GetLabels() != NULL) {
10705 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf] [%s]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo, fH->GetXaxis()->GetBinLabel(binx1)));
10706 } else {
10707 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.*lf..%.*lf]", binx1, valuePrecision, valueFrom, valuePrecision, valueTo));
10708 }
10709 } else {
10710 Double_t valueFrom = fH->GetXaxis()->GetBinLowEdge(binx1);
10711 Double_t valueTo = fH->GetXaxis()->GetBinUpEdge(binx2);
10712 // Limit precision to 1 digit more than the difference between upper and lower bound (to also catch 121.5-120.5).
10713 // binx1 is used here to get equal precision no matter how large the binrange is,
10714 // otherwise precision may change when moving the mouse to the histogram boundaries (limiting effective binrange).
10715 Int_t valuePrecision = -TMath::Nint(TMath::Log10(fH->GetXaxis()->GetBinUpEdge(binx1)-valueFrom))+1;
10716 if (fH->GetXaxis()->GetLabels() != NULL) {
10717 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)));
10718 } else {
10719 hp->SetTitle(TString::Format("ProjectionY of binx=[%d,%d] [x=%.*lf..%.*lf]", binx1, binx2, valuePrecision, valueFrom, valuePrecision, valueTo));
10720 }
10721 }
10722 hp->SetXTitle(fH->GetYaxis()->GetTitle());
10723 hp->SetYTitle("Number of Entries");
10724 hp->Draw();
10725 c->Update();
10726 padsav->cd();
10727 }
10728}
10729
10730////////////////////////////////////////////////////////////////////////////////
10731/// Show projection (specified by `fShowProjection`) of a `TH3`.
10732/// The drawing option for the projection is in `fShowOption`.
10733///
10734/// First implementation; R.Brun
10735///
10736/// Full implementation: Tim Tran (timtran@jlab.org) April 2006
10737
10739{
10740
10741 Int_t nbins=(Int_t)fShowProjection/100; //decode nbins
10742 if (fH->GetDimension() < 3) {
10743 if (fShowProjection%100 == 1) {ShowProjectionX(px,py); return;}
10744 if (fShowProjection%100 == 2) {ShowProjectionY(px,py); return;}
10745 }
10746
10747 gPad->SetDoubleBuffer(0); // turn off double buffer mode
10748 gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode
10749
10750 // Erase old position and draw a line at current position
10751 TView *view = gPad->GetView();
10752 if (!view) return;
10753 TH3 *h3 = (TH3*)fH;
10754 TAxis *xaxis = h3->GetXaxis();
10755 TAxis *yaxis = h3->GetYaxis();
10756 TAxis *zaxis = h3->GetZaxis();
10757 Double_t u[3],xx[3];
10758
10759 static TPoint line1[2];//store end points of a line, initialised 0 by default
10760 static TPoint line2[2];// second line when slice thickness > 1 bin thickness
10761 static TPoint line3[2];
10762 static TPoint line4[2];
10763 static TPoint endface1[5];
10764 static TPoint endface2[5];
10765 static TPoint rect1[5];//store vertices of the polyline (rectangle), initialsed 0 by default
10766 static TPoint rect2[5];// second rectangle when slice thickness > 1 bin thickness
10767
10768 Double_t uxmin = gPad->GetUxmin();
10769 Double_t uxmax = gPad->GetUxmax();
10770 Double_t uymin = gPad->GetUymin();
10771 Double_t uymax = gPad->GetUymax();
10772
10773 int pxmin = gPad->XtoAbsPixel(uxmin);
10774 int pxmax = gPad->XtoAbsPixel(uxmax);
10775 if (pxmin==pxmax) return;
10776 int pymin = gPad->YtoAbsPixel(uymin);
10777 int pymax = gPad->YtoAbsPixel(uymax);
10778 if (pymin==pymax) return;
10779 Double_t cx = (pxmax-pxmin)/(uxmax-uxmin);
10780 Double_t cy = (pymax-pymin)/(uymax-uymin);
10781 TVirtualPad *padsav = gPad;
10782 TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%lx_projection_%d",
10784 if (!c) {
10785 fShowProjection = 0;
10786 return;
10787 }
10788
10789 switch ((Int_t)fShowProjection%100) {
10790 case 1:
10791 // "x"
10792 {
10793 Int_t firstY = yaxis->GetFirst();
10794 Int_t lastY = yaxis->GetLast();
10795 Int_t biny = firstY + Int_t((lastY-firstY)*(px-pxmin)/(pxmax-pxmin));
10796 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
10797 yaxis->SetRange(biny,biny2);
10798 Int_t firstZ = zaxis->GetFirst();
10799 Int_t lastZ = zaxis->GetLast();
10800 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10801 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10802 zaxis->SetRange(binz,binz2);
10803 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10804 if (nbins>1 && line1[0].GetX()) {
10805 gVirtualX->DrawPolyLine(2,line2);
10806 gVirtualX->DrawPolyLine(2,line3);
10807 gVirtualX->DrawPolyLine(2,line4);
10808 gVirtualX->DrawPolyLine(5,endface1);
10809 gVirtualX->DrawPolyLine(5,endface2);
10810 }
10811 xx[0] = xaxis->GetXmin();
10812 xx[2] = zaxis->GetBinCenter(binz);
10813 xx[1] = yaxis->GetBinCenter(biny);
10814 view->WCtoNDC(xx,u);
10815 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10816 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10817 xx[0] = xaxis->GetXmax();
10818 view->WCtoNDC(xx,u);
10819 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10820 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10821 gVirtualX->DrawPolyLine(2,line1);
10822 if (nbins>1) {
10823 xx[0] = xaxis->GetXmin();
10824 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10825 xx[1] = yaxis->GetBinCenter(biny);
10826 view->WCtoNDC(xx,u);
10827 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10828 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10829 xx[0] = xaxis->GetXmax();
10830 view->WCtoNDC(xx,u);
10831 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10832 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10833
10834 xx[0] = xaxis->GetXmin();
10835 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10836 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10837 view->WCtoNDC(xx,u);
10838 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10839 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10840 xx[0] = xaxis->GetXmax();
10841 view->WCtoNDC(xx,u);
10842 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10843 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10844
10845 xx[0] = xaxis->GetXmin();
10846 xx[2] = zaxis->GetBinCenter(binz);
10847 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
10848 view->WCtoNDC(xx,u);
10849 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10850 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10851 xx[0] = xaxis->GetXmax();
10852 view->WCtoNDC(xx,u);
10853 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10854 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10855
10856 endface1[0].SetX(line1[0].GetX());
10857 endface1[0].SetY(line1[0].GetY());
10858 endface1[1].SetX(line2[0].GetX());
10859 endface1[1].SetY(line2[0].GetY());
10860 endface1[2].SetX(line3[0].GetX());
10861 endface1[2].SetY(line3[0].GetY());
10862 endface1[3].SetX(line4[0].GetX());
10863 endface1[3].SetY(line4[0].GetY());
10864 endface1[4].SetX(line1[0].GetX());
10865 endface1[4].SetY(line1[0].GetY());
10866
10867 endface2[0].SetX(line1[1].GetX());
10868 endface2[0].SetY(line1[1].GetY());
10869 endface2[1].SetX(line2[1].GetX());
10870 endface2[1].SetY(line2[1].GetY());
10871 endface2[2].SetX(line3[1].GetX());
10872 endface2[2].SetY(line3[1].GetY());
10873 endface2[3].SetX(line4[1].GetX());
10874 endface2[3].SetY(line4[1].GetY());
10875 endface2[4].SetX(line1[1].GetX());
10876 endface2[4].SetY(line1[1].GetY());
10877
10878 gVirtualX->DrawPolyLine(2,line2);
10879 gVirtualX->DrawPolyLine(2,line3);
10880 gVirtualX->DrawPolyLine(2,line4);
10881 gVirtualX->DrawPolyLine(5,endface1);
10882 gVirtualX->DrawPolyLine(5,endface2);
10883 }
10884 c->Clear();
10885 c->cd();
10886 TH1 *hp = h3->Project3D("x");
10887 yaxis->SetRange(firstY,lastY);
10888 zaxis->SetRange(firstZ,lastZ);
10889 if (hp) {
10890 hp->SetFillColor(38);
10891 if (nbins == 1)
10892 hp->SetTitle(TString::Format("ProjectionX of biny=%d [y=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny),
10893 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
10894 else {
10895 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),
10896 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
10897 }
10898 hp->SetXTitle(fH->GetXaxis()->GetTitle());
10899 hp->SetYTitle("Number of Entries");
10900 hp->Draw(fShowOption.Data());
10901 }
10902 }
10903 break;
10904
10905 case 2:
10906 // "y"
10907 {
10908 Int_t firstX = xaxis->GetFirst();
10909 Int_t lastX = xaxis->GetLast();
10910 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
10911 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
10912 xaxis->SetRange(binx,binx2);
10913 Int_t firstZ = zaxis->GetFirst();
10914 Int_t lastZ = zaxis->GetLast();
10915 Int_t binz = firstZ + Int_t((lastZ-firstZ)*(py-pymin)/(pymax-pymin));
10916 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
10917 zaxis->SetRange(binz,binz2);
10918 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
10919 if (nbins>1 && line1[0].GetX()) {
10920 gVirtualX->DrawPolyLine(2,line2);
10921 gVirtualX->DrawPolyLine(2,line3);
10922 gVirtualX->DrawPolyLine(2,line4);
10923 gVirtualX->DrawPolyLine(5,endface1);
10924 gVirtualX->DrawPolyLine(5,endface2);
10925 }
10926 xx[0]=xaxis->GetBinCenter(binx);
10927 xx[2] = zaxis->GetBinCenter(binz);
10928 xx[1] = yaxis->GetXmin();
10929 view->WCtoNDC(xx,u);
10930 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10931 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10932 xx[1] = yaxis->GetXmax();
10933 view->WCtoNDC(xx,u);
10934 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10935 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10936 gVirtualX->DrawPolyLine(2,line1);
10937 if (nbins>1) {
10938 xx[1] = yaxis->GetXmin();
10939 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10940 xx[0] = xaxis->GetBinCenter(binx);
10941 view->WCtoNDC(xx,u);
10942 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10943 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10944 xx[1] = yaxis->GetXmax();
10945 view->WCtoNDC(xx,u);
10946 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10947 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10948
10949 xx[1] = yaxis->GetXmin();
10950 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
10951 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10952 view->WCtoNDC(xx,u);
10953 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10954 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10955 xx[1] = yaxis->GetXmax();
10956 view->WCtoNDC(xx,u);
10957 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10958 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10959
10960 xx[1] = yaxis->GetXmin();
10961 xx[2] = zaxis->GetBinCenter(binz);
10962 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
10963 view->WCtoNDC(xx,u);
10964 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10965 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
10966 xx[1] = yaxis->GetXmax();
10967 view->WCtoNDC(xx,u);
10968 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
10969 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
10970
10971 endface1[0].SetX(line1[0].GetX());
10972 endface1[0].SetY(line1[0].GetY());
10973 endface1[1].SetX(line2[0].GetX());
10974 endface1[1].SetY(line2[0].GetY());
10975 endface1[2].SetX(line3[0].GetX());
10976 endface1[2].SetY(line3[0].GetY());
10977 endface1[3].SetX(line4[0].GetX());
10978 endface1[3].SetY(line4[0].GetY());
10979 endface1[4].SetX(line1[0].GetX());
10980 endface1[4].SetY(line1[0].GetY());
10981
10982 endface2[0].SetX(line1[1].GetX());
10983 endface2[0].SetY(line1[1].GetY());
10984 endface2[1].SetX(line2[1].GetX());
10985 endface2[1].SetY(line2[1].GetY());
10986 endface2[2].SetX(line3[1].GetX());
10987 endface2[2].SetY(line3[1].GetY());
10988 endface2[3].SetX(line4[1].GetX());
10989 endface2[3].SetY(line4[1].GetY());
10990 endface2[4].SetX(line1[1].GetX());
10991 endface2[4].SetY(line1[1].GetY());
10992
10993 gVirtualX->DrawPolyLine(2,line2);
10994 gVirtualX->DrawPolyLine(2,line3);
10995 gVirtualX->DrawPolyLine(2,line4);
10996 gVirtualX->DrawPolyLine(5,endface1);
10997 gVirtualX->DrawPolyLine(5,endface2);
10998 }
10999 c->Clear();
11000 c->cd();
11001 TH1 *hp = h3->Project3D("y");
11002 xaxis->SetRange(firstX,lastX);
11003 zaxis->SetRange(firstZ,lastZ);
11004 if (hp) {
11005 hp->SetFillColor(38);
11006 if (nbins == 1)
11007 hp->SetTitle(TString::Format("ProjectionY of binx=%d [x=%.1f..%.1f] binz=%d [z=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11008 binz, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz)));
11009 else
11010 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),
11011 binz, binz2, zaxis->GetBinLowEdge(binz), zaxis->GetBinUpEdge(binz2) ) );
11012 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11013 hp->SetYTitle("Number of Entries");
11014 hp->Draw(fShowOption.Data());
11015 }
11016 }
11017 break;
11018
11019 case 3:
11020 // "z"
11021 {
11022 Int_t firstX = xaxis->GetFirst();
11023 Int_t lastX = xaxis->GetLast();
11024 Int_t binx = firstX + Int_t((lastX-firstX)*(px-pxmin)/(pxmax-pxmin));
11025 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11026 xaxis->SetRange(binx,binx2);
11027 Int_t firstY = yaxis->GetFirst();
11028 Int_t lastY = yaxis->GetLast();
11029 Int_t biny = firstY + Int_t((lastY-firstY)*(py-pymin)/(pymax-pymin));
11030 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11031 yaxis->SetRange(biny,biny2);
11032 if (line1[0].GetX()) gVirtualX->DrawPolyLine(2,line1);
11033 if (nbins>1 && line1[0].GetX()) {
11034 gVirtualX->DrawPolyLine(2,line2);
11035 gVirtualX->DrawPolyLine(2,line3);
11036 gVirtualX->DrawPolyLine(2,line4);
11037 gVirtualX->DrawPolyLine(5,endface1);
11038 gVirtualX->DrawPolyLine(5,endface2);
11039 }
11040 xx[0] = xaxis->GetBinCenter(binx);
11041 xx[1] = yaxis->GetBinCenter(biny);
11042 xx[2] = zaxis->GetXmin();
11043 view->WCtoNDC(xx,u);
11044 line1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11045 line1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11046 xx[2] = zaxis->GetXmax();
11047 view->WCtoNDC(xx,u);
11048 line1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11049 line1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11050 gVirtualX->DrawPolyLine(2,line1);
11051 if (nbins>1) {
11052 xx[2] = zaxis->GetXmin();
11053 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11054 xx[0] = xaxis->GetBinCenter(binx);
11055 view->WCtoNDC(xx,u);
11056 line2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11057 line2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11058 xx[2] = zaxis->GetXmax();
11059 view->WCtoNDC(xx,u);
11060 line2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11061 line2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11062
11063 xx[2] = zaxis->GetXmin();
11064 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11065 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11066 view->WCtoNDC(xx,u);
11067 line3[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11068 line3[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11069 xx[2] = zaxis->GetXmax();
11070 view->WCtoNDC(xx,u);
11071 line3[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11072 line3[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11073
11074 xx[2] = zaxis->GetXmin();
11075 xx[1] = yaxis->GetBinCenter(biny);
11076 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11077 view->WCtoNDC(xx,u);
11078 line4[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11079 line4[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11080 xx[2] = zaxis->GetXmax();
11081 view->WCtoNDC(xx,u);
11082 line4[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11083 line4[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11084
11085 endface1[0].SetX(line1[0].GetX());
11086 endface1[0].SetY(line1[0].GetY());
11087 endface1[1].SetX(line2[0].GetX());
11088 endface1[1].SetY(line2[0].GetY());
11089 endface1[2].SetX(line3[0].GetX());
11090 endface1[2].SetY(line3[0].GetY());
11091 endface1[3].SetX(line4[0].GetX());
11092 endface1[3].SetY(line4[0].GetY());
11093 endface1[4].SetX(line1[0].GetX());
11094 endface1[4].SetY(line1[0].GetY());
11095
11096 endface2[0].SetX(line1[1].GetX());
11097 endface2[0].SetY(line1[1].GetY());
11098 endface2[1].SetX(line2[1].GetX());
11099 endface2[1].SetY(line2[1].GetY());
11100 endface2[2].SetX(line3[1].GetX());
11101 endface2[2].SetY(line3[1].GetY());
11102 endface2[3].SetX(line4[1].GetX());
11103 endface2[3].SetY(line4[1].GetY());
11104 endface2[4].SetX(line1[1].GetX());
11105 endface2[4].SetY(line1[1].GetY());
11106
11107 gVirtualX->DrawPolyLine(2,line2);
11108 gVirtualX->DrawPolyLine(2,line3);
11109 gVirtualX->DrawPolyLine(2,line4);
11110 gVirtualX->DrawPolyLine(5,endface1);
11111 gVirtualX->DrawPolyLine(5,endface2);
11112 }
11113 c->Clear();
11114 c->cd();
11115 TH1 *hp = h3->Project3D("z");
11116 xaxis->SetRange(firstX,lastX);
11117 yaxis->SetRange(firstY,lastY);
11118 if (hp) {
11119 hp->SetFillColor(38);
11120 if (nbins == 1)
11121 hp->SetTitle(TString::Format("ProjectionZ of binx=%d [x=%.1f..%.1f] biny=%d [y=%.1f..%.1f]", binx, xaxis->GetBinLowEdge(binx), xaxis->GetBinUpEdge(binx),
11122 biny, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny)));
11123 else
11124 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),
11125 biny, biny2, yaxis->GetBinLowEdge(biny), yaxis->GetBinUpEdge(biny2) ) );
11126 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11127 hp->SetYTitle("Number of Entries");
11128 hp->Draw(fShowOption.Data());
11129 }
11130 }
11131 break;
11132
11133 case 4:
11134 // "xy"
11135 {
11136 Int_t first = zaxis->GetFirst();
11137 Int_t last = zaxis->GetLast();
11138 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11139 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11140 zaxis->SetRange(binz,binz2);
11141 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11142 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11143 xx[0] = xaxis->GetXmin();
11144 xx[1] = yaxis->GetXmax();
11145 xx[2] = zaxis->GetBinCenter(binz);
11146 view->WCtoNDC(xx,u);
11147 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11148 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11149 rect1[4].SetX(rect1[0].GetX());
11150 rect1[4].SetY(rect1[0].GetY());
11151 xx[0] = xaxis->GetXmax();
11152 view->WCtoNDC(xx,u);
11153 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11154 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11155 xx[1] = yaxis->GetXmin();
11156 view->WCtoNDC(xx,u);
11157 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11158 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11159 xx[0] = xaxis->GetXmin();
11160 view->WCtoNDC(xx,u);
11161 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11162 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11163 gVirtualX->DrawPolyLine(5,rect1);
11164 if (nbins>1) {
11165 xx[0] = xaxis->GetXmin();
11166 xx[1] = yaxis->GetXmax();
11167 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11168 view->WCtoNDC(xx,u);
11169 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11170 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11171 rect2[4].SetX(rect2[0].GetX());
11172 rect2[4].SetY(rect2[0].GetY());
11173 xx[0] = xaxis->GetXmax();
11174 view->WCtoNDC(xx,u);
11175 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11176 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11177 xx[1] = yaxis->GetXmin();
11178 view->WCtoNDC(xx,u);
11179 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11180 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11181 xx[0] = xaxis->GetXmin();
11182 view->WCtoNDC(xx,u);
11183 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11184 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11185 gVirtualX->DrawPolyLine(5,rect2);
11186 }
11187
11188 c->Clear();
11189 c->cd();
11190 TH2 *hp = (TH2*)h3->Project3D("xy");
11191 zaxis->SetRange(first,last);
11192 if (hp) {
11193 hp->SetFillColor(38);
11194 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXY of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11195 else hp->SetTitle(TString::Format("ProjectionXY, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11196 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11197 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11198 hp->SetZTitle("Number of Entries");
11199 hp->Draw(fShowOption.Data());
11200 }
11201 }
11202 break;
11203
11204 case 5:
11205 // "yx"
11206 {
11207 Int_t first = zaxis->GetFirst();
11208 Int_t last = zaxis->GetLast();
11209 Int_t binz = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11210 Int_t binz2 = TMath::Min(binz+nbins-1,zaxis->GetNbins() );
11211 zaxis->SetRange(binz,binz2);
11212 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11213 if (nbins>1 && rect2[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11214 xx[0] = xaxis->GetXmin();
11215 xx[1] = yaxis->GetXmax();
11216 xx[2] = zaxis->GetBinCenter(binz);
11217 view->WCtoNDC(xx,u);
11218 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11219 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11220 rect1[4].SetX(rect1[0].GetX());
11221 rect1[4].SetY(rect1[0].GetY());
11222 xx[0] = xaxis->GetXmax();
11223 view->WCtoNDC(xx,u);
11224 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11225 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11226 xx[1] = yaxis->GetXmin();
11227 view->WCtoNDC(xx,u);
11228 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11229 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11230 xx[0] = xaxis->GetXmin();
11231 view->WCtoNDC(xx,u);
11232 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11233 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11234 gVirtualX->DrawPolyLine(5,rect1);
11235 if (nbins>1) {
11236 xx[0] = xaxis->GetXmin();
11237 xx[1] = yaxis->GetXmax();
11238 xx[2] = zaxis->GetBinCenter(binz+nbins-1);
11239 view->WCtoNDC(xx,u);
11240 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11241 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11242 rect2[4].SetX(rect2[0].GetX());
11243 rect2[4].SetY(rect2[0].GetY());
11244 xx[0] = xaxis->GetXmax();
11245 view->WCtoNDC(xx,u);
11246 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11247 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11248 xx[1] = yaxis->GetXmin();
11249 view->WCtoNDC(xx,u);
11250 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11251 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11252 xx[0] = xaxis->GetXmin();
11253 view->WCtoNDC(xx,u);
11254 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11255 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11256 gVirtualX->DrawPolyLine(5,rect2);
11257 }
11258 c->Clear();
11259 c->cd();
11260 TH2 *hp = (TH2*)h3->Project3D("yx");
11261 zaxis->SetRange(first,last);
11262 if (hp) {
11263 hp->SetFillColor(38);
11264 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYX of binz=%d [z=%.1f..%.f]", binz,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz)));
11265 else hp->SetTitle(TString::Format("ProjectionYX, binz=[%d,%d] [z=%.1f..%.1f]", binz,binz2,zaxis->GetBinLowEdge(binz),zaxis->GetBinUpEdge(binz2)));
11266 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11267 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11268 hp->SetZTitle("Number of Entries");
11269 hp->Draw(fShowOption.Data());
11270 }
11271 }
11272 break;
11273
11274 case 6:
11275 // "xz"
11276 {
11277 Int_t first = yaxis->GetFirst();
11278 Int_t last = yaxis->GetLast();
11279 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11280 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11281 yaxis->SetRange(biny,biny2);
11282 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11283 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11284 xx[0] = xaxis->GetXmin();
11285 xx[2] = zaxis->GetXmax();
11286 xx[1] = yaxis->GetBinCenter(biny);
11287 view->WCtoNDC(xx,u);
11288 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11289 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11290 rect1[4].SetX(rect1[0].GetX());
11291 rect1[4].SetY(rect1[0].GetY());
11292 xx[0] = xaxis->GetXmax();
11293 view->WCtoNDC(xx,u);
11294 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11295 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11296 xx[2] = zaxis->GetXmin();
11297 view->WCtoNDC(xx,u);
11298 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11299 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11300 xx[0] = xaxis->GetXmin();
11301 view->WCtoNDC(xx,u);
11302 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11303 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11304 gVirtualX->DrawPolyLine(5,rect1);
11305 if (nbins>1) {
11306 xx[0] = xaxis->GetXmin();
11307 xx[2] = zaxis->GetXmax();
11308 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11309 view->WCtoNDC(xx,u);
11310 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11311 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11312 rect2[4].SetX(rect2[0].GetX());
11313 rect2[4].SetY(rect2[0].GetY());
11314 xx[0] = xaxis->GetXmax();
11315 view->WCtoNDC(xx,u);
11316 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11317 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11318 xx[2] = zaxis->GetXmin();
11319 view->WCtoNDC(xx,u);
11320 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11321 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11322 xx[0] = xaxis->GetXmin();
11323 view->WCtoNDC(xx,u);
11324 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11325 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11326 gVirtualX->DrawPolyLine(5,rect2);
11327 }
11328 c->Clear();
11329 c->cd();
11330 TH2 *hp = (TH2*)h3->Project3D("xz");
11331 yaxis->SetRange(first,last);
11332 if (hp) {
11333 hp->SetFillColor(38);
11334 if (nbins==1)hp->SetTitle(TString::Format("ProjectionXZ of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11335 else hp->SetTitle(TString::Format("ProjectionXZ, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11336 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11337 hp->SetYTitle(fH->GetXaxis()->GetTitle());
11338 hp->SetZTitle("Number of Entries");
11339 hp->Draw(fShowOption.Data());
11340 }
11341 }
11342 break;
11343
11344 case 7:
11345 // "zx"
11346 {
11347 Int_t first = yaxis->GetFirst();
11348 Int_t last = yaxis->GetLast();
11349 Int_t biny = first + Int_t((last-first)*(py-pymin)/(pymax-pymin));
11350 Int_t biny2 = TMath::Min(biny+nbins-1,yaxis->GetNbins() );
11351 yaxis->SetRange(biny,biny2);
11352 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11353 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11354 xx[0] = xaxis->GetXmin();
11355 xx[2] = zaxis->GetXmax();
11356 xx[1] = yaxis->GetBinCenter(biny);
11357 view->WCtoNDC(xx,u);
11358 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11359 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11360 rect1[4].SetX(rect1[0].GetX());
11361 rect1[4].SetY(rect1[0].GetY());
11362 xx[0] = xaxis->GetXmax();
11363 view->WCtoNDC(xx,u);
11364 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11365 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11366 xx[2] = zaxis->GetXmin();
11367 view->WCtoNDC(xx,u);
11368 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11369 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11370 xx[0] = xaxis->GetXmin();
11371 view->WCtoNDC(xx,u);
11372 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11373 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11374 gVirtualX->DrawPolyLine(5,rect1);
11375 if (nbins>1) {
11376 xx[0] = xaxis->GetXmin();
11377 xx[2] = zaxis->GetXmax();
11378 xx[1] = yaxis->GetBinCenter(biny+nbins-1);
11379 view->WCtoNDC(xx,u);
11380 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11381 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11382 rect2[4].SetX(rect2[0].GetX());
11383 rect2[4].SetY(rect2[0].GetY());
11384 xx[0] = xaxis->GetXmax();
11385 view->WCtoNDC(xx,u);
11386 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11387 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11388 xx[2] = zaxis->GetXmin();
11389 view->WCtoNDC(xx,u);
11390 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11391 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11392 xx[0] = xaxis->GetXmin();
11393 view->WCtoNDC(xx,u);
11394 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11395 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11396 gVirtualX->DrawPolyLine(5,rect2);
11397 }
11398 c->Clear();
11399 c->cd();
11400 TH2 *hp = (TH2*)h3->Project3D("zx");
11401 yaxis->SetRange(first,last);
11402 if (hp) {
11403 hp->SetFillColor(38);
11404 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZX of biny=%d [y=%.1f..%.f]", biny,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny)));
11405 else hp->SetTitle(TString::Format("ProjectionZX, biny=[%d,%d] [y=%.1f..%.1f]", biny,biny2,yaxis->GetBinLowEdge(biny),yaxis->GetBinUpEdge(biny2)));
11406 hp->SetXTitle(fH->GetXaxis()->GetTitle());
11407 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11408 hp->SetZTitle("Number of Entries");
11409 hp->Draw(fShowOption.Data());
11410 }
11411 }
11412 break;
11413
11414 case 8:
11415 // "yz"
11416 {
11417 Int_t first = xaxis->GetFirst();
11418 Int_t last = xaxis->GetLast();
11419 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11420 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11421 xaxis->SetRange(binx,binx2);
11422 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11423 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11424 xx[2] = zaxis->GetXmin();
11425 xx[1] = yaxis->GetXmax();
11426 xx[0] = xaxis->GetBinCenter(binx);
11427 view->WCtoNDC(xx,u);
11428 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11429 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11430 rect1[4].SetX(rect1[0].GetX());
11431 rect1[4].SetY(rect1[0].GetY());
11432 xx[2] = zaxis->GetXmax();
11433 view->WCtoNDC(xx,u);
11434 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11435 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11436 xx[1] = yaxis->GetXmin();
11437 view->WCtoNDC(xx,u);
11438 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11439 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11440 xx[2] = zaxis->GetXmin();
11441 view->WCtoNDC(xx,u);
11442 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11443 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11444 gVirtualX->DrawPolyLine(5,rect1);
11445 if (nbins>1) {
11446 xx[2] = zaxis->GetXmin();
11447 xx[1] = yaxis->GetXmax();
11448 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11449 view->WCtoNDC(xx,u);
11450 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11451 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11452 rect2[4].SetX(rect2[0].GetX());
11453 rect2[4].SetY(rect2[0].GetY());
11454 xx[2] = zaxis->GetXmax();
11455 view->WCtoNDC(xx,u);
11456 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11457 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11458 xx[1] = yaxis->GetXmin();
11459 view->WCtoNDC(xx,u);
11460 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11461 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11462 xx[2] = zaxis->GetXmin();
11463 view->WCtoNDC(xx,u);
11464 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11465 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11466 gVirtualX->DrawPolyLine(5,rect2);
11467 }
11468 c->Clear();
11469 c->cd();
11470 TH2 *hp = (TH2*)h3->Project3D("yz");
11471 xaxis->SetRange(first,last);
11472 if (hp) {
11473 hp->SetFillColor(38);
11474 if (nbins==1)hp->SetTitle(TString::Format("ProjectionYZ of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11475 else hp->SetTitle(TString::Format("ProjectionYZ, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11476 hp->SetXTitle(fH->GetZaxis()->GetTitle());
11477 hp->SetYTitle(fH->GetYaxis()->GetTitle());
11478 hp->SetZTitle("Number of Entries");
11479 hp->Draw(fShowOption.Data());
11480 }
11481 }
11482 break;
11483
11484 case 9:
11485 // "zy"
11486 {
11487 Int_t first = xaxis->GetFirst();
11488 Int_t last = xaxis->GetLast();
11489 Int_t binx = first + Int_t((last-first)*(px-pxmin)/(pxmax-pxmin));
11490 Int_t binx2 = TMath::Min(binx+nbins-1,xaxis->GetNbins() );
11491 xaxis->SetRange(binx,binx2);
11492 if (rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect1);
11493 if (nbins>1 && rect1[0].GetX()) gVirtualX->DrawPolyLine(5,rect2);
11494 xx[2] = zaxis->GetXmin();
11495 xx[1] = yaxis->GetXmax();
11496 xx[0] = xaxis->GetBinCenter(binx);
11497 view->WCtoNDC(xx,u);
11498 rect1[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11499 rect1[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11500 rect1[4].SetX(rect1[0].GetX());
11501 rect1[4].SetY(rect1[0].GetY());
11502 xx[2] = zaxis->GetXmax();
11503 view->WCtoNDC(xx,u);
11504 rect1[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11505 rect1[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11506 xx[1] = yaxis->GetXmin();
11507 view->WCtoNDC(xx,u);
11508 rect1[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11509 rect1[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11510 xx[2] = zaxis->GetXmin();
11511 view->WCtoNDC(xx,u);
11512 rect1[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11513 rect1[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11514 gVirtualX->DrawPolyLine(5,rect1);
11515 if (nbins>1) {
11516 xx[2] = zaxis->GetXmin();
11517 xx[1] = yaxis->GetXmax();
11518 xx[0] = xaxis->GetBinCenter(binx+nbins-1);
11519 view->WCtoNDC(xx,u);
11520 rect2[0].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11521 rect2[0].SetY(pymin + Int_t((u[1]-uymin)*cy));
11522 rect2[4].SetX(rect2[0].GetX());
11523 rect2[4].SetY(rect2[0].GetY());
11524 xx[2] = zaxis->GetXmax();
11525 view->WCtoNDC(xx,u);
11526 rect2[1].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11527 rect2[1].SetY(pymin + Int_t((u[1]-uymin)*cy));
11528 xx[1] = yaxis->GetXmin();
11529 view->WCtoNDC(xx,u);
11530 rect2[2].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11531 rect2[2].SetY(pymin + Int_t((u[1]-uymin)*cy));
11532 xx[2] = zaxis->GetXmin();
11533 view->WCtoNDC(xx,u);
11534 rect2[3].SetX(pxmin + Int_t((u[0]-uxmin)*cx));
11535 rect2[3].SetY(pymin + Int_t((u[1]-uymin)*cy));
11536 gVirtualX->DrawPolyLine(5,rect2);
11537 }
11538 c->Clear();
11539 c->cd();
11540 TH2 *hp = (TH2*)h3->Project3D("zy");
11541 xaxis->SetRange(first,last);
11542 if (hp) {
11543 hp->SetFillColor(38);
11544 if (nbins==1)hp->SetTitle(TString::Format("ProjectionZY of binx=%d [x=%.1f..%.f]", binx,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx)));
11545 else hp->SetTitle(TString::Format("ProjectionZY, binx=[%d,%d] [x=%.1f..%.1f]", binx,binx2,xaxis->GetBinLowEdge(binx),xaxis->GetBinUpEdge(binx2)));
11546 hp->SetXTitle(fH->GetYaxis()->GetTitle());
11547 hp->SetYTitle(fH->GetZaxis()->GetTitle());
11548 hp->SetZTitle("Number of Entries");
11549 hp->Draw(fShowOption.Data());
11550 }
11551 }
11552 break;
11553 }
11554 c->Update();
11555 padsav->cd();
11556}
@ kMouseMotion
Definition: Buttons.h:23
@ kWheelUp
Definition: Buttons.h:18
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kWheelDown
Definition: Buttons.h:18
@ kButton1Down
Definition: Buttons.h:17
@ kButton1Locate
Definition: Buttons.h:22
void Class()
Definition: Class.C:29
SVector< double, 2 > v
Definition: Dict.h:5
Handle_t Window_t
Definition: GuiTypes.h:28
ROOT::R::TRInterface & r
Definition: Object.C:4
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define g(i)
Definition: RSha256.hxx:105
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
short Width_t
Definition: RtypesCore.h:78
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
double Double_t
Definition: RtypesCore.h:55
short Color_t
Definition: RtypesCore.h:79
short Style_t
Definition: RtypesCore.h:76
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define BIT(n)
Definition: Rtypes.h:82
#define ClassImp(name)
Definition: Rtypes.h:363
@ kBlack
Definition: Rtypes.h:62
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
float xmin
Definition: THbookFile.cxx:93
int ncx
Definition: THbookFile.cxx:91
float ymin
Definition: THbookFile.cxx:93
int ncy
Definition: THbookFile.cxx:91
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
static TBox * gYHighlightBox
static TString gStringStdDevZ
static TString gStringStdDevX
static TString gStringIntegralBinWidth
const UInt_t kCannotRotate
static TString gStringStdDev
const Int_t kNMAX
Hparam_t Hparam
const Int_t kMAXCONTOUR
static TBox * gXHighlightBox
static TString gStringOverflow
static TString gStringUnderflow
static TString gStringSkewnessY
static TString gStringMean
static TString gStringKurtosis
Hoption_t Hoption
static TString gStringMeanX
static TString gStringEntries
static TString gStringIntegral
static TString gStringKurtosisY
static TString gStringStdDevY
static TString gStringMeanY
static TString gStringSkewnessX
static TString gStringKurtosisX
static TString gStringSkewnessZ
TH1 * gCurrentHist
static TString gStringMeanZ
static TString gStringSkewness
static TString gStringKurtosisZ
const Int_t kMaxCuts
Definition: THistPainter.h:38
double cos(double)
const Int_t kCYLINDRICAL
const Int_t kSPHERICAL
const Int_t kRAPIDITY
#define gROOT
Definition: TROOT.h:410
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
const Int_t kCARTESIAN
Definition: TView3D.cxx:32
const Int_t kPOLAR
Definition: TView3D.cxx:33
#define gPad
Definition: TVirtualPad.h:286
#define gVirtualX
Definition: TVirtualX.h:345
@ kArrowVer
Definition: TVirtualX.h:46
@ kPointer
Definition: TVirtualX.h:47
polygon * polys
Definition: X3DBuffer.c:24
#define snprintf
Definition: civetweb.c:1540
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:3728
Int_t fN
Definition: TArray.h:38
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:44
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:42
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual void SetImageQuality(EImageQuality lquality)
Definition: TAttImage.h:99
@ kImgBest
Definition: TAttImage.h:68
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
virtual Font_t GetTextFont() const
Return the text font.
Definition: TAttText.h:35
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:42
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
Class to manage histogram axis.
Definition: TAxis.h:30
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
const TArrayD * GetXbins() const
Definition: TAxis.h:130
Double_t GetXmax() const
Definition: TAxis.h:134
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition: TAxis.cxx:426
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
const char * ChooseTimeFormat(Double_t axislength=0)
Choose a reasonable time format from the coordinates in the active pad and the number of divisions in...
Definition: TAxis.cxx:124
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Definition: TAxis.cxx:557
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void SetRangeUser(Double_t ufirst, Double_t ulast)
Set the viewing range for the axis from ufirst to ulast (in user coordinates).
Definition: TAxis.cxx:928
virtual const char * GetTimeFormat() const
Definition: TAxis.h:127
const char * GetTitle() const
Returns title of object.
Definition: TAxis.h:129
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:903
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
THashList * GetLabels() const
Definition: TAxis.h:117
Create a Box.
Definition: TBox.h:24
Double_t GetX1() const
Definition: TBox.h:52
virtual void SetY2(Double_t y2)
Definition: TBox.h:66
Double_t GetX2() const
Definition: TBox.h:53
Double_t GetY1() const
Definition: TBox.h:54
virtual void SetX1(Double_t x1)
Definition: TBox.h:63
Double_t GetY2() const
Definition: TBox.h:55
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition: TBox.cxx:180
virtual void SetX2(Double_t x2)
Definition: TBox.h:64
virtual void SetY1(Double_t y1)
Definition: TBox.h:65
virtual void Paint(Option_t *option="")
Paint this box with its current attributes.
Definition: TBox.cxx:619
The candle plot painter class.
Definition: TCandle.h:25
void SetLog(int x, int y, int z)
Definition: TCandle.h:122
CandleOption
Definition: TCandle.h:28
void SetHistoWidth(const Double_t width)
Definition: TCandle.h:126
virtual void Paint(Option_t *option="")
Paint one candle with its current attributes.
Definition: TCandle.cxx:674
Bool_t IsViolinScaled()
Definition: TCandle.cxx:190
Bool_t IsHorizontal()
Definition: TCandle.h:116
int ParseOption(char *optin)
Parsing of the option-string.
Definition: TCandle.cxx:244
void SetOption(CandleOption opt)
Definition: TCandle.h:121
void SetHistogram(TH1D *proj)
Definition: TCandle.h:127
Bool_t IsCandleScaled()
Definition: TCandle.cxx:185
void SetCandleWidth(const Double_t width)
Definition: TCandle.h:125
void SetAxisPosition(const Double_t candlePos)
Definition: TCandle.h:123
static Bool_t SupportAlpha()
Static function returning "true" if transparency is supported.
Definition: TCanvas.cxx:2273
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
void SetName(const char *name)
Definition: TCollection.h:204
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
The color creation and management class.
Definition: TColor.h:19
virtual void SetRGB(Float_t r, Float_t g, Float_t b)
Initialize this color and its associated colors.
Definition: TColor.cxx:1696
static void RGBtoHLS(Float_t r, Float_t g, Float_t b, Float_t &h, Float_t &l, Float_t &s)
Definition: TColor.h:77
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:50
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:1758
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:1897
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:1929
static void HLStoRGB(Float_t h, Float_t l, Float_t s, Float_t &r, Float_t &g, Float_t &b)
Definition: TColor.h:72
virtual void SetAlpha(Float_t a)
Definition: TColor.h:66
To draw a Crown.
Definition: TCrown.h:19
virtual void Paint(Option_t *option="")
Paint this crown with its current attributes.
Definition: TCrown.cxx:181
Graphical cut class.
Definition: TCutG.h:20
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
1-Dim function class
Definition: TF1.h:211
virtual Double_t GetXmax() const
Definition: TF1.h:540
virtual Int_t GetNDF() const
Return the number of degrees of freedom in the fit the fNDF parameter has been previously computed du...
Definition: TF1.cxx:1863
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition: TF1.cxx:1914
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition: TF1.cxx:1904
Double_t GetChisquare() const
Definition: TF1.h:428
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:3387
virtual Double_t GetMaximumStored() const
Definition: TF1.h:457
virtual Int_t GetNpar() const
Definition: TF1.h:465
virtual Int_t GetNumberFreeParameters() const
Return the number of free parameters.
Definition: TF1.cxx:1874
@ kNotDraw
Definition: TF1.h:311
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:3400
virtual const char * GetParName(Int_t ipar) const
Definition: TF1.h:513
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:1424
virtual Double_t GetXmin() const
Definition: TF1.h:536
virtual Double_t GetParameter(Int_t ipar) const
Definition: TF1.h:496
A 2-Dim function with parameters.
Definition: TF2.h:29
virtual void Paint(Option_t *option="")
Paint this 2-D function with its current attributes.
Definition: TF2.cxx:722
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:150
A 3-Dim function with parameters.
Definition: TF3.h:28
The axis painter class.
Definition: TGaxis.h:24
void SetTimeFormat(const char *tformat)
Change the format used for time plotting.
Definition: TGaxis.cxx:2718
virtual void PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Double_t &wmin, Double_t &wmax, Int_t &ndiv, Option_t *chopt="", Double_t gridlength=0, Bool_t drawGridOnly=kFALSE)
Control function to draw an axis.
Definition: TGaxis.cxx:956
void SetTitleOffset(Float_t titleoffset=1)
Definition: TGaxis.h:125
virtual void SetTitle(const char *title="")
Change the title of the axis.
Definition: TGaxis.cxx:2691
void SetLabelOffset(Float_t labeloffset)
Definition: TGaxis.h:107
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
Definition: TGaxis.cxx:906
void SetTickSize(Float_t ticksize)
Definition: TGaxis.h:119
void SetLabelSize(Float_t labelsize)
Definition: TGaxis.h:108
void SetOption(Option_t *option="")
To set axis options.
Definition: TGaxis.cxx:2683
The TGraphDelaunay painting class.
void Paint(Option_t *option)
Paint a TGraphDelaunay according to the value of "option":
TList * GetContourList(Double_t contour)
Returns the X and Y graphs building a contour.
TGraphDelaunay2D generates a Delaunay triangulation of a TGraph2D.
TGraphDelaunay generates a Delaunay triangulation of a TGraph2D.
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
@ kClipFrame
clip to the frame boundary
Definition: TGraph.h:70
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6217
TAxis * GetZaxis()
Definition: TH1.h:318
virtual EBinErrorOpt GetBinErrorOption() const
Definition: TH1.h:268
virtual Float_t GetBarWidth() const
Definition: TH1.h:252
virtual Double_t GetMinimumStored() const
Definition: TH1.h:288
virtual Float_t GetBarOffset() const
Definition: TH1.h:251
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:7012
virtual Int_t GetNbinsY() const
Definition: TH1.h:293
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8384
virtual Int_t GetNbinsZ() const
Definition: TH1.h:294
virtual Double_t GetNormFactor() const
Definition: TH1.h:296
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:6958
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7063
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7770
virtual void SetXTitle(const char *title)
Definition: TH1.h:409
virtual Int_t GetDimension() const
Definition: TH1.h:278
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1225
@ kNoTitle
don't draw the histogram title
Definition: TH1.h:165
@ kUserContour
user specified contour levels
Definition: TH1.h:161
@ kNoStats
don't draw stats box
Definition: TH1.h:160
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition: TH1.cxx:4692
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:7872
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
TAxis * GetYaxis()
Definition: TH1.h:317
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8400
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7813
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7321
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:8542
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8473
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4185
virtual void SetZTitle(const char *title)
Definition: TH1.h:411
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:6989
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2974
virtual Double_t GetMaximumStored() const
Definition: TH1.h:284
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:8053
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:7902
@ kNormal
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4790
const Double_t * GetBuffer() const
Definition: TH1.h:234
virtual Bool_t IsHighlight() const
Definition: TH1.h:330
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8484
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8431
virtual void SetYTitle(const char *title)
Definition: TH1.h:410
virtual Int_t GetSumw2N() const
Definition: TH1.h:310
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7050
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:7957
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7297
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:705
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7741
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1346
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7133
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:291
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:250
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
TH1D * ProjectionY(const char *name="_py", Int_t firstxbin=0, Int_t lastxbin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along Y.
Definition: TH2.cxx:2357
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:2317
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH2.cxx:1202
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH2.h:84
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:1245
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:2233
The histogram painter class.
Definition: THistPainter.h:47
static Int_t ProjectSinusoidal2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
virtual Bool_t IsInside(Int_t x, Int_t y)
Return kTRUE if the cell ix, iy is inside one of the graphical cuts.
TAxis * fYaxis
Definition: THistPainter.h:52
Double_t * fXbuf
Definition: THistPainter.h:58
Int_t fXHighlightBin
Definition: THistPainter.h:66
virtual void DrawPanel()
Display a panel with all histogram drawing options.
virtual void PaintErrors(Option_t *option)
Draw 1D histograms error bars.
virtual void SetHistogram(TH1 *h)
Set current histogram to h
virtual void PaintTF3()
Control function to draw a 3D implicit functions.
virtual void PaintStat(Int_t dostat, TF1 *fit)
Draw the statistics box for 1D and profile histograms.
virtual Int_t TableInit()
Initialize various options to draw 2D histograms.
virtual void PaintTH2PolyScatterPlot(Option_t *option)
Control function to draw a TH2Poly as a scatter plot.
static Int_t ProjectAitoff2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void PaintText(Option_t *option)
Control function to draw a 1D/2D histograms with the bin values.
virtual void PaintAxis(Bool_t drawGridOnly=kFALSE)
Draw axis (2D case) of an histogram.
virtual void PaintColorLevelsFast(Option_t *option)
Rendering scheme for the COL2 and COLZ2 options
virtual Int_t PaintInit()
Compute histogram parameters used by the drawing routines.
virtual void Paint2DErrors(Option_t *option)
Draw 2D histograms errors.
Int_t fYHighlightBin
Definition: THistPainter.h:67
virtual void PaintCandlePlot(Option_t *option)
Control function to draw a 2D histogram as a candle (box) plot or violin plot
virtual void PaintScatterPlot(Option_t *option)
Control function to draw a 2D histogram as a scatter plot.
virtual ~THistPainter()
Default destructor.
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Display the histogram info (bin number, contents, integral up to bin corresponding to cursor position...
virtual void PaintLego(Option_t *option)
Control function to draw a 2D histogram as a lego plot.
virtual void PaintH3(Option_t *option="")
Control function to draw a 3D histograms.
TString fShowOption
Definition: THistPainter.h:65
virtual void PaintHighlightBin(Option_t *option="")
Paint highlight bin as TBox object.
virtual void PaintTH2PolyBins(Option_t *option)
Control function to draw a TH2Poly bins' contours.
virtual Int_t PaintContourLine(Double_t elev1, Int_t icont1, Double_t x1, Double_t y1, Double_t elev2, Int_t icont2, Double_t x2, Double_t y2, Double_t *xarr, Double_t *yarr, Int_t *itarr, Double_t *levels)
Fill the matrix xarr and yarr for Contour Plot.
Int_t fShowProjection
Definition: THistPainter.h:64
virtual void PaintLegoAxis(TGaxis *axis, Double_t ang)
Draw the axis for legos and surface plots.
virtual void PaintTriangles(Option_t *option)
Control function to draw a table using Delaunay triangles.
virtual void HighlightBin(Int_t px, Int_t py)
Check on highlight bin.
virtual void PaintH3Box(Int_t iopt)
Control function to draw a 3D histogram with boxes.
TList * fFunctions
Definition: THistPainter.h:54
static void PaintSpecialObjects(const TObject *obj, Option_t *option)
Static function to paint special objects like vectors and matrices.
virtual void PaintTitle()
Draw the histogram title.
virtual void PaintTH2PolyColorLevels(Option_t *option)
Control function to draw a TH2Poly as a color plot.
virtual std::vector< THistRenderingRegion > ComputeRenderingRegions(TAxis *pAxis, Int_t nPixels, bool isLog)
Returns the rendering regions for an axis to use in the COL2 option.
virtual void ShowProjectionX(Int_t px, Int_t py)
Show projection onto X.
virtual void PaintPalette()
Paint the color palette on the right side of the pad.
virtual void ProcessMessage(const char *mess, const TObject *obj)
Process message mess.
Double_t * fYbuf
Definition: THistPainter.h:59
TAxis * fXaxis
Definition: THistPainter.h:51
virtual void PaintStat2(Int_t dostat, TF1 *fit)
Draw the statistics box for 2D histograms.
virtual void PaintArrows(Option_t *option)
Control function to draw a table as an arrow plot
virtual void RecalculateRange()
Recompute the histogram range following graphics operations.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance from the point px,py to a line.
static Int_t ProjectParabolic2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function code from Ernst-Jan Buis.
TPainter3dAlgorithms * fLego
Definition: THistPainter.h:55
virtual void PaintBarH(Option_t *option)
Draw a bar char in a rotated pad (X vertical, Y horizontal)
virtual void PaintStat3(Int_t dostat, TF1 *fit)
Draw the statistics box for 3D histograms.
virtual void PaintSurface(Option_t *option)
Control function to draw a 2D histogram as a surface plot.
TList * fStack
Definition: THistPainter.h:63
TGraph2DPainter * fGraph2DPainter
Definition: THistPainter.h:56
THistPainter()
Default constructor.
virtual void PaintTH2PolyText(Option_t *option)
Control function to draw a TH2Poly as a text plot.
virtual void ShowProjection3(Int_t px, Int_t py)
Show projection (specified by fShowProjection) of a TH3.
TAxis * fZaxis
Definition: THistPainter.h:53
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms
virtual void PaintFunction(Option_t *option)
Paint functions associated to an histogram.
virtual void PaintBar(Option_t *option)
Draw a bar-chart in a normal pad.
static Int_t ProjectMercator2xy(Double_t l, Double_t b, Double_t &Al, Double_t &Ab)
Static function.
virtual void PaintBoxes(Option_t *option)
Control function to draw a 2D histogram as a box plot
virtual Int_t MakeChopt(Option_t *option)
Decode string choptin and fill Hoption structure.
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute the actions corresponding to event.
virtual void SetShowProjection(const char *option, Int_t nbins)
Set projection.
virtual void ShowProjectionY(Int_t px, Int_t py)
Show projection onto Y.
virtual void SetHighlight()
Set highlight (enable/disable) mode for fH.
static const char * GetBestFormat(Double_t v, Double_t e, const char *f)
This function returns the best format to print the error value (e) knowing the parameter value (v) an...
virtual void PaintContour(Option_t *option)
Control function to draw a 2D histogram as a contour plot.
TCutG * fCuts[kMaxCuts]
Definition: THistPainter.h:62
virtual void PaintTable(Option_t *option)
Control function to draw 2D/3D histograms (tables).
virtual TList * GetContourList(Double_t contour) const
Get a contour (as a list of TGraphs) using the Delaunay triangulation.
virtual Int_t PaintInitH()
Compute histogram parameters used by the drawing routines for a rotated pad.
virtual void PaintFrame()
Calculate range and clear pad (canvas).
Int_t fCutsOpt[kMaxCuts]
Definition: THistPainter.h:61
virtual void PaintH3Iso()
Control function to draw a 3D histogram with Iso Surfaces.
virtual void PaintH3BoxRaster()
Control function to draw a 3D histogram with boxes.
virtual void PaintHist(Option_t *option)
Control routine to draw 1D histograms
virtual Int_t MakeCuts(char *cutsopt)
Decode string choptin and fill Graphical cuts structure.
virtual void DefineColorLevels(Int_t ndivz)
Define the color levels used to paint legos, surfaces etc..
virtual void PaintColorLevels(Option_t *option)
Control function to draw a 2D histogram as a color plot.
A class to define a conversion from pixel values to pixel color.
Definition: TAttImage.h:33
static TImagePalette * CreateCOLPalette(Int_t nContours)
Factory method to creates an image palette for histogram plotting.
Definition: TAttImage.cxx:748
An abstract interface to image processing library.
Definition: TImage.h:29
virtual void SetImage(const Double_t *, UInt_t, UInt_t, TImagePalette *=0)
Definition: TImage.h:116
static TImage * Create()
Create an image.
Definition: TImage.cxx:36
virtual void PaintImage(Drawable_t, Int_t, Int_t, Int_t=0, Int_t=0, UInt_t=0, UInt_t=0, Option_t *="")
Definition: TImage.h:243
void Reset()
Definition: TCollection.h:252
To draw Mathematical Formula.
Definition: TLatex.h:18
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:97
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
Linear Algebra Package.
Definition: TMatrixTBase.h:85
TClass * Class()
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:35
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
void Add(TObject *obj)
Definition: TObjArray.h:73
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:341
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:169
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
@ kCannotPick
if object in a pad cannot be picked
Definition: TObject.h:63
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
The Legos and Surfaces painter class.
void DrawFaceMove3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 3rd variant for "MOVING SCREEN" algorithm (draw level lines only)
void SetDrawFace(DrawFaceFunc_t pointer)
Store pointer to current algorithm to draw faces.
void SetIsoSurfaceParameters(Double_t fmin, Double_t fmax, Int_t ncolor, Int_t ic1, Int_t ic2, Int_t ic3)
void IsoSurface(Int_t ns, Double_t *s, Int_t nx, Int_t ny, Int_t nz, Double_t *x, Double_t *y, Double_t *z, const char *chopt)
Draw set of iso-surfaces for a scalar function defined on a grid.
void DrawLevelLines(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw level lines without hidden line removal.
void ImplicitFunction(Double_t *rmin, Double_t *rmax, Int_t nx, Int_t ny, Int_t nz, const char *chopt)
Draw implicit function FUN(X,Y,Z) = 0 in cartesian coordinates using hidden surface removal algorithm...
void SetLegoFunction(LegoFunc_t pointer)
Store pointer to current lego function.
void SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in cylindrical coordinates.
void SurfaceFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Service function for Surfaces.
void LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in cylindrical coordinates.
void FillPolygonBorder(Int_t nn, Double_t *xy)
Fill a polygon including border ("RASTER SCREEN")
void LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots spheric coordinates.
void SurfaceCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw surface in cartesian coordinate system.
static void SetF3ClippingBoxOff()
Static function Set the implicit function clipping box "off".
void SurfaceProperty(Double_t qqa, Double_t qqd, Double_t qqs, Int_t nnqs, Int_t &irep)
Set surface property coefficients.
void InitMoveScreen(Double_t xmin, Double_t xmax)
Initialize "MOVING SCREEN" method.
void FindVisibleLine(Double_t *p1, Double_t *p2, Int_t ntmax, Int_t &nt, Double_t *t)
Find visible part of a line ("RASTER SCREEN")
void LegoCartesian(Double_t ang, Int_t nx, Int_t ny, const char *chopt)
Draw stack of lego-plots in cartesian coordinates.
void DrawFaceMode1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 1st variant (2 colors: 1st for external surface, 2nd for internal)
void LightSource(Int_t nl, Double_t yl, Double_t xscr, Double_t yscr, Double_t zscr, Int_t &irep)
Set light source.
void GouraudFunction(Int_t ia, Int_t ib, Double_t *f, Double_t *t)
Find part of surface with luminosity in the corners.
void DrawFaceMove1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "MOVING SCREEN" algorithm (draw face with level lines)
void SetSurfaceFunction(SurfaceFunc_t pointer)
Store pointer to current surface function.
void SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in polar coordinates.
static void SetF3ClippingBoxOn(Double_t xclip, Double_t yclip, Double_t zclip)
Static function Set the implicit function clipping box "on" and define the clipping box.
void SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw surface in spheric coordinates.
void BackBox(Double_t ang)
Draw back surfaces of surrounding box.
void ColorFunction(Int_t nl, Double_t *fl, Int_t *icl, Int_t &irep)
Set correspondance between function and color levels.
void DrawFaceRaster2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 2nd variant for "RASTER SCREEN" algorithm (draw face for stacked lego plot)
static void SetF3(TF3 *f3)
Static function Store pointer to current implicit function.
void LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char *chopt)
Draw stack of lego-plots in polar coordinates.
void SetEdgeAtt(Color_t color=1, Style_t style=1, Width_t width=1, Int_t n=0)
void SetMesh(Int_t mesh=1)
void InitRaster(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, Int_t nx, Int_t ny)
Initialize hidden lines removal algorithm (RASTER SCREEN)
void DefineGridLevels(Int_t ndivz)
Define the grid levels drawn in the background of surface and lego plots.
void LegoFunction(Int_t ia, Int_t ib, Int_t &nv, Double_t *ab, Double_t *vv, Double_t *t)
Service function for Legos.
void DrawFaceMove2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 2nd variant for "MOVING SCREEN" algorithm (draw face for stacked lego plot)
void SetColorMain(Color_t color, Int_t n=0)
Store color for stack number n.
void Spectrum(Int_t nl, Double_t fmin, Double_t fmax, Int_t ic, Int_t idc, Int_t &irep)
Set Spectrum.
void DrawFaceRaster1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt)
Draw face - 1st variant for "RASTER SCREEN" algorithm (draw face with level lines)
void DrawFaceMode3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 3rd option (draw face for stacked lego plot)
void FrontBox(Double_t ang)
Draw front surfaces of surrounding box & axes.
void SetColorDark(Color_t color, Int_t n=0)
Store dark color for stack number n.
void DrawFaceMode2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t)
Draw face - 2nd option (fill in correspondance with function levels)
The palette painting class.
Definition: TPaletteAxis.h:29
void SetHistogram(TH1 *h)
Definition: TPaletteAxis.h:57
virtual void Paint(Option_t *option="")
Paint the palette.
TH1 * GetHistogram()
Definition: TPaletteAxis.h:51
The histogram statistics painter class.
Definition: TPaveStats.h:18
Int_t GetOptStat() const
Return the stat option.
Definition: TPaveStats.cxx:265
virtual void SetStatFormat(const char *format="6.4g")
Change (i.e. set) the format for printing statistics.
Definition: TPaveStats.cxx:311
void SetOptStat(Int_t stat=1)
Set the stat option.
Definition: TPaveStats.cxx:302
virtual const char * GetFitFormat() const
Definition: TPaveStats.h:35
void SetParent(TObject *obj)
Definition: TPaveStats.h:52
virtual void SetFitFormat(const char *format="5.4g")
Change (i.e. set) the format for printing fit parameters in statistics box.
Definition: TPaveStats.cxx:285
Int_t GetOptFit() const
Return the fit option.
Definition: TPaveStats.cxx:256
virtual void Paint(Option_t *option="")
Paint the pave stat.
Definition: TPaveStats.cxx:319
void SetOptFit(Int_t fit=1)
Set the fit option.
Definition: TPaveStats.cxx:293
virtual const char * GetStatFormat() const
Definition: TPaveStats.h:36
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:182
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:233
virtual void Paint(Option_t *option="")
Paint this pavetext with its current attributes.
Definition: TPaveText.cxx:410
virtual TText * GetLine(Int_t number) const
Get Pointer to line number in this pavetext.
Definition: TPaveText.cxx:274
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:208
virtual void SetName(const char *name="")
Definition: TPave.h:72
Option_t * GetName() const
Returns name of object.
Definition: TPave.h:53
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:70
Double_t GetX1NDC() const
Definition: TPave.h:56
virtual void SetX2NDC(Double_t x2)
Definition: TPave.h:76
Draw a Pie Chart,.
Definition: TPie.h:23
virtual void Paint(Option_t *)
Paint a Pie chart in a canvas.
Definition: TPie.cxx:802
virtual void ExecuteEvent(Int_t, Int_t, Int_t)
Execute the mouse events.
Definition: TPie.cxx:393
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Evaluate the distance to the chart in gPad.
Definition: TPie.cxx:168
Definition: TPoint.h:31
void SetX(SCoord_t x)
Definition: TPoint.h:49
void SetY(SCoord_t y)
Definition: TPoint.h:50
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:23
Double_t * GetX() const
Definition: TPolyLine.h:54
virtual void SetPoint(Int_t point, Double_t x, Double_t y)
Set point number n to (x, y) If n is greater than the current size, the arrays are automatically exte...
Definition: TPolyLine.cxx:639
Double_t * GetY() const
Definition: TPolyLine.h:55
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X,...
Definition: TProfile2D.h:27
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:790
Profile Histogram.
Definition: TProfile.h:32
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile histogram.
Definition: TProfile.cxx:814
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:27
virtual Double_t Rndm()
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:56
Sequenceable collection abstract base class.
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1100
const char * Data() const
Definition: TString.h:364
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2286
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetOptStat() const
Definition: TStyle.h:232
Color_t GetStatTextColor() const
Definition: TStyle.h:245
Float_t GetTitleX() const
Definition: TStyle.h:267
Int_t GetOptTitle() const
Definition: TStyle.h:233
Float_t GetStatFontSize() const
Definition: TStyle.h:248
Float_t GetBarOffset() const
Definition: TStyle.h:170
Float_t GetStatX() const
Definition: TStyle.h:251
Float_t GetTitleSize(Option_t *axis="X") const
Return title size.
Definition: TStyle.cxx:1045
Float_t GetTitleY() const
Definition: TStyle.h:268
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:1021
Bool_t GetHistMinimumZero() const
Definition: TStyle.h:224
Float_t GetStatY() const
Definition: TStyle.h:252
Color_t GetTitleFillColor() const
Definition: TStyle.h:258
Style_t GetTitleStyle() const
Definition: TStyle.h:260
Color_t GetStatColor() const
Definition: TStyle.h:244
Float_t GetBarWidth() const
Definition: TStyle.h:171
Float_t GetStatH() const
Definition: TStyle.h:254
Width_t GetTitleBorderSize() const
Definition: TStyle.h:262
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:913
Float_t GetErrorX() const
Definition: TStyle.h:174
Double_t GetHistTopMargin() const
Definition: TStyle.h:225
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:313
Float_t GetEndErrorSize() const
Definition: TStyle.h:173
Width_t GetStatBorderSize() const
Definition: TStyle.h:246
Int_t GetTitleAlign()
Definition: TStyle.h:257
Color_t GetTitleTextColor() const
Definition: TStyle.h:259
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:314
Float_t GetTitleH() const
Definition: TStyle.h:270
Style_t GetStatStyle() const
Definition: TStyle.h:249
Float_t GetStatW() const
Definition: TStyle.h:253
const char * GetFitFormat() const
Definition: TStyle.h:187
const char * GetStatFormat() const
Definition: TStyle.h:250
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:979
Int_t GetOptFit() const
Definition: TStyle.h:231
Int_t GetNumberContours() const
Definition: TStyle.h:228
const char * GetPaintTextFormat() const
Definition: TStyle.h:237
Style_t GetStatFont() const
Definition: TStyle.h:247
Float_t GetTitleFontSize() const
Definition: TStyle.h:261
Float_t GetTitleW() const
Definition: TStyle.h:269
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1843
Base class for several text objects.
Definition: TText.h:23
TVectorT.
Definition: TVectorT.h:27
TClass * Class()
See TView3D.
Definition: TView.h:25
virtual Double_t GetPsi()=0
virtual Double_t * GetRmax()=0
virtual void SetAxisNDC(const Double_t *x1, const Double_t *x2, const Double_t *y1, const Double_t *y2, const Double_t *z1, const Double_t *z2)=0
virtual Double_t * GetRmin()=0
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)=0
virtual void SetOutlineToCube()=0
virtual Int_t GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)=0
virtual Double_t * GetTnorm()=0
virtual void ExecuteRotateView(Int_t event, Int_t px, Int_t py)=0
virtual TSeqCollection * GetOutline()=0
virtual void PadRange(Int_t rback)=0
virtual void FindNormal(Double_t x, Double_t y, Double_t z, Double_t &zn)=0
virtual void AxisVertex(Double_t ang, Double_t *av, Int_t &ix1, Int_t &ix2, Int_t &iy1, Int_t &iy2, Int_t &iz1, Int_t &iz2)=0
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)=0
Abstract base class used by ROOT graphics editor.
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
virtual void Show()
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:50
virtual Int_t GetLogz() const =0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Int_t GetLogy() const =0
virtual Int_t GetLogx() const =0
TText * text
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
double beta(double x, double y)
Calculates the beta function.
return c1
Definition: legend1.C:41
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
Double_t ey[n]
Definition: legend1.C:17
Double_t ex[n]
Definition: legend1.C:17
TH1F * h1
Definition: legend1.C:5
TF1 * f1
Definition: legend1.C:11
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
RooCmdArg Bins(Int_t nbin)
static constexpr double mg
static constexpr double s
static constexpr double rad
static constexpr double bar
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:701
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:621
Double_t ATan(Double_t)
Definition: TMath.h:663
constexpr Double_t PiOver2()
Definition: TMath.h:52
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Double_t Log(Double_t x)
Definition: TMath.h:748
constexpr Double_t DegToRad()
Conversion from degree to radian:
Definition: TMath.h:82
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:723
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
Double_t Cos(Double_t)
Definition: TMath.h:629
constexpr Double_t Pi()
Definition: TMath.h:38
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:416
Double_t Sin(Double_t)
Definition: TMath.h:625
Double_t Tan(Double_t)
Definition: TMath.h:633
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMathBase.h:278
constexpr Double_t RadToDeg()
Conversion from radian to degree:
Definition: TMath.h:74
Double_t Log10(Double_t x)
Definition: TMath.h:752
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Definition: first.py:1
fill
Definition: fit1_py.py:6
Definition: graph.py:1
Histogram option structure.
Definition: Hoption.h:24
int Curve
"C" A smooth Curve is drawn.
Definition: Hoption.h:29
int Proj
1: Aitoff, 2: Mercator, 3: Sinusoidal, 4: Parabolic
Definition: Hoption.h:58
int Axis
"A" Axis are not drawn around the graph.
Definition: Hoption.h:27
int Box
"BOX" Draw 2D plot with proportional Boxes.
Definition: Hoption.h:40
int Scat
"SCAT" Draw 2D plot a Scatter plot.
Definition: Hoption.h:47
int Text
"TEXT" Draw 2D plot with the content of each cell.
Definition: Hoption.h:49
int Color
"COL" Draw 2D plot with Colored boxes.
Definition: Hoption.h:42
int AxisPos
Axis position.
Definition: Hoption.h:59
int List
= 1 to generate the TObjArray "contours"
Definition: Hoption.h:57
int Logx
log scale in X. Also set by histogram option
Definition: Hoption.h:66
int Zscale
"Z" to display the Z scale (color palette)
Definition: Hoption.h:54
int Contour
"CONT" Draw 2D plot as a Contour plot.
Definition: Hoption.h:43
int Off
"][" With H option, the first and last vertical lines are not drawn.
Definition: Hoption.h:32
int Func
"FUNC" Draw only the function (for example in case of fit).
Definition: Hoption.h:44
long Candle
"CANDLE" Draw a 2D histogram as candle/box plot or violin plot (also with "VIOLIN").
Definition: Hoption.h:52
int Spec
TSpectrum graphics.
Definition: Hoption.h:60
int FrontBox
= 0 to suppress the front box
Definition: Hoption.h:55
int Pie
"PIE" Draw 1D plot as a pie chart.
Definition: Hoption.h:51
int Char
"CHAR" Draw 2D plot with a character set.
Definition: Hoption.h:41
int Star
"*" A * is plotted at each point
Definition: Hoption.h:38
int Zero
if selected with any LEGO option the empty bins are not drawn.
Definition: Hoption.h:61
int Logz
log scale in Z. Also set by histogram option
Definition: Hoption.h:68
int Tri
"TRI" Draw 2D plot with Delaunay triangles.
Definition: Hoption.h:50
int BackBox
= 0 to suppress the back box
Definition: Hoption.h:56
int Mark
"P" The current Marker is drawn at each point
Definition: Hoption.h:35
int Arrow
"ARR" Draw 2D plot with Arrows.
Definition: Hoption.h:39
int Line
"L" A simple polyline beetwen every point is drawn.
Definition: Hoption.h:34
int Same
"S" Histogram is plotted in the current PAD.
Definition: Hoption.h:36
int Lego
"LEGO" Draw as a Lego plot(LEGO,Lego=1, LEGO1,Lego1=11, LEGO2,Lego=12).
Definition: Hoption.h:46
int Bar
"B" A Bar chart is drawn at each point.
Definition: Hoption.h:28
int Fill
"F" A fill area is drawn ("CF" draw a smooth fill area).
Definition: Hoption.h:31
int Hist
"HIST" Draw only the histogram.
Definition: Hoption.h:45
int Surf
"SURF" Draw as a Surface (SURF,Surf=1, SURF1,Surf=11, SURF2,Surf=12)
Definition: Hoption.h:48
int Logy
log scale in Y. Also set by histogram option
Definition: Hoption.h:67
int System
type of coordinate system(1=car,2=pol,3=cyl,4=sph,5=psr)
Definition: Hoption.h:53
int Error
"E" Draw Errors with current marker type and size.
Definition: Hoption.h:30
Histogram parameters structure.
Definition: Hparam.h:26
Double_t baroffset
offset of bin for bars or legos [0,1]
Definition: Hparam.h:41
Double_t ylowedge
low edge of axis
Definition: Hparam.h:32
Double_t xmin
minimum value along X
Definition: Hparam.h:29
Int_t ylast
last bin number along Y
Definition: Hparam.h:46
Int_t xfirst
first bin number along X
Definition: Hparam.h:43
Double_t zmin
minimum value along Z
Definition: Hparam.h:37
Double_t xbinsize
bin size in case of equidistant bins
Definition: Hparam.h:27
Double_t ymin
minimum value along y
Definition: Hparam.h:33
Double_t allchan
integrated sum of contents
Definition: Hparam.h:40
Double_t xlowedge
low edge of axis
Definition: Hparam.h:28
Double_t ymax
maximum value along y
Definition: Hparam.h:34
Double_t factor
multiplication factor (normalization)
Definition: Hparam.h:39
Int_t xlast
last bin number along X
Definition: Hparam.h:44
Double_t ybinsize
bin size in case of equidistant bins
Definition: Hparam.h:31
Double_t barwidth
width of bin for bars and legos [0,1]
Definition: Hparam.h:42
Double_t zmax
maximum value along Z
Definition: Hparam.h:38
Double_t xmax
maximum value along X
Definition: Hparam.h:30
Int_t yfirst
first bin number along Y
Definition: Hparam.h:45
auto * th2
Definition: textalign.C:17
auto * m
Definition: textangle.C:8
auto * tt
Definition: textangle.C:16
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
#define mark(osub)
Definition: triangle.c:1206