# Draw multiple graphs

Hi,

I would like to draw in one Canvas many graphs (lets say 15), but I don’t want to type for every graph the command
TGraph *gr1 = …

The data for each graph are held by an array[i=15][j=200]. So I would like for each i to draw a graph in the same Canvas. Is there a way to name the pointer (gr) differently for each graph using a loop??

Loukas

\$ROOTSYS/tutorials/graphs/multigraph.C

This is not what I meant.

I would like to have something like this:

``````for(i=1; i<=15; i++){
sprintf(graph,"gr%d",i);
for(int j =1; j<200; j++){
con[i] = totalNeutronsR[i][j];
}
TGraph *graph = new TGraph(200, tR, con);
graph->SetMarkerColor(1);
graph->SetMarkerSize(0.5);
graph->SetMarkerStyle(7);
}
TMultiGraph *mg = new TMultiGraph();
mg->Draw("AP");
``````

Well, the above code gives errors, but I was wondering if there is a way to have something like this ??

Thanks,
Loukas

you can do:

``````{
TGraph *g[10];
Double_t x[10] = {0,1,2,3,4,5,6,7,8,9};
Double_t y[10] = {1,2,3,4,5,6,4,3,2,1};
TMultiGraph *mg = new TMultiGraph();
for (int i=0; i<10; i++) {
g[i] = new TGraph(10, x, y);
y[i] = y[i]+1;
}
mg->Draw("AL");
}``````

Thanks for the tip.

I modified the code to fit into my needs but I still receive errors.
My code is:

``````TGraph *gr[25];
TMultiGraph *mg = new TMultiGraph();
for(int k=0; k<21; k++){
for(int l =1; l<200; l++){
concentration[l] = totalNeutronsR[k][l];
} //end of l loop
gr[k] = new TGraph(200, tR, concentration);
} //end of k loop
mg->Draw("AP");
``````

Any idea?

Loukas

Can you send something running ? totalNeutronsR, and concentration are not declared in the code you sent.

I have declared them at the beginning…

It’s running !!!

I had just to quit ROOT and enter again…

regards,
Loukas

Hello! I have the same situation. In my program I have to analyse 1000 files and access a branch from the tree and execute some code. In the end I have to represent the results in a histogram wich have to contain the data from all the 1000 files. The problem is that the program overwrites the same canvas until the last one.

``````void read() {
for (Int_t ii=1000; ii<=1005; ii++) {
TFile treeFile(fileName.Data());
``````

a part from the reading and

``````void paint ()
{
hit.SetLineColor(kRed);
hit.Draw();
hit. SetTitle("All ");
hit.GetXaxis()->SetTitle("N");
hit.GetYaxis()->SetTitle("Entries");
hit.SetMarkerStyle(30);
hit.SetMarkerColor(kRed+3);
c1.Draw("hist");}"
``````

Also, I created the canvas before the draw function , like ,

``````TCanvas c1("Param", "Nhit", 2800, 1000);
TH1I hit("hit", "hit", 20, 0, 20);
``````

Can you help me?

You should not Draw the canvas . But only the histogram hit. Like:

``````    hit.SetLineColor(kRed);
hit. SetTitle("All ");
hit.GetXaxis()->SetTitle("N");
hit.GetYaxis()->SetTitle("Entries");
hit.SetMarkerStyle(30);
hit.SetMarkerColor(kRed+3);
hir.Draw("hist");
``````

Also it seems that `hit` is drawn in the method `Paint()` but it looks declared elsewhere in your code. Is it global ?

When you draw `hit` with the option `hist` it will overwrite the previous plots. If you want to have several histograms drawing on the same plot you should use the option `same` or use a `THStack` which might be better if you have 1000 histograms in order to compute the global range.

Note: I have re-formatted your post. It was impossible to see relay the code.

Very late reply here, but I’m never sure about the general practice of using `new`. The tool my collaboration has an event display (we generate plots for each event in the detector and iterate to the next event with a GUI so we can take a peek at each event) so for each event we need to clear the graphics.

Am I going to have an issue if I have something like what’s above in a function that iterates over each event?

Asked as a decision between two options:

If I have a function that runs for each event, should I:

I have calls to `new` i and inside this event-by-event function and ROOT will call do the relevant calls to `~TGraph` at the end of the scope of that call to `new`?

Or should I have an array that holds all the `TGraph*`'s (or even `TGraph`’s) then populate them and add them to the `TMultiGraph` and draw it, then clear them with TGraph::Set(0)?

thanks for asking! If you add the `TGraphs` to the `TMultiGraph` via TMultiGraph::Add(), you have to create them with `new` but don’t `delete` them because the `TMultiGraph` will now take care of that (as explained in the linked documentation).

Hope this helps!

Cheers,
Jonas

1 Like