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.
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();
}