Fill color between 2 graphs by TGraph

I have a question about the TGraph. I would like to fill the color or some lines between two graphs. I tried to use “SetFillColor” and "Draw(“AF”) commands, but these do not work.

e.g.)

TGraph *gr0 = new TGraph(i, x0, y0);
gr0 -> SetMarkerColor(1);
gr0 -> SetLineColor(1);
gr0 -> SetFillColor(45);

TGraph *gr1 = new TGraph(i, x0, y1);
gr1 -> SetMarkerColor(1);
gr1 -> SetLineColor(1);
gr1 -> SetFillColor(45);


TMultiGraph *mg = new TMultiGraph();
mg -> Add(gr0);
mg -> Add(gr1);
mg -> Draw(“ACF”);

Would you tell how to fill the color or lines between gr0 and gr1 graphs? I want to show the data range by this graph.

Example:

void twographs() {
   TCanvas *c1 = new TCanvas("c1","c1",200,10,700,500);
   const Int_t n = 20;
   Double_t x[n], y1[n], y2[n];
   for (Int_t i=0;i<n;i++) {
     x[i]  = i*0.1;
     y1[i] = 10*sin(x[i]+0.2);
     y2[i] =  9*sin(x[i]+0.2);
   }
   gr1 = new TGraph(n,x,y1);
   gr1->SetFillColor(2);
   gr2 = new TGraph(n,x,y2);
   gr2->SetFillColor(0);
   gr1->Draw("AF");
   gr2->Draw("F");
}

Another example in attachment

Rene
grshade.C (871 Bytes)

It works, thank you so much both of you, Couet and Brun.

Hi,

I am using the same commands to fill color between my two graphs, but its not working the way I want to show it…Please correct my code…
I am attaching the original and the colored plot( which is not filling the correct way)
Thanks
plot2.pdf (22.9 KB)
plot1.pdf (28.2 KB)

my code:

void rootPlotcode()
{
   ifstream f1; 
   ifstream f2; 
  
   TCanvas *c1 = new TCanvas ("c1", " ",0,0,900,600); 
   double x[1000]={0.}, y[1000]={0.},i,j;
   int ss=0, ss1=0, ss2=0, ss3=0;
   
   f1.open("RefmasstrueNH.dat");
   f2.open("OptmasstrueNH.dat");


  while(!f1.eof())
       {
       f1>>i>>j;
       x[ss]=i;
       y[ss]=j;
       ss++;
       
          }
  
   TGraph *gr = new TGraph(ss-1,x,y);
  
   gr->SetLineColor(1);
   gr->SetLineWidth(2);
   gr-> SetFillColor(2);
   gr->SetTitle("NH");
   gr->GetXaxis()->SetRangeUser(-180,180);
   gr->GetYaxis()->SetRangeUser(0,25);
   gr->GetXaxis()->SetTitle("#delta_{CP}");
   gr->GetYaxis()->SetTitle("#sigma=#sqrt{#bar{#Delta#chi^{2}}}");
   gr->GetXaxis()->CenterTitle();
   gr->GetYaxis()->CenterTitle();
   gr->SetTitle("Mass Hierarchy");
  



    while(!f2.eof())
       {
       f2>>i>>j;
       x[ss1]=i;
       y[ss1]=j;
       ss1++;
        }
 
   TGraph *gr1 = new TGraph(ss1-1,x,y);
   gr1->SetLineStyle(2);
   gr1-> SetFillColor(2);
   gr1->SetLineColor(1);
   gr1->SetLineWidth(2);
  
   gr->Draw("af");
   gr1->Draw("f");


   leg1 = new TLegend(0.9,0.7,0.48,0.9);
   leg1->AddEntry(gr,"CDR Reference Design","l");
   leg1->AddEntry(gr1,"Optimized Design", "l");
   leg1->Draw(); 
  

  f1.close();
  f2.close();
   

 }

Hi,

You have two options:

  1. Add two points to each of your TGraph. First point should be (xmin,0) and other is (xmax, 0). In this case “F” draw option will fill area you want.

  2. You can use TGraphErrors with option “3” or “4”. Check here: https://root.cern/doc/master/classTGraphPainter.html#GP03a. Just Y values in the middle and error distance between your graphs.

I am trying point no. 1, but how will I define xmin and xmax ?

In your case xmin is x of first point and xmax is x of last point.

Something like:

ss = 1;
while(!f1.eof())  {
   f1>>i>>j;
   x[ss]=i;
   y[ss]=j;
   ss++;
}
x[0] = x[1]; y[0] = 0;
x[ss] = x[ss-1]; y[ss] = 0;
  
TGraph *gr = new TGraph(ss+1,x,y);

I have added it, in the second part of the code as below-
Please see…its not showing the shad but only my graphs

’ while(!f2.eof())
{
f2>>i>>j;
x[ss1]=i;
y[ss1]=j;
ss1++;

    }

TGraph *gr1 = new TGraph(ss1-1,x,y);

TGraph *grshade = new TGraph(ss1-1);
grshade->SetPoint(ss1,xmin[ss1],0);
grshade->SetPoint(ss1+1,xmax[ss1-1],0);

gr1->SetLineStyle(2);
gr1-> SetFillColor(2);
gr1->SetLineColor(1);
gr1->SetLineWidth(2);

grshade->SetFillColor(2);

gr->Draw(“acp”);
gr1->Draw(“same”);
grshade->Draw(“same f”);’

You add two points at the end - which is not correct.
The produced filling shape will be wrong.
Add (xmin,0) as first point and (xmax,0) as last point.

Hi,

I corrected it as above…
But there is no color filling done…

’ while(!f2.eof())
{
f2>>i>>j;
x[ss1]=i;
y[ss1]=j;
ss1++;

    }

TGraph *gr1 = new TGraph(ss1-1,x,y);

TGraph *grshade = new TGraph(ss1-1);
grshade->SetPoint(ss1,xmin[ss1],xmax[ss1-1]);

gr1->SetLineStyle(2);
gr1-> SetFillColor(2);
gr1->SetLineColor(1);
gr1->SetLineWidth(2);
grshade->SetFillColor(2);

gr->Draw(“acp”);
gr1->Draw(“same”);
grshade->Draw(“F”);

It is giving me the same graph but no shade in between

This is wrong. You try to add point with coordinates (xmin,xmax)

Can yoo provide your data files?

yes…datafiles.tar.gz (10.9 KB)

I’m not sure what you are trying to achieve but maybe this:

{
  TGraph *g1 = new TGraph("RefmasstrueNH.dat");
  g1->Sort(); // ascending
  TGraph *g0 = new TGraph(*g1); // the "band"
  g0->SetTitle("RefmasstrueNH and OptmasstrueNH;#delta_{CP};#sigma=#sqrt{#bar{#Delta#chi^{2}}}");
  TGraph *g2 = new TGraph("OptmasstrueNH.dat");
#if 1 /* 0 or 1 */
  g2->Sort(); // ascending
  for (Int_t i = (g2->GetN() - 1); i >= 0; i--)
    g0->SetPoint(g0->GetN(), g2->GetX()[i], g2->GetY()[i]);
#else /* 0 or 1 */
  g2->Sort(TGraph::CompareX, kFALSE); // descending
  for (Int_t i = 0; i < g2->GetN(); i++)
    g0->SetPoint(g0->GetN(), g2->GetX()[i], g2->GetY()[i]);
#endif /* 0 or 1 */
  // g0->SetPoint(g0->GetN(), g0->GetX()[0], g0->GetY()[0]); // "close" it
  g0->SetFillColor(kRed); g0->SetLineColor(kRed); g0->SetLineWidth(1);
  g0->Draw("ALF");
  g1->SetMarkerColor(kGreen); g1->SetLineColor(kGreen); g1->SetLineWidth(2);
  g1->Draw("LP");
  g2->SetMarkerColor(kBlue); g2->SetLineColor(kBlue); g2->SetLineWidth(2);
  g2->Draw("LP");
  TLegend *l = new TLegend(0.9,0.7,0.48,0.9);
  l->AddEntry(g1, "CDR Reference Design", "LP");
  l->AddEntry(g2, "Optimized Design", "LP");
  l->Draw();
}

Hi,

I have two graphs and want to fill color in the area between them…
plot1.pdf (28.2 KB)

I tried it like this too… its not filling color
somehow I not able to set the points…

’ TGraph *grshade = new TGraph(ss);
while(!f1.eof() && !f2.eof() )
{
f1>>i>>j;
x[ss]=i;
y[ss]=j;

   f2>>i>>k;
   z[ss]=k;
   ss++;

grshade->SetPoint(1,x[0],y[ss]);
grshade->SetPoint(ss-1,x[ss-1],z[ss-1]);
}

grshade->SetFillColor(2);
gr->Draw(“acp”);
gr1->Draw(“cp”);
grshade->Draw(“f”);

srishino:
The ‘fill’ option only ‘closes’ the graph between its first and last points (with a virtual straight line between them), and then just fills the resulting enclosed area with the fill colour.
To see this, run couet’s ‘twographs’ example of Jun’07 as it is and it looks ok, but now change the the fill of gr2, (e.g. gr2->SetFillColor(1); ) and you’ll see what is actually happening. His example works because of the shapes he used but your case is different.
So, use whe method shown by Rene Brun (grshade.C), which is the same idea proposed by Wile E, and also here:
Make a band with two lines
The idea is explained in my post in that link: order the 2 original graphs in increasing x and then use them to fill a new graph, so that one graph (with n1 points) goes to points 0 to (n1-1) in the new graph and the other graph (n2 points), is filled in reverse, i.e. goes from point (n1+n2-1) to n1 in the new one.
Then draw the new graph with the fill option.
-Daniel