Multigraph Help

I’m a physics undergrad and am basically stuck teaching myself root. Half my classes want me to use root but I’ve only gotten the bare minimum of instruction and am left to my own devices to learn what I need.

The background is that I am taking computational physics and the part one of the assignment was to calculate the distance/time/etc for a baseball with drag. No probs. Part two is to determine the angle at which the baseball travels the farthest with the drag. Again, no probs. The code is pretty easy. But she wants us to display the graph for each angle as a proof. She said just nest the code in a loop, but it isn’t that easy. The code executes perfectly but I am only getting one line on the graph.

I’ve been over the site for the past half hour and I think I need to be using a multigraph, but I’m not clear as to how that works. I’ve included the code bits so you can see where I’m coming from. All the variable names are fairly self-explanatory. Obviously, the parts I’m currently working on are in the Draw Graph Canvas and Draw Data Points for Numerical Solution.

I’m a bit stuck so any help you can provide would be greatly appreciated.

[code]
for (int angleloop = 0; angleloop <= 90; angleloop+=5)
{
// Baseline Calculations - Convert Data Entry into Usable Values
angleRad = (angleDeg + angleloop) * 2 * pi / 360; // Convert Degrees to Radians
v_horiz[0] = initialV * cos(angleRad); // Calculate Horizontal Velocity
v_vert[0] = initialV * sin(angleRad); // Calculate Initial Vertical Velocity

		// Find Exact Solution
		exactTime = v_vert[0] / gravity;
		exactHoriz = v_horiz[0] * 2 * exactTime;
		exactVert = .5 * (-gravity) * exactTime * exactTime + v_vert[0] * exactTime;

		if (exactTime < maxsize * step) 
			{
				// Find Numerical Euler Solution	
				loop = 0;
				do
					{
						t[loop + 1] = t[loop] + step;
						
						totalV = sqrt(v_horiz[loop] * v_horiz[loop] + v_vert[loop] * v_vert[loop]);		// Calculate Composite V
						drag = .0039 + .0058 / (1 + exp((totalV - 35.0) / 5));							// Given Equation 35.0 = Vd, 5 = Delta
						//drag = .00814013975;
						v_horiz[loop + 1] = v_horiz[loop] - drag * totalV * v_horiz[loop] * step;
						v_vert[loop + 1] = v_vert[loop] - gravity * step - drag * totalV * v_vert[loop] * step;
						d_horiz[loop + 1] = d_horiz[loop] + v_horiz[loop] * step;
						d_vert[loop + 1] = d_vert[loop] + v_vert[loop] * step; 
						
						if (d_vert[loop+1] > d_vert[loop]) maxHeight = d_vert[loop+1];

						loop++;
					}
				while (d_vert[loop] > 0)

				cout << endl;
				cout << "Angle = " << angleDeg + angleloop << ", Horizontal Distance = " << d_horiz[loop] << endl;
	
				// Draw Graph Canvas
				if (angleloop == 0)
					{
						TCanvas *c1 = new TCanvas("c1", "Baseball Best Angle", 200, 10, 700, 500);
						c1->SetFillColor(42);
						c1->SetGrid();

						TMultiGraph *mg = new TMultiGraph();
					}
	
				// Draw Data Points for Numerical Solution
				gr[angleloop] = new TGraph(loop, d_horiz, d_vert);
				gr[angleloop]->SetLineColor(2 + angleloop / 5);
				gr[angleloop]->SetLineWidth(4);
				gr[angleloop]->SetMarkerColor(5);
				gr[angleloop]->SetMarkerStyle(20);
				gr[angleloop]->SetTitle("Baseball Flight Path");
				gr[angleloop]->GetXaxis()->SetTitle("Horizontal Distance (m)");
				gr[angleloop]->GetXaxis()->SetLimits(0, exactHoriz);
				gr[angleloop]->GetXaxis()->CenterTitle();
				gr[angleloop]->GetYaxis()->SetTitle("Vertical Height (m)");
				gr[angleloop]->GetYaxis()->SetRangeUser(0, exactVert * 1.05);
				gr[angleloop]->GetYaxis()->CenterTitle();
				gr[angleloop]->Draw("C");

				// Draw Legend
				leg = new TLegend(0.45, 0.3, 0.75, 0.5);
				leg->SetFillColor(42);
				leg->AddEntry(gr[angleloop], (angle + "`f[#circ]").c_str(), "pl");
				leg->Draw("same");
			}
		else cout << "Error.";
	}[/code]

Try something like this: [code] // …
TMultiGraph *mg = new TMultiGraph(“mg”, “mg”);
leg = new TLegend(0.45, 0.3, 0.75, 0.5);
leg->SetFillColor(42);

for (int angleloop = 0; angleloop <= 90; angleloop+=5)
{
// …
if (exactTime < maxsize * step)
{
// …
// gr[angleloop]->Draw(“C”); // … do NOT draw it …
mg->Add(gr[angleloop]); // … but add it to “mg” and “leg” …
leg->AddEntry(gr[angleloop], (angle + “`f[#circ]”).c_str(), “pl”);
}
else cout << “Error.”;
}

// create the canvas and draw everything
TCanvas *c1 = new TCanvas(“c1”, “Baseball Best Angle”, 200, 10, 700, 500);
c1->SetFillColor(42);
c1->SetGrid();
mg->Draw(“C”);
leg->Draw();
// …[/code]

Let me start by saying thank you for your help. I’ve taken another stab at it. I’ve removed the array since I didn’t need it. At some point I might need to keep that data and being able to use a graph array might come in handy, but that is a battle for another day.

[code]if ( (angleStart >= 0) && (angleStart < 90) && (angleEnd > 0) && (angleEnd <= 90) && (angleStep > 0) && ((angleStart + angleStep) <= angleEnd) && (initialV > 0) )
{

		// Create MultiGraph
		TMultiGraph *mg = new TMultiGraph("mg", "mg");
		leg = new TLegend(0.45, 0.3, 0.75, 0.5);
		leg->SetFillColor(42);

		for (int angleloop = 0; angleloop <= 90; angleloop += 5)
			{
				// Baseline Calculations - Convert Data Entry into Usable Values
				angleRad = (angleDeg + angleloop) * 2 * pi / 360;		// Convert Degrees to Radians
				v_horiz[0] = initialV * cos(angleRad);					// Calculate Horizontal Velocity
				v_vert[0] = initialV * sin(angleRad);					// Calculate Initial Vertical Velocity

				// Find Exact Solution
				exactTime = v_vert[0] / gravity;
				exactHoriz = v_horiz[0] * 2 * exactTime;
				exactVert = .5 * (-gravity) * exactTime * exactTime + v_vert[0] * exactTime;

				if (exactTime < maxsize * step)
				{
					// Find Numerical Euler Solution	
					loop = 0;
					do
					{
						t[loop + 1] = t[loop] + step;

						totalV = sqrt(v_horiz[loop] * v_horiz[loop] + v_vert[loop] * v_vert[loop]);		// Calculate Composite V
						drag = .0039 + .0058 / (1 + exp((totalV - 35.0) / 5));							// Given Equation 35.0 = Vd, 5 = Delta
						//drag = .00814013975;
						windDrag = abs(totalV - wind);													// Calculate Wind vs Total V
			
						v_horiz[loop + 1] = v_horiz[loop] - drag * windDrag * (v_horiz[loop] - wind) * step;
						v_vert[loop + 1] = v_vert[loop] - gravity * step - drag * windDrag * v_vert[loop] * step;
						d_horiz[loop + 1] = d_horiz[loop] + v_horiz[loop] * step;
						d_vert[loop + 1] = d_vert[loop] + v_vert[loop] * step;

						if (d_vert[loop + 1] > d_vert[loop]) maxHeight = d_vert[loop + 1];

						loop++;
					} while (d_vert[loop] > 0)

					// Display Results to Root Window
					cout << endl;
					cout << "Wind = " << wind << " mph, " << "Angle (degrees) = " << angleDeg + angleloop << ", Horizontal Distance (feet) = " << d_horiz[loop] << endl;

				
					// Draw Data Points for Numerical Solution
					gr = new TGraph(loop, d_horiz, d_vert);
					
					//gr->SetTitle((angleDeg + " degrees").c_str());
					gr->SetTitle("angleDeg");
					gr->SetLineColor(0 + angleloop / 5);
					gr->SetLineWidth(2);
					gr->SetMarkerColor(0 + angleloop / 5);
					gr->SetMarkerStyle(20);
					gr->SetTitle("Baseball Flight Path");
					gr->GetXaxis()->SetTitle("Horizontal Distance (m)");
					gr->GetXaxis()->SetLimits(0, exactHoriz);
					gr->GetXaxis()->CenterTitle();
					gr->GetYaxis()->SetTitle("Vertical Height (m)");
					gr->GetYaxis()->SetRangeUser(0, exactVert * 1.05);
					gr->GetYaxis()->CenterTitle();
					
					mg->Add(gr); 

// leg->AddEntry(gr,angleDeg,“pl”);
}
else cout << “Error.”;
}

		// Draw Graph Canvas
		TCanvas *c1 = new TCanvas("c1", "Baseball Best Angle", 200, 10, 700, 500);
		c1->SetFillColor(42);
		c1->SetGrid();

		
		mg->Draw("C");

		leg->Draw();
	}[/code]

I’m tackling this a bit at a time. Right now I want to get the lines displaying and then I’ll work on the legend. Right now I am getting a blank canvas with one line and no axes. I’ll try linking the image.
drive.google.com/file/d/0B5RdVV … sp=sharing

I guess my question boils down to:

Can I leave this inside the loop? gr = new TGraph(loop, d_horiz, d_vert);
Where do I put the code for the axes? Do I make them mg-> instead of gr-> and put them right before the mg->Draw()?

I found this code snippet on the site and I think I’ll go back to the array model and try an implementation like this:

[code]{
TCanvas *c2 = new TCanvas(“c2”,“c2”,600,400);

TGraph *g[3];
Double_t x[10] = {0,1,2,3,4,5,6,7,8,9};
Double_t y[10] = {1,2,3,4,5,5,4,3,2,1};
TMultiGraph *mg = new TMultiGraph();
for (int i=0; i<3; i++) {
g[i] = new TGraph(10, x, y);
g[i]->SetMarkerStyle(20);
g[i]->SetMarkerColor(i+2);
for (int j=0; j<10; j++) y[j] = y[j]-1;
mg->Add(g[i]);
}
mg->Draw(“APL”);
mg->GetXaxis()->SetTitle(“E_{#gamma} (GeV)”);
mg->GetYaxis()->SetTitle(“Coefficients”);

// Change the axis limits
gPad->Modified();
mg->GetXaxis()->SetLimits(1.5,7.5);
mg->SetMinimum(0.);
mg->SetMaximum(10.);

return c2;
}[/code]

OMG OMG OMG OMG OMG! I DID IT!

I’ve got LINES! Glorious beautiful lines!

Now I’m going to work on the legend.

I apologise for all the spamming as I worked through this but I think maybe writing it out has helped a great deal! I’ll let you know how I get on!

Everything is working wonderfully and I’m very happy. Now working on the Legend and I need to include a variable in the SetTitle and I am getting the following error.

This is my line of code:

leg->AddEntry(gr[angleloop],(angleDeg + " degrees").c_str(), "l");

I was trying to convert the variable to a string.

I’ve also tried:

leg->AddEntry(gr[angleloop],angleDeg, "l");

[quote]Error: Can’t call TLegend::AddEntry(gr[angleloop],angleDeg,“l”) in current scope
D:\Documents\School\Experimental\Root\macros\215\bestangle.c(136)
Possible candidates are…
(in TLegend)
D:\Documents\School\Experimental\Root\bin\libGraf.dll -1:-1 0 public: TLegend
Entry* TLegend::AddEntry(const TObject* obj,const char* label=“”,Option_t* optio
n=“lpf”);
D:\Documents\School\Experimental\Root\bin\libGraf.dll -1:-1 0 public: TLegend
Entry* TLegend::AddEntry(const char* name,const char* label=“”,Option_t* option=
“lpf”);
(in TPave)
(in TBox)[/quote]

and

leg->AddEntry(gr[angleloop],"angleDeg", "l");

And of course that bit just adds the words “angleDeg” and not the actual variable value.

Ok, in my efforts to cram the board with replies to my own post…

leg->AddEntry(“gr[angleloop]”, Form("%d", angleloop), “l”);

That now displays the variable in the legend, but I’ve lost all my line colours.

leg->AddEntry(gr[angleloop], Form("%d", angleloop), “l”);

removing the quotes returned my line colours. I’m all done, thanks for all your help!! :slight_smile: