How to improve the redrawing speed for histogram?

Dear rooters,

I created a TProfile2D through the data tree, and I need to redraw it frequently when the data changing. But, redrawing it need much long time which I can not accept in pratical using. So, I wander if there are some way to solve this problem.

Thank you in advance.

Next is the key code, if I let them loop over all the entries, the program runs very slowly.

datatree->Draw(“A:B:C>>tprofile”,selection,“goff”, 1, maxEvent );

As already requested, could you post the shortest possible RUNNING script (and a data set) reproducing your problem?


see attatched file, Thank you.

Because I am writting a monitor program, it is impossible to attatch the whole program. So, I just rewrite a simplized macro to show my means. Hope you can understand.
test.C (390 Bytes)

this attached file is the corresponding root file.
tpc_data_2008_11_18_10_54_37.root (518 KB)

Because this Forunm do not permit upload the large root file, so I reproduce a new one for this macro. so if you want to try to test it, please change the filename.

see below:

TFile *f =new TFile(“tpc_data_2008_11_18_09_55_46.root”);
TFile *f =new TFile(“tpc_data_2008_11_18_10_54_37.root”);

Thanks a lot.

Executing your script (10 times the loop) takes 4 seconds on my machine.
Could you explain what is your problem precisely?
If one needs a large file, could you post it in a public readable area (afs, http)?


Hello Rene,

Thank you for your answer.

Sure, it nearly same in my computer. But this is not the only one to be monitored in my program. Besides this one, I need to show the trace in the TPC, and the pedestal and sigma of the raw data, even furthermore, some times I need to show the CM(common mode) correction. if I let all of them work or part of them work, the program runs very slowly. For one event, it will took about 4 seconds.

I check the code, when I disable the ->Draw() methods, the program runs very quickly. So, I think it might be the problem of Draw() method of Histogram, it make the program show this kind of bad behavior. But I can not find a way to solve it. How do you think about that?

I don’t think it is necessary to upload a large rootfile to test. Because large file only means much more events. By the way, in the program, each time, I only fill one event to the histogram.

thanks again


To maximize the refresh rate, you should avoid ‘Draw-ing’ the histogram and instead use Reset and Update it. Your example (leaving the actually creation of the histogram for you to fill) can be updated like:

c->Clear(); c->cd(); tAmpVstTimeVsChId = new TProfile2D("tAmpVstTimeVsChId",...); for (unsigned int i=0; i<10; i++){ //Fill TProfile2D histogram. tAmpVstTimeVsChId->Reset(); datatree->Draw("tAmp:tTime:tChannelId>>tAmpVstTimeVsChId","","goff"); //set the attributes and draw the plot. c->Update(); c->Modified(); } return;which avoid both the ‘new-ing’ and ‘draw-ing’ of the histogram within the loop.


hi Philippe,

Thank you for your answer. You are quite right.

But if I want to draw the plot each time, is there a good way to speed up the refreshing rate?

Thanks a lot.

It is hard to answer your question without understanding what you are doing.
You will find below an example showing how to redraw only the bits not yet shown in a loop.


void fastdraw() { TCanvas *c1 = new TCanvas("c1"); TFile *f = new TFile("fastdraw.root","recreate"); TNtuple *ntuple = new TNtuple("ntuple","Demo ntuple","px:py:pz:random:i"); Float_t px, py, pz; const Int_t kUPDATE = 20000; Long64_t nentriesold = 0; for (Int_t i = 0; i < 1000000; i++) { gRandom->Rannor(px,py); pz = px*px + py*py; Float_t random = gRandom->Rndm(1); ntuple->Fill(px,py,pz,random,i); if (i && (i%kUPDATE) == 0) { printf("i=%d\n",i); Long64_t nentries = ntuple->GetEntries(); if (i == kUPDATE) ntuple->Draw("px:py:pz"); else ntuple->Draw("px:py:pz","","same", nentries-nentriesold,nentriesold); nentriesold = nentries; c1->Modified(); c1->Update(); if (gSystem->ProcessEvents()) break; } } }

I think you have answered my question.

Sure, it is impossible to show all of the histogram event by event. I had to admit this fact.

Thanks a lot.

Thanks all of you.


Following your way, the program runs a bit faster than before. Thanks a lot.

Would you like to give me much more explanation for this change or tell me where to get the explanation?



See the documentation for TTree::Draw for the example of >>+ (it ‘adds’ to the histogram rather than recreating it). The other part is to move the call to Draw outside of the loop and instead really on an update of the existing already ‘Draw-n’ histogram; this saves one several operations (creation of the axis, frames, etc.) that do not really need to be re-done each time you want to refresh the histogram.


Ah, I got it! Very good. Thanks a lot.



The option “+” is the wrong option to use in this case. The solution is the example that I posted. Hoping to have some feedback on it.


[quote]The option “+” is the wrong option to use in this case.[/quote]The ‘+’ would be the correct option is one is interested in the histogram (as the comment in the code suggested) while the partial draw (without the +) is the correct solution is one is interested in the actual set of points (as the actual code in test.C was plotting).


The problem was not with tree.Draw but in drawing a 3-d histogram with a growing number of points. It is stupid to redraw all the points at every iteration. Only the new points should be drawn.