Graphing and plotting in 2D & 3D
 
In reality SpOd implicitly provides a 3D visualisation experience even when you are only using 2 of the available dimensions. Placing multiple graphs in a 3D space can offer advantages if you are trying to relate events in one set against those in another. Part of the 3D experience is also about animation. Being able to ‘play’ a graph sequence over a range of speeds can help to high light events in ways that might otherwise allow them to be missed. The eye has a way of inferring structure where the effects in the data stream are in fact subtle, or masked by noise or other processes.
 
This section provides examples where the graphing exploits the 3D space. In examples-1 we used only the y-x plane to graph in 2D. Changing the y (or Y) to a z (or Z) in the graphics object header translates the 2D graphing plane to the z-x plane. (note also the use of the z-scale and z-offset parameters in the object header.) The z-direction is by default into the screen, but a simple rotation of the space using the mouse will expose the plane.  
 
Example 2.1:  pair of graphs in 3D
echo "O 206 316
L 35 258 148 210 180 333
G 1 0.6 0.6  9.0 5.0 5.0  0.0 0.0 0.0  .3 0 0
C 1 1 0 1 1 1 1
M 0 0 1 10
I -1 0.00010 0.017500 0.050 0.000000
" | awk '{cnt++; print $0
if (cnt==5) {
   numbpoints=1000
   printf "\ny:b:sine %d 1 9 2 0 0 0 0\n", numbpoints;
   for (i=1; i <=numbpoints; i++) { printf "%f ",sin(i*2*3.1415926/100)}
   printf "\nv:n:visible_on";
   printf "\nb:r:redball\nw 1.3";
 
   printf "\nz:m:cosine %d 1 9 0 2 0 0 0\n", numbpoints;
   for (i=1; i <=numbpoints; i++) { printf "%f ",cos(i*2*3.1415926/100)}
   printf "\nv:n:visible_on";
   printf "\nb:g:redball\nw 1.3";
 
}
}' | spod
 
 
Hit the ‘j’ (jump) key to jump to the start of the animation sequence.
 
The ‘j’ and ‘J’ keys provide support for jumping to preset positions or views within a given data set. For more information on this see the extended list of instructions on the graphic object  specification.
 
Use the space bar to halt the animation.
‘g’ or ‘G’ are also effective in controling the scan speed of the animation. ‘t’ or ‘T’ may be used to control the turning speed, and ‘b’ allows both the animated trace to be combined with panning. Hitting ‘b’ more than once also initiates  tumbling of the graphics objects.
 
You may need to experiment with the combination of these keys to understand their full effect, and the order in which they may be combined in order to obtain desired effects. Of course you may simply resort to using the left-mouse button to rotate the objects manually.
 
The adaptation of the above script results in a pair of animated traces in 3D. Here the ‘k’ is exchanged for a ‘K’, and the number of points used to render the curves is increased to 100,000.
 
echo "O 206 316
L 35 258 148 210 180 333
G 1 0.6 0.6  9.0 5.0 5.0  0.0 0.0 0.0  .3 0 0
C 1 1 0 1 1 1 1
M 0 0 1 10
I -1 0.000010 0.017500 0.050 0.000000
" | awk '{cnt++; print $0
if (cnt==5) {
   numbpoints=100000
   printf "\nY:b:sine %d 1 9 2 0 0 0 0\n", numbpoints;
   for (i=1; i <=numbpoints; i++) { printf "%f ",sin(i*2*3.1415926/100)}
   printf "\nv:n:visible_on";
   printf "\nb:r:redball\nw 1.3";
 
   printf "\nZ:m:cosine %d 1 9 0 2 0 0 0\n", numbpoints;
   for (i=1; i <=numbpoints; i++) { printf "%f ",cos(i*2*3.1415926/100)}
   printf "\nv:n:visible_on";
   printf "\nb:g:redball\nw 1.3";
 
}
}' | spod
 
 
Example 2.2: A 3D time trajectory
Using the ‘k’ (or ‘K”) instead of ‘y’,’Y’ or ‘z’, ‘Z’ graphical specifiers allows one to plot the y versus z against time as a 3D kurve, either as a static or dynamic trace (depending on whether the lower case or upper case specifier is used).
 
echo "O 206 316
L 35 258 148 210 180 333
G 1 0.6 0.6  9.0 5.0 5.0  0.0 0.0 0.0  0 0 10
C 1 1 0 1 1 1 1
M 0 0 1 10
I -1 0.001 0.000001 0.05 0
" | awk '{cnt++; print $0
if (cnt==5) {
   numbpoints=1000
   printf "\nk:b:sin_versus_cos %d 1 9 2 2 0 0 0\n", numbpoints;
   for (i=1; i <=numbpoints; i++) { printf "%f ",sin(i*2*3.1415926/100)}
   for (i=1; i <=numbpoints; i++) { printf "%f ",cos(i*2*3.1415926/100)}
      
printf "\nv:n:visible_on";
   printf "\nb:r:redball\nw 1.3";
}
}' | spod
 
 
 
 
Try also the following script:
 
echo "O 206 316
L 35 258 148 210 180 333
G 1 0.6 0.6  9.0 5.0 5.0  0.0 0.0 0.0  0 0 10
C 1 1 0 1 1 1 1
M 0 0 1 10
I -1 0.000010 0.132500 0.050 0.0
" | awk '{cnt++; print $0
if (cnt==5) {
   points=100000
   printf "\nK:m:slinky %d 1 9 .2 .2 0 0 0\n", points;
   for (i=1; i <=points; i++) {printf "%f ",exp(i/10000) * sin(i*2*3.1415926/100) + 10*cos(i*2*3.1415926/1000)}
   for (i=1; i <=points; i++) {printf "%f ",exp(i/10000) * cos(i*2*3.1415926/100) + 10*sin(i*2*3.1415926/1000)}
      
printf "\nv:n:visible_on";
   printf "\nb:r:redball";
}
}' | spod
 
 
 
 
 
 
 
 
 
 
 
 
 
One may achieve useful, even quite spectacular graphical effects using trajectory style plots.
 
For example 3D trajectories may provide a convenient means for visualising the changing state of a dynamical processes.
 
 
 
Example 2.3:  Graphs that are not a function of time!
Up till now all of our example graphs have assumed data points that are implicitly a function of time (where time is mapped to the x-axis). The assumption is that the data points are to be mapped uniformly along the x-axis which is fine for a large number of applications. But this may not always the case. It may be that one would like to explicitly plot data comprised of fully specified (x,y,z) coordinate values. This is done using the ‘x’ graphics object specifier. (‘X’ is reserved for an animation function delt with in due course)
 
In the case of the fully specified graphs the list of x-coordinates are followed by the list of y-coordinates and then finally the z-coordinates.  Some care may need to be taken to ensure sensible scaling into the fixed viewing space.
 
echo "G 0.7 0.5 0.5  9.0 5.0 5.0  0.0 0.0 0.0  1.0 1.0 0.0
x:g:mygraph 100 1 8 8 8 -4 -4 -4" | awk '{cnt++;
printf "%s\n", $0;
if (cnt==2) {
    split($0,an," ");
    for (i=1; i <=an[2]; i++) { printf "%f ",rand();}
    for (i=1; i <=an[2]; i++) { printf "%f ",rand();}
    for (i=1; i <=an[2]; i++) { printf "%f ",rand();}
    printf "\nb:r:red\n";
}
}' | spod
 
 
 
10000 random points in a box:
 
echo "G 0.7 0.5 0.5  9.0 5.0 5.0  0.0 0.0 0.0  1.0 1.0 0.0
x:g:mygraph 10000 1 8 8 8 -4 -4 -4" | awk '{cnt++;
printf "%s\n", $0;
if (cnt==2) {
    split($0,an," ");
    for (i=1; i <=an[2]; i++) { printf "%f ",rand();}
    for (i=1; i <=an[2]; i++) { printf "%f ",rand();}
    for (i=1; i <=an[2]; i++) { printf "%f ",rand();}
    printf "\np:.:points";
}
}' | spod
 
 
Example 2.4:  graph animation
Spod allows you to load thousands of graphs for display as an animated sequence. to date I have successfully loaded several hundred thousand graphs each containing hundreds of points.
 
 
The following script was developed to demonstrate the “sort” function. The first part of the script sets up a cluster of 400 points and saves this to a file /tmp/focus
 
echo "" | awk '{
   printf "x:y:graph %d 1 10 10 10 -5 -5 -5\n",  numb = 400;
   for (i=1; i <= numb; i++) printf "%f ", rand(); printf "\n";
   for (i=1; i <= numb; i++) printf "%f ", rand(); printf "\n";
   for (i=1; i <= numb; i++) printf "%f ", rand();
   printf "\np:.:points\nw 2\n";}' > /tmp/focus
 
 
The next part of the script re-computes a set of points, then computes a connecting graph for each pair of points. Because the format for graphs is largely free-format text, one may put the whole of a graph on a single line, then sort the lines (graphs) into an order based on a particular field. In this example the graphs are sorted with respect to the coordinate in the 15th field.
 
There are a total of around 70,000 graphs generated by the following script. Each begins with the ‘X’ object specifier, that SpOd intreprets to mean that these should be played in sequence. The animated ‘X’ graphs should always be the last graphs in a file.
 
The index counter is now used to index through the graph sequence, and the window-width determines how many of the graphs will be in the view at any given instant.
 
echo "" | awk '{numb = 400;
for (i=1; i <= numb; i++) printf "%f ", rand(); printf "\n";
for (i=1; i <= numb; i++) printf "%f ", rand(); printf "\n";
for (i=1; i <= numb; i++) printf "%f ", rand(); printf "\n";}' | awk '{ cnt++;
if (cnt==1) n=split($0,xn," ");
else if (cnt==2) n=split($0,yn," ");
else if (cnt==3) {
    n=split($0,zn," ");
    for (i=1; i<=n; i++) {
        for (j=1; j<i; j++) {
            printf "X:g:graph_%d 2 1 10 10 10 -5 -5 -5 %f %f %f %f %f %f w .3\n",cntr++, xn[i], xn[j],yn[i],yn[j],zn[i],zn[j];
        }
    }
}
}' | sort -t " " -k 15  >> /tmp/focus
 
Then we display the resultant file
 
echo "O 0 128
L 32 13 0 0 0 0
C 1.000000 1.000000 0.000000 1.000000 0.000000 0.000000 0.000000
G 0.000000 0.000000 0.000000  9.000000 4.000000 6.000000  0.000000 0.000000 0.000000  1.000000 1.000000 0.000000
M 1 0 0 10.000000
P 0.000000 5.000000 5.000000 5.000000
I -0.967501 0.000020 0.010000 0.100000 0.000000
`cat /tmp/focus`" | spod
 
 
 
 
The graph animation may be used in a variety of ways. For example one may simply display traces as if on an oscilloscope.
or the graphs may be displaced in the y- or z-plane to give separation.
 
For example here are the graphs obtained by slicing a surface into its constituent layers. The surface is derived from the entropy of the logistic map which is also used as an example in the next section in relation to rendering surfaces.
 
 
 
 
 
SpOd examples 2:- 3D graphs & traces