3.4 Data plotting

Let me now show how to plot the data. Next section will give much more examples for all plotting functions. Here I just show some basics. MathGL generally has 2 types of plotting functions. Simple variant requires a single data array for plotting, other data (coordinates) are considered uniformly distributed in axis range. Second variant requires data arrays for all coordinates. It allows one to plot rather complex multivalent curves and surfaces (in case of parametric dependencies). Usually each function have one textual argument for plot style and another textual argument for options (see Command options).

Note, that the call of drawing function adds something to picture but does not clear the previous plots (as it does in Matlab). Another difference from Matlab is that all setup (like transparency, lightning, axis borders and so on) must be specified before plotting functions.

Let start for plots for 1D data. Term “1D data” means that data depend on single index (parameter) like curve in parametric form {x(i),y(i),z(i)}, i=1...n. The textual argument allow you specify styles of line and marks (see Line styles). If this parameter is NULL or empty then solid line with color from palette is used (see Palette and colors).

Below I shall show the features of 1D plotting on base of plot function. Let us start from sinus plot:

int sample(mglGraph *gr)
{
  mglData y0(50); 	y0.Modify("sin(pi*(2*x-1))");
  gr->SubPlot(2,2,0);
  gr->Plot(y0);   	gr->Box();

Style of line is not specified in plot function. So MathGL uses the solid line with first color of palette (this is blue). Next subplot shows array y1 with 2 rows:

  gr->SubPlot(2,2,1);
  mglData y1(50,2);
  y1.Modify("sin(pi*2*x-pi)");
  y1.Modify("cos(pi*2*x-pi)/2",1);
  gr->Plot(y1);   	gr->Box();

As previously I did not specify the style of lines. As a result, MathGL again uses solid line with next colors in palette (there are green and red). Now let us plot a circle on the same subplot. The circle is parametric curve x=cos(\pi t), y=sin(\pi t). I will set the color of the circle (dark yellow, ‘Y’) and put marks ‘+’ at point position:

  mglData x(50);  	x.Modify("cos(pi*2*x-pi)");
  gr->Plot(x,y0,"Y+");

Note that solid line is used because I did not specify the type of line. The same picture can be achieved by plot and subdata functions. Let us draw ellipse by orange dash line:

  gr->Plot(y1.SubData(-1,0),y1.SubData(-1,1),"q|");

Drawing in 3D space is mostly the same. Let us draw spiral with default line style. Now its color is 4-th color from palette (this is cyan):

  gr->SubPlot(2,2,2);	gr->Rotate(60,40);
  mglData z(50);  	z.Modify("2*x-1");
  gr->Plot(x,y0,z);	gr->Box();

Functions plot and subdata make 3D curve plot but for single array. Use it to put circle marks on the previous plot:

  mglData y2(10,3);	y2.Modify("cos(pi*(2*x-1+y))");
  y2.Modify("2*x-1",2);
  gr->Plot(y2.SubData(-1,0),y2.SubData(-1,1),y2.SubData(-1,2),"bo ");

Note that line style is empty ‘ ’ here. Usage of other 1D plotting functions looks similar:

  gr->SubPlot(2,2,3);	gr->Rotate(60,40);
  gr->Bars(x,y0,z,"r");	gr->Box();
  return 0;
}

Surfaces surf and other 2D plots (see 2D plotting) are drown the same simpler as 1D one. The difference is that the string parameter specifies not the line style but the color scheme of the plot (see Color scheme). Here I draw attention on 4 most interesting color schemes. There is gray scheme where color is changed from black to white (string ‘kw’) or from white to black (string ‘wk’). Another scheme is useful for accentuation of negative (by blue color) and positive (by red color) regions on plot (string ‘"BbwrR"’). Last one is the popular “jet” scheme (string ‘"BbcyrR"’).

Now I shall show the example of a surface drawing. At first let us switch lightning on

int sample(mglGraph *gr)
{
  gr->Light(true);	gr->Light(0,mglPoint(0,0,1));

and draw the surface, considering coordinates x,y to be uniformly distributed in axis range

  mglData a0(50,40);
  a0.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
  gr->SubPlot(2,2,0);	gr->Rotate(60,40);
  gr->Surf(a0);		gr->Box();

Color scheme was not specified. So previous color scheme is used. In this case it is default color scheme (“jet”) for the first plot. Next example is a sphere. The sphere is parametrically specified surface:

  mglData x(50,40),y(50,40),z(50,40);
  x.Modify("0.8*sin(2*pi*x)*sin(pi*y)");
  y.Modify("0.8*cos(2*pi*x)*sin(pi*y)");
  z.Modify("0.8*cos(pi*y)");
  gr->SubPlot(2,2,1);	gr->Rotate(60,40);
  gr->Surf(x,y,z,"BbwrR");gr->Box();

I set color scheme to "BbwrR" that corresponds to red top and blue bottom of the sphere.

Surfaces will be plotted for each of slice of the data if nz>1. Next example draws surfaces for data arrays with nz=3:

  mglData a1(50,40,3);
  a1.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
  a1.Modify("0.6*cos(2*pi*x)*cos(3*pi*y)+0.4*sin(3*pi*(x*y))",1);
  a1.Modify("0.6*cos(2*pi*x)*cos(3*pi*y)+0.4*cos(3*pi*(x*y))",2);
  gr->SubPlot(2,2,2);	gr->Rotate(60,40);
  gr->Alpha(true);
  gr->Surf(a1);		gr->Box();

Note, that it may entail a confusion. However, if one will use density plot then the picture will look better:

  gr->SubPlot(2,2,3);	gr->Rotate(60,40);
  gr->Dens(a1);		gr->Box();
  return 0;
}

Drawing of other 2D plots is analogous. The only peculiarity is the usage of flag ‘#’. By default this flag switches on the drawing of a grid on plot (grid or mesh for plots in plain or in volume). However, for isosurfaces (including surfaces of rotation axial) this flag switches the face drawing off and figure becomes wired. The following code gives example of flag ‘#’ using (compare with normal function drawing as in its description):

int sample(mglGraph *gr)
{
  gr->Alpha(true);	gr->Light(true);	gr->Light(0,mglPoint(0,0,1));
  mglData a(30,20);
  a.Modify("0.6*sin(2*pi*x)*sin(3*pi*y) + 0.4*cos(3*pi*(x*y))");

  gr->SubPlot(2,2,0);	gr->Rotate(40,60);
  gr->Surf(a,"BbcyrR#");		gr->Box();
  gr->SubPlot(2,2,1);	gr->Rotate(40,60);
  gr->Dens(a,"BbcyrR#");		gr->Box();
  gr->SubPlot(2,2,2);	gr->Rotate(40,60);
  gr->Cont(a,"BbcyrR#");		gr->Box();
  gr->SubPlot(2,2,3);	gr->Rotate(40,60);
  gr->Axial(a,"BbcyrR#");		gr->Box();
  return 0;
}