netAn2: Neural Network Analysis Plotting Functions for Weights
Notebook Version: 2.0
Steve Hunka, University of Alberta, steve.hunka@ualberta.ca
Mod. Date: Oct 29/97 Mod. V3.0

General Description of Notebook netAn2

This Notebook contains plotting functions useful in gaining some understanding of the dynamic and final state characteristics of the back propagated neural network for a particular problem.  The functions use the hidden and output cell weights for each epoch stored in files written during execution of the neural network simulation function bpnn in the Notebook Neural.nb.  The examples use files TCLow and TCLhw.

Caution: A large number of plots may result in using some functions depending upon the number of input cells, hidden cells, output cells, and exemplars used for a particular problem.  For example, a function may create one plot for each exemplar and if the number of exemplars is large, a considerable amount of memory will be required.

Description of Functions
Three types of functions are used:
1) functions which use hidden cell weights or output cell weights
2) functions which are called by those in (1) to do the plotting, and
3) support functions to provide interactive parameter input from the keyboard,
    and read the required data from a file.

Functions:
The functions described below are all designed to take input from the hidden weights and output weights files written by the neural network program bpnn.  Each of these files contains values saved at each epoch.  The first 3 characters of the function names listed below identify the nature of the data file from which the function requires data:

hdw   hidden layer weight file of order (#epochs,#hidden cells,#input cells)
otw   output layer weight file of order (#epochs,#output cells,#hidden cells)  
             
otwAnlz: 3d line/point plot of output weights hc[i],hc[j],hc[k] plotted over 
              epochs and separately for each output cell. Restricted to 3 hidden
              cells i,j, and k selected by user.
              Plots: 1 plot for each output cell (optional) and combined plot
              X axis: hc[i] wt, Y axis: hc[j] wt, Z axis: hc[k] wt        
otwAnlz2: plots output weights applied by each output cell to the response of
             each hidden cell. There are as many plots as output cells, with each
             plot having as many lines as hidden cells.         
hdwAnlz: 3D plot of migration of joint hidden cell weights (hc[i],hc[j],hc[k])
              for each input cell at each epoch. User selects 3 hidden cells {i,j,k}
              Each point is an epoch.
              Plots: 1;  X axis: hc[i] wt; Y axis: hc[j] wt; Z axis: hc[k] wt
              Each line: an input cell.
hdwAnlz2: plots hidden wts for each hidden cell by epoch for each input cell
              Plots: 1 for each input cell, X axis: epoch; Y axis: wt value
              Each line: a hidden cell
hdwAnlz3:  plots hidden weights for each input cell by epoch separately for
              each hidden cell.
               Plots: 1 for each hidden cell; X axis: epochs; Y axis: hidden wt;
               Each line: an input cell
hdwAnlz4: plots joint hidden cell weights for 2 selected input cells. 
                Plots: 1 for each hidden cell (optional) and combined; X axis: hc[j]
                wt; Y axis: hc[k] wt. 
hdwAray: array plot of hidden cell weights; there is one plot for each input cell
               and each plot contains one line for each hidden cell,
      
Supporting Plot Functions:
plotLists3: plots coordinates (x1,y1), (x2,y2)... cols of matrix; option for 
                single/multiple line plots
splt3d:      3D line/point plot; plots (x,y,z) at each epoch; options: point
                or line plot, single/multiple line plot; start/end numbering
mplotLists: called by hdwAray to do the plotting

Other Supporting Functions provided by  the Package netUtil and documented in netUdoc.nb are:
kbin3:       to get numerical input from keyboard
inpvec:      to input a n element vector and check min/max
kbinstrg: to get string input from keyboard
getFdata:  read part or all of data in a user specified file
timeDate: prints Mon, day, at hour:min from Date vector
araydis:    to structure plots in array plot
plotnLists: plots each column of matrix with x axis as integer sequence;
                options for single or multiple line plots; joined/not joined points,
                and end of line numbering
plotLegend: plots legend for colored lines used in plotnLists and plotLists3;
                provided by Package netUtil               

Documentation for function getFdata:

Since this function is used extensively to read data from a file a brief documentation of the user input is provided. (The function and further documentation is in the Package netUdoc.nb. 
 
The user is asked to input the name of the file holding the data; if the file is found a message is given; if the file is not found a message is given and the user is asked to give another name. If the user enters "quit" at the point of entering a file name, the function stops. If the file is available the user is asked whether to use all the data or only part of it. If the user enters "all", all data is read; if "part" is entered, the user is asked to give the starting point (record) in the file and the ending point for which the data is wanted.

Expected File Structure of Input Data

File Structures as Loaded by Neural Program
Caution:Structures which follow assume fixed order of exemplar input to the neural network program generating the files. An iteration is the presentation of one exemplar, an epoch the presentation of all exemplars once. If the option in the neural network program is for random presentation of exemplars, then the output of the hidden layer response data  and output cell responses data does not follow the natural order of presentation of exemplars as assumed in the functions of this notebook.  
  
The following abbreviations apply:
ic[[i]]     ith input cell               hc[[j]]     jth hidden cell
oc[[k]]    kth output cell            ex[[n]]     nth exemplar
#ic  number of input cells          #hc   number of hidden cells
#oc number of output cells        #ex   number of exemplars

errorfile: 
            {oc[[1]], oc[[2]],.....oc[[k]]} repeated for each iteration
   Dimensions={#iterations,#oc}
            
hidden layer response:
     {
       {hc[[1]], hc[[2]],...hc[[j]]},  for exemplar 1
         {hc[[1]], hc[[2]],...hc[[j]]},  for exemplar 2
         .................
         {hc[[1]], hc[[2]],...hc[[j]]},   for exemplar n
     } 
   repeated for each epoch. Dimensions={#epochs,#ex,#hc}

hidden cell weight file
    {
      {ic[[1]], ic[[2]],....ic[[i]]}, for hidden cell 1
      {ic[[1]], ic[[2]],....ic[[i]]}, for hidden cell 2
      ...............
      {ic[[1]], ic[[2]],....ic[[i]]}   for hidden cell j
    }   repeated for each epoch. Dimensions={#epochs,#hc,#ic}
    
output cell weight file
  {
     {hc[[1]], hc[[2]],.....hc[[j]]}, output cell 1
     {hc[[1]], hc[[2]],.....hc[[j]]}, output cell 2
      ...........
       {hc[[1]], hc[[2]],.....hc[[j]]} output cell k
  } repeated for each epoch. Dimensions={#epochs,#oc,#hc}
    
output cell response file
 {
   {ex[[1]], ex[[2]], ...,ex[[n]]},  output cell 1
   {ex[[1]], ex[[2]], ...,ex[[n]]},  output cell 2
   ..........
   {ex[[1]], ex[[2]], ...,ex[[n]]},  output cell k
 } repeated for each epoch. Dimensions={#epochs,#oc,#ex}

Required Packages

<< "Graphics`Graphics3D`"<< "Graphics`MultipleListPlot`"<< "netUtil`"

splt3d[d_,ttl_] 3D line plot of joint parameters over epochs of 3 cells defined by user. 
d is the cell output or weights from the neural network usually stored in a file;
ttl is a title for the plot.
The user input options are:
a) whether each plot should be marked with an id number at the start or end of
    the line or dots plotted.
b) whether lines or points are to be plotted; if points, the point size is
    requested.
c) whether single 3d plots should be made in addition to the combined plot.
   ScatterPlot3D produces Graphics3D[{Point[{x,y,z}],.....},options]; it is
   changed to give Graphics3D[{PointSize[ps],Point[{x,y,z}],.....},options
    in each pobj[j]. Also the first or last point is changed to Text[j,{x,y,z}]
    depending upon option (a) above.
d) the cell data to use, e.g., {1,2,5} plots point as defined by cells 1, 2 and 5. 
e) whether more plots are wanted after the first, to allow user to select other
    cells.
 Note: 
 1)PlotRange->All has been set. If PlotRange->Automatic, then if in (a) "end" is selected an id number may not appear for a specific plot because the plot was truncated.
 2) d is of order (#epochs, #z,#hidden cells) where #z may be number of output cells, number of exemplars, or number of input cells depending on the calling function. 
Calls: kbinstrg, kbin3,inpvec
Rqrs: <<Graphics`Graphics3D`, <<netUtil`
V3.0 Mod: ScatterPlot3D now has a directive GrayLevel[0] in the InputForm of the graphics object which is not in V2.2; changes to indices for line numbering were required.
Mod. Date: Oct 14/97 for V3.0

\(\(splt3d[d_, ttl_] := 
      Module[{p, ans, ln, pobj, temp, ps, ept, ipt, hcv, dt, qplt}, 
        ept = \(Dimensions[d]\)[[1]]; 
        p = \(Dimensions[d]\)[[2]]; 
        qplt = "y"; 
        While["y" == qplt, 
          ans = kbinstrg[
              "Mark start or end?", {{"start"}, {"end"}}]; 
          Print["Line id=", ans]; If[ans == "start", ept = 2]; 
          ans = kbinstrg[
              "Join plotted points? y/n", {{"y"}, {"n"}}]; 
          If[ans == "n",  (*plot\ points\ only*) 
				ln = False; 
            ps = kbin3["Type point size", 0.01]; 
            \(Print["Point size=", ps]; \), \(ln = True; \)]; 
          ipt = kbinstrg["Single plots? y/n", {{"y"}, {"n"}}]; 
          If[ipt == "y", ipt = $DisplayFunction, ipt = Identity]; 
          hcv = inpvec[{1, 
                \(Dimensions[d]\)[[3]]}, 
              3, "hidden cells"]; Print["Selected Cells=", hcv]; 
          pobj = {}; 
          dt = \(Transpose[d, {2, 3, 1}]\)[[hcv
              ]]; dt = Transpose[dt, {3, 2, 1}]; 
          pobj = MapThread[
              ScatterPlot3D[#1, PlotJoined -> ln, Axes -> True, 
                  AxesLabel -> ToString/@hcv, PlotRange -> All, 
                  DisplayFunction -> ipt]&, {dt}]; 

          				 (*now\ mark\ start\ or\ end\ of\ points\ or\ lines*) 	

          					
          If[ans == "n",  (*set\ pt\ size\ directive*) \(Do[
              temp = Append[{PointSize[ps]}, 
                  \(pobj[[j
                      ]]\)[[1
                    ]]]; 
              pobj = ReplacePart[pobj, temp, {j, 1}]; 

              				 (*
                set\ point\ line\ number\ at\ start\ or\ end\ by\ ept*) 	

              					
              \(pobj = 
                pobj /. 
                  pobj[[j, 1, 2, ept]] 
                    -> 
                    Text[ToString[j], 
                      pobj[[j, 1, 2, ept, 1
                        ]]]; \)

              							, {j, 1, p}]; 
            \),  (*else\ set\ line\ line\ number*) 
				
            \(Do[temp = 
                Append[{
                    Text[ToString[j], 
                      pobj[[j, 1, 2, 1, ept
                        ]]]}, 
                  pobj[[j, 1]]]; 
              \(pobj[[j]] = 
                ReplacePart[pobj[[j]], 
                  temp, 1]; \), {j, 1, p}]; \)]; 
			
          Show[pobj, PlotLabel -> ttl, 
            DisplayFunction -> $DisplayFunction]; 
          qplt = kbinstrg["More plots? y/n", {{"y"}, {"n"}}]; ]; 
        
	Return[pobj]; 
	
	]; \)\)

plotLists3[m,tl,xu,yu] plots adjacent columns of matrix m as (x,y) for each exemplar. Lines or points are plotted, and end points are marked by a number as well as being in color. See function plotnLists for color sequence or use plotLegend.
m is the matrix,
tl is plot title
xu is x-axis label
yu is the y-axis label
User Input:
a) single plots (y/n); if n one plot with multiple lines
b) points joined or not
Mod. Date: Mar 9/97

plotLists3[m_, tl_, xu_, yu_] := 
      Module[{ans, pobj, colr, ipt, tempobj, ln, ept, etxt}, 
        If[OddQ[Dimensions[m][[2
                ]]] == True, 
          Print["Error:odd # cols in data"]; Return[]]; pobj = {}; 
        colr = {0. , 0. , 0. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 
            1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0. , 0. ,  .5, 
            0. ,  .5, 0. , 0. ,  .5,  .5,  .5, 0. , 0. ,  .5, 0. ,  .5}; 
        ipt = kbinstrg["Single plots? y/n", {{"y"}, {"n"}}]; 
        If[ipt == "y", ipt = $DisplayFunction, ipt = Identity]; 
        ans = kbinstrg[
            "Join plotted points? y/n", {{"y"}, {"n"}}]; 
        If[ans == "n", ln = False; , ln = True; ]; 
        ept = Dimensions[m][[1]]; 
        Do[tempobj = 
            ListPlot[
              Transpose[
                Transpose[m][[{i, i + 1}
                    ]]], AxesLabel -> {xu, yu}, 
              PlotJoined -> ln, PlotRange -> All, 
              PlotStyle 
                -> {
                  RGBColor[colr[[1]], 
                    colr[[2]], 
                    colr[[3]]]}, 
              DisplayFunction -> Identity]; colr = RotateLeft[colr, 3]; 
          If[ans == "n", 
            tempobj = 
              tempobj /. 
                tempobj[[1, 2, ept]] 
                  -> 
                  Text[ToString[((i + 1)/2)], 
                    tempobj[[1, 2, ept, 1
                      ]]]; , 
            etxt = Append[{
                  Text[ToString[((i + 1)/2)], 
                    tempobj[[1, 2, 1, ept
                      ]]]}, 
                tempobj[[1]]]; 
            tempobj[[1]] = 
              ReplacePart[tempobj[[1]], 
                etxt, 2]; ]; 
          tempobj = 
            ReplacePart[tempobj, 
              Append[{PointSize[ .001]}, 
                tempobj[[1]]], 1]; 
          Show[tempobj, DisplayFunction -> ipt]; 
          AppendTo[pobj, tempobj];, {i, 1, Length[Transpose[m]], 2}]; 
        Show[pobj, PlotLabel -> tl, 
          DisplayFunction -> $DisplayFunction]; ];

otwAnlz 3D plots joint output cell weights assigned each hidden cell for each epoch. 
Each dot is an epoch, each line is an output cell, each axis is a hidden cell. The input is read from a file written by bpnn and is of order (epochs,#output cells, #hidden cells).
User Input:
a) See getFdata description; 
splt3d user input is:
b) whether lines to be identified at start or end
c) whether plotted points are joined; if no, point size requested
d) whether single plots for each line to be displayed
e) indices of 3 hidden cells as a vector
f) option to plot again with different hidden cells
Calls: getFdata,timeDate,splt3d,kbin3,kbinstrg
Mod. Date: Mar 22/97

otwAnlz := 
      Module[{data, extnt}, 
        Print["Plot of output cell weights for 3 hidden cells"]; 
        Print["Xaxis=wt hc[i];Yaxis=wt hc[j];Zax=wt hc[k]"]; 
        Print["LineId[j]=oc[j]"]; 
        Print["User specifies 3 hidden cells as vector"]; {data, extnt} = 
          getFdata; If[0 == extnt, Print["No data read"]; Return[]]; 
        Print["Number of output cells=", 
          Dimensions[data][[2]]]; 
        Print["Number of hidden cells=", 
          Dimensions[data][[3]]]; 
        splt3d[data, "Output Cell Weight"]; ];

otwAnlz

otwAnlz2: plots output weights applied by each output cell to the response of each hidden cell. The data is read from the output cell weight file written by bpnn and is of order (#epochs, #output cells, # hidden cells). There are as many plots as output cells, with each plot having as many lines as hidden cells.
Calls: getFdata, plotnLists 
Mod. Date: Apr 29/97

otwAnlz2 := 
      Module[{data, extnt, ttl, noc, nhc}, 
        Print["Output Weights for each hidden cell"]; 
        Print["Yaxis=output cell wt; Xaxis=epoch; Line=hc[j]"]; {data, 
            extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        nhc = Dimensions[data][[3]]; 
        Print["Number of hidden cells=", nhc]; 
        noc = Dimensions[data][[2]]; 
        Print["Number of Output cells=", noc]; plotLegend[nhc]; 
        Do[ttl = StringInsert["Output cell=", ToString[i], -1]; 
          plotnLists[
              Transpose[
                Transpose[data, {3, 1, 2}][[i
                  ]]], ttl, "epochs", 0, 1, 1];, {i, 
            1, noc}]; ];

otwAnlz2

hdwAnlz: 3D plot of migration of hidden cell weight (hc[i],hc[j],hc[k]) for each input cell at each epoch. Each dot is an epoch; each line is an input cell; each axis is a hidden cell. The data input is from the hidden weight file written by bpnn and is of order (#epochs, #hidden cells, #input cells).
User Input:
a) See getFdata description; splt3d user input is:
b) whether lines to be identified at start or end
c) whether plotted points are joined; if no, point size requested
d) whether single plots for each line to be displayed
e) indices of 3 hidden cells as a vector
f) option to plot again with different hidden cells
Calls: getFdata, kbin3, kbinstrng, splt3d
Mod. Date: Mar 24/97

hdwAnlz := 
      Module[{data, extnt, title}, 
        Print["Three Hidden Cell Weights for each Input cell"]; 
        Print["Xaxis=hc[i] wt; Yaxis=hc[j] wt; Zaxis=hc[k] wt"]; 
        Print["User specifies 3 hidden cells indices as vector"]; 
        Print["Line[n]=inputcell[n]"]; {data, extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        Print["Number of hidden cells=", 
          Dimensions[data][[2]]]; 
        Print["Number of input cells=", 
          Dimensions[data][[3]]]; 
        title = "Hidden Cell Weight"; 
        splt3d[Transpose[data, {1, 3, 2}], title]; ];

hdwAnlz

hdwAnlz2; plots hidden wts for each hidden cell by epoch for each input cell.The data input is from the hidden weight file written by bpnn and is of order (#epochs, #hidden cells, #input cells). Caution: There are as many plots as input cells, and each plot will contain as many lines as hidden cells. 
User Input: see getFdata
Calls: plotnLists, plotLegend, getFdata,timeDate
Mod. Date: Mar 24/97

hdwAnlz2 := 
      Module[{data, extnt, ttl, nic, nhc}, 
        Print["Hidden Weights for each input cell"]; 
        Print["Yaxis=hidden cell wt; Xaxis=epoch; Line=hc[j]"]; {data, 
            extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        nic = Dimensions[data][[3]]; 
        Print["Number of input cells=", nic]; 
        nhc = Dimensions[data][[2]]; 
        Print["number of hidden cells=", nhc]; plotLegend[nhc]; 
        Do[ttl = StringInsert["Input cell=", ToString[i], -1]; 
          plotnLists[
              Transpose[
                Transpose[data, {3, 2, 1}][[i
                  ]]], ttl, "epochs", 0, 1, 1];, {i, 
            1, nic}]; ];

hdwAnlz2

hdwAnlz3 plots weights for each input cell by epoch separately for each hidden cell. There are as many plots as hidden cells each containing as many lines as input cells. The data input is from the hidden weight file written by bpnn and is of order (#epochs, #hidden cells, #input cells).
User Input: see getFdata 
Calls: plotnLists, plotLegend, getFdata,timeDate
Mod. Date: Mar 24/97

hdwAnlz3 := 
      Module[{data, extnt, ttl, nhc, nic}, 
        Print["Hidden Weights,Plots=hc[j]"]; 
        Print["Yaxis=wt value; Xaxis=epoch; Line=incel[k]"]; {data, 
            extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        nhc = Dimensions[data][[2]]; 
        Print["number of hidden cells=", nhc]; 
        nic = Dimensions[data][[3]]; 
        Print["number of input cells=", nic]; plotLegend[nic]; 
        Do[ttl = StringInsert["Hidden cell ", ToString[i], -1]; 
          plotnLists[
              Transpose[data, {2, 1, 3}][[i
                ]], ttl, "epoch", 0, 1, 1];, {i, 1, 
            nhc}]; ];

hdwAnlz3

hdwAnlz4; plots weights assigned jointly to 2 selected input cells by each hidden cell. End points numbered by hidden cell number. There are as many lines in each plot as hidden cells. Each point represents an epoch. The data input is from the hidden weight file written by bpnn and is of order (#epochs, #hidden cells, #input cells). 
User Input:
a) See function getFdata
b) 2 input cell indices as a vector
c) See function plotLists3
d) option to plot again with different set of input cell indices
Calls: kbin3,kbinstrg,getFdata,timeDate,plotLists3,inpvec,plotLegend
Mod. Date: Mar 25/97

hdwAnlz4 := 
      Module[{ans, alpr, pr, data, extnt, ttl, nic, nhc, data2, ax, ay}, 
        Print["Joint hidden cell weights for pair of input cells"]; 
        Print["Line=hc[i]"]; 
        Print["Xaxis=incell[j] wt;Yaxis=incell[k] wt"]; 
        Print["Line id=end point"]; {data, extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        nhc = Dimensions[data][[2]]; 
        nic = Dimensions[data][[3]]; 
        Print["Number of hidden cells=", nhc]; 
        Print["Number input cells=", nic]; plotLegend[nhc]; 
        ans = "y"; 
        While[ans == "y", pr = inpvec[{1, nic}, 2, "input cells"]; 
          Print["Input cell pair to plot=", pr]; alpr = {}; 
          Do[AppendTo[alpr, pr + j {nic, nic}]; , {j, 0, nhc - 1}]; 
          data2 = Transpose[
              Flatten[Transpose[data, {3, 1, 2}], 1]
                  [[Flatten[alpr]]]]; 
          ay = StringInsert["i", 
              ToString[pr[[2]]], 
              -1]; 
          ax = StringInsert["i", 
              ToString[pr[[1]]], 2]; 
          ttl = StringInsert["Input cells=", ToString[pr], -1]; 
          plotLists3[data2, ttl, ax, ay]; 
          ans = kbinstrg[
              "More plots? y/n", {{"y"}, {"n"}}]; ]; ];

hdwAnlz4

hdwAray[d___]: used for making an array plot of the hidden cell weights by epoch for each input cell (exemplar attribute).
d  is optional; if d is present it contains the hidden weights of order (#epochs,#hidden cells,#input cells). d may be obtained from the appropriate  file created by the neural network program bpnn by using ReadList["filename"].  If d is absent, the user is requested to give the name of the file holding the hidden weights. 

Each plot contains one colored line for each hidden cell, and each plot represents a different attribute of the exemplars input (input cell). The plots are brought together in an array of plots for which the user may specify a common y-axis scaling (or default the scaling) and the plot arrangement. If the sum of the number of plots in each row exceeds the number of plots available an error message is given.
User Input: 
1) See getFdata 
2) plot range (y/n); if y, {min,max} required; if no PlotRange->All
3) a vector specifying the number of plots in each row of the array plot. The sum of the elements in this vector should equal the number of input cells.
Calls: mplotLists, araydis, kbinstrg, kbin3,getFdata, timeDate,plotLegend
Mod. Date: Mar 28/97

hdwAray[d___] := 
      Module[{data, extnt, nhc, nic, p, prng, ans, lim, apat, ok}, 
        Print["Hidden Weights,Plots=inc[j]"]; 
        Print["Yaxis=wt; Xaxis=epoch; Line=hc[j]"]; 
        Print["Point=wt at each epoch"]; 
        If[Length[{d}] == 0, {data, extnt} = getFdata; , data = d]; 
        nhc = Dimensions[data][[2]]; 
        nic = Dimensions[data][[3]]; 
        Print["Number Hidden cells=", nhc]; 
        Print["Number of input cells=", nic]; 
        Print["Minimum weight=", Min[data]]; 
        Print["Maximim weight=", Max[data]]; plotLegend[nhc]; p = {}; 
        ans = kbinstrg["Set plot range? y/n", {{"y"}, {"n"}}]; 
        If[ans == "y", 
          prng = kbin3["Type {min,max} plot range", {2}]; , 
          prng = All]; 
        Do[AppendTo[p, 
            mplotLists[
              Transpose[
                Transpose[data, {3, 2, 1}][[i
                  ]]], prng]]; , {i, 1, nic}]; ok = 0; 
        While[ok == 0, 
          apat = Input["Type vector of # plots in each row of array"]; 
          If[Plus@@apat > Length[p], 
            Print["Error: too many plots in vector"]; , ok = 1]; ]; 
        Show[GraphicsArray[araydis[Flatten[p], apat]], 
          DisplayFunction -> $DisplayFunction]; ];

mplotLists[m,lim]; plots the values in the columns of a 2 dimensional matrix m using MultipleListPlot, but the plotting symbols are removed; up to 12 different colors are used to plot the lines after which the color cycle repeats.
$LineStyles is changed. The colors are rotated through the following color sequence:(1) black, (2) blue (3) green, (4) cyan, (5) red, (6) magenta, (7) yellow, (8) dark blue, (9) dark green (10) turquoise, (11)brown, and (12) purple. (Colors numbered 8 to 12 may vary with different monitors.) lim is a 2 element vector of min and max plot range or All to default the plot range of y.  
Returns: graphic object for array plot
Required: Graphics`MultipleListPlot, netUtil
V3.0 Mod: removal of plot symbol from graphic object and use of option SymbolShape->None in MultipleListPlot
Mod. Date: Oct 15/97 V3.0

mplotLists[m_, lim_] := 
      Module[{pobj, mtr, indx, nr, lstyl, colr}, pobj = {}; 
        mtr = Transpose[m]; 
        nr = Dimensions[mtr][[1]]; 
        lstyl = Table[{Thickness[0.005], RGBColor[0, 1, 0]}, {nr}]; 
        colr = {0. , 0. , 0. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 
            1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0. , 0. ,  .5, 
            0. ,  .5, 0. , 0. ,  .5,  .5,  .5, 0. , 0. ,  .5, 0. ,  .5}; 
        Do[lstyl[[j]] = 
            ReplacePart[lstyl[[j]], 
              RGBColor[colr[[1]], 
                colr[[2]], 
                colr[[3]]], {2}]; 
          colr = RotateLeft[colr, 3]; , {j, 1, nr}]; $LineStyles = lstyl; 
        pobj = (
              MultipleListPlot[##1, DefaultFont -> {"Times", 8}, 
                  AxesLabel -> {"x", "y"}, SymbolShape -> None, 
                  PlotJoined -> True, PlotRange -> lim, 
                  DisplayFunction -> Identity]&)@@mtr; 
        Return[pobj]; ];

araydis[m,in]; arranges the plots in m for GraphicsArray according to the arrangement specified by in. For example if m had 9 plots, and in={2,3,4} then the 1st row will contain 2 plots, the next 3 plots, and the last row 4 plots as displayed by Graphics Array. This function differs from araydis3 in that 
araydis allows specification of the number of plots in each row of the array 
while araydis3 does not.
Length[in] <= Length[m].
Mod. Date: Feb 20/97

araydis[m_, in_] := 
      Module[{pa, ma, nt}, pa = {}; nt = Length[in]; ma = m; 
        Do[AppendTo[pa, 
            Take[ma, in[[i]]]]; 
          ma = Drop[ma, in[[i]]];, {
            i, 1, nt}]; Return[pa]; ];

hdwAray[]