Question about Draw() and DrawClone

Hi, I’m a root novice. When I took some practice on drawing histogram, I meet a question as follow.
I wanted to generate a uniform distribution on area ranging [-3,3]*[-3,3] and draw it with histogram. The code I used is as follow:
‘’’
void hw1(){
TCanvas *c=new TCanvas(“c”,“TCanvas”,10,10,800,800);
int npoints=50000;
TRandom3 xgenerator, ygenerator;
xgenerator.SetSeed(0);
ygenerator.SetSeed(0);
TH2F hist2(“hist2”,“histogram”,600,-3,3,600,-3,3);
for(int i=0;i<npoints;i++){
float x = xgenerator.Uniform(-3,3);
float y = ygenerator.Uniform(-3,3);
hist2.Fill(x,y);
}
c->cd();
hist2.Draw(“COLZ”);
}
‘’’

But the canvas showed nothing. When I replaced “Draw()” with “DrawClone()”, it shows the expected image. I don’t know what mistake I made. Many thanks in advance.
The empty canvas


The expected image

TH2F *hist2 = new TH2F(“hist2”,“histogram”,600,-3,3,600,-3,3);

Thank you. I got the expected image via your code. But why should it be pointer rather than a new class object?

Object lifetime
Lifetime

1 Like

Thank you. I add “static” before the declaration TH2F hist2, this time it works. Are the lifetime of the random numbers come to the end during the “{}” of the for statement ends?

1 Like

ROOT provides a default global random generator instance (based on TRandom3), no need to create your own.
Simply use:

// ...
gRandom->SetSeed(0);
// ...
double x = gRandom->Uniform(-3,3);
double y = gRandom->Uniform(-3,3);
// ...
1 Like

I see, thank you. And what is the difference of Draw() and DrawClone? Why did DrawClone() work in my code not Draw()?

Your histogram hist2 was not a pointer in your original code so it did not survive after the execution (see the references @Wile_E_Coyote sent you). DrawClone creates a Clone of the histogram before drawing it, as a pointer … that’s why it survives. The simplest way to write your macro is:

void hw1(){
    auto c = new TCanvas("c","TCanvas",10,10,800,800);

    int npoints = 50000;
    TRandom3 xgenerator, ygenerator;
    xgenerator.SetSeed(0);
    ygenerator.SetSeed(0);
    auto hist2 = new TH2F("hist2","histogram",600,-3,3,600,-3,3);
    for(int i=0; I<npoints ;i++){
        float x = xgenerator.Uniform(-3,3);
        float y = ygenerator.Uniform(-3,3);
        hist2->Fill(x,y);
    }

    hist2->Draw("COLZ");
}
1 Like

I see. Thanks you very much

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