TPaletteAxis.cxx

Go to the documentation of this file.
00001 // @(#)root/histpainter:$Id: TPaletteAxis.cxx 37541 2010-12-11 10:50:58Z couet $
00002 // Author: Rene Brun   15/11/2002
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include "TROOT.h"
00014 #include "TPaletteAxis.h"
00015 #include "TVirtualPad.h"
00016 #include "TStyle.h"
00017 #include "TMath.h"
00018 #include "TView.h"
00019 #include "TH1.h"
00020 #include "TGaxis.h"
00021 
00022 ClassImp(TPaletteAxis)
00023 
00024 
00025 //______________________________________________________________________________
00026 /* Begin_Html
00027 <center><h2>The palette painting class</h2></center>
00028 
00029 A <tt>TPaletteAxis</tt> object is used to display the color palette when
00030 drawing 2-d histograms.
00031 <p>
00032 The <tt>TPaletteAxis</tt> is automatically created drawn when drawing a 2-D
00033 histogram when the option "Z" is specified.
00034 <p>
00035 A <tt>TPaletteAxis</tt> object is added to the histogram list of functions and
00036 can be retrieved doing:
00037 <pre>
00038    TPaletteAxis *palette = (TPaletteAxis*)h->GetListOfFunctions()->FindObject("palette");
00039 </pre>
00040 then the pointer <tt>palette</tt> can be used to change the pallette attributes.
00041 <p>
00042 Because the palette is created at painting time only, one must issue a:
00043 <pre>
00044    gPad->Update();
00045 </pre>
00046 before retrieving the palette pointer in order to create the palette. The following
00047 macro gives an example.
00048 
00049 End_Html
00050 Begin_Macro(source)
00051 {
00052    TCanvas *c1 = new TCanvas("c1","c1",600,400);
00053    TH2F *h2 = new TH2F("h2","Example of a resized palette ",40,-4,4,40,-20,20);
00054    Float_t px, py;
00055    for (Int_t i = 0; i < 25000; i++) {
00056       gRandom->Rannor(px,py);
00057       h2->Fill(px,5*py);
00058    }
00059    gStyle->SetPalette(1);
00060    h2->Draw("COLZ");
00061    gPad->Update();
00062    TPaletteAxis *palette = (TPaletteAxis*)h2->GetListOfFunctions()->FindObject("palette");
00063    palette->SetY2NDC(0.7);
00064    return c1;
00065 }
00066 End_Macro
00067 Begin_Html
00068 
00069 <tt>TPaletteAxis</tt> inherits from <tt>TBox</tt> and <tt>TPave</tt>. The methods
00070 allowing to specify the palette position are inherited from these two classes.
00071 <p>
00072 The palette can be interactively moved and resized. The context menu
00073 can be used to set the axis attributes.
00074 <p>
00075 It is possible to select a range on the axis to set the min/max in z
00076 
00077 End_Html */
00078 
00079 
00080 //______________________________________________________________________________
00081 TPaletteAxis::TPaletteAxis(): TPave()
00082 {
00083    // Palette default constructor.
00084 
00085    fH  = 0;
00086    SetName("");
00087 }
00088 
00089 
00090 //______________________________________________________________________________
00091 TPaletteAxis::TPaletteAxis(Double_t x1, Double_t y1,Double_t x2, Double_t  y2, TH1 *h)
00092        :TPave(x1,y1,x2,y2)
00093 {
00094    // Palette normal constructor.
00095 
00096    fH = h;
00097    SetName("palette");
00098    TAxis *zaxis = fH->GetZaxis();
00099    fAxis.ImportAxisAttributes(zaxis);
00100    if (gPad->GetView()) SetBit(kHasView);
00101 }
00102 
00103 
00104 //______________________________________________________________________________
00105 TPaletteAxis::~TPaletteAxis()
00106 {
00107    // Palette destructor.
00108 
00109    if (fH) fH->GetListOfFunctions()->Remove(this);
00110 }
00111 
00112 
00113 //______________________________________________________________________________
00114 TPaletteAxis::TPaletteAxis(const TPaletteAxis &palette) : TPave(palette)
00115 {
00116    // Palette copy constructor.
00117 
00118    ((TPaletteAxis&)palette).Copy(*this);
00119 }
00120 
00121 
00122 //______________________________________________________________________________
00123 void TPaletteAxis::Copy(TObject &obj) const
00124 {
00125    // Copy a palette to a palette.
00126 
00127    TPave::Copy(obj);
00128    ((TPaletteAxis&)obj).fH    = fH;
00129    ((TPaletteAxis&)obj).fName = fName;
00130 }
00131 
00132 
00133 //______________________________________________________________________________
00134 Int_t TPaletteAxis::DistancetoPrimitive(Int_t px, Int_t py)
00135 {
00136    // Check if mouse on the axis region.
00137 
00138    Int_t plxmax = gPad->XtoAbsPixel(fX2);
00139    Int_t plymin = gPad->YtoAbsPixel(fY1);
00140    Int_t plymax = gPad->YtoAbsPixel(fY2);
00141    if (px > plxmax && px < plxmax+30 && py >= plymax &&py <= plymin) return px-plxmax;
00142 
00143    //otherwise check if inside the box
00144    return TPave::DistancetoPrimitive(px,py);
00145 }
00146 
00147 
00148 //______________________________________________________________________________
00149 void TPaletteAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00150 {
00151    // Check if mouse on the axis region.
00152 
00153    static Int_t kmode = 0;
00154    Int_t plxmin = gPad->XtoAbsPixel(fX1);
00155    Int_t plxmax = gPad->XtoAbsPixel(fX2);
00156    if (kmode != 0 || px <= plxmax) {
00157       if (event == kButton1Down) kmode = 1;
00158       TBox::ExecuteEvent(event,px,py);
00159       if (event == kButton1Up) kmode = 0;
00160       // In case palette coordinates have been modified, recompute NDC coordinates
00161       Double_t dpx  = gPad->GetX2() - gPad->GetX1();
00162       Double_t dpy  = gPad->GetY2() - gPad->GetY1();
00163       Double_t xp1  = gPad->GetX1();
00164       Double_t yp1  = gPad->GetY1();
00165       fX1NDC = (fX1-xp1)/dpx;
00166       fY1NDC = (fY1-yp1)/dpy;
00167       fX2NDC = (fX2-xp1)/dpx;
00168       fY2NDC = (fY2-yp1)/dpy;
00169       return;
00170    }
00171    gPad->SetCursor(kHand);
00172    static Double_t ratio1, ratio2;
00173    static Int_t px1old, py1old, px2old, py2old;
00174    Double_t temp, xmin,xmax;
00175 
00176    switch (event) {
00177 
00178    case kButton1Down:
00179       ratio1 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
00180       py1old = gPad->YtoAbsPixel(fY1+ratio1*(fY2 - fY1));
00181       px1old = plxmin;
00182       px2old = plxmax;
00183       py2old = py1old;
00184       gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
00185       gVirtualX->SetLineColor(-1);
00186       // No break !!!
00187 
00188    case kButton1Motion:
00189       gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
00190       ratio2 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
00191       py2old = gPad->YtoAbsPixel(fY1+ratio2*(fY2 - fY1));
00192       gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
00193       break;
00194 
00195    case kButton1Up:
00196       if (gROOT->IsEscaped()) {
00197          gROOT->SetEscape(kFALSE);
00198          break;
00199       }
00200 
00201       ratio2 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
00202       xmin = ratio1;
00203       xmax = ratio2;
00204       if (xmin > xmax) {
00205          temp   = xmin;
00206          xmin   = xmax;
00207          xmax   = temp;
00208          temp   = ratio1;
00209          ratio1 = ratio2;
00210          ratio2 = temp;
00211       }
00212       if (ratio2 - ratio1 > 0.05) {
00213          if (fH->GetDimension() == 2) {
00214             Double_t zmin = fH->GetMinimum();
00215             Double_t zmax = fH->GetMaximum();
00216             if(gPad->GetLogz()){
00217                if (zmin <= 0 && zmax > 0) zmin = TMath::Min((Double_t)1,
00218                                                             (Double_t)0.001*zmax);
00219                zmin = TMath::Log10(zmin);
00220                zmax = TMath::Log10(zmax);
00221             }
00222             Double_t newmin = zmin + (zmax-zmin)*ratio1;
00223             Double_t newmax = zmin + (zmax-zmin)*ratio2;
00224             if(newmin < zmin)newmin = fH->GetBinContent(fH->GetMinimumBin());
00225             if(newmax > zmax)newmax = fH->GetBinContent(fH->GetMaximumBin());
00226             if(gPad->GetLogz()){
00227                newmin = TMath::Exp(2.302585092994*newmin);
00228                newmax = TMath::Exp(2.302585092994*newmax);
00229             }
00230             fH->SetMinimum(newmin);
00231             fH->SetMaximum(newmax);
00232             fH->SetBit(TH1::kIsZoomed);
00233          }
00234          gPad->Modified(kTRUE);
00235       }
00236       gVirtualX->SetLineColor(-1);
00237       kmode = 0;
00238       break;
00239    }
00240 }
00241 
00242 
00243 //______________________________________________________________________________
00244 Int_t TPaletteAxis::GetBinColor(Int_t i, Int_t j)
00245 {
00246    // Returns the color index of the bin (i,j).
00247    //
00248    // This function should be used after an histogram has been plotted with the
00249    // option COL or COLZ like in the following example:
00250    //
00251    //   h2->Draw("COLZ");
00252    //   gPad->Update();
00253    //   TPaletteAxis *palette =
00254    //      (TPaletteAxis*)h2->GetListOfFunctions()->FindObject("palette");
00255    //   Int_t ci = palette->GetBinColor(20,15);
00256    //
00257    // Then it is possible to retrieve the RGB components in the following way:
00258    //
00259    //   TColor *c = gROOT->GetColor(ci);
00260    //   float x,y,z;
00261    //   c->GetRGB(x,y,z);
00262 
00263    Double_t zc = fH->GetBinContent(i,j);
00264    return GetValueColor(zc);
00265 }
00266 
00267 
00268 //______________________________________________________________________________
00269 char *TPaletteAxis::GetObjectInfo(Int_t /* px */, Int_t py) const
00270 {
00271    // Displays the z value corresponding to cursor position py.
00272 
00273    Double_t z;
00274    static char info[64];
00275 
00276    Double_t zmin = fH->GetMinimum();
00277    Double_t zmax = fH->GetMaximum();
00278    Int_t   y1   = gPad->GetWh()-gPad->VtoPixel(fY1NDC);
00279    Int_t   y2   = gPad->GetWh()-gPad->VtoPixel(fY2NDC);
00280    Int_t   y    = gPad->GetWh()-py;
00281 
00282    if (gPad->GetLogz()) {
00283       if (zmin <= 0 && zmax > 0) zmin = TMath::Min((Double_t)1,
00284                                                    (Double_t)0.001*zmax);
00285       Double_t zminl = TMath::Log10(zmin);
00286       Double_t zmaxl = TMath::Log10(zmax);
00287       Double_t zl    = (zmaxl-zminl)*((Double_t)(y-y1)/(Double_t)(y2-y1))+zminl;
00288       z = TMath::Power(10.,zl);
00289    } else {
00290       z = (zmax-zmin)*((Double_t)(y-y1)/(Double_t)(y2-y1))+zmin;
00291    }
00292 
00293    snprintf(info,64,"(z=%g)",z);
00294    return info;
00295 }
00296 
00297 
00298 //______________________________________________________________________________
00299 Int_t TPaletteAxis::GetValueColor(Double_t zc)
00300 {
00301    // Returns the color index of the given z value
00302    //
00303    // This function should be used after an histogram has been plotted with the
00304    // option COL or COLZ like in the following example:
00305    //
00306    //   h2->Draw("COLZ");
00307    //   gPad->Update();
00308    //   TPaletteAxis *palette =
00309    //      (TPaletteAxis*)h2->GetListOfFunctions()->FindObject("palette");
00310    //   Int_t ci = palette->GetValueColor(30.);
00311    //
00312    // Then it is possible to retrieve the RGB components in the following way:
00313    //
00314    //   TColor *c = gROOT->GetColor(ci);
00315    //   float x,y,z;
00316    //   c->GetRGB(x,y,z);
00317 
00318    Double_t wmin  = fH->GetMinimum();
00319    Double_t wmax  = fH->GetMaximum();
00320    Double_t wlmin = wmin;
00321    Double_t wlmax = wmax;
00322 
00323    if (gPad->GetLogz()) {
00324       if (wmin <= 0 && wmax > 0) wmin = TMath::Min((Double_t)1,
00325                                                    (Double_t)0.001*wmax);
00326       wlmin = TMath::Log10(wmin);
00327       wlmax = TMath::Log10(wmax);
00328    }
00329 
00330    Int_t ncolors = gStyle->GetNumberOfColors();
00331    Int_t ndivz   = TMath::Abs(fH->GetContour());
00332    Int_t theColor,color;
00333    Double_t scale = ndivz/(wlmax - wlmin);
00334 
00335    if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz()) zc = TMath::Log10(zc);
00336    if (zc < wlmin) zc = wlmin;
00337 
00338    color = Int_t(0.01+(zc-wlmin)*scale);
00339 
00340    theColor = Int_t((color+0.99)*Double_t(ncolors)/Double_t(ndivz));
00341    return gStyle->GetColorPalette(theColor);
00342 }
00343 
00344 
00345 //______________________________________________________________________________
00346 void TPaletteAxis::Paint(Option_t *)
00347 {
00348    // Paint the palette.
00349 
00350    ConvertNDCtoPad();
00351 
00352    SetFillStyle(1001);
00353    Double_t ymin = fY1;
00354    Double_t ymax = fY2;
00355    Double_t xmin = fX1;
00356    Double_t xmax = fX2;
00357    Double_t wmin = fH->GetMinimum();
00358    Double_t wmax = fH->GetMaximum();
00359    Double_t wlmin = wmin;
00360    Double_t wlmax = wmax;
00361    Double_t y1,y2,w1,w2,zc;
00362 
00363    if ((wlmax - wlmin) <= 0) { 
00364       Double_t mz = wlmin*0.1;
00365       wlmin = wlmin-mz;
00366       wlmax = wlmax+mz;
00367       wmin = wlmin;
00368       wmax = wlmax;
00369    }
00370 
00371    if (gPad->GetLogz()) {
00372       if (wmin <= 0 && wmax > 0) wmin = TMath::Min((Double_t)1,
00373                                                    (Double_t)0.001*wmax);
00374       wlmin = TMath::Log10(wmin);
00375       wlmax = TMath::Log10(wmax);
00376    }
00377    Double_t ws    = wlmax-wlmin;
00378    Int_t ncolors = gStyle->GetNumberOfColors();
00379    Int_t ndivz = TMath::Abs(fH->GetContour());
00380    Int_t theColor,color;
00381    Double_t scale = ndivz/(wlmax - wlmin);
00382    for (Int_t i=0;i<ndivz;i++) {
00383 
00384       zc = fH->GetContourLevel(i);
00385       if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
00386          zc = TMath::Log10(zc);
00387       w1 = zc;
00388       if (w1 < wlmin) w1 = wlmin;
00389 
00390       w2 = wlmax;
00391       if (i < ndivz-1) {
00392          zc = fH->GetContourLevel(i+1);
00393          if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
00394             zc = TMath::Log10(zc);
00395          w2 = zc;
00396       }
00397 
00398       if (w2 <= wlmin) continue;
00399       y1 = ymin + (w1-wlmin)*(ymax-ymin)/ws;
00400       y2 = ymin + (w2-wlmin)*(ymax-ymin)/ws;
00401 
00402       if (fH->TestBit(TH1::kUserContour)) {
00403          color = i;
00404       } else {
00405          color = Int_t(0.01+(w1-wlmin)*scale);
00406       }
00407 
00408       theColor = Int_t((color+0.99)*Double_t(ncolors)/Double_t(ndivz));
00409       SetFillColor(gStyle->GetColorPalette(theColor));
00410       TAttFill::Modify();
00411       gPad->PaintBox(xmin,y1,xmax,y2);
00412    }
00413    Int_t ndiv  = fH->GetZaxis()->GetNdivisions()%100; //take primary divisions only
00414    char chopt[5] = "S   ";
00415    chopt[1] = 0;
00416    strncat(chopt, "+L", 2);
00417    if (ndiv < 0) {
00418       ndiv =TMath::Abs(ndiv);
00419       strncat(chopt, "N", 1);
00420    }
00421    if (gPad->GetLogz()) {
00422       wmin = TMath::Power(10.,wlmin);
00423       wmax = TMath::Power(10.,wlmax);
00424       strncat(chopt, "G", 1);
00425    }
00426    fAxis.PaintAxis(xmax,ymin,xmax,ymax,wmin,wmax,ndiv,chopt);
00427 }
00428 
00429 
00430 //______________________________________________________________________________
00431 void TPaletteAxis::SavePrimitive(ostream &out, Option_t * /*= ""*/)
00432 {
00433    // Save primitive as a C++ statement(s) on output stream out.
00434 
00435    //char quote = '"';
00436    out<<"   "<<endl;
00437    if (gROOT->ClassSaved(TPaletteAxis::Class())) {
00438       out<<"   ";
00439    } else {
00440       out<<"   "<<ClassName()<<" *";
00441    }
00442    if (fOption.Contains("NDC")) {
00443       out<<"palette = new "<<ClassName()<<"("<<fX1NDC<<","<<fY1NDC<<","<<fX2NDC<<","<<fY2NDC
00444       <<","<<fH->GetName()<<");"<<endl;
00445    } else {
00446       out<<"palette = new "<<ClassName()<<"("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
00447       <<","<<fH->GetName()<<");"<<endl;
00448    }
00449    out<<"palette->SetLabelColor(" <<fAxis.GetLabelColor()<<");"<<endl;
00450    out<<"palette->SetLabelFont("  <<fAxis.GetLabelFont()<<");"<<endl;
00451    out<<"palette->SetLabelOffset("<<fAxis.GetLabelOffset()<<");"<<endl;
00452    out<<"palette->SetLabelSize("  <<fAxis.GetLabelSize()<<");"<<endl;
00453    out<<"palette->SetTitleOffset("<<fAxis.GetTitleOffset()<<");"<<endl;
00454    out<<"palette->SetTitleSize("  <<fAxis.GetTitleSize()<<");"<<endl;
00455    SaveFillAttributes(out,"palette",-1,-1);
00456    SaveLineAttributes(out,"palette",1,1,1);
00457 }
00458 
00459 
00460 //______________________________________________________________________________
00461 void TPaletteAxis::UnZoom()
00462 {
00463    // Unzoom the palette
00464 
00465    TView *view = gPad->GetView();
00466    if (view) {
00467       delete view;
00468       gPad->SetView(0);
00469    }
00470    fH->GetZaxis()->SetRange(0,0);
00471    if (fH->GetDimension() == 2) {
00472       fH->SetMinimum();
00473       fH->SetMaximum();
00474       fH->ResetBit(TH1::kIsZoomed);
00475    }
00476 }

Generated on Tue Jul 5 14:24:31 2011 for ROOT_528-00b_version by  doxygen 1.5.1