I have a program that pulls some data from a stream every few seconds and feeds them into a histogram ,like this:
TCanvas *canv = new TCanvas("canv","",0,0,500,200);
TH2F *hist = new TH2F("hist","",10,xmin,xmax,100,ymin,ymax);
//xmin, xmax are some numbers to start with
//ymin, ymax are minimum and maximum possible y bounds.
//here's an infinite loop
while (1)
{
//calls a process that feeds data to a file
//waits for 10 seconds while data being poured in to that file
sleep (10)
//X axis is time so, the first value from the file is the minimum hence changes the axis range using:
//let's say the the time is fed to the arry Time[i] and they are in seconds, then I am doing:
hist->GetXaxis->SetRangeUser(Time[0],Time[0]+10);
//printing the array shows there's no problem with the data, that is time here
//then filling here
hist->Fill(Time[i],Y[i]); // where Y[i] is the y variable
hist->Draw();
canv->Modified();
canv->Update();
gPad->Modified();
gPad->Update();
}
But I see that the X axis range doesn’t change ! So in a few seconds I am out of the range and hence empty canvas ! How can I have a moving axis ?
hist->Fill(Time[i],Y[i]); // where Y[i] is the y variable
hist->Draw();
gPad->Modified();
gPad->Update();
hist->GetXaxis->SetRangeUser(Time[0],Time[0]+10);
gPad->Update();
But redefining the histogram at the beginning works which is nasty because there’s “potential memory leak” involved of course, that’s why I will not keep doing this.
What do you expect to happen with the “old bins”? Should they be forgotten?
Then you’re not looking for a histogram but for a histogram visualization of a queue - showing the N newest data points; is that correct?
What you could do is use a TGraph, replacing always the oldest point by the newest data - and then updating the drawing of that graph. What do you think?
Thanks for your reply and sorry for not being clear enough. Ok, here’s what I want:
N number of data points will arrive in every M seconds and I would like to display there time behavior as in real-time display of some kind using ROOT’s TCanvas. Right now I am using TH2Fs but eventually I would also like to display TProfiles etc. I want that those M points always remain at any given point in the canvas, hence the time axis (X axis) must update every N seconds.
Any other fancy/ugly way of achieving that is most welcome. Right now I am redefining TH2Fs in every loop leading to potential memory leaks, that I would certainly like to avoid.
Thanks a lot.
PS: @Axel: how do I feed that TH2F to a TGraph and achieve what you are suggesting as achievable ?
O I see - you don’t want the data points to walk through your plot - you want an updated plot every M seconds, displaying a new chunk of N data points.
Well, in that case using new histograms for each snapshot should be just fine. Make sure to delete it at the end of the round.
Or call hist->Reset() between the chunks; that empties the histogram. Afterwards you can update the axis through GetXaxis()->Set(nbins, min, max) to reflect the new range, you fill it, and then you draw it.
If that doesn’t work for you I’ll post a complete script tomorrow.