I have a TPad *p1 = new TPad("p1", "p1", 0, 0, 1, 1);
, for which I set p1->SetFillStyle(0);
, p1->SetFillColor(0);
and p1->SetFrameFillStyle(0);
.
I also have a TF2 *f
which I f->Draw("cont3");
in this “transparent” pad.
Then I create a TMarker *m = new TMarker(x0, y0, 2);
which I m->Draw();
on top of it.
Now, I would also like to draw three vertical lines at “x1”, “x2” and “x3” (going up-down over all the picture) plus a “vertical shaded area” (going over all the picture) between the “x1” and “x3” (vertical) lines.
This should look like a vertical stripe: “mean” (“x2”) -+ 1 “sigma” (from “x1” to “x3”).
What is the easiest way to achieve it?
BTW. The pad “p1” is “transparent” as below there is another “standard” TPad *p0 = new TPad("p0", "p0", 0, 0, 1, 1);
in which I first f->Draw("cont4");
.
Can you post a small macro ready to run ?
Thanks
Maybe something like this:
{
TF2 *f = new TF2("f", "x*x+y*y", -1, 1, -2, 2);
TCanvas *c = new TCanvas("c", "c", 500, 500);
TPad *p0 = new TPad("p0", "p0", 0, 0, 1, 1);
TPad *p1 = new TPad("p1", "p1", 0, 0, 1, 1);
p1->SetFillStyle(0); /* "p1" will be transparent */
p1->SetFillColor(0);
p1->SetFrameFillStyle(0);
p0->Draw(); p0->cd();
f->Draw("cont4");
p0->Update(); p0->Modified();
p1->Draw(); p1->cd();
f->Draw("cont3");
TMarker *m = new TMarker(0.0, 0.0, 2);
m->SetMarkerSize(2);
m->Draw();
p1->Update(); p1->Modified();
}
And now I would like to add three vertical lines at “x1” = 0.2, “x2” = 0.4 and “x3” = 0.6 plus a vertical “stripe” (shaded / hashed/ …) between “x1” and “x3”.
Another stupid question … both the “cont4” and “cont3” draw the “contents” starting at some distant from the axes. Can I somehow force them to start exactly at axes (so that there is are no white stripes between the axes and the “coloured” contents)?
{
TF2 *f = new TF2("f", "x*x+y*y", -1, 1, -2, 2);
TCanvas *c = new TCanvas("c", "c", 500, 500);
f->Draw("cont4");
gPad->Update();
Double_t bm = gPad->GetBottomMargin();
Double_t lm = gPad->GetLeftMargin();
Double_t rm = gPad->GetRightMargin();
Double_t tm = gPad->GetTopMargin();
Double_t x1 = f->GetXaxis()->GetXmin();
Double_t y1 = f->GetYaxis()->GetXmin();
Double_t x2 = f->GetXaxis()->GetXmax();
Double_t y2 = f->GetYaxis()->GetXmax();
TPad *null=new TPad("null","null",0,0,1,1);
null->SetFillStyle(0);
null->SetFrameFillStyle(0);
null->Draw();
null->cd();
null->Range(x1-(x2-x1)*(lm/(1-rm-lm)),
y1-(y2-y1)*(bm/(1-tm-lm)),
x2+(x2-x1)*(rm/(1-rm-lm)),
y2+(y2-y1)*(tm/(1-tm-lm)));
gPad->Update();
f->DrawClone("cont3 same");
TMarker *m = new TMarker(0.0, 0.0, 2);
m->SetMarkerSize(2);
m->Draw();
TLine *l1 = new TLine(0.2,-2,0.2,2); l1->Draw();
TLine *l2 = new TLine(0.4,-2,0.4,2); l2->Draw();
TLine *l3 = new TLine(0.6,-2,0.6,2); l3->Draw();
TBox *b = new TBox(0.2,-2,0.6,2);
b->SetFillColor(1); b->SetFillStyle(3004);
b->Draw();
}
Thanks.
I can see that one needs to create the “lines” and the “stipe” manually (that’s what I was afraid of).
What about the “white stipes” along axes? Can I get rid of them?
Yes, of course … how could it be an other way ?
No. The contour algorithms connect bins’ centers.
Black magic?
Well, I hoped for a simple solution like saying “hocus-pocus, abracadabra” in ROOT’s prompt.
That’s the usual thing you need to do … you just need to know the magic of ROOT in your case.
Many thanks for your help.
Yes, may be you should try this site: en.wikipedia.org/wiki/Harry_Potter
Does anybody of the ROOT development team give lectures at the Hogwarts school?
If not, maybe that would be a good idea for the future!
http://en.wikipedia.org/wiki/Hogwarts
Please find below an improved version of the Olivier’s example source code.
Two things are fixed:
- “y-low” and “y-high” coordinates for the transparent TPad were miscalculated,
- “y-low” and “y-high” coordinates for all TLine and the TBox were hard-coded fixed numbers.
For the completeness of this example, I added a “horizontal” shaded area.
{
TF2 *f = new TF2("f", "x*x+y*y", -3, 3, -5, 5);
f->SetLineWidth(1.0);
TCanvas *c = new TCanvas("c", "c", 500, 500);
f->Draw("cont4");
gPad->Update();
Double_t bm = gPad->GetBottomMargin();
Double_t lm = gPad->GetLeftMargin();
Double_t rm = gPad->GetRightMargin();
Double_t tm = gPad->GetTopMargin();
Double_t x1 = f->GetXaxis()->GetXmin();
Double_t y1 = f->GetYaxis()->GetXmin();
Double_t x2 = f->GetXaxis()->GetXmax();
Double_t y2 = f->GetYaxis()->GetXmax();
TPad *null=new TPad("null", "null", 0, 0, 1, 1);
null->SetFillStyle(0); /* a transparent pad */
null->SetFrameFillStyle(0);
null->Draw();
null->cd();
#if 0 /* 0 or 1 */
f->Draw("cont3");
gPad->Update();
#else /* 0 or 1 */
null->Range(x1-(x2-x1)*(lm/(1-rm-lm)),
y1-(y2-y1)*(bm/(1-tm-bm)),
x2+(x2-x1)*(rm/(1-rm-lm)),
y2+(y2-y1)*(tm/(1-tm-bm)));
gPad->Update();
f->DrawClone("cont3 same");
#endif /* 0 or 1 */
// "vertical" shaded area
Double_t xl = 0.2; // "left" line
Double_t xm = 0.4; // "middle" line
Double_t xr = 0.6; // "right" line
TBox *bv = new TBox(xl, y1, xr, y2);
bv->SetFillColor(1); bv->SetFillStyle(3005);
bv->Draw();
TLine *lv1 = new TLine(xl, y1, xl, y2); lv1->Draw();
TLine *lv2 = new TLine(xm, y1, xm, y2); lv2->Draw();
TLine *lv3 = new TLine(xr, y1, xr, y2); lv3->Draw();
// "horizontal" shaded area
Double_t yb = -0.6; // "bottom" line
Double_t ym = -0.4; // "middle" line
Double_t yt = -0.2; // "top" line
TBox *bh = new TBox(x1, yb, x2, yt);
bh->SetFillColor(1); bh->SetFillStyle(3004);
bh->Draw();
TLine *lh1 = new TLine(x1, yb, x2, yb); lh1->Draw();
TLine *lh2 = new TLine(x1, ym, x2, ym); lh2->Draw();
TLine *lh3 = new TLine(x1, yt, x2, yt); lh3->Draw();
// the "middle" marker
Double_t x0 = 0.0; // marker's "x" position
Double_t y0 = 0.0; // marker's "y" position
TMarker *m = new TMarker(x0, y0, 2);
m->SetMarkerSize(2);
m->Draw();
}