### Histogram Libraries

### THn, THnBase, THNSparse

- The new, non-sparse n-dimensional histogram `THn` has been introduced. It follows the same interfaces as `THnSparse`, and thus also implements `THnF THnD THnC THnS THnI THnL`.
  NOTE: the memory usage of this class increases with the number of bins, i.e. exponentially with the number of dimensions! A 5-dimensional `THnD` with 100 bins per dimension uses more than 80GB of RAM! Better use `THnSparse` if only a small fraction of the bins are filled.
- Most algorithms are now implemented in `THnBase`, the new common base class of `THnSparse` and `THn`. If a function does not care about the actual storage format on in incoming objects it might as well reference a `THnBase`.
- The bins of `THn` are held by objects of the new type `TNDArray`: an n-dimensional array with lazy allocation (only when a bin is set) that implements an `operator []`.
- `THn` and `THnSparse` can be created from histograms and from each other, allowing for easy conversion. There is currently no support for drawing a `THnBase`-derived object; project it into a `TH1/2/3` first.

### THistPainter

- When 1D histograms are painted with the options TEXT and BAR simultaneously, the text for each bin is placed taking into account the bar offset and bar width attributes. Previously, when several histogram were drawn that way, the texts overlapped.
- When a `TF1` was clipped vertically, horizotal lines appeared at the maximum and minimum when the function was draw with a line width greater than 1. The follwoing macro reproduces the problem:

      {
         TCanvas *c1=new TCanvas("c1", "A canvas", 10,0, 800, 600);
         c1->SetLogy();
         histo_dummy=c1->DrawFrame(0,1e-4,27,10);
         TF1 gaussian_func("gaussian_func","gaus",0,25.4);
         gaussian_func.SetLineColor(kRed);
         gaussian_func.SetParameters(1e-2,10,3);
         gaussian_func.Draw("same");
      }

- When two histograms where painted on top of each other with the option BOX (the 2nd one with BOX,SAME) the plot was wrong if the minimum of the first histogram was not zero.
- Take into account the absolute value of the histogram's minimum to compute the maximal boxes' size when an histogram is drawn with the option BOX.
- Add support for drawing the asymmetric errors for the TH1 and TH2
- The fit function was not drawn in the correct range when a fitted 2D histogram was painted with the option lego or surf.
- With option TEXT, do not draw the bins with 0 content for 1D histograms to be consistent with the 2D histograms case. Example:

      root [0] TH1D * histo = new TH1D ("histo","",20,-5.,5.) ;
      root [1] histo->FillRandom("gaus",1000) ;
      root [2] histo->Draw("hist,text") ;

- With option COL `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.
- With option COLZ the axis attributes were not imported correctly on the palette axis.
- Make sure the 2D drawing options COL, ARR, CONT and BOX are ignored when used to plot a 1D histogram. 1D histograms plotted with one of these options is now drawn with the default 1D plotting option. This is useful when the default option in the TBrowser is, for instance, COL. Before this change the 1D histogram appeared as blank.
- New plotting option `"LEGO3"`. Like the option `"LEGO1"`, the option `"LEGO3"` draws a lego plot using the hidden surface removal technique but doesn't draw the border lines of each individual lego-bar. This is very useful for histograms having many bins. With such histograms the option `"LEGO1"` gives a black image because of the border lines. This option also works with stacked legos.
- New plotting option `"LEGO4"`. Draw a lego plot with hidden surface removal, like LEGO1, but without the shadow effect on each lego-bar.
- Line attributes can be used in lego plots to change the edges' style. It works when drawing a `TH2` in LEGO or SURF mode whatever the coordinate system used (car, pol, cyl, sph, and psr). It also handles `THStack` (lego only).
- Implement in THistPainter::GetObjectInfo the case of TProfile and TProfile2D to print the tooltip information on each bin. Disable the printing of the bin information for TH3, since it is not currently possible to retrieve the 3d bin number from the pixel coordinate.

- Fit parameters with very long name destroyed the stats display. This is now fixed.
  Example:

          {
             gStyle->SetOptFit(111);
             TH1F *hist = new TH1F("hist","hist",100,-5,5);
             TF1 *fit = new TF1("fit","gaus",-5,5);
             fit->SetParName(2,"Parameter with very very very very long name");
             hist->FillRandom("gaus",5000);
             hist->Draw();
             hist->Fit(fit);
          }

- The statistics display has a new option: "I"=2 (the default one remains "i"=1). The value displayed for integral is `TH1::Integral("width")` instead of `TH1::Integral()`. Example:

          {
             TH1D * histo1D = new TH1D ("histo1D","",2,0.,4.) ;
             histo1D->SetBinContent( 1,1.) ;
             histo1D->SetBinContent( 2,2.) ;
             TCanvas * canvas = new TCanvas () ;
             canvas->Divide(2,1) ;
             canvas->cd(1) ; gStyle->SetOptStat("nemruoi") ; histo1D->DrawClone() ;
             canvas->cd(2) ; gStyle->SetOptStat("nemruoI") ; histo1D->DrawClone() ;
          }

- `TH1` was drawn improperly in "Logx" mode if "X" axis starts at negative values. The following macro illustrades this problem.

          {
             TCanvas *c1 = new TCanvas("c1", "c1",0,0,1200,700);
             int n = 100;
             Float_t d = 0.5;
             TH1F *h1 = new TH1F("h1", "x_min = - d", n, -d, 100-d);
             h1->Fill(1, 1); h1->Fill(3, 3); h1->Fill(5, 5); h1->Fill(7, 7);

             TH1F *h2 = new TH1F("h2", "x_min = +d", n, d, 100+d);
             h2->Fill(1, 1); h2->Fill(3, 3); h2->Fill(5, 5); h2->Fill(7, 7);

             c1->Divide(1, 2);
             c1->cd(1); gPad->SetLogx(); h1->Draw(); // upper picture
             c1->cd(2); gPad->SetLogx(); h2->Draw(); // lower picture
             h1->GetXaxis()->SetMoreLogLabels();
             h2->GetXaxis()->SetMoreLogLabels();
             c1_1->SetGridx();
             c1_2->SetGridx();
          }

- In `PaintStat2` the temporary string used to paint the fit parameters was too small and in some cases the errors where truncated. The size of the string is now the same as in `PaintStat`.
- Display the bin error for 2D histograms in the status bar.

- New option `CANDLE` to draw 2D histograms as Candle-PLot (Box-PLot). A Candle plot (also known as a "box-and whisker plot" or simply "box plot") is a convenient way to describe graphically a data distribution (D) with only the five numbers. It was invented in 1977 by John Tukey.

  With the option CANDLEX five numbers are:

  1. The minimum value of the distribution D (bottom dashed line).
  2. The lower quartile (Q1): 25% of the data points in D are less than Q1 (bottom of the box).
  3. The median (M): 50% of the data points in D are less than M (thick line segment inside the box).
  4. The upper quartile (Q3): 75% of the data points in D are less than Q3 (top of the box).
  5. The maximum value of the distribution D (top dashed line).

  The mean value of the distribution D is also represented as a circle.

  In this implementation a TH2 is considered as a collection of TH1 along X (option `CANDLE` or `CANDLEX`) or Y (option `CANDLEY`). Each TH1 is represented as a candle plot.

  Example:

          {
             TH2F *hcandle = new TH2F("hcandle","Option CANDLE example ",40,-4,4,40,-20,20);
             Float_t px, py;
             for (Int_t i = 0; i < 25000; i++) {
                gRandom->Rannor(px,py);
                hcandle->Fill(px,5*py);
             }
             hcandle->SetMarkerSize(0.5);
             hcandle->Draw("CANDLE");
          }

  Candle plot example

- The option "9" as been removed. It is not needed anymore since the line compression has been implemented in `TPadPainter`.

- The `BOX` option was handling `TH2::SetMinimum()` differently from the other drawing options. As reported here.

#### TGraphPainter

- Fix the problem described here. When drawn with option SAME the histogram 1st and last bins might be wrong. The following macro shows the problem:

          {
             TCanvas *c = new TCanvas("c","c",900,900);
             c->Divide (1,2);

             TH1D * histo1 = new TH1D ("histo1","histo1",100,0.,100.) ;
             histo1->SetBinContent(51,80.) ;

             TH1D * histo2 = new TH1D ("histo2","histo2",100,49.9,51.1) ;  /// not ok
             histo2->SetMinimum(0.) ; histo2->SetMaximum(100.) ;

             c->cd(1); gPad->DrawFrame(49.9, 0., 51.1, 100);
             histo1->Draw("same");

             Double_t xAxis[4] = {3., 5., 7., 9.};
             TH1D *histo2 = new TH1D("histo","",3, xAxis);
             histo2->SetBinContent(1,2.);
             histo2->SetBinContent(2,4.);
             histo2->SetBinContent(3,3.);

             c->cd(2); gPad->DrawFrame(4.,0., 10.,5.);
             histo2->Draw("same");
          }

- In `TGraph2DPainter::PaintLevels` the colour levels used to paint the triangles did not match the minimum and maximum set by the user on the `TGraph2D`. This problem was reported here

#### TPaletteAxis

- The histogram Z axis title is now painted along the palette axis.

### TAxis

- A time axis defined with the GMT option, saved into a root file in a given time zone, was different when displayed in an other time zone. The time zone offset in which the axis was created is now saved with the time axis offset allowing to make the right adjustments when the axis is displayed in an other time zone.

### TGraph2DPainter

- Because of the range along the Z axis, the following macro produced a wrong plot. The markers' colors did not match the palette and some of them were not clipped.

      {
         Double_t x[10] = {1.,2.,3.,4.,5.,6.,7.,8.,9.,10.};
         Double_t y[10] = {.4,.5,.1,.3,.8,.4,.5,.6,.2,.1};
         Double_t z[10] = {1.,2.,3.,4.,5.,6.,7.3,8.,9.,10.};
         TGraph2D *gr = new TGraph2D("graph2d","graph2d",10,x,y,z);
         gr->SetMarkerStyle(20);
         gr->SetMaximum(7.5);
         gr->SetMinimum(2.5);
         gr->Draw("zpcol");
      }

### TMultiGraph

- A new option `3D` allows to draw the graphs in a 3D space. See the following example:

      {
         c1 = new TCanvas("c1","multigraph L3",200,10,700,500);
         c1->SetFrameFillColor(30);

         TMultiGraph *mg = new TMultiGraph();

         TGraph *gr1 = new TGraph(); gr1->SetLineColor(kBlue);
         TGraph *gr2 = new TGraph(); gr2->SetLineColor(kRed);
         TGraph *gr3 = new TGraph(); gr3->SetLineColor(kGreen);
         TGraph *gr4 = new TGraph(); gr4->SetLineColor(kOrange);

         Double_t dx = 6.28/100;
         Double_t x  = -3.14;
         for (int i=0; i<=100; i++) {
            x = x+dx;
            gr1->SetPoint(i,x,2.*TMath::Sin(x));
            gr2->SetPoint(i,x,TMath::Cos(x));
            gr3->SetPoint(i,x,TMath::Cos(x*x));
            gr4->SetPoint(i,x,TMath::Cos(x*x*x));
         }

         mg->Add(gr4); gr4->SetTitle("Cos(x*x*x)"); gr4->SetLineWidth(3);
         mg->Add(gr3); gr3->SetTitle("Cos(x*x)")  ; gr3->SetLineWidth(3);
         mg->Add(gr2); gr2->SetTitle("Cos(x)")    ; gr2->SetLineWidth(3);
         mg->Add(gr1); gr1->SetTitle("2*Sin(x)")  ; gr1->SetLineWidth(3);

         mg->Draw("a fb  l3d");
      }

### TH1

- A canvas saved in a `.C` file generated wrong code if it contained an histogram drawn with the option `COLZ`.
- Add the support for asymmetric errors, by adding the methods `TH1::GetBinErrorLow(ibin)` and `TH1::GetBinErrorUp(ibin)`.
- Add possibility to use different bin error types with `TH1::SetBinErrorOption(type)`. The type of errors which one can set are:
  - `TH1::kNormal`: this are the default errors (symmetric) based on the normal approximation. Bin error = sqrt(N). In case of a weighted histogram (non-integer bin content), the normal approximation is always used
  - TH1::kPoisson: in this case the lower and upper error are defined by the 68% classical (frequentist) Poisson interval for N counts (Garwood Poisson interval).
  - TH1::kPoisson2: as above but in this case a 95% (2-sigma) Poisson interval is used.
- Change all the `TH1::Add`, `TH1::Divide`, `TH1::Multiply`, methods and those in the derived classes (e.g. in TProfile classes) to return a boolean. The boolean is set to false in case the method fails (e.g when the histograms are not consistent, they have different bins)
- Add in TH1::Add a check for the labels. If the histogram axes to be added have same bin labels no warning is produced