*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     SUBROUTINE PLOTYX (X, Y, IDIM, NPT, NGRAPH,
*                        XMIN, XMAX, YMIN, YMAX, OPTION)
*
*
* Purpose:
*     Plot tabulated data on a labelled graph
*
*
* Description:
*     This subroutine plots real data.  The function values are
*     supplied in a two-dimensional array, and the abscissa values
*     are given in another array.  The plotting scale may be specified
*     directly or the routine can be allowed to determine an
*     appropriate plotting scale.
*
*     This routine draws the graph of the function along with labelled
*     axes.  The default axes have an integral number of intervals,
*     such that increment corresponding to an interval is a number of
*     the form 1, 2 or 5 times a power of ten.
*
*
* Parameters:
* R <-> X      - Array of abscissa values (NPT values).  These values
*                are altered if a log X-axis is selected.  For a log
*                X-axis, the values are converted to log values and
*                then back again to linear values.  For the LINE-TYPE=
*                SMOOTH option, the abscissa values must be in
*                increasing order.
* R <-> Y      - Two dimensional array of function values.  Y(1,1)
*                through Y(NPT,1) are plotted on the first graph,
*                Y(1,2) through Y(NPT,2) are plotted on the second
*                graph, and so on.  If only one graph is to be plotted,
*                Y may be one dimensional. For a log Y-axis, the values
*                are converted to log values and then back again to
*                linear values.
* I ->  IDIM   - First dimension of the input array Y
* I ->  NPT    - Number of points per graph (less than or equal to
*                IDIM).  For the LINE-TYPE=SMOOTH option, NPT can be at
*                most 301.
* I ->  NGRAPH - Number of graphs to be simultaneously plotted.  If
*                NGRAPH is zero, only the axes are drawn.
* R ->  XMIN   - Lower limit for the X-axis
* R ->  XMAX   - Upper limit for the X-axis
*                If XMIN is equal to XMAX, the subroutine will find a
*                range for the X-axis of the graph such that all values
*                of X and also the value XMIN (and XMAX) are included
*                in the range of the graph.  Automatic scaling is
*                enabled by setting XMIN=XMAX=X(n), where X(n) is any
*                of the abscissa values.
* R ->  YMIN   - Lower limit for the Y-axis
* R ->  YMAX   - Upper limit for the Y-axis
*                If YMIN is equal to YMAX, the subroutine will find a
*                range for the Y-axis of the graph such that all values
*                of Y and also the value YMIN (and YMAX) are included
*                in the range of the graph.  Automatic scaling is
*                enabled by setting YMIN=YMAX=Y((i,j), where Y(i,j) is
*                any of the function values.
* C ->  OPTION - Character string specifying the options
*                Individual option specifications are separated by
*                white space (blanks, tabs or null characters) or
*                commas.  The general form of the option specifications
*                is KEYWORD=arg or KEYWORD, where KEYWORD is a keyword
*                string.  Keywords can be specified in upper or lower
*                case and in most cases allow for short forms.  The
*                argument string following the keyword is used to
*                specify values or subsidiary option specifications.
*                Within the argument string, parentheses are used to
*                group lists of values or subsidiary option
*                specifications.  Lists of values are enclosed in
*                parentheses with the values separated by white space
*                or commas.  The same keyword may be given more than
*                once, with the last invokation taking precedence.
*                Default options are used if some or all of the
*                keywords are omitted.
*
*                Keywords are listed below.  An asterisk character is
*                used to indicate the position corresponding to the
*                minimum length short forms for the keywords.
*                CHAR*ACTER_SIZE = (Iwidth Iheight) - Character size
*                  This option specifies the size of characters to be
*                  used for labelling the axes.  This character size
*                  also serves as the default plot symbol size.  Note
*                  that axis tick lengths scale with the character
*                  size.
*                  (default 32 by 48)
*                LINE*-TYPE - Type of line used to plot the data
*                  = POINT*S, symbols plotted at the points
*                  = LINE, straight lines joining the points (default)
*                  = LINE+*POINTS, both symbols and lines
*                  = SMOOTH, monotonic cubic interpolant (smooth
*                     plotting curve passing through the data values)
*                  = SMOOTH+*POINTS, both points and a smooth curve
*                  = (PATTERN=(xx yy ...)), line pattern
*                     The argument indicates the on/off pattern for
*                     the line to be used in drawing the graphs.  Each
*                     of the elements in the pattern represents the
*                     length (in plotting units) of an ON pattern
*                     (positive value) or an OFF pattern (negative
*                     value).  Up to 5  pattern elements may be
*                     specified.
*                     (default continuous line, PATTERN=0).
*                  = (SYM*BOLS="xxxxx"), plotting symbols
*                     The character string specifies the plot symbols
*                     to be used for the graphs. The first character is
*                     used for the first graph, the second character
*                     for the second graph, and so on. If the number of
*                     graphs is larger than the number of symbols
*                     specified, the symbols are used cyclically. Up to
*                     20 symbols may be specified. Leading and trailing
*                     white space is ignored unless the symbol string
*                     is enclosed in quotes (").  Special plotting
*                     symbols may be accessed as characters with ASCII
*                     codes in the range 161-170.
*                     161 square           162 octagon (circle)
*                     163 triangle         164 inverted triangle
*                     165 ex               166 cross
*                     167 filled squadre   168 filled octagon
*                     169 filled triangle  170 filled inverted triangle
*                     (default square, octagon, triangle,...).
*                  = (SYMBOL_SIZE=(Iwidth Iheight)), plotting symbol
*                     size in plotting units
*                     (default size is set by the CHARACTER_SIZE option
*                     which itself defaults to 32 by 48)
*                  = (SYMBOL_ANGLE=angle), plotting symbol angle
*                     This option sets the angle of the plot symbols in
*                     degrees measured from the horizontal axis.
*                     (default 0)
*                POS*ITION = (IX IY) - Position of the plot
*                  This option specifies the X-Y coordinates (in
*                  plotting units) of the lower lefthand corner of the
*                  plot.
*                  (default position (720 440))
*                SIZE = (LenX LenY) - Size of the plot
*                  This option specifies the size of the plotting area
*                  (in plotting units).
*                  (default size (3240 2400))
*                X-AX*IS - Plot limits and horizontal axes
*                  Axis generation is automatic unless the TICKS option
*                  is specified.
*                  (default (LIMITS=EXACT ON LINEAR), if the axis
*                  range is explicitly specified (XMAX > XMIN),
*                  (LIMITS=TICKS ON LINEAR) otherwise)
*                  = LIN*EAR - linear scale
*                     In the automatic mode, the axis ticks are chosen
*                     to correspond to uniformly spaced "nice" values
*                     of the form 1, 2 or 5 times a power of ten, but
*                     only every second tick is labelled with a value.
*                  = LOG*ARITHMIC - logarithmic scale
*                     In the automatic mode, the axis ticks correspond
*                     to the decade points 10**n.  For a data range
*                     encompassing a small number of decades,
*                     intermediate ticks at 2*10**n and 5*10**n are
*                     also generated.  For a single decade, ticks at
*                     2*10**n, 3*10**n, ..., 9*10**n are generated.
*                     The decade points are always labelled.  If the
*                     number of decades is small, intermediate ticks
*                     are also labelled.
*                  = (LIM*ITS = EXACT)
*                    (LIM*ITS = TICK*S)
*                    (LIM*ITS = (LOW*ER_LIMIT=EXACT or TICK))
*                    (LIM*ITS = (UP*PER_LIMIT=EXACT or TICK)) - plot
*                     limit options
*                     EXACT - The plot limits are set to the values
*                     determined from XSTART and XINCR.
*                     TICKS - The plot limits are set to coincide with
*                     axis tick values which include the range
*                     determined from XSTART and XINCR.
*                     The LOWER_LIMIT and UPPER_LIMIT options allow for
*                     separate specification of the plot limit type at
*                     each end of the axis.
*                  = ON, enable default plot axes
*                     This option is equivalent to specifying the
*                     X-AXIS options (BOTTOM=LABELLED TOP=ON
*                     ORIGIN=ON).
*                  = OFF, disable plot axes
*                     This option is equivalent to specifying the
*                     X-AXIS options (BOTTOM=OFF TOP=OFF ORIGIN=OFF).
*                  = (BOT*TOM = *ON, OFF, LABEL*LED, LINE), bottom axis
*                     This option determines whether an axis is to be
*                     drawn at the bottom of the graph.  Labels, if
*                     selected, appear below the axis.
*                     OFF  - No axis
*                     *ON  - Unlabelled axis with tick marks
*                     LABEL*LED - Labelled axis with tick marks
*                     LINE - Unlabelled axis with no tick marks
*                  = (TOP = *ON, OFF, LABEL*LED, LINE), top axis
*                     This option determines whether an axis is to be
*                     drawn at the top of the graph.  Labels, if
*                     selected, appear above the axis.
*                  = (ORIG*IN = *ON, OFF, LABEL*LED, LINE), origin axis
*                     This option determines whether an axis is to be
*                     drawn through y=0 if y=0 appears within the range
*                     of a graph. Labels, if selected, appear below the
*                     axis.
*                  = (TICK*S = (val1 val2 val3 ...)), axis tick values
*                     This option specifies the data values at which
*                     axis ticks are to appear. Up to 100 values may be
*                     specified.  Tick values outside the range of the
*                     graph are not plotted.  If this option is
*                     omitted, or the list of data values is not given,
*                     axis ticks are placed automatically.
*                  = (LABEL*S = ("label1" "label2" "label3" ...)), axis
*                     labels
*                     This option specifies character strings to be
*                     associated with the tick marks given by the
*                     TICKS option.  The labels are centred above or
*                     below the corresponding tick marks.  Leading and
*                     trailing white space in each label is ignored
*                     unless the label string is enclosed by quotes
*                     (").  Control characters can be included to allow
*                     for superscripts for power of ten notation (see
*                     subroutine PLTEXT).  Any or all labels may be
*                     empty ("").  Tick marks associated with empty
*                     labels are shorter than tick marks associated
*                     with non-empty labels.  This holds even if other
*                     options select an axis that is to be drawn as
*                     unlabelled (tick marks only).  The labels may be
*                     up to 20 characters in length.  The LABELS option
*                     has no effect unless the TICKS option is also
*                     specified.  If the LABELS option is omitted, or
*                     the list of labels is null, LABELS are generated
*                     automatically.
*                Y-AX*IS - Plot limits and vertical axes
*                  Axis generation is automatic unless the TICKS option
*                  is specified.
*                  (default (LIMITS=EXACT ON LINEAR), if the axis
*                  range is explicitly specified (YMAX > YMIN),
*                  (LIMITS=TICKS ON LINEAR) otherwise)
*                  = LIN*EAR - linear scale
*                     In the automatic mode, the axis ticks are chosen
*                     to correspond to uniformly spaced "nice" values
*                     of the form 1, 2 or 5 times a power of ten, but
*                     only every second tick is labelled with a value.
*                  = LOG*ARITHMIC - logarithmic scale
*                     The input Y array is converted to log values.  In
*                     the automatic mode, the axis ticks correspond to
*                     the decade points 10**n.  For a data range
*                     encompassing a small number of decades,
*                     intermediate ticks at 2*10**n and 5*10**n are
*                     also generated.  For a single decade, ticks at
*                     2*10**n, 3*10**n, ..., 9*10**n are generated.
*                     The decade points are always labelled.  If the
*                     number of decades is small, intermediate ticks
*                     are also labelled.
*                  = (LIM*ITS = EXACT)
*                    (LIM*ITS = TICK*S)
*                    (LIM*ITS = (LOW*ER_LIMIT=EXACT or TICK))
*                    (LIM*ITS = (UP*PER_LIMIT=EXACT or TICK)) - plot
*                     limit options
*                     EXACT - The plot limits are set to the values
*                     determined from YMIN and YMAX.  For YMAX > YMIN,
*                     the limits are [YMIN,YMAX].  Otherwise, the plot
*                     limits are determined as [min(YMIN,Y(i,j)),
*                     max(YMAX,Y(i,j))].
*                     TICKS - The plot limits are set to coincide with
*                     axis tick values which include the range
*                     determined from YMIN and YMAX.
*                     The LOWER_LIMIT and UPPER_LIMIT options allow for
*                     separate specification of the plot limit type at
*                     each end of the axis.
*                  = ON, enable default plot axes
*                     This option is equivalent to specifying the
*                     X-AXIS options (LEFT=LABELLED RIGHT=ON
*                     ORIGIN=ON).
*                  = OFF, disable plot axes
*                     This option is equivalent to specifying the
*                     X-AXIS options (LEFT=OFF RIGHT=OFF ORIGIN=OFF).
*                  = (L*EFT = *ON, OFF, LABEL*LED, LINE), left axis
*                     This option determines whether an axis is to be
*                     drawn to the left of the graph.  Labels, if
*                     selected, appear to the left of the axis.
*                     OFF  - No axis
*                     *ON  - Unlabelled axis with tick marks
*                     LABEL*LED - Labelled axis with tick marks
*                     LINE - Unlabelled axis with no tick marks
*                  = (R*IGHT = *ON, OFF, LABEL*LED, LINE), right axis
*                     This option determines whether an axis is to be
*                     drawn to the right of the graph.  Labels, if
*                     selected, appear to the right of the axis.
*                  = (ORIG*IN = *ON, OFF, LABEL*LED, LINE), origin axis
*                     This option determines whether an axis is to be
*                     drawn through x=0 if x=0 appears within the range
*                     of a graph.  Labels, if selected, appear to the
*                     left of the axis.
*                  = (TICK*S = (val1 val2 val3 ...)), axis tick values
*                     This option specifies the data values at which
*                     axis ticks are to appear. Up to 100 values may be
*                     specified.  Tick values outside the range of the
*                     graph are not plotted.  If this option is
*                     omitted, or the list of data values is not given,
*                     axis ticks are placed automatically.
*                  = (LABEL*S = ("label1" "label2" "label3" ...)), axis
*                     labels
*                     This option specifies character strings to be
*                     associated with the tick marks given by the
*                     TICKS option.  The labels are centred above or
*                     below the corresponding tick marks.  Leading and
*                     trailing white space in each label is ignored
*                     unless the label string is enclosed by quotes
*                     (").  Control characters can be included to allow
*                     for superscripts for power of ten notation (see
*                     subroutine PLTEXT).  Any or all labels may be
*                     empty ("").  Tick marks associated with empty
*                     labels are shorter than tick marks associated
*                     with non-empty labels.  This holds even if other
*                     options select an axis that is to be drawn as
*                     unlabelled (tick marks only).  The labels may be
*                     up to 20 characters in length.  The LABELS option
*                     has no effect unless the TICKS option is also
*                     specified.  If the LABELS option is omitted, or
*                     the list of labels is null, LABELS are generated
*                     automatically.
*
*                As an example, the following call to this routine
*                results in the same options as the default ones if
*                XMIN < XMAX and YMIN < YMAX.
*                CALL PLOTYX (X,Y,IDIM,NPT,NGRAPH,XMIN,XMAX,YMIN,YMAX,
*               -             'LINE-TYPE=(LINE PATTERN=0) '//
*               -             'SIZE=(3240 2400) ORIGIN=(720 440) '//
*               -             'X-AXIS=(LIMITS=EXACT LINEAR) '//
*               -             'Y-AXIS=(LIMITS=EXACT)')
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.6 $  $Date: 1995/03/08 15:28:23 $
*
*
*-----------------------------------------------------------------------

      SUBROUTINE PLOTYX (X, Y, IDIM, NPT, NGRAPH,
     -                   XMIN, XMAX, YMIN, YMAX, OPTION)


      INTEGER POINT,LINE,LINEPT,SMOOTH,SMOOPT,OFF
      INTEGER MXTICK,MAXNI
      PARAMETER (POINT=1,LINE=2,LINEPT=3,SMOOTH=4,SMOOPT=5,
     -           OFF=0)
      PARAMETER (MXTICK=100,MAXNI=301)

      INTEGER IDIM,NPT,NGRAPH
      INTEGER ICSIZE(2),IPATTN(5),ISSIZE(2),IXAX(0:3),IYAX(0:3)
      INTEGER LINTYP,IXORIG,IYORIG,LENX,LENY,NTICKX,NTICKY,
     -        IEXPX,IEXPY,LS,J,NIPT,K,ILOGX,ILOGY
      INTEGER LENNUL

      CHARACTER*(*) OPTION
      CHARACTER*20 SYMBOL,ALABLX(MXTICK),ALABLY(MXTICK)

      REAL X(*),Y(IDIM,*)
      REAL XMIN,XMAX,YMIN,YMAX
      REAL SANG,VMIN,VMAX
      REAL ATICKX(MXTICK),ATICKY(MXTICK)
      REAL XI(MAXNI),YI(MAXNI)
      REAL DATREG(2,2)


* Decode the options string
      CALL DECPLT(OPTION,ICSIZE,LINTYP,IPATTN,SYMBOL,ISSIZE,SANG,
     -            IXAX,IYAX,IXORIG,IYORIG,LENX,LENY,
     -            ATICKX,ATICKY,ALABLX,ALABLY,NTICKX,NTICKY)
      CALL SETGRS(IXORIG,IYORIG,LENX,LENY)

********** Scaling
* X - Find the minimum and maximum values
* X-axis scaling and labels
      CALL AXLIMS(X,IDIM,NPT,1,XMIN,XMAX,ATICKX,NTICKX,
     -            IXAX(0),VMIN,VMAX)
      CALL AXSCAL(VMIN,VMAX,IXAX(0),DATREG(1,1),DATREG(1,2),
     -            ATICKX,ALABLX,NTICKX,IEXPX)

* Y - Find the minimum and maximum values
* Y-axis scaling and labels
      CALL AXLIMS(Y,IDIM,NPT,NGRAPH,YMIN,YMAX,ATICKY,NTICKY,
     -            IYAX(0),VMIN,VMAX)
      CALL AXSCAL(VMIN,VMAX,IYAX(0),DATREG(2,1),DATREG(2,2),
     -            ATICKY,ALABLY,NTICKY,IEXPY)

* Log scaling of the abscissa values and plot limits
      ILOGX=MOD(IXAX(0)/64,2)
      IF (ILOGX.NE.0) THEN
        CALL VLOG10(X,X,NPT)
        DATREG(1,1)=LOG10(DATREG(1,1))
        DATREG(1,2)=LOG10(DATREG(1,2))
      END IF
      ILOGY=MOD(IYAX(0)/64,2)
      IF (ILOGY.NE.0) THEN
        DATREG(2,1)=LOG10(DATREG(2,1))
        DATREG(2,2)=LOG10(DATREG(2,2))
      END IF


********** Plotting
      CALL SETCHR(ISSIZE(1),ISSIZE(2),SANG)
      LS=LENNUL(SYMBOL)

      DO 300 J=1,NGRAPH

* Log scaling of the Y values
        IF (ILOGY.NE.0) CALL VLOG10(Y(1,J),Y(1,J),NPT)

* Straight line segments
        IF (LINTYP.EQ.LINE .OR. LINTYP.EQ.LINEPT) THEN
          CALL PLVCFX(X,Y(1,J),NPT,DATREG,IPATTN)

* Interpolation to give a smooth curve
        ELSE IF (LINTYP.EQ.SMOOTH .OR. LINTYP.EQ.SMOOPT) THEN
          CALL EQDINC(X,NPT,XI,MAXNI,NIPT)
          CALL PMCINT(X,Y,NPT,XI,YI,NIPT)
          CALL PLVCFX(XI,YI,NIPT,DATREG,IPATTN)
        END IF

* Plot symbols at the data points
        IF (LS.GT.0 .AND.
     -      (LINTYP.EQ.POINT .OR. LINTYP.EQ.LINEPT .OR.
     -       LINTYP.EQ.SMOOPT)) THEN
          K=MOD(J-1,LS)+1
          CALL PLVCPX(SYMBOL(K:K),X,Y(1,J),NPT,DATREG)
        END IF

* Undo the log scaling of the data values
        IF (ILOGY.NE.0) CALL VEXP10(Y(1,J),Y(1,J),NPT)

 300  CONTINUE

* Undo the log scaling of the abscissa values
      IF (ILOGX.NE.0) CALL VEXP10(X,X,NPT)

********** Axes
* Labelled axes around the plot
      IF (ILOGX.NE.0) CALL VLOG10(ATICKX,ATICKX,NTICKX)
      IF (ILOGY.NE.0) CALL VLOG10(ATICKY,ATICKY,NTICKY)
      CALL SETCHR(ICSIZE(1),ICSIZE(2),0.)
      CALL PLAXES(IXAX(1),ATICKX,ALABLX,NTICKX,IEXPX,
     -            IYAX(1),ATICKY,ALABLY,NTICKY,IEXPY,DATREG)


      RETURN

      END
