MODULE GraphingRoutines
!------------------------------------------------------------------------

! Module that contains the subroutines for producing various kinds

! of graphs

!    ScatterPlot

!    DensityPlot

!    . . .

!-------------------------------------------------------------------------



CONTAINS


  !-ScatterPlot----------------------------------------------------------

  ! Subroutine to produce a scatter plot of data points stored in a file,

  ! the first line of which contains values for X_Min, X_Max, Y_Min, and

  ! Y_Max, in this order. Local identifiers used are:
  !   Horiz_Limit,

  !   Vert_Limit     : limits on the size of the graphics window

  !                    (constants)

  !   Window         : two-dimensional character array -- the graphics

  !                    window

  !   PlotChar       : plotting character -- represents a point on the

  !                    graph

  !   X_Min, X_Max   : minimum and maximum X values

  !   Y_Min, Y_Max   : minimum and maximum Y values



  !   DeltaX, DeltaY : X and Y increments!   X, Y: a point on the graph
  !   X_Loc, Y_Loc   : location of a point in the window

  !   Count          : counts units on Y-axis for labeling purposes
  !   EndOfFile      : end-of-file indicator

  !
  ! Accepts:          FileName

  ! Output (screen):  The graphics window

  !-----------------------------------------------------------------------



  SUBROUTINE ScatterPlot(FileName)


    IMPLICIT NONE
    CHARACTER(*), INTENT(IN) :: FileName
    REAL :: X_Min, X_Max, Y_Min, Y_Max, DeltaX, DeltaY, X, Y

    INTEGER, PARAMETER :: Horiz_Limit = 70, Vert_Limit = 20

    INTEGER :: X_Loc, Y_Loc, EndOfFile, Count

    CHARACTER(1), DIMENSION(0: Horiz_Limit, 0:Vert_Limit) :: Window

    CHARACTER(1), PARAMETER :: PlotChar = "*"



    OPEN (UNIT = 20, FILE = FileName, STATUS = "OLD")


    READ (20, *)  X_Min, X_Max, Y_Min, Y_Max
    DeltaX = (X_Max - X_Min) / REAL(Horiz_Limit)

    DeltaY = (Y_Max - Y_Min) / REAL(Vert_Limit)



    Window = " "



    ! Read data pairs and turn on points in window corresponding to pairs
  
    DO
       READ (20, *, IOSTAT = EndOfFile) X, Y



       IF (EndOfFile < 0) EXIT

       ! If end of file, terminate repetition

       ! Otherwise plot point

       X_Loc = NINT((X - X_Min)/ DeltaX)

       Y_Loc = NINT((Y - Y_Min)/ DeltaY)

       Window(X_Loc, Y_Loc) = PlotChar

    END DO

    ! Draw the window together with labeled Y-axis



    Y = Y_Max
    Count = 5 * (Vert_Limit / 5)

    DO Y_Loc = Vert_Limit, 0, -1

       IF (MOD(Count, 5) == 0) THEN
           PRINT '(1X, F8.2, ":", 200A)', &

             Y, (Window(X_Loc,Y_Loc), X_Loc = 0, Horiz_Limit)

       ELSE

            PRINT '(9X, ":", 200A)', &

                (Window(X_Loc,Y_Loc), X_Loc = 0, Horiz_Limit)

       END IF

       Count = Count - 1

       Y = Y - DeltaY

    END DO



    ! Draw a labeled X-axis


    PRINT '(9X, 200A)', (".", X_Loc = 0, Horiz_Limit)
    PRINT '(3X, 50F10.3)', &

           (X_Min + X_Loc*DeltaX, X_Loc = 0, Horiz_Limit, 10)



    RETURN

    END SUBROUTINE ScatterPlot



END MODULE GraphingRoutines

PROGRAM Scatter_Plot_of_Data

!-------------------------------------------------------------------------

! Program to produce a scatter plot of a data set stored in a file.

! The name of the file is passed to subroutine ScatterPlot imported

! from module GraphingRoutines.  Identifiers used are:

!   FileName : name of file containing data set to be plotted

!   Plot     : subroutine called to produce scatter plot

!

! Input:  FileName

! Output: User prompts and the scatter plot

!-------------------------------------------------------------------------



  USE GraphingRoutines, ONLY: ScatterPlot



  IMPLICIT NONE
  CHARACTER(20) :: FileName



  PRINT *, "This program produces a scatter plot of data points"
  PRINT *, "stored in a data file.  The first line of this file"

  PRINT *, "must contain the minimum and maximum x values and"

  PRINT *, "the minimum and maximum y values, in this order."

  WRITE (*, '(/ 1X, A)', ADVANCE = "NO") "Enter the name of the data file: "

  READ *, FileName

  CALL ScatterPlot(FileName)

  STOP



END PROGRAM Scatter_Plot_of_Data

