Polar Color Graph


_ROOT Version:Both 5 and 6
_Platform:Ubuntu 14-16-18
Compiler: Not Provided


Dear root experts,

I would like to make a polar graph which I don’t know if possible under root framework.

I just made a quick sketch of it and attached.

I will define histograms like

TGraphErrors* hist[4];

hist[i] = new TGraphErrors(16, x, y, ex, ey); for i=0,1

where double x[16]; and double y[16];

hist[j] = new TGraphErrors(8, x, y, ex, ey); for j=2,3

where double x[8]; and double y[8];

Polar graph will have 4 concentric circles and 16/8 division along the circle. Divisions will be labeled by numbers and not by angles.

I tried TGraphPolar instead of TGraphErrors, couldn’t do.

I tried TH2D and then fill x,y and then Draw->(“colzpol”) or Draw->(“pollego2z”)

I tried lots of other stuff too, all to no avail.

Is it possible to make a graph as shown in the sketch ? If possible, can you tell me how I can do it ? Just give me the recipe, I can do the rest.

Thanks

Hi,

I’m sure @couet knows if it’s possible, and how :wink:

Cheers, Bertrand.

may be this:

{
   TCanvas *c1 = new TCanvas("c1","c1",600,400);
   TH2F *hcol1 = new TH2F("hcol1","Option COLor combined with POL",40,-4,4,40,-4,4);
   Float_t px, py;
   for (Int_t i = 0; i < 25000; i++) {
      gRandom->Rannor(px,py);
      hcol1->Fill(px,py);
   }
   hcol1->Draw("COLZPOL");
   return c1;
}

I tried that one indeed. But it doesn’t produce plots close to what I want.

For a single circle, it produces a plot of which top view is attachedpolarcolor_1_1_20_2

So, what you see is, x value is represented by the number of divisions in the phi plane, which is what I want, but y value is represented by the radius, and not by the color.

I wish that y value is not represented by radius, all the y values will have the same radius but differ only in color corresponding to their value.

Radius will be assigned to different circles.

Closest to what I demand is done only by one person, zhiyi, in this topic. Maybe I should have a contact with him. Plot polar TH2

can you post a small script ?

I created a small macro,

void polarcolor(){
        TCanvas * c1 = new TCanvas("c1", "", 600, 600);
        c1->SetTheta(90);
        c1->SetPhi(180);
        TH2D* hist[2];

        hist[0] = new TH2D("polar hist","",8, 0 , 8, 10, 0.8 , 1.0);
        hist[1] = new TH2D("polar hist","",4, 0 , 8, 10, 0.8 , 1.0);

        double x1[8]={1,2,3,4,5,6,7,8};
        double y1[8]={0.85,0.9,0.95,0.95,0.98,0.86,0.82,0.94};
        double x2[4]={1,3,5,7};
        double y2[4]={0.92,0.95,0.88,0.99};

        for(int i=0; i<8; i++){hist[0]->Fill(x1[i],y1[i]);}
        for(int j=0; j<4; j++){hist[1]->Fill(x2[j],y2[j]);}

        for(int k=0; k<2; k++){
                c1->cd(1);
                if(k==0){hist[k]->Draw("pollego2z");}
                else{hist[k]->Draw("same");}
        }
}

If we succeed with this small example a plot like the following, then we are done. I tried polcolz instead of pollego2z, too. Didn’t work either.

(note : colors are not representative of the data in the macro above)

May be this:

void polarcolor(){
   TCanvas * c1 = new TCanvas("c1", "", 600, 600);
   c1->SetTheta(90.);
   c1->SetPhi(0.);

   TH2D* hist[2];
   auto hs = new THStack();

   hist[0] = new TH2D("polar hist","",8, 0 , 8, 10, 0.8 , 1.0);
   hist[1] = new TH2D("polar hist","",4, 0 , 8, 10, 0.8 , 1.0);

   double x1[8]={1,2,3,4,5,6,7,8};
   double y1[8]={0.85,0.9,0.95,0.95,0.98,0.86,0.82,0.94};
   double x2[4]={1,3,5,7};
   double y2[4]={0.92,0.95,0.88,0.99};

   for(int i=0; i<8; i++){hist[0]->Fill(x1[i],y1[i]);}
   for(int j=0; j<4; j++){hist[1]->Fill(x2[j],y2[j]);}

   hist[0]->SetFillColor(kRed);
   hist[1]->SetFillColor(kBlue);

   hs->Add(hist[0]);
   hs->Add(hist[1]);

   hs->Draw("lego1 0 pol ");

}

Not actually, @couet,

The red ones must have the same radial distance from the center and not all of them must have the same color. The same is true for blue ones. The color must represent y value.

So, I thought a 3D histogram might be the answer, where, x value will be the number of divisions along the phi plane, y value will be radial distance and z value will be the value we want to show with color.

        hist[0] = new TH3D("polar hist","", 8, 0 , 8, 10, 0, 10, 10, 0.8 , 1.0);
        hist[1] = new TH3D("polar hist","", 4, 0 , 8, 10, 0, 10, 10, 0.8 , 1.0);

        double x1[8]={1,2,3,4,5,6,7,8};
        double y1[8]={5,5,5,5,5,5,5,5};
        double z1[8]={0.85,0.9,0.95,0.95,0.93,0.86,0.83,0.94};

        double x2[4]={1,3,5,7};
        double y2[4]={6,6,6,6};
        double z2[4]={0.92,0.95,0.88,0.99};

However, it didn’t work. Also THStack is not defined for 3D histograms.

@couet, I managed to plot 2D cartesian version. It just looks fine. All I need is the polar version of this plot with appropriate labeling of polar divisions. When I change the draw option to polcolz, root gets confused all of a sudden.

void polarcolor(){
        TCanvas * c1 = new TCanvas("c1", "", 600, 600);

        gStyle->SetOptStat(0);
        gStyle->SetPalette(kDeepSea);

        TH2D* hist[2];

        hist[0] = new TH2D("polar hist","",10, 0,10,4,0,4);
        hist[1] = new TH2D("polar hist","",6, -1,11,4,0,4);

        double x1[8]={1,2,3,4,5,6,7,8};
        double y1[8]={0.85,0.95,0.85,0.95,0.85,0.95,0.85,0.95};
        double x2[4]={1,3,5,7};
        double y2[4]={0.95,0.85,0.95,0.85};


        for(int i=0; i<8; i++){hist[0]->Fill(x1[i],1,y1[i]);}
        for(int j=0; j<4; j++){hist[1]->Fill(x2[j],2,y2[j]);}

        c1->cd(1);
        hist[0]->Draw("colz");
        hist[1]->Draw("colsame");
}

I think with the current version (0,0) is assumed to be in the center of the plot when you use the COLPOL option. So what you are trying to do will not work. The following code shows the problem:

void polarcolor(){
        TCanvas * c1 = new TCanvas("c1", "", 600, 600);

        gStyle->SetOptStat(0);

        TH2D* hist[2];

        hist[0] = new TH2D("h1","h1",10, 0,10,4,0,4);
        hist[1] = new TH2D("h2","h2",6, -1,11,4,0,4);

        double x1[8]={1,2,3,4,5,6,7,8};
        double y1[8]={0.85,0.95,0.85,0.95,0.85,0.95,0.85,0.95};
        double x2[4]={1,3,5,7};
        double y2[4]={0.95,0.85,0.95,0.85};


        for(int i=0; i<8; i++){hist[0]->Fill(x1[i],1,y1[i]);}
        for(int j=0; j<4; j++){hist[1]->Fill(x2[j],2,y2[j]);}

        hist[0]->Draw("colz pol");
}

@couet, What do you get as the output of this code ?

I am using root v6.10.02 and I get the following which is not what I want. The center of the circle must be at the center of the pad so that the whole of the circle is seen.

I don’t know how pol is mapping from cartesian coordinates but it does it in an awkward way.

I get the same plot you posted that’s how I conclude the polar plot is drawn according to (0,0)

@couet, Playing with the histograms ranges which are initially set suitable for cartesian system, I am able to make a progress to some degree, but still not in there,

So, this one produces the following,

void polarcolor(){
        TCanvas * c1 = new TCanvas("c1", "", 600, 600);
     
        gStyle->SetOptStat(0);
        gStyle->SetPalette(kDeepSea);

        TH2D* hist[2];

        hist[0] = new TH2D("h1","h1",16, -TMath::Pi()*2 , TMath::Pi()*2, 8, -4 , 4);
        hist[1] = new TH2D("h2","h2", 8, -TMath::Pi()*2 , TMath::Pi()*2, 8, -4 , 4);

        double x1[8]={1,2,3,4,5,6,7,8};
        double y1[8]={0.75,0.95,0.85,0.95,0.75,0.85,0.95,0.85};
        double x2[4]={1,3,5,7};
        double y2[4]={0.75,0.85,0.75,0.95};

        for(int i=0; i<8; i++){hist[0]->Fill(x1[i],1,y1[i]);}
        for(int j=0; j<4; j++){hist[1]->Fill(x2[j],2,y2[j]);}

        hist[0]->Draw("pol colz");
        hist[1]->Draw("pol col same");
}

Do you have an idea why some portions are not drawn, @couet ?

As explained here empty bin are not drawn unless the minimum of the histogram is negative

@couet I would like to report an issue, Olivier. When I set the histogram range as (0,2π) both along x and y axes with appropriate binning, I get the the figure on the left, which is perfectly good, y values are correctly represented. Then, I reset the histogram range as (-2π,2π) for both axes, doubling the binning as well. I do this, because when drawing this one with “pol” option, it will give me the desired plot. However, this time, hist[0] is not correctly filled in, as you can see in the figure on the right. The range of color palette doubled as well, which should not be the case. On the other hand, hist[1] still seems ok. What’s wrong here ? I am attaching the macros for both figures. Only lines 11-12 differ.

polarcolor_v17.C (924 Bytes)
polarcolor_v19.C (872 Bytes)

You are facing floating point “rounding errors” (coming mainly from bins’ edges calculation in ROOT).
To understand it better, try to calculate e.g.:

((TMath::Pi()*5.)/3.) - ((TMath::Pi()/3.)*5.)

and try your macro with e.g.:

double slip = -1e-11; // try with -1e-11, 0, +1e-11
hist[0] = new TH2D("h1","h1",16, -TMath::TwoPi(), TMath::TwoPi() + slip, 8, -TMath::TwoPi(), TMath::TwoPi() + slip);
hist[1] = new TH2D("h2","h2", 8, -TMath::TwoPi(), TMath::TwoPi() + slip, 8, -TMath::TwoPi(), TMath::TwoPi() + slip);

Exactly !!! @Wile_E_Coyote
The calculation turned out to be a non-zero number
Now with an infinitessimal slip, I can get the following figure which is what I wanted from the very beginning. y values seem to be correctly color-mapped.

Don’t know words to express the magnitude of my gratitude, Wile_E_Coyote.

Note that you probably need appropriate “slips” (positive or negative, I’m not sure, you need to play with it) to the negative “[xy]low” of your histograms (I’ve modified the positive “[xy]up” only), too.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.