A TMultiGraph problem

Hi,
I am trying to do the same thing with a TMultiGraph. (the macro file attached, the data file is attached to my other mail)

Reading my data from the file is OK, and even they are drawn.
However, not quite so as I want.

1./ I do not see the markers, only some dots, even if I set the marker size differently.

2./ Again, is there another method to disable line drawing, or only to set the line color to the canvas fill color?

3./ The markers are not displayed in the TLegend.

4./ The vertical scale is normalized correctly, but I cannot change it. The SetRangeUser dialog appears, accepts my new values but nothing happens.

5./ If I try the logarithmic Y scale, I receive the message “Error in THistPainter::PaintInit: log scale requested with zero or negative argument (0.000000)” and the graph goes to the bottom.

6./ The log X scale option seems to work, but
a) it switches X grid off
b) the X scale disappears

Do I wrong something?

Janos
myfile.C (2.44 KB)

see the answers to your questions in the comments inside the code:

{
   c1 = new TCanvas("c1","Difference of cross sections",200,10,700,500);
   c1->SetFillColor(0);
   c1->SetGrid();
   c1->SetBorderMode(0);

   TMultiGraph *mg = new TMultiGraph();

   TLegend *legend=new TLegend(0.5,0.65,0.88,0.85);
   legend->SetTextFont(72);
   legend->SetTextSize(0.05);
   legend->SetFillColor(0);

   const Int_t n = 1000; const Int_t N = 5;
   Double_t x[n], y[N][n];

   ifstream in;
   in.open("lossbg1.csv");
   Float_t E,Y,T,S,P,TP;
   Int_t nlines = 0;
   while (1) {
      in >> E >> Y >> T >> S >> P >> TP;
      if (!in.good() || (nlines>=1000)) break;
      x[nlines]    = E;
      y[0][nlines] = Y;
      y[1][nlines] = T;
      y[2][nlines] = S;
      y[3][nlines] = P;
      y[4][nlines] = TP;
      nlines++;
   }
   in.close();

   gr = new TGraph(nlines,x,y[0]);
   gr->SetLineColor(3);
   gr->SetLineWidth(2);

// 1. Marker pyte 1 (point) is not scalable use an other maker style.
   gr->SetMarkerStyle(21);

   gr->SetMarkerSize(0.4);
   gr->SetMarkerColor(2);
   mg->Add(gr);
   char a[50];
   sprintf(a,"Measured");

// 3. To display the marker in the legend  you need option P
   legend->AddEntry(gr,a,"p");

// 2. Remove "C" to avoid line drawing
   mg->Draw("A P");

// 4. User range
   mg->GetYaxis()->SetRangeUser(1000,100000);

// 5. Y Log scale
   c1->SetLogy();

// 6. X Log scale: If you switch log scale on this X axis you see nothing
//    because your plot is much less than a decade.

   legend->Draw();
}

Hello,

thanks for trying to help.

[quote]// 1. Marker pyte 1 (point) is not scalable use an other maker style.
gr->SetMarkerStyle(21);

// 3. To display the marker in the legend you need option P
legend->AddEntry(gr,a,“p”);[/quote]
The first two works fine, thanks.

[quote]// 2. Remove “C” to avoid line drawing
mg->Draw(“A P”);[/quote]

Well, in this case all my graphs are drawn with no line.
What I wanted, is to draw the first graph with markers, and the rest with continuous lines. So, what I need, is something like AddEntry() above, i.e. to specify the style when adding the graph. Is this possible?

[quote]// 4. User range
mg->GetYaxis()->SetRangeUser(1000,100000);[/quote]

I tried this option, but CINT replied

so I think something is wrong in ROOT here: in programmed mode I receive the message above, in interactive mode it makes nothing, although it seems to accept the arguments.

[quote]// 5. Y Log scale
c1->SetLogy();[/quote]
Yes, it works, although I do not understand why the automatic scaling changes the limits if I change to log mode and back.

[quote]// 6. X Log scale: If you switch log scale on this X axis you see nothing
// because your plot is much less than a decade.[/quote]
I am afraid, I do not understand. If I change to log scale, the graph appears OK, but no scale ticks and no labels. I.e. ROOT calculates the graph correctly (I see a slight change) and I think one could calculate labels for less than a decade range, too.

Regards

Janos

SetOption is not implemented for TGraph. So all the TGraphs are drawn with the same when they are in a MultiiGraph (as far as I can see from the code).

I do not have problems with SetRangeUser. May be your ROOT version is too old.
Have you tried the macro I sent you ? For me it is working fine.

The log axis are drawn decade per decade. 1 10 100 1000 and the intermediate labels are:
2 3 4 5 6 8 9
10 20 30 …
for the decade 1000 the indtermediate are
2000 3000 4000 etc …your plot doesn’t have these labels.

I was wrong in my previous reply. You can change the option for each individual TGraph. Just put the option you need as 2nd parameter in the “Add” method. Sorry to have missed that.

I see. Can you please suggest an alternative?

[quote=“couet”]I do not have problems with SetRangeUser. May be your ROOT version is too old.
Have you tried the macro I sent you ? For me it is working fine.[/quote]

well, the old version was 4.00/08, now I dowloaded the new one. Here is the result:

[quote]C:\veghj\docs\Papers\IntrinsicBG>root


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 4.02/00 16 December 2004 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      [root.cern.ch](http://root.cern.ch)            *
    
  •                                     *
    

Compiled for win32 with thread support.

CINT/ROOT C/C++ Interpreter version 5.15.159, Nov 14 2004
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .x myfile.c
Error: illegal pointer to class object GetYaxis() 0x0 507 FILE:C:\veghj\docs\Papers\IntrinsicBG\myfile.c LINE:80
*** Interpreter error recovered ***
root [1] .x myfile_corr.c
Error: C++ exception caught FILE:C:\veghj\docs\Papers\IntrinsicBG\myfile_corr.c LINE:2
*** Interpreter error recovered ***
root [2][/quote]

The first case is my script, where I uncommented the SetRangeUser line.
The second case is your script, as I received, after my script failed.
Then, even ROOT aborts. After this I restarted ROOT and tried your script again. This time it runs OK, but I see only my first dataset (Yes, you removed the rest).
I try to run my own script again, with the SetRangeUser line, and it CINT fails again. Then I run your script again, it runs fine. (no abort, no crash)

So, I have the feeling that something is indefinite. Do you have any idea, what do I wrong?

[quote=“couet”]The log axis are drawn decade per decade. 1 10 100 1000 and the intermediate labels are:
2 3 4 5 6 8 9
10 20 30 …
for the decade 1000 the indtermediate are
2000 3000 4000 etc …your plot doesn’t have these labels.[/quote]
Thanks, now I see, but do not agree. I think the algoritm should not use the maximum value buf the difference, to find out the frequency of the ticks and labels.

Regards

Janos

See my previous reply … Add(gr,“P”) …

My root version is 4.03/01 and I have no problems with the file I sent you.

[quote=“couet”]See my previous reply … Add(gr,“P”) …

My root version is 4.03/01 and I have no problems with the file I sent you.[/quote]
Well, I am using the productive version, not the developer’s one.

In the meantime, I think I found the reason, but I do not understand it.
If I use

mg->Draw("ACP"); mg->GetYaxis()->SetRangeUser(0,40000);

everything goes right. If I use

mg->GetYaxis()->SetRangeUser(0,40000); mg->Draw("ACP");
I receive the errors I mentioned.

So, it looks like I could not use the axes before I call Draw()?
My guess was that first I set up also the ranges, as well as other settings, and only then I call Draw(). Do I misunderstand something?

  1. Does the “Add() with option” works for you ?

  2. I am not surprise you need to Draw() before setting the range. Seems to me the axis don’t exist before the graphs are drawn.

Yes, thanks.

I am. I guessed that Draw makes what its name suggests: just puts out the graph, but does not create anything for it. I found the idea strange, to create a graph which has no axes.
In other cases (for example a missing TCanvas) some default is used, so I think in this case GetYAxis() should make a default axis, if not yet creeated, rather then return a null pointer. I think it is a bug.

in all root example GetX(Y)axis is called after Draw().

Please read the very basics about graphics in the Users guide or shorter
root.cern.ch/root/HowtoDraw.html
You must understand what the Draw and Paint functions do, in particular when the Paint function is called.

Rene

[quote=“brun”]Please read the very basics about graphics in the Users guide or shorter
root.cern.ch/root/HowtoDraw.html
You must understand what the Draw and Paint functions do, in particular when the Paint function is called.

Rene[/quote]

Thanks, I read it. This is more or less the same as in other windowing packages.
What I do not understand, is the following. When I create a TGraph, or TMultiGraph, I believe that the graph is operable, i.e. I can use all member functions and member variables. In this particular case, I wish to see only a subrange of my data and from this point of view, I would not need to Draw() my data before I would set the range.
As I understood, ROOT follows the (otherwise very sympatic) phylosophy of “just use it (and implicitly create it before, if does not exist)”, and my understanding seems to be confirmed by the sentence from the cited URL [quote]If a canvas does not exist, a default canvas (named c1) is automatically created.[/quote] My guess was that Draw() (or Paint()) simply follows the way above, i.e. uses the axis if it exists and creates it if it does not.
From this line I guessed that if I use GetYaxis(), it should return the axis if it exists and create one for me if not, but anyhow, it must be transparent for me. Where am I wrong? Or, where are the limits of user-friendlyness of ROOT?

Regards

Janos

You should create a canvas first.
The current implementation of TMultiGraph::GetXaxis calls TMultiGraph::GetHistogram. This function creates the internal histogram by forcing an update of the pad. However if you have not called Draw the TMultiGraph is unknown to the pad and nothing happens.

Rene