plott(3f) - [M_datapac:GENERIC_LINE_PLOT] generate a line printer
plot of Y vs X for the terminal (71 characters wide)
SUBROUTINE PLOTT(Y,X,N)
REAL(kind=wp),intent(in) :: X(:)
REAL(kind=wp),intent(in) :: Y(:)
INTEGER,intent(in) :: N
PLOTT(3f) yields a narrow-width (71-character) plot of Y(i) versus
X(i). Its narrow width makes it appropriate for use on a terminal.
Note values in the vertical axis vector (y) or the horizontal axis
vector (x) which are equal to or in excess of 10.0**10 will not
be plotted.
This convention greatly simplifies the problem of plotting when
some elements in the vector y (or x) are 'missing data', or when
we purposely want to ignore certain elements in the vector y (or x)
for plotting purposes (that is, we do not want certain elements in
y (or x) to be plotted). To cause specific elements in y (or x)
to be ignored, we replace the elements beforehand (by, for example,
use of the REPLAC(3f) subroutine) by some large value (like, say,
10.0**10) and they will subsequently be ignored in the plot subroutine.
Note that the storage requirements for this (and the other) terminal
plot subroutines are very small. This is due to the "one line at
a time" algorithm employed for the plot.
Y The vector of (unsorted or sorted) observations to be plotted vertically.
X The REAL vector of (unsorted or sorted) observations to be plotted horizontally.
N The integer number of observations in the vector Y. There is no restriction on the maximum value of N for this subroutine.
A narrow-width (71-character) terminal plot of y(i) versus x(i).
The body of the plot (not counting axis values and margins) is 25 rows
(lines) and 49 columns.
Sample program:
program demo_plott
use M_datapac, only : plott, label
implicit none
integer :: i
integer,parameter :: dp=kind(0.0d0)
real(kind=dp), allocatable :: x(:), y(:)
call label('plott')
y=[(real(i)/10.0,i=1,30)]
x=y**3.78-6*y**2.52+9*y**1.26
call plott(x,y,size(x))
end program demo_plott
Results:
The following is a plot of Y(I) (vertically) versus X(I) (horizontally)
I-----------I-----------I-----------I-----------I
0.4000000E+01 - X X X X
0.3833356E+01 I X X
0.3666712E+01 I X
0.3500068E+01 I X
0.3333424E+01 I X
0.3166780E+01 I X
0.3000137E+01 - X
0.2833493E+01 I X
0.2666849E+01 I X
0.2500205E+01 I X
0.2333561E+01 I X
0.2166917E+01 I X
0.2000273E+01 -
0.1833629E+01 I
0.1666985E+01 I X X X
0.1500341E+01 I
0.1333698E+01 I X
0.1167054E+01 I
0.1000410E+01 - X
0.8337659E+00 I X X
0.6671220E+00 I
0.5004781E+00 I X X
0.3338342E+00 I X
0.1671903E+00 I X X
0.5463774E-03 - X X
I-----------I-----------I-----------I-----------I
0.1000E+00 0.8250E+00 0.1550E+01 0.2275E+01 0.3000E+01
The original DATAPAC library was written by James Filliben of the
Statistical Engineering Division, National Institute of Standards
and Technology.
John Urban, 2022.05.31
CC0-1.0
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | Y(:) | |||
real(kind=wp), | intent(in) | :: | X(:) | |||
integer, | intent(in) | :: | N |
SUBROUTINE PLOTT(Y,X,N) REAL(kind=wp),intent(in) :: X(:) REAL(kind=wp),intent(in) :: Y(:) INTEGER,intent(in) :: N REAL(kind=wp) :: aim1, airow, anumcm, anumlm, anumr, anumrm REAL(kind=wp) :: cutoff, delx, dely, hold, xlable, xmax, xmin, xwidth, ylable, ylower, ymax, ymin REAL(kind=wp) :: yupper, ywidth INTEGER :: i, icol, icolmx, irow, ixdel, n2, numcol, numlab, numr25, numr50, numr75, numrow CHARACTER(len=4) :: iline CHARACTER(len=4) :: iaxisc CHARACTER(len=4) :: sbnam1 , sbnam2 CHARACTER(len=4) :: alph11 , alph12 , alph21 , alph22 , alph31 , alph32 CHARACTER(len=4) :: blank , hyphen , alphai , alphax DIMENSION iline(72) , xlable(10) DATA sbnam1 , sbnam2/'PLOT' , 'T '/ DATA alph11 , alph12/'FIRS' , 'T '/ DATA alph21 , alph22/'SECO' , 'ND '/ DATA alph31 , alph32/'THIR' , 'D '/ DATA blank , hyphen , alphai , alphax/' ' , '-' , 'I' , 'X'/ ! cutoff = (10.0_wp**10) - 1000.0_wp ! ! CHECK THE INPUT ARGUMENTS FOR ERRORS ! IF ( N<1 ) THEN WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99013) alph31 , alph32 , sbnam1 , sbnam2 WRITE (G_IO,99001) N 99001 FORMAT (' is non-negative (with value = ',I0,')') WRITE (G_IO,99011) RETURN ELSE IF ( N==1 ) THEN WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99013) alph31 , alph32 , sbnam1 , sbnam2 WRITE (G_IO,99002) N 99002 FORMAT (' has the value 1') WRITE (G_IO,99011) RETURN ELSE ! hold = Y(1) DO i = 2 , N IF ( Y(i)/=hold ) GOTO 50 ENDDO WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99013) alph11 , alph12 , sbnam1 , sbnam2 WRITE (G_IO,99014) hold WRITE (G_IO,99011) RETURN ENDIF 50 continue hold = X(1) DO i = 2 , N IF ( X(i)/=hold ) GOTO 100 ENDDO WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99013) alph21 , alph22 , sbnam1 , sbnam2 WRITE (G_IO,99014) hold WRITE (G_IO,99011) RETURN ENDIF ! 100 continue DO i = 1 , N IF ( Y(i)<cutoff ) GOTO 200 ENDDO WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99013) alph11 , alph12 , sbnam1 , sbnam2 WRITE (G_IO,99015) WRITE (G_IO,99016) cutoff WRITE (G_IO,99011) RETURN 200 continue DO i = 1 , N IF ( X(i)<cutoff ) GOTO 300 ENDDO WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99013) alph21 , alph22 , sbnam1 , sbnam2 WRITE (G_IO,99015) WRITE (G_IO,99016) cutoff WRITE (G_IO,99011) RETURN ! 300 continue n2 = 0 DO i = 1 , N IF ( Y(i)<cutoff .AND. X(i)<cutoff ) THEN n2 = n2 + 1 IF ( n2>=2 ) GOTO 400 ENDIF ENDDO WRITE (G_IO,99011) WRITE (G_IO,99012) WRITE (G_IO,99003) alph11 , alph12 , alph21 , alph22 99003 FORMAT (' The ',A4,A4,', and ',A4,A4) WRITE (G_IO,99004) sbnam1 , sbnam2 99004 FORMAT (' input arguments to the ',A4,A4,' subroutine') WRITE (G_IO,99005) 99005 FORMAT (' are such that too many points have been', ' excluded from the plot.') WRITE (G_IO,99006) n2 99006 FORMAT (' only ',I0,' points are left to be plotted.') WRITE (G_IO,99011) RETURN ! !-----START POINT----------------------------------------------------- ! ! DEFINE THE NUMBER OF ROWS AND COLUMNS WITHIN THE PLOT-- ! THIS HAS BEEN SET TO 25 ROWS AND 49 COLUMNS. ! 400 continue numrow = 25 numcol = 49 anumr = numrow anumrm = numrow - 1 anumcm = numcol - 1 numr25 = (numrow/4) + 1 numr50 = (numrow/2) + 1 numr75 = 3*(numrow/4) + 1 ixdel = (numcol-1)/4 numlab = 5 anumlm = numlab - 1 ! ! SKIP A LINE, WRITE OUT AN IDENTIFYING LINE FOR THE TYPE OF PLOT, ! WRITE OUT THE TOP HORIZONTAL AXIS OF THE PLOT, AND SKIP 1 LINE ! FOR A MARGIN WITHIN THE PLOT. ! WRITE (G_IO,99007) 99007 FORMAT (' ') WRITE (G_IO,99008) ! 99008 FORMAT (' The following is a plot of Y(I) (vertically) versus X(I) (horizontally)') DO icol = 1 , numcol iline(icol) = hyphen ENDDO DO icol = 1 , numcol , ixdel iline(icol) = alphai ENDDO WRITE (G_IO,99017) (iline(i),i=1,numcol) WRITE (G_IO,99018) blank ! ! DETERMINE THE MIN AND MAX VALUES OF Y, AND OF X. ! DO i = 1 , N IF ( Y(i)<cutoff ) THEN IF ( X(i)<cutoff ) THEN ymin = Y(i) ymax = Y(i) xmin = X(i) xmax = X(i) EXIT ENDIF ENDIF ENDDO DO i = 1 , N IF ( Y(i)<cutoff ) THEN IF ( X(i)<cutoff ) THEN IF ( Y(i)<ymin ) ymin = Y(i) IF ( Y(i)>ymax ) ymax = Y(i) IF ( X(i)<xmin ) xmin = X(i) IF ( X(i)>xmax ) xmax = X(i) ENDIF ENDIF ENDDO dely = ymax - ymin delx = xmax - xmin ywidth = dely/anumrm xwidth = delx/anumcm ! ! DETERMINE AND WRITE OUT THE PLOT POSITIONS ONE LINE AT A TIME. ! DO irow = 1 , numrow DO icol = 1 , numcol iline(icol) = blank ENDDO airow = irow yupper = ymax + (1.5_wp-airow)*ywidth ylable = ymax + (1.0_wp-airow)*ywidth ylower = ymax + (0.5_wp-airow)*ywidth IF ( irow==numrow ) ylable = ymin DO i = 1 , N IF ( Y(i)<cutoff ) THEN IF ( X(i)<cutoff ) THEN IF ( ylower<=Y(i) .AND. Y(i)<yupper ) THEN icol = ((X(i)-xmin)/xwidth) + 1.5_wp iline(icol) = alphax ENDIF ENDIF ENDIF ENDDO icolmx = 1 DO icol = 1 , numcol IF ( iline(icol)==alphax ) icolmx = icol ENDDO iaxisc = alphai IF ( irow==1 .OR. irow==numrow ) iaxisc = hyphen IF ( irow==numr25 .OR. irow==numr50 .OR. irow==numr75 ) iaxisc = hyphen WRITE (G_IO,99009) ylable , iaxisc , (iline(icol),icol=1,icolmx) 99009 FORMAT (' ',E14.7,1X,A1,2X,50A1) ENDDO ! ! SKIP 1 LINE FOR A BOTTOM MARGIN WITHIN THE PLOT, WRITE OUT THE ! BOTTOM HORIZONTAL AXIS, AND WRITE OUT THE X AXIS LABELS. ! WRITE (G_IO,99018) blank DO icol = 1 , numcol iline(icol) = hyphen ENDDO DO icol = 1 , numcol , ixdel iline(icol) = alphai ENDDO WRITE (G_IO,99017) (iline(icol),icol=1,numcol) DO i = 1 , numlab aim1 = i - 1 xlable(i) = xmin + (aim1/anumlm)*delx ENDDO WRITE (G_IO,99010) (xlable(i),i=1,numlab) 99010 FORMAT (' ',9X,5E12.4) 99011 FORMAT (' **********************************************************************') 99012 FORMAT (' FATAL ERROR ') 99013 FORMAT (' The ',A4,A4,' input argument to the ',A4,A4,' subroutine') 99014 FORMAT (' has all elements = ',E15.8) 99015 FORMAT (' has all elements in excess of the cutoff') 99016 FORMAT (' value of ',E15.8) 99017 FORMAT (' ',18X,54A1) 99018 FORMAT (' ',15X,A1) END SUBROUTINE PLOTT