Full Code of kookma/ogpf for AI

master bd18021949be cached
11 files
187.6 KB
49.5k tokens
1 requests
Download .txt
Repository: kookma/ogpf
Branch: master
Commit: bd18021949be
Files: 11
Total size: 187.6 KB

Directory structure:
gitextract_axg7b2oj/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── doc/
│   └── readme.txt
├── example/
│   └── demo.f90
├── fpm.toml
├── meson.build
├── revision.txt
├── sample_script.gp
└── src/
    └── ogpf.f90

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

# fpm build directory
build*
bin*



================================================
FILE: LICENSE
================================================
Copyright (c) 2012-2018 Mohammad Rahmani

! Author:    Mohammad Rahmani
!            Chem Eng Dep., Amirkabir Uni. of Tech
!            Tehran, Ir
!            url:    aut.ac.ir/m.rahmani
!            github: github.com/kookma
!            email:  m[dot]rahmani[at]aut[dot]ac[dot]ir

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: Makefile
================================================
#
# This Makefile was generated by Code::Blocks IDE.
#

SRCS_f90d1 = \
ogpf.f90

SRCS_f90d2 = \
demo.f90

OBJS_f90d1 = \
ogpf.o

OBJS_f90d2 = \
demo.o

SRC_DIR_f90d1 = \
./src/

SRC_DIR_f90d2 = \
./example/


OBJS_DIR = ./obj/Debug/
EXE_DIR = ./bin/Debug/

EXE = ogpf.exe
FC = gfortran.exe
LD = gfortran.exe
IDIR = 
CFLAGS = -Wall -std=f2008 -Wl, -J$(OBJS_DIR) $(IDIR)
LFLAGS = 
LIBS = 

VPATH = $(SRC_DIR_f90d1):$(OBJS_DIR):$(SRC_DIR_f90d2)
OBJS = $(addprefix $(OBJS_DIR), $(OBJS_f90d1) $(OBJS_f90d2))

all : $(EXE)

$(EXE) : $(OBJS_f90d1) $(OBJS_f90d2)
	@mkdir -p $(EXE_DIR)
	$(LD) -o $(EXE_DIR)$(EXE) $(OBJS) $(LFLAGS) $(LIBS)

$(OBJS_f90d1):
	@mkdir -p $(OBJS_DIR)
	$(FC) $(CFLAGS) -c $(SRC_DIR_f90d1)$(@:.o=.f90) -o $(OBJS_DIR)$@
	
$(OBJS_f90d2):
	@mkdir -p $(OBJS_DIR)
	$(FC) $(CFLAGS) -c $(SRC_DIR_f90d2)$(@:.o=.f90) -o $(OBJS_DIR)$@

clean :
	rm -f $(OBJS_DIR)*.*
	rm -f $(EXE_DIR)$(EXE)

# Dependencies of files	
demo.o: \
	demo.f90 \
	ogpf.o

ogpf.o: \
	ogpf.f90


================================================
FILE: README.md
================================================
# ogpf
Object Based Interface to GnuPlot from Fortran (ogpf)

## Installation

__Prerequisite:__ [gnuplot](http://www.gnuplot.info/) must be installed on your system.


### Zero Installation Library
The ogpf is a **zero installation library**! Just copy and paste the `ogpf.f90` in your project folder or in your library folder and use it! No any further step is required. However if you like to add ogpf to your projects through package managers, builders, installers see below options!

###

<details>
	<summary><b>Fortran Package Manager (fpm)</b></summary>
	
>To use ogpf with your [fpm](https://github.com/fortran-lang/fpm) project, add the following to your package manifest file (`fpm.toml`):
>
>```toml
>[dependencies]
>ogpf = { git = "https://github.com/kookma/ogpf.git" }
>```
>
>You can then `use` the package as normal in your Fortran program with `use ogpf`.
>
>To run the example program in this package with fpm:
>
>```sh
>$ git clone https://github.com/kookma/ogpf.git
>$ cd ogpf
>$ fpm build
>$ fpm run --example
>```

		
</details>	

###

<details>
	<summary><b>Meson Builder</b></summary>


>The alternative is through the use of the [Meson builder](https://mesonbuild.com/index.html), which is
>multiplatform and multi source language build system. You can just use the ogpf git repo as a
>subproject in your own meson project. If you're unfamiliar with it, just read this
>[begginer's guide](https://mesonbuild.com/SimpleStart.html).
>
>After learning the basics, you can create a folder called subprojects on the root of your project
>and create a file inside with the following content:
>
>```
>[wrap-git]
>url=https://github.com/kookma/ogpf
>revision=head
>```
>
>Then on the meson.build file you have to import the subproject and grab the library variable.
>This is a sample meson.build file:
>
>```python
>project('research','fortran')
>
>ogpf_proj = subproject('ogpf')
>ogpf_dep = ogpf_proj.get_variable('ogpf_dep')
>
>executable('research',
>    dependencies: ogpf_dep)
>```
>and all the compiler flags will be handled.

</details>

# Usage
Make sure you have a working version of [gnuplot](http://www.gnuplot.info/) must be installed on your system. Start with provideed examples.


## 2D Plots

Simple plot                    | Animation
:-----------------------------:|:------------------------------------:
![Example 04](doc/exmp04.png)  | ![Example 09](doc/exmp09.gif)

## 3D Plots

Surface                        | Contour
:-----------------------------:|:------------------------------------:
![Example 04](doc/exmp105.png) | ![Example 09](doc/exmp105_2.png)



### GnuPlot Interface

	Purpose:   Object Based Interface to GnuPlot from Fortran (ogpf)
	Platform:  Windows XP/Vista/7/10, Linux
			   (It should work on other platforms, e.g Mac see the finalize_plot subroutine in ogpf.f90)
	Language:  Fortran 2003 and 2008
	Requires:  1. Fortran 2003 compiler (e.g gfortran 4.7, IVF 12.1, and later ...)
	              There is only two more features needs Fortran 2008 standard
                  execute_command_line and passing internal function as argument.
			   2. gnuplot 5 and higher (other previous version can be used)
    Author:    Mohammad Rahmani
               Chem Eng Dep., Amirkabir Uni. of Tech
               Tehran, Ir
               url:    aut.ac.ir/m.rahmani
               github: github.com/kookma
               email:  m[dot]rahmani[at]aut[dot]ac[dot]ir
    License:   MIT. Please always give a link to this repo

## PLotting Capabilities
### 2D Plots
* plot(v)
* plot(x,y)
* plot(x,y, linespec)
* plot(x1,y1,ls1, x2,y2,ls2, x3,y3,ls3, x4,y4,ls4)
* plot(x, M)
* semilogx(x,y)
* semilogy(x,y)
* loglog(x,y)
### 3D Plots
* surf(x,y,z)
* surf(x,y,z,lspec)
* surf(x,y,z, palette)
* surf(z, palette)
* contour(x,y,z,palette)
* contour(z,palette)
### Animation
* animation_start(delay)
* animation_show()

### Multiplot
* multiplot(rows, cols)

## Mathematical Utility Functions
* linspace(a,b,n)
* linspace(a,b)
* arange(a,b,dx)
* meshgrid(X,Y, xgv,ygv)
* meshgrid(X,Y, xgv)

## Color palette

Nine different color palettes are available. See [Ann Schnider](https://github.com/aschn/gnuplot-colorbrewer) gnuplot color palettes and [Gnuplotting](https://github.com/Gnuplotting/gnuplot-palettes).
These color palettes can be used with:

> `surf(x,y,z,palette='plt-name')`

> `contour(x,y,z,palette='plt-name')`

* set1
* set2
* set3
* palette1
* palette2
* paired
* dark2
* accent
* jet

## The ogpf library other features
There are plenty of commands to customise the plots. This includes:

* Plot annotation (e.g. title, xlabel, ylabel, and zlabel)
* Axes setting (e.g. xrange, yrange, zrange, and grid)

```fortran
call gp%axis([-1.0,+1.0])                     ! Sets xrange
call gp%axis([-1.0,+1.0,-2.0,+2.0])           ! Sets both xrange and yrange
call gp%axis([-1.0,+1.0,-2.0,+2.0,-3.0,+3.0]) ! Sets all axis at same time

call gp%xlim([-1.0,+1.0]) ! Sets only the xrange
call gp%ylim([-2.0,+3.0]) ! Sets only the yrange
call gp%zlim([-3.0,+3.0]) ! Sets only the zrange
```

* Line and marker color and style
* Gnuplot options (e.g. fonts, tics format, frame format,... )

### The ogpf options command
The option command is a very powerful command and can be used to customize the gnuplot in many ways. Options can be set by calling the ogpf options.
In every call, it is possible to set several options separated by semicolon or options can be set by several calls. Below shows few samples:

* **Sample 1**

Set the legend (key) at the right bottom of window

`call gp%options('set key bottom right')`

* **Sample 2**

Define a new line style

`call gp%options('set style line 1 lc rgb "blue" lt 1 lw 2 pt 6 ps 1.5')`

* **Sample 3**

Use several options each uses separate command

`call gp%options('set tics')`

`call gp%options('set tics font ",8"') ! font size for tics`


* **Sample 4**

Set several options at the same time using semicolon as delimiter

`call gp%options('unset tics; unset colorbox') `

# Demo
There is a collection of examples in demo.f90 to show the capabilities of ogpf.

### Easy to use
To use ogpf in your project, add the library file to your fortran project (code)
* ogpf.f90 (the main library)

For details see 'demo.f90'

##### Important Note
To use ogpf on other operating system, you may need to modify the terminal type and fonts
in the section of **Configuration Parameters**.
A Makefile has been provided to build the demo from command line.

### Example codes
This section shows selected example codes from **demo.f90**
* **Example 1**
```fortran
    SUBROUTINE Exmp01
        !...............................................................................
        !Example 1: A very basic example
        !...............................................................................
        TYPE(gpf):: gp
        INTEGER, PARAMETER:: n=17
        Real(wp):: x(n)
        Real(wp):: y(n)
        ! Input data
        x=dble([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])
        y=dble([66,51,38,27,18,11,6,3,2,3,6,11,18,27,38,51,66])

        ! Annotation: set title, xlabel, ylabel
        CALL gp%title('Example 1. A simple xy plot')
        CALL gp%xlabel('my x axis ...')
        CALL gp%ylabel('my y axis ...')
        Call gp%options('set style data linespoints')
        !Call Plot to draw a vector against a vector of data
        CALL gp%plot(x, y)
    END SUBROUTINE Exmp01
```

Will produce

![Example 01](doc/exmp01.png)


* **Example 04**

Plot several data series at the same time
```fortran
    subroutine exmp04

        type(gpf):: gp
        integer, parameter:: n=50
        integer, parameter:: m=65
        real(wp):: x(n)
        real(wp):: y(n)
        real(wp):: xv(m)
        real(wp):: yv(m)
        real(wp), parameter :: pi=4.d0*atan(1.d0)
        ! Input data
        x=linspace(-pi,pi,n)  !linspace is a utility function from module ogpf
        y=sin(x)

        xv=linspace(0.d0, 2.d0*pi,m)
        yv=cos(2.d0*xv)
        !           This is the maximum number of plot can be drawn at the same time
        !           If you have more data see, you can plot can be used with matrices!
        call gp%title('Example 4. Plot four data sets using gnuplot')
        call gp%options('set key top left; set grid')

        call gp%plot(x,y, 'title "sin(x)"', &
            xv,yv, 'with lp lt 6 title "cos(2x)"', &
            xv, 2.d0*yv, 'title "2cos(2x)" lt 7', &
            xv, 0.5d0*yv, 'title "0.5cos(2x)" with points pt 8')

        ! Another example with keyboard arguments
        call gp%plot(x1=x,y1=y,x2=xv,y2=yv)

    end subroutine exmp04

```
Will produce

![Example 04](doc/exmp04.png)
![Example 04](doc/exmp04_2.png)





* **Example 05**
```fortran
    SUBROUTINE Exmp05
        !...............................................................................
        ! Example 5: Use line style and legends
        !...............................................................................
        TYPE(gpf):: gplot
        INTEGER, PARAMETER:: n=50
        Real(wp):: x(n)
        Real(wp):: ys(n)
        Real(wp):: yc(n)
        Real(wp):: ysc(n)
        Real(wp), PARAMETER :: pi=4.d0*atan(1.d0)
        ! Input data
        x=linspace(-2.d0*pi,2.d0*pi,n)  !linspace is a utility function from module Utils
        ys=sin(x)
        yc=exp(-0.1d0*x)*cos(x)
        ysc=sin(x/2.d0)*cos(2.d0*x)

        ! Annotation, set title, xlabel, ylabel
        CALL gplot%title('Example 5. A sample with style and legends')
        CALL gplot%xlabel('x, rad')
        CALL gplot%ylabel('y, dimensionless')

        ! Plot to draw three set of data
        CALL gplot%plot(x,ys,'title "sin" with lines lt 5 lc rgb "#0008B0"', &
                        x,yc,'title "cos" with points lt 6 lc rgb "#FF1100"', &
                        x,ysc,'title "sin(x/2)cos(2x)" with lp lt 7 lc rgb "#00AA04"' )

    END SUBROUTINE Exmp05
```
Will produce

![Example 05](doc/exmp05.png)

* **Example 06**

```fortran
     subroutine exmp06

        type(gpf):: gplot
        integer, parameter:: n=125

        real(wp):: x(n)
        real(wp):: y(n)

        real(wp), parameter :: pi=4.d0*atan(1.d0)
        ! Input data
        x=linspace(0.d0,pi*2.d0,n)  !linspace is a utility function from module Utils
        y=sin(6.d0*x)*exp(-x)


        ! Annotation, set title, xlabel, ylabel
        call gplot%title('Example 6. A sample shows sin(x) and its zero on the plot')
        call gplot%xlabel('x, rad')
        call gplot%ylabel('sin(x), dimensionless')
        call gplot%options('set grid')

        ! Plot to draw two set of data, a series and a single point
        call gplot%plot(x,y,'title "sin(x)" with lines lt 2 lw 3', &
            [pi],[0.d0],'title "zero" with points pt 7 ps 3 lc rgb "#FF0000"')
    end subroutine exmp06
```

Will produce

![Example 06](doc/exmp06.png)


* **Example 08**

Plotting matrix against a vector with customized linestyles

```fortran
    subroutine exmp08

        type(gpf):: matplot
        integer, parameter:: n=25, m=6
        integer :: i
        real(wp):: tf
        real(wp):: vo
        real(wp):: g
        real(wp):: t(n)
        real(wp):: y(n,m)

        !Create data
        tf=10.d0
        g=32.d0;
        t=linspace(0.d0,tf,n)
        do i = 1, m
            vo = 25.0d0 * i
            y(:, i) = vo*t-0.5d0*g*t**2
        end do

        !Draw the matrix y againest vector x
        call matplot%title('Example 8. Plotting a Matrix against a vector')
        call matplot%xlabel ('t, sec')
        call matplot%ylabel ('y, feet')
        call matplot%options('set xrange[0:10];set yrange [0:400];')
        call matplot%plot(t, y)

        !Another Matrix plot with legends and line specification
        call matplot%title('Example 8.2: Matrix plot, legends and linespec')
        call matplot%plot(t, 2.0d0*y(:,3:4), &
            lspec='t "vo=100" w lp lt 6 ps 3 lw 2;&
            & t "v=125" w lp lt 7 ps 3 lw 2 lc rgb "#ad6000"')

    end subroutine exmp08

```
Will produce

![Example 08](doc/exmp08.png)
![Example 08](doc/exmp08_2.png)


* **Example 9**
Animation with 2D plot

```fortran
   subroutine exmp09

        type(gpf):: gp
        integer, parameter::   n  = 35
        real(wp), parameter :: pi = 4.d0*atan(1.d0)
        real(wp):: x(n)
        real(wp):: y(n), z(n)
        integer :: i


        x=linspace(-pi, pi,n)
        y = 0.0_wp
        z = 0.0_wp
        call gp%animation_start(1.0) ! start animation, set delay is one second between frames
        call gp%axis([-pi, pi, -1.2_wp, 1.2_wp])
        call gp%options('set grid')
        ! add frames
        do i=1, n, 10
            y(i) = sin(x(i))
            z(i) = cos(x(i))
            ! each plot command adds one frame
            call gp%plot(x(1:i),y(1:i), 'w lines lc "red" lw 2', &
                x(i:i), y(i:i),'w points ps 3 pt 7 lc "red"', &
                x(1:i),z(1:i), 'w lines lc "blue" lw 2', &
                x(i:i), z(i:i), 'w points ps 3 pt 7 lc "blue"' )
        end do
        ! finalize and show frames one by one with delay between them
        ! as set by animation_start
        call gp%animation_show()
   end subroutine exmp09
```
will produce

![Example 09](doc/exmp09.gif)

* **Example 10**

Use options

```fortran
   subroutine exmp10()


        type(gpf):: mp
        real(wp):: x(15)
        real(wp):: y(15)

        !Options is a dynamic length string and can set all kind of gnuplot
        call mp%options('set style line 1 lc rgb "#0060ad" lt 1 lw 2 pt 5 ps 1.5 # --- blue')
        call mp%options('set style line 2 lc rgb "#ad6000" lt 2 lw 2 pt 6 ps 1.5 # --- red')
        call mp%options('set style line 3 lc rgb "#00ad00" lt 2 lw 2 pt 7 ps 1.5 # --- green')
        ! this is a multipart string spanned over several lines
        call mp%options('&
            &set style data linespoints;&
            &set xrange [0.1:100];&
            &set yrange [0.01:10000];&
            &set autoscale')
        call mp%options('set key top left') ! set the key location

        x=linspace(0.1d0,100d0,15);
        y=x**2;
        call mp%title("Example 10. x vs. x^2")
        call mp%plot(x1=x, y1=1.50*y, ls1='t "y=1.5x^2" ls 1', &
            x2=x, y2=2.00*y, ls2='t "y=2.0x^2" ls 2', &
            x3=x, y3=2.50*y, ls3='t "y=2.5x^2" ls 3')
        call mp%reset()
        call mp%title('Reset to initial setting')
        call mp%plot(x,2*y)
    end subroutine exmp10
```
The first output is:

![Example 09](doc/exmp10.png)

* **Example 11**

```fortran
    subroutine exmp11
        type(gpf):: gp
        integer, parameter :: n=125
        real(wp):: t(n)
        real(wp):: r(n)
        real(wp):: pi=4.d0*atan(1.d0)
        !1. reset gplot
        !!!   CALL gp%reset()
        ! TODOD: There is a problem with reset, persist is off by reset
        !2. set option, and set plot as polar
        call gp%options("&
            &set polar;&
            &set trange [-pi:pi]")

        ! 3. create data
        t=linspace(-pi,pi,n)
        r=sin(3.d0*t)

        !Annotation, set title, xlabel, ylabel
        call gp%title("Example 11: simple polar plot")
        call gp%xlabel("x,...")
        call gp%ylabel("y,...")

        !Call plot method
        call gp%plot(t,r, 'title "sin(3t)"')
        call gp%plot(t, cos(4*t))

    end subroutine exmp11
```
Will produce

![Example 11](doc/exmp11.png)
![Example 11](doc/exmp11_2.png)

### Logarithmic scale

* **Example 13**

```fortran
    subroutine exmp13
        type(gpf):: gp
        integer, parameter :: n=25
        real(wp):: x(n)
        real(wp):: y(n)


        ! 1. create data
        x=linspace(0.1d0,10.d0,n)
        y=5.d0*x**3+4.d0*x**2+3.d0*x+1.d0

        !Annotation, set title, xlabel, ylabel
        call gp%title("Example 13: A simple matrix plot with semi-log y")
        call gp%ylabel("y,logarithmic scale")
        call gp%xlabel("x, normal scale")

        ! plot a matrix against vector in logarithmic y axis with line specification
        call gp%semilogy(x,reshape([y,10.d0*y],[n,2]), 'with lines lt 8; with points pt 7')

    end subroutine exmp13
```
will produce
![Example 13](doc/exmp13.png)


* **Example 14**

```fortran
   subroutine exmp14
        type(gpf):: gp
        integer, parameter :: n=75
        real(wp):: x(n)
        real(wp):: y(n)
        real(wp):: pi=4.d0*atan(1.d0)

        ! 1. create data
        x=exp(linspace(0.d0,2.d0*pi,n))
        y=50.d0+exp( 3.d0* linspace(0.d0,2.d0*pi,n) )

        ! 2. Annotation, set title, xlabel, ylabel
        call gp%title("Example 14: A loglog plot")
        call gp%xlabel("x,logarithmic scale")
        call gp%ylabel("y,logarithmic scale")

        ! 3. Set grid on
        call gp%options('set grid xtics ytics mxtics')

        ! 4. Call plot method
        call gp%loglog(x,y)

    end subroutine exmp14
```
will produce
![Example 14](doc/exmp14.png)



* **Example 16**

Save the script file for future use

```fortran
   subroutine exmp16()
        type(gpf):: gp
        real(wp):: pi=4.d0*atan(1.d0)
        integer, parameter :: n=100
        real(wp) :: x(n)
        real(wp) :: y(n)
        real(wp) :: z(n)

        ! create data
        x = linspace(-pi, 3.0d0*pi)
        y = sin(2.0d0*x)*exp(-x/5.0d0)
        z = cos(2.0d0*x)*exp(-x/5.0d0)

        ! several gnuplot optuons
        call gp%options('set border linewidth 1.5')
        call gp%options('set style line 1 lc rgb "#ad6009" lt 1 lw 2 pt 7 ps 1.5 # --- red like')
        call gp%options('set style line 2 lc rgb "#00ad09" lt 2 lw 2 pt 6 ps 1.5 # --- green like')
        call gp%options('unset key')
        call gp%options('set grid')
        call gp%options('set ytics 1')
        call gp%options('set tics scale 0.75')

        call gp%title("Example 16. Save the script into file for future use")
        call gp%xlabel("x...")
        call gp%ylabel("y...")

        ! save the script into a file
        call gp%filename("Example16.gp")
        call gp%plot(x, y, ls1='with lp ls 1', x2=x, y2=z, ls2='with lp ls 2')

        print*  ! empty line
        print*, 'Plot commands were written in Example16.gp successfully'
        print*, 'Open gnuplot and load this script file to plot the results!'
        print*  ! empty line

    end subroutine exmp16
```
will produce
![Example 16](doc/exmp16.png)

* **Example 17**
Use add_script and run_script to do versatile operation with gnuplot

```fortran
   subroutine exmp17()
        ! Script is used to create multi window plots
        ! Each "set term wxt <number>" creates a new window
        type(gpf):: gp

        call gp%add_script('set term wxt 0 title "My first plot" size 640,480')
        call gp%add_script('set title "Example 17. Multi windows plot using script"')
        call gp%add_script('plot x*x+2*x+1')
        call gp%add_script('set term wxt 1 title "My second plot"')
        call gp%add_script('set ylabel "xsin(x)"')
        call gp%add_script('plot x*sin(x)')

        call gp%run_script()

    end subroutine exmp17
```
will produce
![Example 17](doc/exmp17.png)
![Example 17](doc/exmp17_2.png)


* **Example 18**

```fortran
     subroutine exmp18()

        !Use gnuplot script
        !to send a special external script file to gnuplot
        !the file is an external file here is called "simple.plt"
        type(gpf):: gp

        ! add some options and commands
        call gp%title("Example 18. Running an external script file")
        call gp%add_script('load "sample_script.gp" ')

        ! run script
        call gp%run_script()

    end subroutine exmp18

```
Will produce

![Example 18](doc/exmp18.png)

* **Example 20**

Scatter plot

```fortran
   subroutine exmp20()
        !...............................................................................
        ! Example 20: Making a scatter plot
        !...............................................................................

        type(gpf):: gp
        integer,  parameter :: n=750
        real(wp) :: x(n), y(n), ym(n), noise(n), d(n)
        real(wp) :: a, b

        ! generate data
        a = 00.0_wp
        b = 05.0_wp
        ! 1. generate the model data
        x  = linspace(a,b,n)
        ym = sqrt(x)  ! model data


        ! 2. generate the measured data with noise (ensembles the experimental data)
        call random_number(noise)       ! generate noise in [0, 1]
        d = (b-a)/100.0_wp * (x-a)**2   ! define the deviation function
        d = 2.0_wp*(noise - 0.5_wp) * d ! distribute noise around y=0
        y = ym + d


        call gp%title('Example 20. Scatter plot')
        call gp%xlabel('x,....')
        call gp%options('set key top left')
        call gp%options('set autoscale fix')
        call gp%options('set style line 1 lc rgb "blue" lt 1 lw 2 pt 6 ps 1.5')
        call gp%plot(x, y,  't "exp data" with points pt 6 ps 1.2 lc rgb "#ad2060"', &
            x, ym, 't "mode: y=sqrt(x)" w lines lt 1 lw 3 lc "blue"')

        ! plot only the experimental data
        call gp%title('Example 20. Scatter plot: data with noise')
        call gp%plot(x,y,'w l lc "blue"', x, ym, 'w l lc "dark-red" lw 2')

    end subroutine exmp20
```
Will produce

![Example 20](doc/exmp20.png)
![Example 20](doc/exmp20_2.png)


* **Example 21**

Stem plot

```fortran
    subroutine exmp21()
        !...............................................................................
        ! Example 21: Making a stem plot
        !...............................................................................

        type(gpf):: gp
        integer,  parameter :: n=50
        real(wp) :: x(n), y(n)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! generate data
        x = linspace(0.0_wp, 4.0_wp*pi, n)
        y = exp(-x/4.0)*sin(x)

        call gp%title('Example 21. Stem plot')
        ! making plot
        call gp%plot(x,y, 'with impulses lw 2.5', &
            x, y,  'with points pt 7')

    end subroutine exmp21
```
Will produce

![Example 21](doc/exmp21.png)


* **Example 22**

Animation with stem plot

```fortran

    subroutine exmp22()
        !...............................................................................
        ! Example 22: Stem plot animation
        !...............................................................................

        type(gpf):: gp
        integer,  parameter :: n=50
        real(wp) :: x(n), y(n)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)
        integer :: i

        ! generate data
        x = linspace(0.0_wp, 4.0_wp*pi, n)
        y = exp(-x/4.0)*sin(x)
        ! important, set the xy axis range
        call gp%axis([0.0_wp, 4.0_wp*pi, -1.0_wp, 1.0_wp])

        ! start animation
        call gp%animation_start(delay=1.) ! one second delay between frames
        do i=1,n ! add frames
            ! each plot command adds one frame
            call gp%plot(x(1:i), y(1:i), 'with impulses lw 2', &
                x(1:i), y(1:i),  'with points pt 6')
        end do
        ! finalize and show all frames in ornithological order with pause as
        ! set by animation_start
        call gp%animation_show()

    end subroutine exmp22
```
Will produce

![Example 22](doc/exmp22.gif)


* **Example 25**

Multiplot layout

```fortran
    subroutine exmp25()

        type(gpf):: gp
        integer,  parameter :: n=25
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)
        real(wp) :: x(n), y(n,4)
        integer :: i

        x=linspace(-pi, pi, n)
        y(:,1) = sin(x)
        y(:,2) = sin(x)*cos(x)
        y(:,3) = (1-x)*sin(x)
        y(:,4) = (1-x)*cos(x)

        ! general options
        call gp%options('set tics font ",8"')

        call gp%multiplot(2,2)
        do i=1, 4
            call gp%plot(x, y(:,i), 'lt 4 pt 6')
        end do
        ! a new window will be started when all places in the multiplot
        ! layout is occupied. The multiplot window will be closed
        call gp%plot(x,y)
    end subroutine exmp25
```
Will produce

![Example 25](doc/exmp25.png)
![Example 25](doc/exmp25_2.png)

## 3D plots: surf and contour

* **Example 101**

Using different color palettes

```fortran
    subroutine exmp101

        type(gpf):: gp
        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        real(wp):: a=0.5d0
        real(wp):: b=2.0d0
        real(wp), allocatable :: xgrid(:)
        real(wp), allocatable :: ygrid(:)
        integer:: m
        integer:: n

        ! create 3D data
        m=55 ! number of grid points in y direction
        n=25 ! number of grid points in x direction
        xgrid=linspace(-10.0_wp, 10.0_wp, m)
        ygrid=linspace(0.0_wp, 5.0_wp, n)
        allocate( z(m,n) )

        call meshgrid(x, y, xgrid, ygrid) ! generate the 2D grid data
        z=(x**2/a - y**2/b)

        ! annotation
        call gp%title('Example 101: Simple 3D plot')
        call gp%xlabel('x-axis,...')
        call gp%ylabel('y-axis,...')
        call gp%zlabel('z-axis,...')

        !plot the 3D data
        call gp%surf(x, y, z, lspec='t "default color spec"' ) ! color palette: gnuplot default
        call gp%surf(x, y, z, lspec='t "Ann Schnider set1"', palette='set1' ) ! color palette: set1
        call gp%surf(x, y, z, lspec='t "Matlab Jet"', palette='jet' ) ! color palette: Matlab jet
    end subroutine exmp101

```
Will produce

![Example 101](doc/exmp101.png)
![Example 101_2](doc/exmp101_2.png)
![Example 101_3](doc/exmp101_3.png)


* **Example 102**

Simple surface plot with color palette


```fortran
   subroutine exmp102()
        type(gpf):: gp

        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        integer:: m
        integer:: n

        ! generate data
        call meshgrid(x, y, linspace(-0.75_wp*pi, 0.75_wp*pi, 35) ) ! xgrid == ygrid
        m=size(x,1)
        n=size(x,2)
        allocate( z(m,n) )

        !z= sin(x) * cos (y)
        where (x**2 + y**2 == 0.0_wp)
            z=1.0_wp
        elsewhere
            z=sin(x**2+y**2)/(x**2+y**2)
        end where


        call gp%title('Example 102: Simple 3D plot with color palette')
        call gp%xlabel('x-axis,...')
        call gp%ylabel('y-axis,...')
        call gp%options('set style data lines')

        !plot the 3D data
        CALL gp%surf(X,Y,Z, palette='jet')

    end subroutine exmp102
```
Will produce

![Example ](doc/exmp102.png)


* **Example 103**

A beautiful surface and contour plot

```fortran
    subroutine exmp103()

        type(gpf):: gp
        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        real(wp):: a=-0.5_wp
        real(wp):: b= 0.5_wp
        real(wp):: pi= 4.0_wp * atan(1.0_wp)
        integer:: m
        integer:: n

        ! create 3D data
        call meshgrid( x, y, linspace(a, b, 55) )
        m=size(x,1)
        n=size(x,2)
        allocate( z(m,n) )
        z= cos(2.0*pi*x) * sin(2.0*pi*y)



        ! annotation
        call gp%title('Example 103: A beautiful surface plot with hidden details')
        call gp%options('set hidden3d')
        call gp%options('unset key')

        !plot the 3D data
        call gp%surf(x, y, z, palette='jet' ) ! color palette: Matlab jet
        ! contour
        call gp%contour(x,y,z, palette='set1')

    end subroutine exmp103
```
Will produce

![Example ](doc/exmp103.png)
![Example ](doc/exmp103_2.png)


* **Example 104**

Cylindrical mapping


```fortran
    subroutine exmp104()
        type(gpf):: gp
        integer, parameter :: m = 35
        integer, parameter :: n = 15
        real(wp)           :: xv(m), yv(n)
        real(wp), dimension(:,:), allocatable:: x,y,z
        real(wp):: pi= 4.0_wp * atan(1.0_wp)

        xv = linspace(0.0_wp, pi, m)
        yv = linspace(0.0_wp, pi, n)
        call meshgrid(x,y, xv, yv)
        allocate( z(size(x,dim=1), size(x, dim=2)) )
        z = sin(y)


        ! advanced options
        call gp%options('set mapping cylindrical')
        call gp%options('unset tics')
        call gp%options('unset border')
        call gp%options('set view 147,312')
        call gp%options('set hidden3d')

        !
        call gp%title('Example 104. Cylindrical Mapping')
        call gp%surf(x,y,z)

    end subroutine exmp104
```
Will produce

![Example ](doc/exmp104.png)


* **Example 105**

Contour plot and surface plot with color palette


```fortran

    subroutine exmp105()

        type(gpf):: gp

        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        integer:: m
        integer:: n
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! create the xyz data
        call meshgrid(x, y, linspace(-2.0_wp,2.0_wp, 65), linspace(-2.0_wp,3.0_wp, 65)  )

        m=size(x,1)
        n=size(x,2)
        allocate( z(m,n) )

        z = x * exp(-x**2 - y**2)

        call gp%options('unset key')
        call gp%options('unset surface')
        call gp%axis([real(wp):: -2, 2, -2, 3])

        !plot the contour
        call gp%title('Example 105: Contour plot')
        call gp%options('unset border; unset tics')
        call gp%surf(x,y,z, palette='accent')
        call gp%contour(x,y,z, palette='jet')

    end subroutine exmp105

```
Will produce

![Example ](doc/exmp105.png)
![Example ](doc/exmp105_2.png)


* **Example 106**

Animation with 3D plots


```fortran
   subroutine exmp106()

        type(gpf):: gp
        integer,  parameter :: n=25, m=55
        real(wp) :: xv(m), yv(n), t
        real(wp), allocatable :: x(:,:), y(:,:), z(:,:)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! generate data
        xv = linspace(0.0_wp, 2.0_wp*pi, m)
        yv = linspace(0.0_wp, 2.0_wp*pi, n)
        call meshgrid(x, y, xv, yv)
        z = sin(x) + cos(y)

        call gp%title('Example 106. Animation of surface plot')
        call gp%axis([0.0_wp, 2.0*pi, 0.0_wp, 2.0*pi])
        call gp%options('unset colorbox')
        call gp%options('set ticslevel 0')
        call gp%axis([0.0_wp, 2.0*pi, 0.0_wp, 2.0*pi, -2.0_wp, 2.0_wp])

        call gp%animation_start(1.0)
        t=0.050_wp
        do
            ! add frames
            call gp%surf(x, y, sin(t*pi/2.0)*z, palette='jet')
            t=t+0.1_wp
            if (t > 1.0_wp) exit
        end do
        ! show frames in ornithological order with a pause set in
        ! animation_start
        call gp%animation_show()

    end subroutine exmp106

```
Will produce

![Example 106](doc/exmp106.gif)


* **Example 107**

Multiplot layout for 3D plots

```fortran
  subroutine exmp107()
        !...............................................................................
        !Example 107: Multiplot layout in 3D and Contour plot
        !...............................................................................
        type(gpf):: gp

        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z1(:,:)
        real(wp), allocatable:: z2(:,:)
        integer:: m
        integer:: n
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! create the xyz data
        call meshgrid(x, y, linspace(-pi,pi, 60)  )

        m=size(x,1)
        n=size(x,2)
        allocate( z1(m,n) )
        allocate( z2(m,n) )

        z1 = sin(x) + cos(y)
        z2 = sin(x) * cos(y)

        call gp%options('unset key')
        call gp%axis([-pi,pi,-pi,pi])
        call gp%options('unset colorbox')
        call gp%options('set autoscale fix')
        call gp%options('unset tics')

        !plot the contour
        call gp%title('Example 105: Contour plot')
        call gp%multiplot(1,2)
        call gp%surf(x,y,z1)
        call gp%surf(x,y,z2)

        call gp%multiplot(2,1)
        call gp%options('set colorbox')
        call gp%options('set tics')
        call gp%options('set tics font ",8"') ! font size for tics
        call gp%contour(x,y,z1, palette='jet')
        call gp%contour(x,y,z2, palette='set1')


    end subroutine exmp107
```
Will produce

![Example 107](doc/exmp107_2.png)




================================================
FILE: doc/readme.txt
================================================
This folder contains some outputs generated by demo.f90
Rev 0.2
March 1st, 2018


================================================
FILE: example/demo.f90
================================================
!-------------------------------------------------------------------------------
!    GnuPlot Interface
!-------------------------------------------------------------------------------
!    Purpose:   Object Based Interface to GnuPlot from Fortran (ogpf)
!    Platform:  Windows XP/Vista/7/10
!               (It should work on other platforms, see the Write2GnuPlot subroutine below)
!    Language:  Fortran 2003 and 2008
!    Requires:  1. Fortran 2003 compiler (e.g gfortran 4.7, IVF 12.1, ...) or 2008
!               2. gnuplot 4.5 and higher (other previous version can be used
!    Author:    Mohammad Rahmani
!               Chem Eng Dep., Amirkabir Uni of Tech
!               Tehran, Ir
!               url: aut.ac.ir/m.rahmani
!               email: m[dot]rahmani[at]aut[dot]ac[dot]ir
!   License:    MIT

! This file demonstrate the capability of ogpf module
! An object based Fortran interface to gnuplot
!
! Acknowledgement:
! Special thanks to Hagen Wierstorf (http://www.gnuplotting.org)
! For vluable codes and examples on using gnuplot
! Some examples and color palletes are provided by gnuplotting.
!
!
! Revision 0.22
! Date: Mar 9th, 2018
! - see ogpf.f90 for details
! - more examples to reflect the new features

! Revision:  0.20
! Date:     Feb 20th, 2018
!  - more examples
!  - animation of 2D and 3D plots

! Revision:  0.19
! Date:     Jan 15th, 2018
!  - new contour plot procedure


! Revision:  0.18
! Date:     Dec 22th, 2017
! More example based on ogpf 0.18

! Version:  0.17
! Date:     Dec 18th, 2017
!   Minor corrections
! - Multi window plots using script



! Version:  0.16
! Date:     Feb 11th, 2016
!   Minor corrections
!   Correct the lspec processing in plot2D_matrix_vs_vector
!   Some examples revised!


! Version:  0.15
! Date:     Apr 20th, 2012
!   Minor corrections
!   Use of select_precision module and working precision: wp


! Version:  0.14
! Date:     Mar 28th, 2012
!   Minor corrections
!   use of import keyboard and  removing ogpf precision module


! Version:  0.13
! Date:     Feb 12th, 2012
!   Minor corrections
!   Added more samples
!   Use ogpf precision module



! Version:  0.12
! Date:     Feb 9th, 2012
! New examples for semilogx, semilogy, loglog
! New set options method

! Version:  0.11
! Date:     Feb 9th, 2012

program demo

    use ogpf
    implicit none
    ! parameters
    ! local variables
    integer:: i=0


    mainloop: do
        print*  ! empty line
        print*, "gpf: gnuplot from Fortran Demonstration"
        print*, "Example 1: Demo for xy plot"
        print*, "Example 2: Line specification"
        print*, "Example 3: Plot several data series at the same time"
        print*, "Example 4: Plot four data series at the same time"
        print*, "Example 5: Use line style, line colors and more..."
        print*, "Example 6: An interesting plot, sin(x) and its zero on the same plot"
        print*, "Example 7: Plot a matrix against a vector"
        print*, "Example 8: Plot a matrix against a vector and set the linespec and legend"
        print*, "Example 9: Use gnuplot for animation"
        print*, "Example 10: Use ogpf options"
        print*, "Example 11: simple polar plot"
        print*, "Example 12: A plot with logarithmic x axis"
        print*, "Example 13: A matrix plot with logarithmic y axis"
        print*, "Example 14: A loglog plot"
        print*, "Example 15: Plotting a function"
        print*, "Example 16: Save the gnuplot script into a file for future use"
        print*, "Example 17: Multi window plots, using script"
        print*, "Example 18: Running an external script file"
        print*, "Example 19: Multiple linestyle in matrix plot"
        print*, "Example 20: Scatter plot"
        print*, "Example 21: Stem plot"
        print*, "Example 22: Stem plot animation"
        print*, "Example 23: Another animation using matrix plot"
        print*, "Example 24: Multiplot layout"
        print*, "Example 25: Multiplot layout followed by simple plot"
        print*, "Example 26: Plot matrix vs. matrix"

        print*, "Example 27: Using secondary y axis"
        print*, "Example 28: Using secondary x and y axis"
        print*, "Example 29: Using color and size for title and labels"
        print*, "Example 30: More on labels color and size with secondary axes"
        print*
        print*, "***   Surface and Contour Plots ***"
        print*
        print*, "Example 101: Simple 3D plot using surf"
        print*, "Example 102: Surface plot and color palette "
        print*, "Example 103: Surface plot with hidden details and its contour"
        print*, "Example 104: Cylindrical mapping"
        print*, "Example 105: More contour plot"
        print*, "Example 106: Animation of 3D plots"
        print*, "Example 106: Multiplot layout in 3D"
        print*, "Example 107: Multiplot layout for 3D data"
        print*, "Example 108: Plot a 2D grid"
        print*, "Example 109: Plot a 2D grid with random data, but use zlim to select a zrange"

        print*
        write (unit=*, fmt='(a)') "2D plots: select an example: 1 through 30"
        write (unit=*, fmt='(a)') "3D plots: select an example: 101 through 109"
        write (unit=*, fmt='(a)', advance='no') "enter 0 for exit:  "
        read*, i

        select case(i)
            case(1)
                call exmp01
            case(2)
                call exmp02
            case(3)
                call exmp03
            case(4)
                call exmp04
            case(5)
                call exmp05
            case(6)
                call exmp06
            case(7)
                call exmp07
            case(8)
                call exmp08
            case(9)
                call exmp09
            case(10)
                call exmp10
            case(11)
                call exmp11
            case(12)
                call exmp12
            case(13)
                call exmp13
            case(14)
                call exmp14
            case(15)
                call exmp15
            case(16)
                call exmp16
            case(17)
                call exmp17
            case(18)
                call exmp18
            case(19)
                call exmp19
            case(20)
                call exmp20
            case(21)
                call exmp21
            case(22)
                call exmp22
            case(23)
                call exmp23
            case(24)
                call exmp24
            case(25)
                call exmp25
            case(26)
                call exmp26
            case(27)
                call exmp27
            case(28)
                call exmp28
            case(29)
                call exmp29
           case(30)
                call exmp30

                ! 3D plots

            case(101)
                call exmp101
            case(102)
                call exmp102
            case(103)
                call exmp103
            case(104)
                call exmp104
            case(105)
                call exmp105
            case(106)
                call exmp106
            case(107)
                call exmp107
           case(108)
                call exmp108
           case(109)
                call exmp109


            case (0)
                print*, "Program terminated successfully"
                exit mainloop
            case default
                print*, "Try again, use a valid example number"
                print*, "Enter 0 to exit"
        end select
        print*
        print*, "press any key to continue..."
        read*
    end do mainloop


contains


    !...............................................................................
    !Example 1: A very basic example
    !...............................................................................
    subroutine exmp01

        type(gpf):: gp
        integer, parameter:: n=17
        real(wp):: x(n)
        real(wp):: y(n)
        ! Input data
  !      x=dble([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])
        x=dble([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])

        x= abs(x) + 5

        y=dble([66,51,38,27,18,11,6,3,2,3,6,11,18,27,38,51,66])

        ! Annotation: set title, xlabel, ylabel
        call gp%title('Example 1. A simple xy plot','#990011')
        call gp%xlabel('my x axis ...','#99aa33',font_name="Tahoma")
       ! call gp%ylabel('my y axis ...')
        call gp%options('set border lc "#99aa33"; set ylabel "my label..." tc "#99aa33"')

        call gp%options('set logscale y2')
        call gp%plot(x, y)

    end subroutine exmp01


    !...............................................................................
    !Example 2: Set line specification and legends
    !...............................................................................
    subroutine exmp02

        type(gpf):: gp
        integer, parameter:: n=17
        real(wp):: x(n)
        real(wp):: y(n)
        ! Input data
        x=dble([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])
        y=dble([66,51,38,27,18,11,6,3,2,3,6,11,18,27,38,51,66])

        ! Annotation: set title, xlabel, ylabel, line specification
        call gp%title('Example 2. A simple xy plot')
        call gp%xlabel('my x axis ...')
        call gp%ylabel('my y axis ...')

        !Call Plot to draw a vector against a vector of data
        !The last argument defines the line specification
        call gp%plot(x,y,'with linespoints lt 2 pt 4')
    end subroutine exmp02


    !...............................................................................
    ! Example 3: Plot several data set at the same time
    !...............................................................................
    subroutine exmp03

        type(gpf):: g
        integer, parameter:: n = 50
        integer, parameter:: m = 65
        real(wp):: x(n)
        real(wp):: y(n)
        real(wp):: xv(m)
        real(wp):: yv(m)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! Input data
        x=linspace(-pi,pi,n)  !linspace is a utility function in ogpf module
        y=sin(x)              !linspace(a,b,n) create a linear vector in [a,b] with n elements

        xv=linspace(0.d0, 2.d0*pi,m)
        yv=cos(2.d0*xv)

        ! Annotation, set title, xlabel, ylabel
        call g%title('Example 3. Plot two data series using gnuplot')
        call g%xlabel(' x axis ...')
        call g%ylabel(' y axis ...')
        call g%options('set key top left')

        ! Sample 1: Plot to draw two set of data
        call g%plot(x,y,'title "sin"','', xv,yv,'title "cos"')

        !Sample 2: Use keyword arguments to plot the same example as above
        call g%title('Example 3. Another plot using keyword arguments...')
        call g%plot(x1=x,y1=y,ls1='pt 8',x2=xv,y2=yv,ls2='title "cos(2x)"')

        ! Sample 3: An xy plot with line specification no legends
        call g%title('Example 3. Another plot without keyword arguments...')
        call g%plot(x,y,'title "sin(x)" with points pt 6 lc "blue"', '',xv,yv,'title "cos(2x)" pt 7 lc rgb "#993300"')

    end subroutine exmp03


    !...............................................................................
    ! Example 4: Plot four data series, the maximum number of data series can be plotted!
    !...............................................................................
    subroutine exmp04

        type(gpf):: gp
        integer, parameter:: n=50
        integer, parameter:: m=65
        real(wp):: x(n)
        real(wp):: y(n)
        real(wp):: xv(m)
        real(wp):: yv(m)
        real(wp), parameter :: pi=4.d0*atan(1.d0)
        ! Input data
        x=linspace(-pi,pi,n)  !linspace is a utility function from module ogpf
        y=sin(x)

        xv=linspace(0.d0, 2.d0*pi,m)
        yv=cos(2.d0*xv)
        !           This is the maximum number of plot can be drawn at the same time
        !           If you have more data see, you can plot can be used with matrices!
        call gp%title('Example 4. Plot four data sets using gnuplot')
        call gp%options('set key top left; set grid')

        call gp%plot(x,y, 'title "sin(x)"', '', &
            xv,yv, 'with lp lt 6 title "cos(2x)"', '', &
            xv, 2.d0*yv, 'title "2cos(2x)" lt 7', '', &
            xv, 0.5d0*yv, 'title "0.5cos(2x)" with points pt 8')

        ! Another example with keyboard arguments
        call gp%plot(x1=x,y1=y,x2=xv,y2=yv)

    end subroutine exmp04


    !...............................................................................
    ! Example 5: Use line style, line color and moree
    !...............................................................................
    subroutine exmp05

        type(gpf):: gplot
        integer, parameter:: n=50
        real(wp):: x(n)
        real(wp):: ys(n)
        real(wp):: yc(n)
        real(wp):: ysc(n)
        real(wp), parameter :: pi=4.d0*atan(1.d0)
        ! Input data
        x=linspace(-2.d0*pi,2.d0*pi,n)  !linspace is a utility function from module Utils
        ys=  sin(x)
        yc=  exp(-0.1d0*x)*cos(x)
        ysc= sin(x/2.d0)*cos(2.d0*x)

        ! Annotation, set title, xlabel, ylabel
        call gplot%title('Example 5. A sample with customized line style')
        call gplot%xlabel('x, rad')
        call gplot%ylabel('y, dimensionless')

        ! Plot to draw three set of data
        call gplot%plot( &
            x,ys, 'title "sin" with lines lt 5 lc rgb "#0008B0"', '', &
            x,yc, 'title "cos" with points lt 6 lc rgb "#FF1100"', '', &
            x,ysc,'title "sin(x/2)cos(2x)" with lp lt 7 lc rgb "#00AA04"' )

    end subroutine exmp05


    !...............................................................................
    ! Example 6: Plot a single point along with a series of data
    !...............................................................................
    subroutine exmp06

        type(gpf):: gplot
        integer, parameter:: n=125

        real(wp):: x(n)
        real(wp):: y(n)

        real(wp), parameter :: pi=4.d0*atan(1.d0)
        ! Input data
        x=linspace(0.d0,pi*2.d0,n)  !linspace is a utility function from module Utils
        y=sin(6.d0*x)*exp(-x)


        ! Annotation, set title, xlabel, ylabel
        call gplot%title('Example 6. A sample shows f(x) and its zero on the plot')
        call gplot%xlabel('x, rad')
        call gplot%ylabel('f(x) = sin(6x)exp(-x) dimensionless')
        call gplot%options('set grid')

        ! Plot to draw two set of data, a series and a single point
        call gplot%plot(x,y,'title "sin(6x)exp(-x)" with lines lt 2 lw 3', '', &
            [pi],[0.d0],'title "zero" with points pt 7 ps 3 lc rgb "#FF0000"')
    end subroutine exmp06


    !...............................................................................
    ! Example 7: Plot a matrix against a vector
    !...............................................................................
    subroutine exmp07

        type(gpf):: g
        integer, parameter:: n=25
        real(wp), parameter :: pi=4.d0*atan(1.d0)
        real(wp):: x(n)
        real(wp):: y(n,6)

        !Create data
        x=linspace(-pi,pi,n)
        y(:,1)=sin(x)
        y(:,2)=cos(x)
        y(:,3)=cos(0.5d0*x)
        y(:,4)=sin(0.5d0*x)
        y(:,5)=sin(x)*cos(x)
        y(:,6)=sin(x)*exp(-x**2)


        !Draw the matrix y against vector x
        call g%title  ('Example 7. Plotting a Matrix against a vector')
        call g%xlabel ('my x axis')
        call g%ylabel ('my y axis')
        call g%plot   (x, y)
    end subroutine exmp07


    !...............................................................................
    ! Example 08. Plot a matrix against a vector and set the linespec and legend (key)
    !...............................................................................
    subroutine exmp08

        type(gpf):: matplot
        integer, parameter:: n=25, m=6
        integer :: i
        real(wp):: tf
        real(wp):: vo
        real(wp):: g
        real(wp):: t(n)
        real(wp):: y(n,m)

        !Create data
        tf=10.d0
        g=32.d0;
        t=linspace(0.d0,tf,n)
        do i = 1, m
            vo = 25.0d0 * i
            y(:, i) = vo*t-0.5d0*g*t**2
        end do

        !Draw the matrix y againest vector x
        call matplot%title('Example 8. Plotting a Matrix against a vector')
        call matplot%xlabel ('t, sec')
        call matplot%ylabel ('y, feet')
        call matplot%options('set xrange[0:10];set yrange [0:400];')
        call matplot%plot(t, y)

        !Another Matrix plot with legends and line specification
        call matplot%title('Example 8.2: Matrix plot, legends and linespec')
        call matplot%plot(t, 2.0d0*y(:,3:4), &
            lspec='t "vo=100" w lp lt 6 ps 3 lw 2;&
            & t "v=125" w lp lt 7 ps 3 lw 2 lc rgb "#ad6000"')

    end subroutine exmp08


    !...............................................................................
    ! Example 09: Use gnuplot for annimation
    !...............................................................................
    subroutine exmp09

        type(gpf):: gp
        integer, parameter::   n  = 35
        real(wp), parameter :: pi = 4.d0*atan(1.d0)
        real(wp):: x(n)
        real(wp):: y(n), z(n)
        integer :: i


        x=linspace(-pi, pi,n)
        y = 0.0_wp
        z = 0.0_wp
        call gp%animation_start(1.) ! start animation, set delay is one second between frames
        call gp%axis([-pi, pi, -1.2_wp, 1.2_wp])
        call gp%title('A beautiful animation using ogpf library', textcolor='#aa5500')
        ! add frames
        do i=1, n, 1
            y(i) = sin(x(i))
            z(i) = cos(x(i))
            ! each plot command adds one frame
            call gp%plot(x(1:i),y(1:i), 'w lines lc "red" lw 2','', &
                x(i:i), y(i:i),'w points ps 3 pt 7 lc "red"','', &
                x(1:i),z(1:i), 'w lines lc "blue" lw 2', '',&
                x(i:i), z(i:i), 'w points ps 3 pt 7 lc "blue"' )
        end do
        ! finalize and show frames one by one with delay between them
        ! as set by animation_start
        call gp%animation_show()


    end subroutine exmp09


    !...............................................................................
    ! Example 10: Use gnuplot options
    !...............................................................................
    subroutine exmp10()


        type(gpf):: mp
        real(wp):: x(15)
        real(wp):: y(15)

        !Options is a dynamic length string and can set all kind of gnuplot
        call mp%options('set style line 1 lc rgb "#0060ad" lt 1 lw 2 pt 5 ps 1.5 # --- blue')
        call mp%options('set style line 2 lc rgb "#ad6000" lt 2 lw 2 pt 6 ps 1.5 # --- red')
        call mp%options('set style line 3 lc rgb "#00ad00" lt 2 lw 2 pt 7 ps 1.5 # --- green')
        ! this is a multipart string spanned over several lines
        call mp%options('&
            &set style data linespoints;&
            &set xrange [0.1:100];&
            &set yrange [0.01:10000];&
            &set autoscale')
        call mp%options('set key top left') ! set the key location

        x=linspace(0.1d0,100d0,15);
        y=x**2;
        call mp%title("Example 10. x vs. x^2")
        call mp%plot(x1=x, y1=1.50*y, ls1='t "y=1.5x^2" ls 1', &
            x2=x, y2=2.00*y, ls2='t "y=2.0x^2" ls 2', &
            x3=x, y3=2.50*y, ls3='t "y=2.5x^2" ls 3')
        call mp%reset()
        call mp%title('Reset to initial setting')
        call mp%plot(x,2*y)
    end subroutine exmp10


    !...............................................................................
    ! Example 11: A simple polar plot
    !...............................................................................
    subroutine exmp11
        type(gpf):: gp
        integer, parameter :: n=125
        real(wp):: t(n)
        real(wp):: r(n)
        real(wp):: pi=4.d0*atan(1.d0)
        !1. reset gplot
        !!!   CALL gp%reset()
        ! TODOD: There is a problem with reset, persist is off by reset
        !2. set option, and set plot as polar
        call gp%options("&
            &set polar;&
            &set trange [-pi:pi]")

        ! 3. create data
        t=linspace(-pi,pi,n)
        r=sin(3.d0*t)

        !Annotation, set title, xlabel, ylabel
        call gp%title("Example 11: simple polar plot")
        call gp%xlabel("x,...")
        call gp%ylabel("y,...")

        !Call plot method
        call gp%plot(t,r, 'title "sin(3t)"')
        call gp%plot(t, cos(4*t))

    end subroutine exmp11


    !...............................................................................
    ! Example 12: A simple plot with logarithmic x axis
    !...............................................................................
    subroutine exmp12
        type(gpf):: gp
        integer, parameter :: n=70
        real(wp):: x(n)
        real(wp):: y(n)


        ! 1. create data
        x=linspace(0.0d0,10.d0,n)
        y=10**(exp(-x/2.d0)*sin(2.d0*x))


        !Annotation, set title, xlabel, ylabel
        call gp%title("Example 12: A semi-log x plot")
        call gp%xlabel("x,logarithmic scale")
        call gp%ylabel("y, normal scale")

        !Sample 1
        call gp%semilogx(y,x)


    end subroutine exmp12


    !...............................................................................
    ! Example 13: A simple matrix plot with logarithmic y axis
    !...............................................................................
    subroutine exmp13
        type(gpf):: gp
        integer, parameter :: n=25
        real(wp):: x(n)
        real(wp):: y(n)


        ! 1. create data
        x=linspace(0.1d0,10.d0,n)
        y=5.d0*x**3+4.d0*x**2+3.d0*x+1.d0

        !Annotation, set title, xlabel, ylabel
        call gp%title("Example 13: A simple matrix plot with semi-log y")
        call gp%ylabel("y,logarithmic scale")
        call gp%xlabel("x, normal scale")

        ! plot a matrix against vector in logarithmic y axis with line specification
        call gp%semilogy(x,reshape([y,10.d0*y],[n,2]), 'with lines lt 8; with points pt 7')

    end subroutine exmp13


    !...............................................................................
    ! Example 14: A simple plot with logarithmic xy axes
    !...............................................................................
    subroutine exmp14
        type(gpf):: gp
        integer, parameter :: n=75
        real(wp):: x(n)
        real(wp):: y(n)
        real(wp):: pi=4.d0*atan(1.d0)

        ! 1. create data
        x=exp(linspace(0.d0,2.d0*pi,n))
        y=50.d0+exp( 3.d0* linspace(0.d0,2.d0*pi,n) )

        ! 2. Annotation, set title, xlabel, ylabel
        call gp%title("Example 14: A loglog plot")
        call gp%xlabel("x,logarithmic scale")
        call gp%ylabel("y,logarithmic scale")

        ! 3. Set grid on
        call gp%options('set grid xtics ytics mxtics')

        ! 4. Call plot method
        call gp%loglog(x,y)

    end subroutine exmp14

    !...............................................................................
    ! Example 15: Plotting a function
    !...............................................................................
    subroutine exmp15()
        type(gpf):: gp
        real(wp):: pi=4.d0*atan(1.d0)

        call gp%title("Example 15. Plotting a function using fplot")
        call gp%xlabel("x...")
        call gp%ylabel("y...")
        ! call fplot to plot a function in range of [a, b] with n points
        call gp%fplot(myfun,[0d0,15.d0*pi],150)

    end subroutine exmp15

    function myfun(x)
        ! The function to be plotted
        ! see example 15
        real(wp), intent(in) :: x
        real(wp):: myfun
        myfun=x*sin(x)
    end function myfun


    !...............................................................................
    ! Example 16: Save the gnuplot script into a file for future use
    !...............................................................................
    subroutine exmp16()
        type(gpf):: gp
        real(wp):: pi=4.d0*atan(1.d0)
        integer, parameter :: n=100
        real(wp) :: x(n)
        real(wp) :: y(n)
        real(wp) :: z(n)

        ! create data
        x = linspace(-pi, 3.0d0*pi)
        y = sin(2.0d0*x)*exp(-x/5.0d0)
        z = cos(2.0d0*x)*exp(-x/5.0d0)

        ! several gnuplot optuons
        call gp%options('set border linewidth 1.5')
        call gp%options('set style line 1 lc rgb "#ad6009" lt 1 lw 2 pt 7 ps 1.5 # --- red like')
        call gp%options('set style line 2 lc rgb "#00ad09" lt 2 lw 2 pt 6 ps 1.5 # --- green like')
        call gp%options('unset key')
        call gp%options('set grid')
        call gp%options('set ytics 1')
        call gp%options('set tics scale 0.75')

        call gp%title("Example 16. Save the script into file for future use")
        call gp%xlabel("x...")
        call gp%ylabel("y...")

        ! save the script into a file
        call gp%filename("Example16.gp")
        call gp%plot(x, y, ls1='with lp ls 1', x2=x, y2=z, ls2='with lp ls 2')

        print*  ! empty line
        print*, 'Plot commands were written in Example16.gp successfully'
        print*, 'Open gnuplot and load this script file to plot the results!'
        print*  ! empty line

    end subroutine exmp16


    !...............................................................................
    ! Example 17: Plot in two separate windows using script
    !...............................................................................
    subroutine exmp17()
        ! Script is used to create multi window plot
        ! Each "set term wxt <number>" creates a new window
        type(gpf):: gp

        call gp%add_script('set term wxt 0 title "My first plot" size 640,480')
        call gp%add_script('set title "Example 17. Multi windows plot using script"')
        call gp%add_script('plot x*x+2*x+1')
        call gp%add_script('set term wxt 1 title "My second plot"')
        call gp%add_script('set ylabel "xsin(x)"')
        call gp%add_script('plot x*sin(x)')

        call gp%run_script()

    end subroutine exmp17

    !...............................................................................
    ! Example 18: Running an external script file
    !...............................................................................

    subroutine exmp18()

        !Use gnuplot script
        !to send a special external script file to gnuplot
        !the file is an external file here is called "simple.plt"
        type(gpf):: gp

        ! add some options and commands
        call gp%title("Example 18. Running an external script file")
        call gp%add_script('load "sample_script.gp" ')

        ! run script
        call gp%run_script()

    end subroutine exmp18


    !...............................................................................
    !Example 19: USE multiple linespec in plotting a matrix vs a vector
    !...............................................................................
    subroutine exmp19
        ! see also example 8
        type(gpf):: gp
        integer, parameter:: n=17
        real(wp):: x(n)
        real(wp):: y(n,8)
        integer :: j
        ! Input data
        x=linspace(0.d0,10.d0,17)
        do j=1, 8
            y(:,j)=dble(3*j)
        end do


        !Annotation, set title, xlabel, ylabel
        call gp%title('Example 19. Matrix plot with different line specification')
        call gp%xlabel('my x axis ...')
        call gp%ylabel('my y axis ...')
        call gp%options('set key bottom right')
        call gp%axis([-2.d0,20.d0,-2.d0,20.d0])

        !Call Plot to draw a matrix against a vector of data
        call gp%plot(x,y,lspec='with linespoints lt 1 title "lt 1";&
            & with lp lt 2 title "lt 2";&
            & with lp lt 3 title "lt 3";&
            & with lp lt 4 title "lt 4";&
            & with lp lt 5 title "lt 5";&
            & with lp lt 6 title "lt 6";&
            & with lp lt 7 title "lt 7";&
            & with lp lt 8 title "lt 8"')


    end subroutine exmp19

    !...............................................................................
    ! Example 20: Making a scatter plot
    !...............................................................................
    subroutine exmp20()
        type(gpf):: gp
        integer,  parameter :: n=750
        real(wp) :: x(n), y(n), ym(n), noise(n), d(n)
        real(wp) :: a, b

        ! generate data
        a = 00.0_wp
        b = 05.0_wp
        ! 1. generate the model data
        x  = linspace(a,b,n)
        ym = sqrt(x)  ! model data


        ! 2. generate the measured data with noise (ensembles the experimental data)
        call random_number(noise)       ! generate noise in [0, 1]
        d = (b-a)/100.0_wp * (x-a)**2   ! define the deviation function
        d = 2.0_wp*(noise - 0.5_wp) * d ! distribute noise around y=0
        y = ym + d


        call gp%title('Example 20. Scatter plot')
        call gp%xlabel('x,....')
        call gp%options('set key top left')
        call gp%options('set autoscale fix')
        call gp%options('set style line 1 lc rgb "blue" lt 1 lw 2 pt 6 ps 1.5')
        call gp%plot(x, y,  't "exp data" with points pt 6 ps 1.2 lc rgb "#ad2060"', &
            x2=x, y2=ym, ls2='t "mode: y=sqrt(x)" w lines lt 1 lw 3 lc "blue"')

        ! plot only the experimental data
        call gp%title('Example 20. Scatter plot: data with noise')
        call gp%plot(x,y,'w l lc "blue"', x2=x, y2=ym, ls2='w l lc "dark-red" lw 2')


    end subroutine exmp20

    !...............................................................................
    ! Example 21: Making a stem plot
    !...............................................................................
    subroutine exmp21()
        type(gpf):: gp
        integer,  parameter :: n=50
        real(wp) :: x(n), y(n)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! generate data
        x = linspace(0.0_wp, 4.0_wp*pi, n)
        y = exp(-x/4.0)*sin(x)

        call gp%title('Example 21. Stem plot')
        ! making plot
        call gp%plot(x,y, 'with impulses lw 2.5', &
            x2=x, y2=y,  ls2='with points pt 7')

    end subroutine exmp21


    !...............................................................................
    ! Example 22: Stem plot animation
    !...............................................................................
    subroutine exmp22()

        type(gpf):: gp
        integer,  parameter :: n=50
        real(wp) :: x(n), y(n)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)
        integer :: i

        ! generate data
        x = linspace(0.0_wp, 4.0_wp*pi, n)
        y = exp(-x/4.0)*sin(x)
        ! important, set the xy axis range
        call gp%axis([0.0_wp, 4.0_wp*pi, -1.0_wp, 1.0_wp])

        ! start animation
        call gp%animation_start(pause_seconds=1.) ! one second delay between frames
        do i=1,n ! add frames
            ! each plot command adds one frame
            call gp%plot(x(1:i), y(1:i), ls1='with impulses lw 2', &
                x2=x(1:i), y2=y(1:i),  ls2='with points pt 6')
        end do
        ! finalize and show all frames in ornithological order with pause as
        ! set by animation_start
        call gp%animation_show()

    end subroutine exmp22


    !...............................................................................
    ! Example 23: Another animation using matrix plot
    !...............................................................................
    subroutine exmp23()
        type(gpf):: gp
        integer,  parameter :: n=55
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)
        real(wp) :: x(n), y(n,2)
        integer :: i

        ! generate data
        x = linspace(0.0_wp, 4.0_wp*pi, n)
        y(:,1) = exp(-x/4.0)*sin(x)
        y(:,2) = exp(-x/8.0)*cos(x)

        call gp%axis([0.0_wp, 4.0*pi, -0.8_wp, 1.0_wp])

        call gp%animation_start(1.)
        do i=1, n, 2
            ! making plot: add frames
            call gp%plot(x(1:i),y(1:i, :), 'with lines lw 2')
        end do
        call gp%animation_show()

    end subroutine exmp23


    !...............................................................................
    ! Example 24: Use of multiplot layout
    !...............................................................................
    subroutine exmp24()

        type(gpf):: gp
        integer,  parameter :: n=25
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)
        real(wp) :: x(n), y(n,2)
        x=linspace(-pi, pi, n)
        y(:,1) = sin(x)*exp(-x/2.0)
        y(:,2) = cos(x)*(1-exp(-x/5.0))


        call gp%multiplot(2,1)  ! create a 2x1 multiplot layout

        call gp%title('Example 24. Multiplot layout, first row')
        call gp%xlabel('x1, ...')
        call gp%ylabel('y1, ...')
        call gp%plot(x, y(:,1), 'pt 7 lw 2 lc "red"') ! plot in first row

        call gp%title('Example 24. Multiplot layout,second row')
        call gp%xlabel('x2, ...')
        call gp%ylabel('y2, ...')

        call gp%plot(x, y(:,2), 'pt 6 lw 2 lc "blue"') ! plot in the second

    end subroutine exmp24


    !...............................................................................
    ! Example 25: Use multiplot followed by other plot command
    !...............................................................................
    subroutine exmp25()

        type(gpf):: gp
        integer,  parameter :: n=25
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)
        real(wp) :: x(n), y(n,4)
        integer :: i

        x=linspace(-pi, pi, n)
        y(:,1) = sin(x)
        y(:,2) = sin(x)*cos(x)
        y(:,3) = (1-x)*sin(x)
        y(:,4) = (1-x)*cos(x)

        ! general options
        call gp%options('set tics font ",8"')

        call gp%multiplot(2,2)
        do i=1, 4
            call gp%plot(x, y(:,i), 'lt 4 pt 6')
        end do
        ! a new window will be started when all places in the multiplot
        ! layout is occupied. The multiplot window will be closed
        call gp%plot(x,y)
    end subroutine exmp25



    !...............................................................................
    !Example 26: Plot matrix against matrix
    !...............................................................................
    subroutine exmp26
        ! see also example 8
        type(gpf):: gp
        integer, parameter:: n=35
        integer, parameter:: m=3
        real(wp)  :: x(n,m)
        real(wp)  :: y(n,m)

        ! create data
        x(:,1) = linspace(-3.15d0,3.15d0,n)
        x(:,2) = 3.15d0 + x(:,1)
        x(:,3) = 3.15d0 - x(:,1)

        y(:,1) =1.0d0 * sin(x(:,1)) * (1-x(:,1))
        y(:,2) =2.0d0 * sin(x(:,1)) * (1-x(:,1))
        y(:,3) =3.0d0 * sin(x(:,1)) * (1-x(:,1))


        !Annotation, set title, xlabel, ylabel
        call gp%title('Example 26. Plot matrix vs. matrix')
        call gp%xlabel('my x axis ...')
        call gp%ylabel('my y axis ...')
        call gp%options('set key bottom left')


        !Call Plot to draw a matrix against a vector of data
        call gp%plot(x,y,lspec='t "y1" lw 2 ps 2 pt 6; t "y2" lw 2 ps 2 pt 7; t "y3" lw 2 ps 2 pt 9')

    end subroutine exmp26


    !...............................................................................
    !Example 27: Using secondary y axis
    !...............................................................................
    subroutine exmp27()

        type(gpf):: gp
        integer, parameter:: n1=50, n2=75
        real(wp):: x(n1), u(n1)
        real(wp):: t(n2), v(n2)

        ! Input data
        x = linspace(-5._wp,5._wp,n1)
        t = linspace(0._wp,15._wp,n2)
        u = sin(x) * cos(x)
        v = t*sin(t)
        ! Annotation: set title, xlabel, ylabel
        call gp%title('Example 27. Using secondary y axis')
        call gp%xlabel('primary x axis ...')
        call gp%ylabel('primary y axis ...')
        call gp%y2label('secondary y axis ...')

        ! turn on the y2 tics
        call gp%options('set y2tics')

        ! plot first data set with primary axes (defualt)
        ! and the second data set with secondary y axis
        call gp%plot(x, u, ls1= 't "primary y axis"', x2=t, y2=v, axes2='x1y2', ls2='t "secondary y axis"')

    end subroutine exmp27


    !...............................................................................
    !Example 28: Using secondary x and secondary y axis
    !...............................................................................
    subroutine exmp28()
        ! exmp28
        type(gpf):: gp
        integer, parameter:: n=50
        real(wp):: t(n), v(n)

        ! Input data
        t = linspace(-3.1415d0, 3.1415d0, n)
        v = sin(t) * cos(t)

        ! Annotation: set title, xlabel, ylabel
        call gp%title  ('Example 28. Plot using secondary x and y axis')
        call gp%xlabel ('primary x axis ...')
        call gp%ylabel ('primary y axis ...')
        call gp%x2label('secondary x axis ...')
        call gp%y2label('secondary y axis ...')

        ! use different color for secondary axis
        call gp%options('set x2tics tc "red"; set y2tics tc "red"')
        call gp%options('set xtics tc "blue"; set ytics tc "blue"')

        call gp%plot(t,v, axes1='x1y1', ls1='lc "blue" lw 2', x2=t, y2=t*t*v, axes2='x2y2', ls2='lc "red"')

    end subroutine exmp28

    !...............................................................................
    !Example 29: Use color, font and size for labels
    !...............................................................................
    subroutine exmp29

        type(gpf):: gp
        real(wp), dimension(100) :: x, y

        ! create data
        call random_number(x)
        call random_number(y)

        !Annotation, set title, xlabel, ylabel with color and font and rotation
        call gp%title('Example 29. Use color, font and size for labels', textcolor='blue', font_size=14)
        call gp%xlabel('rotated ...',   textcolor='red', font_size=14, font_name='arial', rotate=10)
        call gp%ylabel('my y axis ...', textcolor='violet')
        call gp%options('set key bottom left')
        call gp%options('set style data points')


        !Call Plot to draw a matrix against a vector of data
        call gp%plot(x,y, 'lt 5 ps 1.25')

    end subroutine exmp29


    !...............................................................................
    !Example 30: More on colors and size of labels
    !...............................................................................
    subroutine exmp30()
        ! exmp30 shows more customization on ogpf
        type(gpf) :: plt

        integer, parameter :: n=40
        integer, parameter :: m=80
        real(wp), dimension(n)  :: t1, u1
        real(wp), dimension(m)  :: t2, u2

        character(len=:), allocatable :: colorp, colors
        character(len=:), allocatable :: ls1, ls2

        ! define rgb colors for primary and secondary axes
        colorp = '"#D95F02"'
        colors = '"#7570B3"'

        ! set the line specification and legends
        ls1='t "primary"   lt 4 lw 1.25 ps 1.2 lc rgb  '  // colorp
        ls2='t "secondary" lt 5 lw 1.25 ps 1.2 lc rgb '  // colors

        ! create data
        t1 = linspace(-10._wp, 10._wp, n)
        t2 = linspace(-3.14_wp, 3.14_wp, m)

        u1 = 0.5_wp * t1**2
        u2 = exp(-t2)*sin(2.0*t2)


        ! turn on the second axes
        call plt%options('set xtics tc ' // colorp)
        call plt%options('set ytics tc ' // colorp)

        call plt%options('set x2tics tc ' // colors)
        call plt%options('set y2tics tc ' // colors)

        ! set labels and title
        call plt%title('Example 30. A customizes plot', textcolor='#E7298A', font_size = 15)
        call plt%xlabel('primary x', textcolor=colorp(2:8), font_size = 9)
        call plt%ylabel('primary y', textcolor=colorp(2:8), font_size = 9)

        call plt%x2label('secondary x', textcolor=colors(2:8), font_size = 12)
        call plt%y2label('secondary y', textcolor=colors(2:8), font_size = 12)

        ! plot data
        call plt%plot(t1,u1,ls1=ls1 , axes1='x1y1', x2=t2,y2=u2, ls2=ls2, axes2='x2y2')

    end subroutine exmp30



    !-------------------------------------------------------------------------------
    ! 3D Plots
    !-------------------------------------------------------------------------------

    ! surface plot examples  (gnuplot equivalent routine is splot)
    ! contour plot examples
    ! animation of 3D plots


    !...............................................................................
    !Example 101: A simple 3d plot
    !...............................................................................
    subroutine exmp101

        type(gpf):: gp
        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        real(wp):: a=0.5d0
        real(wp):: b=2.0d0
        real(wp), allocatable :: xgrid(:)
        real(wp), allocatable :: ygrid(:)
        integer:: m
        integer:: n

        ! create 3D data
        m=55 ! number of grid points in y direction
        n=25 ! number of grid points in x direction
        allocate(xgrid,source=linspace(-10.0_wp, 10.0_wp, m))
        ygrid=linspace(0.0_wp, 5.0_wp, n)
        allocate( z(m,n) )

        call meshgrid(x, y, xgrid, ygrid) ! generate the 2D grid data
        z=(x**2/a - y**2/b)

        ! annotation
        call gp%title('Example 101: Simple 3D plot')
        call gp%xlabel('x-axis,...')
        call gp%ylabel('y-axis,...')
        call gp%zlabel('z-axis,...')

        !plot the 3D data
        call gp%surf(x, y, z, lspec='t "default color spec"' ) ! color palette: gnuplot default
        call gp%surf(x, y, z, lspec='t "Ann Schnider set1"', palette='set1' ) ! color palette: set1
        call gp%surf(x, y, z, lspec='t "Matlab Jet"', palette='jet' ) ! color palette: Matlab jet
    end subroutine exmp101


    !...............................................................................
    !Example 102: Another simple surface plot with legend and line color
    !...............................................................................
    subroutine exmp102()
        type(gpf):: gp

        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        integer:: m
        integer:: n

        ! generate data
        call meshgrid(x, y, linspace(-0.75_wp*pi, 0.75_wp*pi, 35) ) ! xgrid == ygrid
        m=size(x,1)
        n=size(x,2)
        allocate( z(m,n) )

        !z= sin(x) * cos (y)
        where ((.not. x**2 + y**2 > 0.0_wp) .and. (.not. x**2 + y**2 < 0.0_wp))
            z=1.0_wp
        elsewhere
            z=sin(x**2+y**2)/(x**2+y**2)
        end where


        call gp%title('Example 102: Simple 3D plot with color palette')
        call gp%xlabel('x-axis,...')
        call gp%ylabel('y-axis,...')

        !plot the 3D data
        CALL gp%surf(X,Y,Z, palette='jet')

    end subroutine exmp102


    !...............................................................................
    !Example 103: A beautiful surface plot with hidden details
    !...............................................................................
    subroutine exmp103()

        type(gpf):: gp
        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        real(wp):: a=-0.5_wp
        real(wp):: b= 0.5_wp
        real(wp):: pi= 4.0_wp * atan(1.0_wp)
        integer:: m
        integer:: n

        ! create 3D data
        call meshgrid( x, y, linspace(a, b, 55) )
        m=size(x,1)
        n=size(x,2)
        allocate( z(m,n) )
        z= cos(2.0*pi*x) * sin(2.0*pi*y)



        ! annotation
        call gp%title('Example 103: A beautiful surface plot with hidden details')
        call gp%options('set hidden3d')
        call gp%options('set tics font ",8"')
        call gp%options('unset key')

        !plot the 3D data
        call gp%surf(x, y, z, palette='jet' ) ! color palette: Matlab jet
        ! contour
        call gp%contour(x,y,z, palette='set1')

    end subroutine exmp103


    !...............................................................................
    !Example 104: Cylindrical mapping
    !...............................................................................
    subroutine exmp104()
        type(gpf):: gp
        integer, parameter :: m = 35
        integer, parameter :: n = 15
        real(wp)           :: xv(m), yv(n)
        real(wp), dimension(:,:), allocatable:: x,y,z
        real(wp):: pi= 4.0_wp * atan(1.0_wp)

        xv = linspace(0.0_wp, pi, m)
        yv = linspace(0.0_wp, pi, n)
        call meshgrid(x,y, xv, yv)
        allocate( z(size(x,dim=1), size(x, dim=2)) )
        z = sin(y)


        ! advanced options
        call gp%options('set mapping cylindrical')
        call gp%options('unset tics')
        call gp%options('unset border')
        call gp%options('set view 147,312')
        call gp%options('set hidden3d')

        !
        call gp%title('Example 104. Cylindrical Mapping')
        call gp%surf(x,y,z)

    end subroutine exmp104

    !...............................................................................
    !Example 105: contour plot
    !...............................................................................
    subroutine exmp105()
        type(gpf):: gp

        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z(:,:)
        integer:: m
        integer:: n

        ! create the xyz data
        call meshgrid(x, y, linspace(-2.0_wp,2.0_wp, 65), linspace(-2.0_wp,3.0_wp, 65)  )

        m=size(x,1)
        n=size(x,2)
        allocate( z(m,n) )

        z = x * exp(-x**2 - y**2)

        call gp%options('unset key')
        call gp%options('unset surface')
        call gp%axis([real(wp):: -2, 2, -2, 3])

        !plot the contour
        call gp%options('unset border; unset tics')
        call gp%title('Example 105: Surface plot')
        call gp%surf(x,y,z, palette='accent')
        call gp%title('Example 105: Contour plot')
        call gp%contour(x,y,z, palette='jet')

    end subroutine exmp105


    !...............................................................................
    !Example 106: Animation of surface plot
    !...............................................................................
    subroutine exmp106()

        type(gpf):: gp
        integer,  parameter :: n=25, m=55
        real(wp) :: xv(m), yv(n), t
        real(wp), allocatable :: x(:,:), y(:,:), z(:,:)
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! generate data
        xv = linspace(0.0_wp, 2.0_wp*pi, m)
        yv = linspace(0.0_wp, 2.0_wp*pi, n)
        call meshgrid(x, y, xv, yv)
        allocate(z, source = sin(x) + cos(y))

        call gp%title('Example 106. Animation of surface plot')
        call gp%axis([0.0_wp, 2.0*pi, 0.0_wp, 2.0*pi])
        call gp%options('unset colorbox')
        call gp%options('set ticslevel 0')
        call gp%axis([0.0_wp, 2.0*pi, 0.0_wp, 2.0*pi, -2.0_wp, 2.0_wp])

        call gp%animation_start(1.)
        t=0.050_wp
        do
            ! add frames
            call gp%surf(x, y, sin(t*pi/2.0)*z, palette='jet')
            t=t+0.1_wp
            if (t > 1.0_wp) exit
        end do
        ! show frames in ornithological order with a pause set in
        ! animation_start
        call gp%animation_show()

    end subroutine exmp106

    !...............................................................................
    !Example 107: Multiplot layout for 3D data
    !...............................................................................
    subroutine exmp107()
        type(gpf):: gp

        real(wp), allocatable:: x(:,:)
        real(wp), allocatable:: y(:,:)
        real(wp), allocatable:: z1(:,:)
        real(wp), allocatable:: z2(:,:)
        integer:: m
        integer:: n
        real(wp), parameter :: pi=4.0_wp*atan(1.0_wp)

        ! create the xyz data
        call meshgrid(x, y, linspace(-pi,pi, 60)  )

        m=size(x,1)
        n=size(x,2)
        allocate( z1(m,n) )
        allocate( z2(m,n) )

        z1 = sin(x) + cos(y)
        z2 = sin(x) * cos(y)

        call gp%options('unset key')
        call gp%axis([-pi,pi,-pi,pi])
        call gp%options('unset colorbox')
        call gp%options('set autoscale fix')
        call gp%options('unset tics')

        !plot the contour
        call gp%title('Example 107: surface plot')
        call gp%multiplot(1,2)
        call gp%surf(x,y,z1)
        call gp%surf(x,y,z2)

        call gp%multiplot(2,1)
        call gp%title('Example 107: Contour plot')
        call gp%options('set colorbox')
        call gp%options('set tics')
        call gp%options('set tics font ",8"') ! font size for tics
        call gp%contour(x,y,z1, palette='jet')
        call gp%contour(x,y,z2, palette='set1')


    end subroutine exmp107


    !...............................................................................
    !Example 108: Plod a 2D grid
    !...............................................................................
    subroutine exmp108
        type(gpf):: gp
        integer, parameter:: n=10
        real(wp), allocatable :: x(:,:)
        real(wp), allocatable :: y(:,:), z(:,:)

    ! create data
    call meshgrid(x,y,linspace(1.0d0, 10.0d0, n))
    allocate(z(n,n))
    z=1.0d0

    ! set gnuplot  options
    call gp%options('unset border') ! turn off border line (axes)
    call gp%options('unset tics')   ! turn off axes values (tics)
    call gp%options('set view map') ! set viewpoint top down
    ! plot using linespec
    call gp%surf(x,y,z,lspec='w lp ps 2 pt 6 lc "#99aa33')

    end subroutine exmp108


    !...............................................................................
    !Example 109: Plot a 2D grid with random data, but use zlim to select a zrange
    !...............................................................................
    subroutine exmp109()
        type(gpf):: gp
        integer, parameter:: n=100

        real(wp),    allocatable:: x(:,:)
        real(wp),    allocatable:: y(:,:)
        real(wp),    allocatable:: z(:,:)

        ! create the xyz data
        call meshgrid(x,y,linspace(-1.5_wp,1.5_wp,n))
        allocate(z(n,n))
        ! fills with random numbers
        call random_number(z)
        ! make them between -1.0_wp and 1.0_wp
        z = z - 2.0_wp*z
        ! create regions outsize such range
        z = merge(-2.0_wp, z, x >= -.2_wp .and. x <= .2_wp)
        z = merge(-2.0_wp, z, y >= -.2_wp .and. y <= .2_wp)

        !plot the contour
        call gp%title('Example 109: Zlim Example')
        call gp%options('unset border') ! turn off border line (axes)
        call gp%options('set view map')
        ! Anything outside -1.0_wp and 1.0_wp will be cut off
        call gp%zlim([-1.0_wp,1.0_wp])
        call gp%options('set cbrange[-1.0:1.0]')
        call gp%surf(x,y,z,palette='set1')

    end subroutine exmp109



end program demo


================================================
FILE: fpm.toml
================================================
name="ogpf"
description = "Object Based Interface to GnuPlot from Fortran"
version = "0.4.0"
license = "MIT"
author = "Mohammad Rahmani"
copyright = "2020 Mohammad Rahmani"


================================================
FILE: meson.build
================================================
project('Ogpf', 'fortran')

gnuplot = find_program('gnuplot',
  required: true)

libogpf = library('ogpf', 'src/ogpf.f90',
  fortran_args: '-std=f2008')

libogpf_dep = declare_dependency(
  link_with: libogpf)

executable('demo', 'example/demo.f90',
  dependencies: libogpf_dep)


================================================
FILE: revision.txt
================================================
Rev 0.20

March 1st, 2018


================================================
FILE: sample_script.gp
================================================
# https://linuxgazette.net/133/luana.html

set size ratio -1
 set nokey
 set noxtics
 set noytics
 set noborder
 set parametric
#
 x(t) = (R-r)*cos(t) + p*cos((R-r)*t/r)
 y(t) = (R-r)*sin(t) - p*sin((R-r)*t/r)
#
# Greatest common divisor:
 gcd(x,y) = (x%y==0 ? y : gcd(y,x%y))

# change these integer parameters to get very nice drawings
 R = 100; r = 2; p = 70; res = 175

 #
 rr = abs(r)
 nturns = rr / gcd(R,rr)
 samp = 1 + res * nturns
 set samples samp
#
plot [t=0:nturns*2*pi] x(t),y(t)  

================================================
FILE: src/ogpf.f90
================================================
!-------------------------------------------------------------------------------
!    GnuPlot Interface
!-------------------------------------------------------------------------------
!    Purpose:   Object Based Interface to GnuPlot from Fortran (ogpf)
!    Platform:  Windows XP/Vista/7/10
!               (It should work on other platforms, see the finalize_plot subroutine below)
!    Language:  Fortran 2003 and 2008
!    Requires:  1. Fortran 2003 compiler (e.g gfortran 5, IVF 12.1, ...)
!                  There is only two more features needs Fortran 2008 standard
!                  execute_command_line and passing internal function as argument.
!               2. gnuplot 5 and higher (other previous version can be used
!    Author:    Mohammad Rahmani
!               Chem Eng Dep., Amirkabir Uni. of Tech
!               Tehran, Ir
!               url:    aut.ac.ir/m.rahmani
!               github: github.com/kookma
!               email:  m[dot]rahmani[at]aut[dot]ac[dot]ir
!
!
! Acknowledgement:
! Special thanks to Hagen Wierstorf (http://www.gnuplotting.org)
! For vluable codes and examples on using gnuplot
! Some examples and color palletes are provided by gnuplotting.
!


! Revision History

! Revision 0.22
! Date: Mar 9th, 2018
! - a new procedure called use_extra_configuration is used to set general gnuplot settings
! - new type for labels (xlabel, ylabel, zlabel, title,...)
! - all lables now accept text color, font name, font size, rorate by degree
! - Secondary axes can use different scale (linear or logarithmic)
! - subroutine plot2d_matrix_vs_matrix(xmat,ymat)
!    now plots a matrix columns ymat aganist another matrix column xmat
! - added more examples

! Revision 0.21
! Date: Mar 8th, 2018
! - new axes to plot command to use secondary axes added!


! Revision:  0.20
! Date:     Feb 20th, 2018
!  - ogpf now supports animation for 2D and 3D plots
!  - rewrite contour and surface plot
!  - select_precision has been merged into ogpf
!  - new add_script procedure replaced old script
!  - new run_script procedure
!  - writestring procedure removed
!  - linespec for plor2d_matrix_vs_plot now is a single dynamic string
!  - splot now uses datablok instead of inline data
!  - meshgrid now support full grid vector
!  - arange a numpy similar function to create a range in the form of [xa, xa+dx, xa+2*dx, ...]
!  - new num2str routines



! Revision:  0.19
! Date:     Jan 15th, 2018
!  - new contour plot procedure


! Revision:  0.18
! Date:     Dec 22th, 2017
!   Major revision
!   - The dynamic string allocation of Fortran 2003 is used (some old compilers
!     does not support this capability)
!   - Multiple windows plot now supported
!   - Multiplot now supported
!   - Gnuplot script file extension is changed from .plt to .gp
!   - Default window size (canvas) changed to 640x480
!   - Persist set to on (true) by default
!   - A separate subroutine is used now to create the output file for gnuplot commands
!   - A separate subroutine is used now to finalize the output

!


! Revision:  0.17
! Date:     Dec 18th, 2017
!   Minor corrections
!   - Correct the meshgrid for wrong dy calculation when ygv is sent by two elements.
!   - Remove the subroutine ErrHandler (development postponed to future release)


! Revision:  0.16
! Date:     Feb 11th, 2016
!   Minor corrections
!   Correct the lspec processing in plot2D_matrix_vs_vector
!   Now, it is possible to send less line specification and gpf will cycle through lspec

! Revision:  0.15
! Date:     Apr 20th, 2012
!   Minor corrections
!   Use of select_precision module and working precision: wp

! Revision:  0.14
! Date:     Mar 28th, 2012
!   Minor corrections
!   Use of import keyboard and removing the Precision module
!   Length of Title string increased by 80 chars


! Revision:  0.13
! Date:     Feb 12th, 2012
!   Minor corrections
!   Added axis method which sets the axis limits for x-axis, y-axis and z-axis
!   Added Precision module



! Version:  0.12
! Date:     Feb 9th, 2012
!   Minor corrections
!   New semilogx, semilogy, loglog methods
!   New options method, allow to be called several times to set the gnuplot options



! Version:  0.11
! Date:     Feb 9th, 2012
!   Minor corrections
!   Use of NEWUINT specifier from Fortran 2008
!   Added configuration parameters
!   Extra procedures have been removed
!   Temporary file is now deleted using close(...,status='delete')

!
! Version:  0.1
! Date:     Jan 5th, 2012
! First object-based version

module ogpf

    implicit none

    private

    public arange, linspace, meshgrid, wp
    public num2str

    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ! select precision
    !
    !     sp: kind for single precision
    !     dp: kind for double precision
    !
    !     wp: kind for working precision (set to either sp or dp)
    integer, parameter :: sp = kind( 1.0 )
    integer, parameter :: dp = kind( 1.0d0 )

    integer, parameter :: wp = dp
    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ! Library information
    character(len=*), parameter :: md_name = 'ogpf libray'
    character(len=*), parameter :: md_rev  = 'Rev. 0.22 of March 9th, 2018'
    character(len=*), parameter :: md_lic  = 'Licence: MIT'

    ! ogpf Configuration parameters
    ! The terminal and font have been set for Windows operating system
    ! Correct to meet the requirements on other OS like Linux and Mac.
    character(len=*), parameter ::  gnuplot_term_type = 'wxt'                      ! Output terminal
    character(len=*), parameter ::  gnuplot_term_font = 'verdana,10'               ! font
    character(len=*), parameter ::  gnuplot_term_size = '640,480'   !'960,840'                  ! plot window size
    character(len=*), parameter ::  gnuplot_output_filename='ogpf_temp_script.gp' ! temporary file for output
    ! extra configuration can be set using ogpf object

    ! module procedure
    interface num2str ! convert integer, real, double precision into string
        module procedure num2str_i4
        module procedure num2str_r4
        module procedure num2str_r8
    end interface

    !> 0.22
    ! tplabel is a structure for gnuplot labels including
    ! title, xlabel, x2label, ylabel, ...
    integer, parameter, private :: NOT_INITIALIZED = -32000
    type tplabel
        logical                       :: has_label = .false.
        character(len=:), allocatable :: lbltext
        character(len=:), allocatable :: lblcolor
        character(len=:), allocatable :: lblfontname
        integer                       :: lblfontsize = NOT_INITIALIZED
        integer                       :: lblrotate   = NOT_INITIALIZED
    end type tplabel


    type, public :: gpf
        ! the gpf class implement the object for using gnuplot from fortran in a semi-interactive mode!
        ! the fortran actually do the job and write out the commands and data in a single file and then
        ! calls the gnuplot by shell command to plot the data

        private

        !> 0.22
        type(tplabel) :: tpplottitle
        type(tplabel) :: tpxlabel
        type(tplabel) :: tpx2label
        type(tplabel) :: tpylabel
        type(tplabel) :: tpy2label
        type(tplabel) :: tpzlabel

        character(len=:), allocatable  :: txtoptions    ! a long string to store all type of gnuplot options
        character(len=:), allocatable  :: txtscript     ! a long string to store gnuplot script
        character(len=:), allocatable  :: txtdatastyle  ! lines, points, linepoints

        logical :: hasxrange      = .false.
        logical :: hasx2range     = .false.
        logical :: hasyrange      = .false.
        logical :: hasy2range     = .false.
        logical :: haszrange      = .false.
        logical :: hasoptions     = .false.
        logical :: hasanimation   = .false.
        logical :: hasfilename    = .false.
        logical :: hasfileopen    = .false.

        real(wp)           :: xrange(2), yrange(2), zrange(2)
        real(wp)           :: x2range(2), y2range(2)
        character(len=8)   :: plotscale


        ! multiplot parameters
        logical :: hasmultiplot = .false.
        integer :: multiplot_rows
        integer :: multiplot_cols
        integer :: multiplot_total_plots

        ! animation
        real                            :: pause_seconds = 0  ! keep plot on screen for this value in seconds
        integer                         :: frame_number   ! frame number in animation

        ! use for debugging and error handling
        character(len=:), allocatable   :: msg      !Message from plot procedures
        integer                         :: status=0 !Status from plot procedures

        !
        integer                         :: file_unit      ! file unit identifier
        character(len=:), allocatable   :: txtfilename    ! the name of physical file
                                                          ! to write the gnuplot script


        ! ogpf preset configuration (kind of gnuplot initialization)
        logical :: preset_configuration = .true.


    contains

        private

        ! local private procedures
        procedure, pass, private :: preset_gnuplot_config

        procedure, pass, private :: plot2d_vector_vs_vector
        procedure, pass, private :: plot2d_matrix_vs_vector
        procedure, pass, private :: plot2d_matrix_vs_matrix

        procedure, pass, private :: semilogxv
        procedure, pass, private :: semilogxm
        procedure, pass, private :: semilogyv
        procedure, pass, private :: semilogym
        procedure, pass, private :: loglogv
        procedure, pass, private :: loglogm

        !> 0.22
        procedure, pass, private :: set_label

        ! public procedures
        procedure, pass, public :: options      => set_options
        procedure, pass, public :: title        => set_plottitle
        procedure, pass, public :: xlabel       => set_xlabel
        procedure, pass, public :: x2label      => set_x2label
        procedure, pass, public :: ylabel       => set_ylabel
        procedure, pass, public :: y2label      => set_y2label
        procedure, pass, public :: zlabel       => set_zlabel
        procedure, pass, public :: axis         => set_axis
        procedure, pass, public :: axis_sc      => set_secondary_axis
        procedure, pass, public :: xlim         => set_xlim
        procedure, pass, public :: ylim         => set_ylim
        procedure, pass, public :: zlim         => set_zlim
        procedure, pass, public :: filename     => set_filename
        procedure, pass, public :: reset        => reset_to_defaults
        procedure, pass, public :: preset       => use_preset_configuration


        procedure, pass, public :: multiplot  => sub_multiplot
        generic, public         :: plot       => plot2d_vector_vs_vector, &
                                                 plot2d_matrix_vs_vector, &
                                                 plot2d_matrix_vs_matrix
        generic, public         :: semilogx   => semilogxv, semilogxm
        generic, public         :: semilogy   => semilogyv, semilogym
        generic, public         :: loglog     => loglogv, loglogm

        procedure, pass, public :: surf       => splot  ! 3D surface plot
        procedure, pass, public :: lplot      => lplot3d  ! 3D line plot
        procedure, pass, public :: contour    => cplot  ! contour plot

        procedure, pass, public :: fplot      => function_plot

        procedure, pass, public :: add_script => addscript
        procedure, pass, public :: run_script => runscript

        procedure, pass, public :: animation_start => sub_animation_start
        procedure, pass, public :: animation_show  => sub_animation_show

    end type gpf


contains

    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section One: Set/Get Methods for ogpf object
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    subroutine use_preset_configuration(this,flag)
        !..............................................................................
        !Set a flag to tell ogpf if the customized gnuplot configuration should
        !be used
        !..............................................................................

        class(gpf):: this
        logical, intent(in) :: flag

        ! default is true
        this%preset_configuration = flag

    end subroutine use_preset_configuration



    subroutine set_filename(this,string)
        !..............................................................................
        !Set a file name for plot command output
        !This file can be used later by gnuplot as an script file to reproduce the plot
        !..............................................................................

        class(gpf):: this
        character(len=*), intent(in) :: string

        this%txtfilename = trim(string)
        this%hasfilename = .true.

    end subroutine set_filename


    subroutine set_options(this,stropt)
        !..............................................................................
        ! Set the plot options. This is a very powerfull procedure accepts many types
        ! of gnuplot command and customization
        !..............................................................................

        class(gpf):: this
        character(len=*), intent(in) :: stropt

        if(.not.allocated(this%txtoptions))this%txtoptions=''
        if (len_trim(this%txtoptions) == 0 ) then
            this%txtoptions = '' ! initialize string
        end if
        if ( len_trim(stropt)>0 ) then
            this%txtoptions = this%txtoptions // splitstr(stropt)
          end if

        this%hasoptions=.true.

    end subroutine set_options


    subroutine set_xlim(this,rng)
        !..............................................................................
        !Set the x axis limits in form of [xmin, xmax]
        !..............................................................................

        class(gpf):: this
        real(wp), intent(in) :: rng(2)
        this%hasxrange=.true.
        this%xrange=rng

    end subroutine


    subroutine set_ylim(this,rng)
        !..............................................................................
        !Set the y axis limits in form of [ymin, ymax]
        !..............................................................................

        class(gpf):: this
        real(wp), intent(in) :: rng(2)
        this%hasyrange=.true.
        this%yrange=rng

    end subroutine


    subroutine set_zlim(this,rng)
        !..............................................................................
        !Set the z axis limits in form of [zmin, zmax]
        !..............................................................................

        class(gpf):: this
        real(wp), intent(in) :: rng(2)
        this%haszrange=.true.
        this%zrange=rng

    end subroutine


    subroutine set_axis(this,rng)
        !..............................................................................
        !Set the axes limits in form of [xmin, xmax, ymin, ymax, zmin, zmax]
        !..............................................................................

        class(gpf):: this
        real(wp), intent(in) :: rng(:)
        integer :: n
        n=size(rng,dim=1)
        select case(n)
            case(2) !Only the range for x-axis has been sent
                this%hasxrange=.true.
                this%xrange=rng(1:2)
            case(4)
                this%hasxrange=.true.
                this%hasyrange=.true.
                this%xrange=rng(1:2)
                this%yrange=rng(3:4)
            case(6)
                this%hasxrange=.true.
                this%hasyrange=.true.
                this%haszrange=.true.
                this%xrange=rng(1:2)
                this%yrange=rng(3:4)
                this%zrange=rng(5:6)
            case default
                print*, 'gpf error: wrong axis range setting!'
                return
        end select

    end subroutine set_axis


    subroutine set_secondary_axis(this,rng)
        !..............................................................................
        !Set the secondary axes limits in form of [x2min, x2max, y2min, y2max]
        !..............................................................................

        class(gpf):: this
        real(wp), intent(in) :: rng(:)
        integer :: n
        n=size(rng,dim=1)
        select case(n)
            case(2) !Only the range for x2-axis has been sent
                this%hasx2range=.true.
                this%x2range=rng(1:2)
            case(4)
                this%hasx2range=.true.
                this%hasy2range=.true.
                this%x2range=rng(1:2)
                this%y2range=rng(3:4)
            case default
                print*, 'gpf error: wrong axis range setting!'
                return
        end select

    end subroutine set_secondary_axis


    subroutine set_plottitle(this, string, textcolor, font_size, font_name, rotate)
        !..............................................................................
        !Set the plot title
        !..............................................................................
        class(gpf):: this
        character(len=*), intent(in)           :: string
        character(len=*), intent(in), optional :: textcolor
        integer, optional                      :: font_size
        character(len=*), intent(in), optional :: font_name
        integer, optional                      :: rotate

        call this%set_label('plot_title', string, textcolor, font_size, font_name, rotate)

    end subroutine set_plottitle


    subroutine set_xlabel(this, string, textcolor, font_size, font_name, rotate)
        !..............................................................................
        !Set the xlabel
        !..............................................................................
        class(gpf):: this
        character(len=*), intent(in)           :: string
        character(len=*), intent(in), optional :: textcolor
        integer, optional                      :: font_size
        character(len=*), intent(in), optional :: font_name
        integer, optional                      :: rotate

        call this%set_label('xlabel', string, textcolor, font_size, font_name, rotate)

    end subroutine set_xlabel


    subroutine set_x2label(this, string, textcolor, font_size, font_name, rotate)
        !..............................................................................
        !Set the x2label
        !..............................................................................
        class(gpf):: this
        character(len=*), intent(in)           :: string
        character(len=*), intent(in), optional :: textcolor
        integer, optional                      :: font_size
        character(len=*), intent(in), optional :: font_name
        integer, optional                      :: rotate

        call this%set_label('x2label', string, textcolor, font_size, font_name, rotate)

    end subroutine set_x2label


    subroutine set_ylabel(this, string, textcolor, font_size, font_name, rotate)
        !..............................................................................
        !Set the ylabel
        !..............................................................................
        class(gpf):: this
        character(len=*), intent(in)           :: string
        character(len=*), intent(in), optional :: textcolor
        integer, optional                      :: font_size
        character(len=*), intent(in), optional :: font_name
        integer, optional                      :: rotate

        call this%set_label('ylabel', string, textcolor, font_size, font_name, rotate)

    end subroutine set_ylabel



    subroutine set_y2label(this, string, textcolor, font_size, font_name, rotate)
        !..............................................................................
        !Set the y2label
        !..............................................................................
        class(gpf):: this
        character(len=*), intent(in)           :: string
        character(len=*), intent(in), optional :: textcolor
        integer, optional                      :: font_size
        character(len=*), intent(in), optional :: font_name
        integer, optional                      :: rotate

        call this%set_label('y2label', string, textcolor, font_size, font_name, rotate)

    end subroutine set_y2label


    subroutine set_zlabel(this, string, textcolor, font_size, font_name, rotate)
        !..............................................................................
        !Set the zlabel
        !..............................................................................
        class(gpf):: this
        character(len=*), intent(in)           :: string
        character(len=*), intent(in), optional :: textcolor
        integer, optional                      :: font_size
        character(len=*), intent(in), optional :: font_name
        integer, optional                      :: rotate

        call this%set_label('zlabel', string, textcolor, font_size, font_name, rotate)

    end subroutine set_zlabel


    !> 0.22

    subroutine set_label(this, lblname, lbltext, lblcolor, font_size, font_name, rotate)
        !..............................................................................
        ! Set the text, color, font, size and rotation for labels including
        ! title, xlabel, x2label, ylabel, ....
        !..............................................................................

        class(gpf):: this
        character(len=*), intent(in)           :: lblname
        character(len=*), intent(in)           :: lbltext
        character(len=*), intent(in), optional :: lblcolor
        character(len=*), intent(in), optional :: font_name
        integer, optional :: font_size
        integer, optional                      :: rotate

        ! local variable
        type(tplabel) :: label

        label%has_label = .true.
        label%lbltext   = trim(lbltext)

        if (present(lblcolor)) then
            label%lblcolor = lblcolor
        end if

        if (present(font_name)) then
            label%lblfontname = font_name
        else
            if(.not.allocated(label%lblfontname))then
                label%lblfontname = ''
            endif
        end if

        if (present(font_size)) then
            label%lblfontsize = font_size
        end if

        if (present(rotate)) then
            label%lblrotate = rotate
        end if

        select case (lblname)
            case ('xlabel')
                this%tpxlabel     = label
            case ('x2label')
                this%tpx2label    = label
            case ('ylabel')
                this%tpylabel     = label
            case ('y2label')
                this%tpy2label    = label
            case ('zlabel')
                this%tpzlabel     = label
            case ('plot_title')
                this%tpplottitle  = label
        end select


    end subroutine set_label



    subroutine reset_to_defaults(this)
        !..............................................................................
        !Reset all ogpf properties (params to their default values
        !...............................................................................
        class(gpf):: this

        this%preset_configuration    = .true.
        this%txtfilename             = gnuplot_output_filename

        if (allocated(this%txtoptions))    deallocate(this%txtoptions)
        if (allocated(this%txtscript))     deallocate(this%txtscript)
        if (allocated(this%txtdatastyle))  deallocate(this%txtdatastyle)
        if (allocated(this%msg))           deallocate(this%msg)

        this%hasoptions            = .false.

        this%hasxrange             = .false.
        this%hasx2range            = .false.
        this%hasyrange             = .false.
        this%hasy2range            = .false.
        this%haszrange             = .false.

        this%pause_seconds         = 0.0
        this%status                = 0
        this%hasanimation          = .false.
        this%hasfileopen           = .false.
        this%hasmultiplot          = .false.

        this%plotscale             = ''
        this%tpplottitle%has_label =.false.
        this%tpxlabel%has_label    =.false.
        this%tpx2label%has_label   =.false.
        this%tpylabel%has_label    =.false.
        this%tpy2label%has_label   =.false.
        this%tpzlabel%has_label    =.false.


    end subroutine reset_to_defaults


    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section Two: Main Plotting Routines
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    subroutine sub_multiplot(this, rows, cols)
        !..............................................................................
        ! This subroutine sets flag and number of rows and columns in case
        ! of multiplot layout
        !..............................................................................

        class(gpf):: this
        integer, intent(in) :: rows
        integer, intent(in) :: cols

        ! ogpf does not support multiplot in animation mode
        if (this%hasanimation) then
            print*, md_name // ': ogpf does not support animation in multiplot mode'
            stop
        end if

        ! set multiplot cols and rows
        if (rows> 0 ) then
            this%multiplot_rows = rows
        else

        end if
        if (cols > 0 ) then
            this%multiplot_cols = cols
        else

        end if

        ! set the multiplot layout flag and plot numbers
        this%hasmultiplot = .true.
        this%multiplot_total_plots = 0

        ! create the ouput file for writting gnuplot script
        call create_outputfile(this)


    end subroutine sub_multiplot


    subroutine plot2d_vector_vs_vector(this, x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4, axes4  )
        !..............................................................................
        ! This procedure plots:
        !   1. A vector against another vector (xy plot)
        !   2. A vector versus its element indices (yi plot).
        !   3. Can accept up to 4 data sets as x,y pairs!
        ! Arguments
        ! xi, yi vectors of data series,
        ! lsi a string maximum 80 characters containing the line specification,
        ! legends, ...
        ! axesi is the axes for plotting: secondary axes are x2, and y2
        !..............................................................................

        class(gpf):: this
        ! Input vector
        real(wp),  intent(in)                          :: x1(:)  ! vector of data for x
        real(wp),  intent(in), optional                :: y1(:)  ! vector of data for y
        character(len=*),  intent(in), optional        :: ls1    ! line specification
        character(len=*),  intent(in), optional        :: axes1

        real(wp),  intent(in), dimension(:), optional  :: x2
        real(wp),  intent(in), dimension(:), optional  :: y2
        character(len=*),  intent(in), optional        :: ls2
        character(len=*),  intent(in), optional        :: axes2

        real(wp),  intent(in), dimension(:), optional  :: x3
        real(wp),  intent(in), dimension(:), optional  :: y3
        character(len=*),  intent(in), optional        :: ls3
        character(len=*),  intent(in), optional        :: axes3

        real(wp),  intent(in), dimension(:), optional  :: x4
        real(wp),  intent(in), dimension(:), optional  :: y4
        character(len=*),  intent(in), optional        :: ls4
        character(len=*),  intent(in), optional        :: axes4

        !   Local variables
        !----------------------------------------------------------------------

        integer:: nx1
        integer:: ny1
        integer:: nx2
        integer:: ny2
        integer:: nx3
        integer:: ny3
        integer:: nx4
        integer:: ny4
        integer::           number_of_plots
        character(len=3)::  plottype
        integer:: i
        character(len=80) ::  pltstring(4)  ! Four 80 characters string

        !Initialize variables
        plottype  = ''
        pltstring = ''

        !   Check the input
        nx1=size(x1)
        if ((present(y1) )) then
            ny1=size(y1)
            if (checkdim(nx1,ny1)) then
                plottype='xy1'
                number_of_plots=1
            else
                print*, md_name // ':plot2d_vector_vs_vector:' // 'length of x1 and y1 does not match'
                return
            end if
        else !plot only x againest its element indices
            plottype='xi'
            number_of_plots=1
        end if

        !Process line spec and axes set for first data set if present
        call process_linespec(1, pltstring(1), ls1, axes1)


        if (present(x2) .and. present (y2)) then
            nx2=size(x2)
            ny2=size(y2)
            if (checkdim(nx2,ny2)) then
                plottype='xy2'
                number_of_plots=2
            else
                return
            end if
            !Process line spec for 2nd data set if present
            call process_linespec(2, pltstring(2), ls2, axes2)
        end if

        if (present(x3) .and. present (y3)) then
            nx3=size(x3)
            ny3=size(y3)
            if (checkdim(nx3,ny3)) then
                plottype='xy3'
                number_of_plots=3
            else
                return
            end if
            !Process line spec for 3rd data set if present
            call process_linespec(3, pltstring(3), ls3, axes3)
        end if

        if (present(x4) .and. present (y4)) then
            nx4=size(x4)
            ny4=size(y4)
            if (checkdim(nx4,ny4)) then
                plottype='xy4'
                number_of_plots=4
            else
                return
            end if
            !Process line spec for 4th data set if present
            call process_linespec(4, pltstring(4), ls4, axes4)
        end if


        call create_outputfile(this)

        ! Write plot title, axis labels and other annotations
        call processcmd(this)

        ! Write plot command and line styles and legend if any
        if (number_of_plots ==1) then
            write ( this%file_unit, '(a)' )  trim(pltstring(1))
        else
            write ( this%file_unit, '(a)' )  ( trim(pltstring(i)) // ' \' , i=1, number_of_plots-1)
            write ( this%file_unit, '(a)' )  trim(pltstring(number_of_plots))
        end if
        ! Write xy data into file
        select case (plottype)
            case ('xi')
                call write_xydata(this%file_unit,nx1,x1)
            case ('xy1')
                call write_xydata(this%file_unit,nx1,x1,y1)
            case ('xy2')
                call write_xydata(this%file_unit,nx1,x1,y1)
                call write_xydata(this%file_unit,nx2,x2,y2)
            case ('xy3')
                call write_xydata(this%file_unit,nx1,x1,y1)
                call write_xydata(this%file_unit,nx2,x2,y2)
                call write_xydata(this%file_unit,nx3,x3,y3)
            case ('xy4')
                call write_xydata(this%file_unit,nx1,x1,y1)
                call write_xydata(this%file_unit,nx2,x2,y2)
                call write_xydata(this%file_unit,nx3,x3,y3)
                call write_xydata(this%file_unit,nx4,x4,y4)
        end select

        !> Rev 0.2
        ! if there is no animation finalize
        if (.not. (this%hasanimation)) then
            call finalize_plot(this)
        else
            write(this%file_unit, '(a, F5.2)') 'pause ', this%pause_seconds
        end if


        !: End of plot2D_vector_vs_vector
    end subroutine plot2d_vector_vs_vector



    subroutine  plot2d_matrix_vs_vector(this, xv,ymat, lspec)
        !..............................................................................
        ! plot2D_matrix_vs_vector accepts a vector xv and a matrix ymat and plots
        ! columns of ymat against xv. lspec is an optional array defines the line
        ! specification for each data series. If a single element array is sent for
        ! lspec then all series are plotted using the same linespec
        !..............................................................................

        implicit none
        class(gpf):: this
        ! Input arrays
        real(wp),  intent(in)                       :: xv(:)
        real(wp),  intent(in)                       :: ymat(:,:)
        character(len=*),  intent(in), optional     :: lspec
        !----------------------------------------------------------------------
        !       Local variables
        integer:: nx
        integer:: ny
        integer:: ns
        integer:: number_of_curves
        integer:: i
        integer:: j
        integer:: ierr
        character(len=80), allocatable ::  pltstring(:), lst(:)
        !

        !*******************************************************************************
        !   Check the input
        nx=size(xv)
        ny=size(ymat,dim=1)
        if (.not. checkdim(nx,ny)) then
            print*, md_name // ':plot2d_matrix_vs_vector:' // 'The length of arrays does not match'
            return
        end if
        ! create the outfile to write the gnuplot script
        call create_outputfile(this)

        ! Write titles and other annotations
        call processcmd(this)

        ! Write plot command and line styles and legend if any
        number_of_curves=size(ymat,dim=2)
        allocate(pltstring(number_of_curves), stat=ierr)
        if (ierr /=0) then
            print*, 'allocation error'
            return
        end if

        ! assume no linespec is available
        pltstring(1:number_of_curves) = ''

        if ( present(lspec) ) then

            call splitstring2array(lspec,lst,';')
            ns = size(lst, dim=1)

            if (ns == number_of_curves) then
                ! there is a linespec for each curve
                pltstring = lst
            elseif (ns < number_of_curves) then
                ! not enough linespec
                do i=1, ns
                    pltstring(i) = lst(i)
                end do
            else ! ns > number_of curves
                print*, 'ogpf: plot2d_matrix_vs_vector: wrong number of linespec'
                print*, 'semicolon ";" acts as delimiter, check the linespec'
            end if
        end if

        if ( present(lspec) ) then

            call process_linespec(1,pltstring(1),lst(1))
            ns=size(lst)
            ! gpf will cylce through line specification, if number of specification passed
            ! is less than number of plots
            do i=1, number_of_curves
                j=mod(i-1, ns) + 1
                call process_linespec(i, pltstring(i), lst(j))
            end do
        else !No lspec is available
            pltstring(1)=' plot "-" notitle,'
            pltstring(2:number_of_curves-1)='"-" notitle,'
            pltstring(number_of_curves)='"-" notitle'
        end if

        ! Write plot command and line styles and legend if any
        write ( this%file_unit, '(a)' ) ( trim(pltstring(i)) // ' \' , i=1, number_of_curves-1)
        write ( this%file_unit, '(a)' )   trim(pltstring(number_of_curves))

        ! Write data into script file
        do j=1, number_of_curves
            do i = 1, nx
                write ( this%file_unit, * ) xv(i),ymat(i,j)
            end do
            write ( this%file_unit, '(a)' ) 'e'  !end of jth set of data
        end do


        !> Rev 0.2
        ! if there is no animation finalize
        if (.not. (this%hasanimation)) then
            call finalize_plot(this)
        else
            write(this%file_unit, '(a, F5.2)') 'pause ', this%pause_seconds
        end if

        !Release memory
        if (allocated(pltstring)) then
            deallocate(pltstring)
        end if
        !: End of plot2D_matrix_vs_vector
    end subroutine  plot2d_matrix_vs_vector



    subroutine  plot2d_matrix_vs_matrix(this, xmat,ymat, lspec)
        !..............................................................................
        ! plot2D_matrix_vs_matrix accepts a matrix xmat and a matrix ymat and plots
        ! columns of ymat against columns of xmat. lspec is an optional array defines
        ! the line specification for each data series. If a single element array is
        ! sent for lspec then all series are plotted using the same linespec
        !..............................................................................

        implicit none
        class(gpf):: this
        ! Input arrays
        real(wp),  intent(in)                       :: xmat(:,:)
        real(wp),  intent(in)                       :: ymat(:,:)
        character(len=*),  intent(in), optional     :: lspec
        !----------------------------------------------------------------------
        !       Local variables
        integer:: mx, nx
        integer:: my, ny
        integer:: ns
        integer:: number_of_curves
        integer:: i
        integer:: j
        integer:: ierr
        character(len=80), allocatable ::  pltstring(:), lst(:)
        !

        !*******************************************************************************
        !   Check the input
        ! check number of rows
        mx=size(xmat,dim=1)
        my=size(ymat,dim=1)
        if (.not. checkdim(mx,my)) then
            print*, md_name // ':plot2d_matrix_vs_matrix:' // 'The length of arrays does not match'
            return
        end if
        ! check number of rows
        nx=size(xmat,dim=2)
        ny=size(ymat,dim=2)
        if (.not. checkdim(nx,ny)) then
            print*, 'gpf error: The number of columns are different, check xmat, ymat'
            return
        end if


        ! create the outfile to write the gnuplot script
        call create_outputfile(this)

        ! Write titles and other annotations
        call processcmd(this)

        ! Write plot command and line styles and legend if any
        number_of_curves=size(ymat,dim=2)
        allocate(pltstring(number_of_curves), stat=ierr)
        if (ierr /=0) then
            print*, 'allocation error'
            return
        end if

        ! assume no linespec is available
        pltstring(1:number_of_curves) = ''

        if ( present(lspec) ) then

            call splitstring2array(lspec,lst,';')
            ns = size(lst, dim=1)

            if (ns == number_of_curves) then
                ! there is a linespec for each curve
                pltstring = lst
            elseif (ns < number_of_curves) then
                ! not enough linespec
                do i=1, ns
                    pltstring(i) = lst(i)
                end do
            else ! ns > number_of curves
                print*, md_name // ': plot2d_matrix_vs_matrix:'//' wrong number of linespec'
                print*, 'semicolon ";" acts as delimiter, check the linespec'
            end if
        end if

        if ( present(lspec) ) then

            call process_linespec(1,pltstring(1),lst(1))
            ns=size(lst)
            ! gpf will cylce through line specification, if number of specification passed
            ! is less than number of plots
            do i=1, number_of_curves
                j=mod(i-1, ns) + 1
                call process_linespec(i, pltstring(i), lst(j))
            end do
        else !No lspec is available
            pltstring(1)=' plot "-" notitle,'
            pltstring(2:number_of_curves-1)='"-" notitle,'
            pltstring(number_of_curves)='"-" notitle'
        end if

        ! Write plot command and line styles and legend if any
        write ( this%file_unit, '(a)' ) ( trim(pltstring(i)) // ' \' , i=1, number_of_curves-1)
        write ( this%file_unit, '(a)' )   trim(pltstring(number_of_curves))

        ! Write data into script file
        do j=1, number_of_curves
            do i = 1, mx
                write ( this%file_unit, * ) xmat(i,j),ymat(i,j)
            end do
            write ( this%file_unit, '(a)' ) 'e'  !end of jth set of data
        end do

        !> Rev 0.2
        ! if there is no animation finalize
        if (.not. (this%hasanimation)) then
            call finalize_plot(this)
        else
            write(this%file_unit, '(a, F5.2)') 'pause ', this%pause_seconds
        end if

        !Release memory
        if (allocated(pltstring)) then
            deallocate(pltstring)
        end if
        !: End of plot2D_matrix_vs_vector
    end subroutine  plot2d_matrix_vs_matrix


    subroutine splot(this, x, y, z, lspec, palette)
        !..............................................................................
        ! splot create a surface plot
        ! datablock is used instead of  gnuplot inline file "-"
        !..............................................................................

        class(gpf):: this
        ! Input vector
        real(wp),  intent(in)            :: x(:,:)
        real(wp),  intent(in), optional  :: y(:,:)
        real(wp),  intent(in), optional  :: z(:,:)
        character(len=*),  intent(in), optional   ::  lspec
        character(len=*),  intent(in), optional   ::  palette

        !   Local variables
        !----------------------------------------------------------------------
        integer:: ncx
        integer:: nrx
        integer:: i
        integer:: j
        logical:: xyz_data
        character(len=80)::  pltstring
        character(len=*), parameter ::  datablock = '$xyz'

        pltstring=''
        !   Check the input data
        ncx=size(x,dim=2)
        nrx=size(x,dim=1)
        if (present(y) .and. present(z)) then
            xyz_data=.true.
        elseif (present(y)) then
            print*, "gpf error: Z matrix was not sent to 3D plot routine"
            return
        else
            xyz_data=.false.
        end if

        ! set default line style for 3D plot, can be overwritten
        this%txtdatastyle = 'lines'
        ! create the script file for writting gnuplot commands and data
        call create_outputfile(this)

        ! Write titles and other annotations
        call processcmd(this)

        ! Write xy data into file
        write ( this%file_unit, '(a)' ) '#data x y z'
        ! Rev 0.20
        ! write the $xyz datablocks
        write( this%file_unit, '(a)' )  datablock // ' << EOD'
        if (xyz_data) then
            do j=1,ncx
                do i=1, nrx
                    write ( this%file_unit, * ) x(i,j), y(i,j), z(i,j)
                enddo
                write( this%file_unit, '(a)' )  !put an empty line
            enddo
            write ( this%file_unit, '(a)' ) 'EOD'  !end of datablock
        else !only Z has been sent (i.e. single matrix data)
            do j=1,ncx
                do i=1, nrx
                    write ( this%file_unit, * ) i, j, x(i,j)
                enddo
                write( this%file_unit, '(a)' )  !put an empty line
            enddo
            write ( this%file_unit, '(a)' ) 'EOD'  !end of datablock
        end if


        !write the color palette into gnuplot script file
        if (present(palette)) then
            write ( this%file_unit, '(a)' )  color_palettes(palette)
            write ( this%file_unit, '(a)' )  'set pm3d' ! a conflict with lspec
        end if


        if ( present(lspec) ) then
            if (hastitle(lspec)) then
                pltstring='splot ' // datablock // ' ' // trim(lspec)
            else
                pltstring='splot ' // datablock // ' notitle '//trim(lspec)
            end if
        else
            pltstring='splot ' // datablock // ' notitle '
        end if

        write ( this%file_unit, '(a)' ) trim(pltstring)


        !> Rev 0.2: animation
        ! if there is no animation finalize
        if (.not. (this%hasanimation)) then
            call finalize_plot(this)
        else
            write(this%file_unit, '(a, F5.2)') 'pause ', this%pause_seconds
        end if

        !: End of splot
    end subroutine splot


    subroutine cplot(this, x, y, z, lspec, palette)
        !..............................................................................
        !   Rev 0.19
        !   cplot creates a contour plot based on the three dimensional data
        !..............................................................................

        class(gpf):: this
        ! Input vector
        real(wp),  intent(in)            :: x(:,:)
        real(wp),  intent(in), optional  :: y(:,:)
        real(wp),  intent(in), optional  :: z(:,:)
        character(len=*),  intent(in), optional   ::  lspec
        character(len=*),  intent(in), optional   ::  palette

        !   Local variables
        !----------------------------------------------------------------------

        integer:: ncx
        integer:: nrx
        integer:: i
        integer:: j
        logical:: xyz_data
        character(len=80)::  pltstring
        character(len=*), parameter ::  datablock  = '$xyz'
        !       character(len=*), parameter ::  cntr_table = '$xyz_contour'

        pltstring=''
        !   Check the input data
        ncx=size(x,dim=2)
        nrx=size(x,dim=1)
        if (present(y) .and. present(z)) then
            xyz_data=.true.
        elseif (present(y)) then
            print*, "gpf error: Z matrix was not sent to 3D plot routine"
            return
        else
            xyz_data=.false.
        end if

        ! set default line style for 3D plot, can be overwritten
        this%txtdatastyle = 'lines'
        ! create the script file for writting gnuplot commands and data
        call create_outputfile(this)

        ! Write titles and other annotations
        call processcmd(this)

        ! Write xy data into file
        write ( this%file_unit, '(a)' ) '#data x y z'
        ! write the $xyz datablocks
        write( this%file_unit, '(a)' )  datablock // ' << EOD'
        if (xyz_data) then
            do j=1,ncx
                do i=1, nrx
                    write ( this%file_unit, fmt=* ) x(i,j), y(i,j), z(i,j)
                enddo
                write( this%file_unit, '(a)' )  !put an empty line
            enddo
            write ( this%file_unit, '(a)' ) 'EOD'  !end of datablock
        else !only Z has been sent (i.e. single matrix data)
            do j=1,ncx
                do i=1, nrx
                    write ( this%file_unit, fmt=* ) i, j, x(i,j)
                enddo
                write( this%file_unit, '(a)' )  !put an empty line
            enddo
            write ( this%file_unit, '(a)' ) 'EOD'  !end of datablock
        end if


        ! create the contour lines
        write ( this%file_unit, '(a)' ) ! empty line
        write ( this%file_unit, '(a)' ) '# create the contour'
        write ( this%file_unit, '(a)' ) 'set contour base'
        write ( this%file_unit, '(a)' ) 'set cntrparam levels 14'
        write ( this%file_unit, '(a)' ) 'unset surface'
        write ( this%file_unit, '(a)' ) 'set view map'


        !write the color palette into gnuplot script file
        if (present(palette)) then
            write ( this%file_unit, '(a)' )  color_palettes(palette)
            write ( this%file_unit, '(a)' )  'set pm3d' ! a conflict with lspec
        end if


        write ( this%file_unit, '(a)' ) ! empty line

        if ( present(lspec) ) then
            if (hastitle(lspec)) then
                pltstring='splot ' // datablock // ' ' // trim(lspec)
            else
                pltstring='splot ' // datablock // ' notitle '//trim(lspec)
            end if
        else
            pltstring='splot ' // datablock // ' notitle '
        end if

        write ( this%file_unit, '(a)' ) trim(pltstring)

        !> Rev 0.20
        ! if there is no animation finalize
        if (.not. (this%hasanimation)) then
            call finalize_plot(this)
        else
            write(this%file_unit, '(a, F5.2)') 'pause ', this%pause_seconds
        end if

        !: End of cplot
    end subroutine cplot

     subroutine lplot3d(this, x, y, z, lspec, palette)
         !..............................................................................
         ! lplot3d create a line plot in 3d
         ! datablock is used instead of  gnuplot inline file "-"
         !..............................................................................

         class(gpf):: this
         ! Input vector
         real(wp),  intent(in)            :: x(:)
         real(wp),  intent(in), optional  :: y(:)
         real(wp),  intent(in), optional  :: z(:)
         character(len=*),  intent(in), optional   ::  lspec
         character(len=*),  intent(in), optional   ::  palette

         !   Local variables
         !----------------------------------------------------------------------
         integer:: nrx
         integer:: i
         logical:: xyz_data
         character(len=80)::  pltstring
         character(len=*), parameter ::  datablock = '$xyz'

         pltstring=''
         !   Check the input data
         nrx=size(x)
         if (present(y) .and. present(z)) then
             xyz_data=.true.
         elseif (present(y)) then
             print*, "gpf error: Z matrix was not sent to 3D plot routine"
             return
         else
             xyz_data=.false.
         end if

         ! set default line style for 3D plot, can be overwritten
         this%txtdatastyle = 'lines'
         ! create the script file for writing gnuplot commands and data
         call create_outputfile(this)

         ! Write titles and other annotations
         call processcmd(this)

         ! Write xy data into file
         write ( this%file_unit, '(a)' ) '#data x y z'
         ! Rev 0.20
         ! write the $xyz datablocks
         write( this%file_unit, '(a)' )  datablock // ' << EOD'
         if (xyz_data) then
             do i=1, nrx
                 write ( this%file_unit, * ) x(i), y(i), z(i)
             enddo
             write( this%file_unit, '(a)' )  !put an empty line
             write ( this%file_unit, '(a)' ) 'EOD'  !end of datablock
         else !only Z has been sent (i.e. single matrix data)
             do i=1, nrx
                 write ( this%file_unit, * ) i, x(i)
             enddo
             write( this%file_unit, '(a)' )  !put an empty line
             write ( this%file_unit, '(a)' ) 'EOD'  !end of datablock
         end if


         !write the color palette into gnuplot script file
         if (present(palette)) then
             write ( this%file_unit, '(a)' )  color_palettes(palette)
             write ( this%file_unit, '(a)' )  'set pm3d' ! a conflict with lspec
         end if


         if ( present(lspec) ) then
             if (hastitle(lspec)) then
                 pltstring='splot ' // datablock // ' ' // trim(lspec) // 'with lines'
             else
                 pltstring='splot ' // datablock // ' notitle '//trim(lspec) // 'with lines'
             end if
         else
             pltstring='splot ' // datablock // ' notitle with lines'
         end if

         write ( this%file_unit, '(a)' ) trim(pltstring)


         !> Rev 0.2: animation
         ! if there is no animation finalize
         if (.not. (this%hasanimation)) then
             call finalize_plot(this)
         else
             write(this%file_unit, '(a, F5.2)') 'pause ', this%pause_seconds
         end if

         !: End of lplot3d
     end subroutine lplot3d

    subroutine function_plot(this, func,xrange,np)
        !..............................................................................
        ! fplot, plot a function in the range xrange=[xmin, xamx] with np points
        ! if np is not sent, then np=50 is assumed!
        ! func is the name of function to be plotted
        !..............................................................................

        class(gpf):: this
        interface
            function func(x)
                import :: wp
                real(wp), intent(in) :: x
                real(wp) :: func
            end function func
        end interface
        real(wp), intent(in) :: xrange(2)
        integer, optional, intent(in):: np

        integer:: n
        integer:: i
        integer:: alloc_err
        real(wp), allocatable :: x(:)
        real(wp), allocatable :: y(:)

        if (present(np)) then
            n=np
        else
            n=50
        end if
        allocate(x(1:n), y(1:n), stat=alloc_err)
        if (alloc_err /=0) then
            stop "Allocation error in fplot procedure..."
        end if
        !Create set of xy data
        x=linspace(xrange(1),xrange(2), n)
        y=[ (func(x(i)), i=1, n) ]

        call plot2d_vector_vs_vector(this,x,y)

        ! cleanup memory
        if (allocated(x)) deallocate(x)
        if (allocated(y)) deallocate(y)


    end subroutine function_plot


    subroutine semilogxv(this, x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4, axes4  )
        !..............................................................................
        !   This procedure is the same as plotXY with logarithmic x1 and x2 axes
        !..............................................................................

        class(gpf):: this
        ! Input vector
        real(wp),  intent(in)                          :: x1(:)  ! vector of data for x
        real(wp),  intent(in), optional                :: y1(:)  ! vector of data for y
        character(len=*),  intent(in), optional        :: ls1    ! line specification
        character(len=*),  intent(in), optional        :: axes1

        real(wp),  intent(in), dimension(:), optional  :: x2
        real(wp),  intent(in), dimension(:), optional  :: y2
        character(len=*),  intent(in), optional        :: ls2
        character(len=*),  intent(in), optional        :: axes2

        real(wp),  intent(in), dimension(:), optional  :: x3
        real(wp),  intent(in), dimension(:), optional  :: y3
        character(len=*),  intent(in), optional        :: ls3
        character(len=*),  intent(in), optional        :: axes3

        real(wp),  intent(in), dimension(:), optional  :: x4
        real(wp),  intent(in), dimension(:), optional  :: y4
        character(len=*),  intent(in), optional        :: ls4
        character(len=*),  intent(in), optional        :: axes4
        this%plotscale='semilogx'
        call plot2d_vector_vs_vector(this, &
            x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4, axes4  )
        ! Set the plot scale as linear. It means log scale is off
        this%plotscale='linear'

    end subroutine semilogxv


    !..............................................................................
    subroutine semilogyv(this, x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4,axes4  )
        !..............................................................................
        !   This procedure is the same as plotXY with logarithmic y1 and y2 axes
        !..............................................................................

        class(gpf):: this
        ! Input vector
        real(wp),  intent(in)                          :: x1(:)  ! vector of data for x
        real(wp),  intent(in), optional                :: y1(:)  ! vector of data for y
        character(len=*),  intent(in), optional        :: ls1    ! line specification
        character(len=*),  intent(in), optional        :: axes1

        real(wp),  intent(in), dimension(:), optional  :: x2
        real(wp),  intent(in), dimension(:), optional  :: y2
        character(len=*),  intent(in), optional        :: ls2
        character(len=*),  intent(in), optional        :: axes2

        real(wp),  intent(in), dimension(:), optional  :: x3
        real(wp),  intent(in), dimension(:), optional  :: y3
        character(len=*),  intent(in), optional        :: ls3
        character(len=*),  intent(in), optional        :: axes3

        real(wp),  intent(in), dimension(:), optional  :: x4
        real(wp),  intent(in), dimension(:), optional  :: y4
        character(len=*),  intent(in), optional        :: ls4
        character(len=*),  intent(in), optional        :: axes4

        this%plotscale='semilogy'
        call plot2d_vector_vs_vector(this, &
            x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4, axes4  )
        ! Set the plot scale as linear. It means log scale is off
        this%plotscale='linear'


    end subroutine semilogyv



    subroutine loglogv(this, x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4, axes4  )
        !..............................................................................
        !   This procedure is the same as plotXY with logarithmic x1, y1, x2, y2 axes
        !..............................................................................

        class(gpf):: this
        ! Input vector
        real(wp),  intent(in)                          :: x1(:)  ! vector of data for x
        real(wp),  intent(in), optional                :: y1(:)  ! vector of data for y
        character(len=*),  intent(in), optional        :: ls1    ! line specification
        character(len=*),  intent(in), optional        :: axes1

        real(wp),  intent(in), dimension(:), optional  :: x2
        real(wp),  intent(in), dimension(:), optional  :: y2
        character(len=*),  intent(in), optional        :: ls2
        character(len=*),  intent(in), optional        :: axes2

        real(wp),  intent(in), dimension(:), optional  :: x3
        real(wp),  intent(in), dimension(:), optional  :: y3
        character(len=*),  intent(in), optional        :: ls3
        character(len=*),  intent(in), optional        :: axes3

        real(wp),  intent(in), dimension(:), optional  :: x4
        real(wp),  intent(in), dimension(:), optional  :: y4
        character(len=*),  intent(in), optional        :: ls4
        character(len=*),  intent(in), optional        :: axes4


        this%plotscale='loglog'
        call plot2d_vector_vs_vector(this, &
            x1, y1, ls1, axes1, &
            x2, y2, ls2, axes2, &
            x3, y3, ls3, axes3, &
            x4, y4, ls4, axes4  )
        ! Set the plot scale as linear. It means log scale is off
        this%plotscale='linear'

    end subroutine loglogv



    subroutine  semilogxm(this, xv, ymat, lspec)
        !..............................................................................
        !Plots a matrix against a vector with logarithmic x-axis
        !For more information see plot2D_matrix_vs_vector procedure
        !Everything is the same except the x-axis scale
        !..............................................................................

        implicit none
        class(gpf)                                :: this
        ! Input arrays
        real(wp),  intent(in)                     :: xv(:)
        real(wp),  intent(in)                     :: ymat(:,:)
        character(len=*),  intent(in), optional   :: lspec

        this%plotscale='semilogx'
        call plot2d_matrix_vs_vector(this, xv,ymat, lspec)
        ! Set the plot scale as linear. It means log scale is off
        this%plotscale='linear'


    end subroutine semilogxm



    subroutine  semilogym(this, xv,ymat, lspec)
        !..............................................................................
        !Plots a matrix against a vector with logarithmic y-axis
        !For more information see plot2D_matrix_vs_vector procedure
        !Everything is the same except the x-axis scale
        !..............................................................................

        implicit none
        class(gpf)                                  :: this
        ! Input arrays
        real(wp),  intent(in)                       :: xv(:)
        real(wp),  intent(in)                       :: ymat(:,:)
        character(len=*),  intent(in), optional     :: lspec

        this%plotscale='semilogy'
        call plot2d_matrix_vs_vector(this, xv,ymat, lspec)
        ! Set the plot scale as linear. It means log scale is off
        this%plotscale='linear'


    end subroutine semilogym


    subroutine  loglogm(this, xv,ymat, lspec)
        !..............................................................................
        !Plots a matrix against a vector with logarithmic x-axis and y-axis
        !For more information see plot2D_matrix_vs_vector procedure
        !Everything is the same except the axes scale
        !..............................................................................

        implicit none
        class(gpf)                                :: this
        ! Input arrays
        real(wp),  intent(in)                     :: xv(:)
        real(wp),  intent(in)                     :: ymat(:,:)
        character(len=*),  intent(in), optional   :: lspec

        this%plotscale='loglog'
        call plot2d_matrix_vs_vector(this, xv,ymat, lspec)
        ! Set the plot scale as linear. It means log scale is off
        this%plotscale='linear'


    end subroutine loglogm



    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section Three: Animation Routines
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    subroutine sub_animation_start(this, pause_seconds)
        !-------------------------------------------------------------------------------
        ! sub_animation_start: set the setting to start an animation
        ! it simply set flags and open a script file to write data
        !-------------------------------------------------------------------------------
        class(gpf)                  :: this
        real, intent(in), optional  :: pause_seconds


        ! ogpf does not support multiplot with animation at the same time
        if (this%hasmultiplot) then
            print*, md_name // ': does not support animation in multiplot mode!'
            stop
        end if


        if (present(pause_seconds)) then
            this%pause_seconds = pause_seconds
        else
            this%pause_seconds = 2  ! delay in second
        end if

        this%frame_number = 0

        ! create the ouput file for writting gnuplot script
        call create_outputfile(this)
        this%hasfileopen  = .true.
        this%hasanimation = .true.

    end subroutine sub_animation_start


    subroutine sub_animation_show(this)
        !-------------------------------------------------------------------------------
        ! sub_animation_show: simply resets the animation flags
        ! and finalize the plotting.
        !-------------------------------------------------------------------------------

        class(gpf) :: this

        this%frame_number = 0
        this%hasanimation = .false.

        call finalize_plot(this)

    end subroutine sub_animation_show




    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section Four: Gnuplot direct scriptting
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    subroutine addscript(this,strcmd)
        !..............................................................................
        ! addscript: accepts all type of gnuplot command as a string and store it
        ! in global txtscript to be later sent to gnuplot
        !..............................................................................

        class(gpf)                   :: this
        character(len=*), intent(in) :: strcmd

        if (.not.allocated(this%txtscript)) this%txtscript=''
        if (len_trim(this%txtscript) == 0 ) then
            this%txtscript = '' ! initialize string
        end if
        if ( len_trim(strcmd)>0 ) then
            this%txtscript = this%txtscript // splitstr(strcmd)
        end if

    end subroutine addscript



    subroutine runscript(this)
        !..............................................................................
        ! runscript sends the the script string (txtstring) into a script
        ! file to be run by gnuplot
        !..............................................................................

        class(gpf):: this

        !REV 0.18: a dedicated subroutine is used to create the output file
        call create_outputfile(this)

        !write the script
        call processcmd(this)
        write(unit=this%file_unit, fmt='(a)') this%txtscript

        ! close the file and call gnuplot
        call finalize_plot(this)

    end subroutine runscript



    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section Five: gnuplot command processing and data writing to script file
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    subroutine process_axes_set(axes_set, axes)
        !..............................................................................
        ! process_axesspec accepts the axes set and interpret it into
        ! a format to be sent to gnuplot.
        ! the axes set can be one of the following set
        ! x1y1, x1y2, x2y1, x2y2
        !..............................................................................

        character(len=*), intent(in)  :: axes_set
        character(len=4), intent(out) :: axes


        if (len_trim (adjustl(axes_set)) == 0) then
            axes=''
            return
        end if

        select case ( lcase(trim (adjustl (axes_set) ) ) )
            case ('x1y1')
                axes='x1y1'
            case ('x1y2')
                axes='x1y2'
            case ('x2y1')
                axes='x2y1'
            case ('x2y2')
                axes='x2y2'
            case default ! wrong strings
                print*, md_name // ':process_axes_set:' // ' wrong axes set is sent.'// new_line(' ') &
                    // 'axes set can be on of: x1y1, x1y2, x2y1, x2y2'
                axes=''
                return
        end select

    end subroutine process_axes_set



    subroutine process_linespec(order, lsstring, lspec, axes_set)
        !..............................................................................
        ! process_linespec accepts the line specification and interpret it into
        ! a format to be sent to gnuplot
        !..............................................................................

        integer, intent(in) :: order !1 for the first data series
        character(len=*), intent(out) :: lsstring
        character(len=*), intent(in), optional :: lspec
        character(len=*), intent(in), optional :: axes_set

        !local variables
        character(len=4)  :: axes
        character(len=10) :: axes_setting

        !check the axes set
        axes_setting = ''
        if ( present (axes_set)) then
            call process_axes_set(axes_set, axes)
            if (len(trim(axes))> 0 ) then
                axes_setting = ' axes ' // axes
            end if
        end if

        select case(order)
            case(1)
                if ( present(lspec) ) then
                    if (hastitle(lspec)) then
                        lsstring='plot "-" '//trim(lspec) // axes_setting
                    else
                        lsstring='plot "-" notitle '//trim(lspec) // axes_setting
                    end if
                else
                    lsstring='plot "-" notitle' // axes_setting
                end if
            case  default !e.g. 2, 3, 4, ...
                if (present(lspec)) then
                    if (hastitle(lspec)) then
                        lsstring=', "-" '// trim(lspec) // axes_setting
                    else
                        lsstring=', "-" notitle '// trim(lspec) // axes_setting
                    end if
                else
                    lsstring=', "-" notitle' // axes_setting
                end if
        end select
    end subroutine process_linespec



    subroutine processcmd(this)
        !..............................................................................
        !   This subroutine writes all the data into plot file
        !   to be read by gnuplot
        !..............................................................................

        class(gpf) :: this

        ! write the plot style for data
        ! this is used only when 3D plots (splot, cplot) is used
        if (allocated(this%txtdatastyle)) then
            write ( this%file_unit, '("set style data ", a)' ) this%txtdatastyle
            write ( this%file_unit, '(a)' )
        end if


        ! Write options
        if ( this%hasoptions ) then
            write ( this%file_unit, '(" ")' )
            write ( this%file_unit, '("# options")' )
            write ( this%file_unit, '(a)' ) this%txtoptions
            write ( this%file_unit, '(a)' )
        end if

        ! Check with plot scale: i.e linear, logx, logy, or log xy
        write( this%file_unit, '(" ")' )
        write( this%file_unit, '("# plot scale")' )
        select case (this%plotscale)
            case ('semilogx')
                write ( this%file_unit, '("set logscale  x")' )
            case ('semilogy')
                write ( this%file_unit, '("set logscale  y")' )
            case ('loglog')
                write ( this%file_unit, '("set logscale  xy")' )
            case default !for no setting
                !pass
        end select

        !!>0.22
        ! write annotation
        write ( this%file_unit, '(" ")' )
        write ( this%file_unit, '("# Annotation: title and labels")' )
        call write_label(this, 'plot_title')
        call write_label(this, 'xlabel'    )
        call write_label(this, 'x2label'   )
        call write_label(this, 'ylabel'    )
        call write_label(this, 'y2label'   )
        call write_label(this, 'zlabel'    )

        ! axes range
        write ( this%file_unit, '(" ")')
        write ( this%file_unit, '("# axes setting")')
        if (this%hasxrange) then
            write ( this%file_unit, '("set xrange [",G0,":",G0,"]")' ) this%xrange
        end if
        if (this%hasyrange) then
            write ( this%file_unit, '("set yrange [",G0,":",G0,"]")' ) this%yrange
        end if
        if (this%haszrange) then
            write ( this%file_unit, '("set zrange [",G0,":",G0,"]")' ) this%zrange
        end if

        ! secondary axes range
        if (this%hasx2range) then
            write ( this%file_unit, '("set x2range [",G0,":",G0,"]")' ) this%x2range
        end if
        if (this%hasy2range) then
            write ( this%file_unit, '("set y2range [",G0,":",G0,"]")' ) this%y2range
        end if
        ! finish by new line
        write ( this%file_unit, '(a)' ) ! emptyline

    end subroutine processcmd



    subroutine write_label(this, lblname)
        !..............................................................................
        !   This subroutine writes the labels into plot file
        !   to be read by gnuplot
        !..............................................................................


        ! write_label
        class(gpf)                    :: this
        character(len=*)              :: lblname

        ! local var
        character(len=:), allocatable :: lblstring
        character(len=:), allocatable :: lblset
        type(tplabel)                 :: label

        select case (lblname)
            case ('xlabel')
                if (.not. (this%tpxlabel%has_label) ) then
                    return ! there is no label
                end if
                lblset = 'set xlabel "'
                label = this%tpxlabel
            case ('x2label')
                if (.not. (this%tpx2label%has_label) ) then
                    return ! there is no label
                end if
                lblset = 'set x2label "'
                label = this%tpx2label
            case ('ylabel')
                if (.not. (this%tpylabel%has_label) ) then
                    return ! there is no label
                end if
                lblset = 'set ylabel "'
                label = this%tpylabel
            case ('y2label')
                if (.not. (this%tpy2label%has_label) ) then
                    return ! there is no label
                end if
                lblset = 'set y2label "'
                label = this%tpy2label
            case ('zlabel')
                if (.not. (this%tpzlabel%has_label) ) then
                    return ! there is no label
                end if
                lblset = 'set zlabel "'
                label = this%tpzlabel
            case ('plot_title')
                if (.not. (this%tpplottitle%has_label) ) then
                    return ! there is no label
                end if
                lblset = 'set title "'
                label = this%tpplottitle
        end select

        lblstring = ''
        ! if there is a label continue to set it
        lblstring                  = lblstring // lblset // trim(label%lbltext)//'"'
        if (allocated(label%lblcolor)) then
            lblstring              = lblstring // ' tc "' //trim(label%lblcolor) // '"'
        end if
        ! set font and size
        if (allocated(this%tpxlabel%lblfontname)) then
            lblstring              = lblstring // ' font "'// trim(label%lblfontname) // ','
            if (label%lblfontsize /= NOT_INITIALIZED) then
                lblstring          = lblstring // num2str(label%lblfontsize) //'"'
            else
                lblstring          = lblstring //'"'
            end if
        else ! check if only font size has been given
            if (label%lblfontsize /= NOT_INITIALIZED ) then
                lblstring          = lblstring // ' font ",' // num2str(label%lblfontsize) //'"'
            end if
        end if
        ! set rotation
        if (label%lblrotate       /= NOT_INITIALIZED ) then
            lblstring              = lblstring // ' rotate by ' // num2str(label%lblrotate )
        end if


        ! write to ogpf script file
        write ( this%file_unit, '(a)' ) lblstring


    end subroutine write_label



    function color_palettes(palette_name) result(str)
        !...............................................................................
        ! color_palettes create color palette as a
        ! string to be written into gnuplot script file
        ! the palettes credit goes to: Anna Schnider (https://github.com/aschn) and
        ! Hagen Wierstorf (https://github.com/hagenw)
        !...............................................................................
        character(len=*), intent(in)  :: palette_name
        character(len=:), allocatable :: str

        ! local variables
        character(len=1)              :: strnumber
        character(len=11)             :: strblank
        integer                       :: j
        integer                       :: maxcolors

        ! define the color palettes
        character(len=:), allocatable :: pltname
        character(len=7)              :: palette(9) ! palettes with maximum 9 colors

        maxcolors = 8 ! default number of discrete colors
        palette=''
        select case ( lcase(trim(adjustl(palette_name))) )
            case ('set1')
                pltname='set1'
                palette(1:maxcolors)=[&
                    "#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", &
                    "#FF7F00", "#FFFF33", "#A65628", "#F781BF" ]
            case ('set2')
                pltname='set2'
                palette(1:maxcolors)=[&
                    "#66C2A5", "#FC8D62", "#8DA0CB", "#E78AC3", &
                    "#A6D854", "#FFD92F", "#E5C494", "#B3B3B3" ]
            case ('set3')
                pltname='set3'
                palette(1:maxcolors)=[&
                    "#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072", &
                    "#80B1D3", "#FDB462", "#B3DE69", "#FCCDE5" ]
            case ('palette1')
                pltname='palette1'
                palette(1:maxcolors)=[&
                    "#FBB4AE", "#B3CDE3", "#CCEBC5", "#DECBE4", &
                    "#FED9A6", "#FFFFCC", "#E5D8BD", "#FDDAEC" ]
            case ('palette2')
                pltname='palette2'
                palette(1:maxcolors)=[&
                    "#B3E2CD", "#FDCDAC", "#CDB5E8", "#F4CAE4", &
                    "#D6F5C9", "#FFF2AE", "#F1E2CC", "#CCCCCC" ]
            case ('paired')
                pltname='paired'
                palette(1:maxcolors)=[&
                    "#A6CEE3", "#1F78B4", "#B2DF8A", "#33A02C", &
                    "#FB9A99", "#E31A1C", "#FDBF6F", "#FF7F00" ]
            case ('dark2')
                pltname='dark2'
                palette(1:maxcolors)=[&
                    "#1B9E77", "#D95F02", "#7570B3", "#E7298A", &
                    "#66A61E", "#E6AB02", "#A6761D", "#666666" ]
            case ('accent')
                pltname='accent'
                palette(1:maxcolors)=[&
                    "#7FC97F", "#BEAED4", "#FDC086", "#FFFF99", &
                    "#386CB0", "#F0027F", "#BF5B17", "#666666" ]
            case ('jet')
                ! Matlab jet palette
                maxcolors = 9
                pltname='jet'
                palette(1:maxcolors)=[&
                    '#000090', '#000fff', '#0090ff', '#0fffee', &
                    '#90ff70', '#ffee00', '#ff7000', '#ee0000', '#7f0000' ]
            case default
                print*, md_name // ": color_palettes: wrong palette name"
                print*, 'gnuplot default palette will be used!'
                str=' ' ! empty palette is returned!
                return
        end select

        ! generate the gnuplot palette as a single multiline string
        str                 = '# Define the ' // pltname // ' pallete' // new_line(' ')
        str                 = str // 'set palette defined ( \' // new_line(' ')
        strblank            = '           ' ! pad certain number of paces
        do j=1, maxcolors - 1
            write(unit      =strnumber, fmt='(I1)' ) j-1
            str             = str // strblank // strnumber // ' "' // palette(j) // '",\' // new_line(' ')
        end do

        j                   =maxcolors
        write(strnumber, fmt='(I1)') j
        str                 = str // strblank // strnumber // ' "' // palette(j) // '" )' // new_line(' ')

    end function color_palettes



    subroutine write_xydata(file_unit,ndata,x,y)
        !..............................................................................
        ! Writes set of xy data into a file
        !..............................................................................

        integer,  intent(in)           ::  file_unit
        integer,  intent(in)           ::  ndata
        real(wp), intent(in)           ::  x(:)
        real(wp), intent(in), optional ::  y(:)

        integer:: i

        ! TODO (Mohammad#1#12/22/17): The format string shall be modified to write the
        ! number in more suitable form
        ! Rev 0.18
        if (present(y) ) then !both x and y are present, data are xy set
            do i = 1, ndata
                write ( file_unit, * ) x(i), y(i)
            end do
        else !only x is passed, data are index-x set
            do i = 1, ndata
                write ( file_unit, * ) x(i)
            end do
        end if
        write ( file_unit, '(a)' ) 'e'  !end of set of data

    end subroutine write_xydata



    subroutine create_outputfile(this)
        !..............................................................................
        ! Create an output file, assign a file_unit
        ! for writing the gnuplot commands
        !..............................................................................

        ! Rev 0.18
        class(gpf), intent(inout)   :: this

        if (this%hasfileopen) then
            ! there is nothing to do, file has been already open!
            return
        end if

        !> Rev 0.2 animation

        ! animation handling
        if (this%hasanimation ) then
            this%frame_number = this%frame_number + 1 ! for future use
        end if

        ! Open the output file

        if (.not. (this%hasfilename)) then ! check if no file has been set by user
            this%txtfilename=gnuplot_output_filename
        end if

        open ( newunit = this%file_unit, file = this%txtfilename, status = 'replace', iostat = this%status )


        if (this%status /= 0 ) then
            print*, "md_helperproc, create_outputfile: cannot open file for output"
            stop
        end if


        ! Set the gnuplot terminal, write ogpf configuration (customized setting)
        ! Can be overwritten by options

        ! write signature
        write ( this%file_unit, '(a)' ) '# ' // md_name
        write ( this%file_unit, '(a)' ) '# ' // md_rev
        write ( this%file_unit, '(a)' ) '# ' // md_lic
        write ( this%file_unit, '(a)' )  ! emptyline

        ! write the global settings
        write ( this%file_unit, '(a)' ) '# gnuplot global setting'
        write(unit=this%file_unit, fmt='(a)') 'set term ' // gnuplot_term_type // &
            ' size ' // gnuplot_term_size // ' enhanced font "' // &
            gnuplot_term_font // '"' // &
            ' title "' // md_name // ': ' // md_rev //'"'   ! library name and version

        ! write the preset configuration for gnuplot (ogpf customized settings)
        if (this%preset_configuration) then
            call this%preset_gnuplot_config()
        end if
        ! write multiplot setting
        if (this%hasmultiplot) then
            write(this%file_unit, fmt='(a, I2, a, I2)') 'set multiplot layout ', &
                this%multiplot_rows, ',',  this%multiplot_cols
        end if
        ! set flag true for file is opened
        this%hasfileopen = .true.

    end subroutine create_outputfile


    subroutine preset_gnuplot_config(this)
        !..............................................................................
        ! To write the preset configuration for gnuplot (ogpf customized settings)
        !..............................................................................
        class(gpf) :: this

        write(this%file_unit, fmt='(a)')
        write(this%file_unit, fmt='(a)') '# ogpf extra configuration'
        write(this%file_unit, fmt='(a)') '# -------------------------------------------'


        ! color definition
        write(this%file_unit, fmt='(a)') '# color definitions'
        write(this%file_unit, fmt='(a)') 'set style line 1 lc rgb "#800000" lt 1 lw 2'
        write(this%file_unit, fmt='(a)') 'set style line 2 lc rgb "#ff0000" lt 1 lw 2'
        write(this%file_unit, fmt='(a)') 'set style line 3 lc rgb "#ff4500" lt 1 lw 2'
        write(this%file_unit, fmt='(a)') 'set style line 4 lc rgb "#ffa500" lt 1 lw 2'
        write(this%file_unit, fmt='(a)') 'set style line 5 lc rgb "#006400" lt 1 lw 2'
        write(this%file_unit, fmt='(a)') 'set style line 6 lc rgb "#0000ff" lt 1 lw 2'
        write(this%file_unit, fmt='(a)') 'set style line 7 lc rgb "#9400d3" lt 1 lw 2'
        write(this%file_unit, fmt='(a)')
        ! axes setting
        write(this%file_unit, fmt='(a)') '# Axes'
        write(this%file_unit, fmt='(a)') 'set border linewidth 1.15'
        write(this%file_unit, fmt='(a)') 'set tics nomirror'
        write(this%file_unit, fmt='(a)')

        write(this%file_unit, fmt='(a)') '# grid'
        write(this%file_unit, fmt='(a)') '# Add light grid to plot'
        write(this%file_unit, fmt='(a)') 'set style line 102 lc rgb "#d6d7d9" lt 0 lw 1'
        write(this%file_unit, fmt='(a)') 'set grid back ls 102'
        write(this%file_unit, fmt='(a)')
        ! set the plot style
        write(this%file_unit, fmt='(a)') '# plot style'
        write(this%file_unit, fmt='(a)') 'set style data linespoints'
        write(this%file_unit, fmt='(a)')

        write(this%file_unit, fmt='(a)') '# -------------------------------------------'
        write(this%file_unit, fmt='(a)') ''


    end subroutine preset_gnuplot_config



    subroutine finalize_plot(this)
        !..............................................................................
        ! To finalize the writing of gnuplot commands/data and close the output file.
        !..............................................................................
        class(gpf) :: this

        ! check for multiplots
        if (this%hasmultiplot) then
            if (this%multiplot_total_plots < this%multiplot_rows * this%multiplot_cols - 1 ) then
                ! increment the number of plots
                this%multiplot_total_plots = this%multiplot_total_plots + 1
                return ! do not finalize plot, still there is places in multiplot
            else
                ! close multiplot
                write(this%file_unit, fmt='(a)') 'unset multiplot'
                ! reset multiplot flag
                this%hasmultiplot = .false.

            end if
        end if

        close ( unit = this%file_unit )   ! close the script file
        this%hasfileopen = .false.        ! reset file open flag
        this%hasanimation = .false.
        ! Use shell command to run gnuplot
        if (get_os_type() == 1) then
            call execute_command_line ('wgnuplot -persist ' // this%txtfilename)  !   Now plot the results
        else
            call execute_command_line ('gnuplot -persist ' // this%txtfilename)  !   Now plot the results
        end if
    contains
        integer function get_os_type() result(r)
            !! Returns one of OS_WINDOWS, others
            !! At first, the environment variable `OS` is checked, which is usually
            !! found on Windows.
            !! Copy from fpm/fpm_environment: https://github.com/fortran-lang/fpm/blob/master/src/fpm_environment.f90
            character(len=32) :: val
            integer :: length, rc

            integer, parameter :: OS_OTHERS = 0
            integer, parameter :: OS_WINDOWS = 1

            r = OS_OTHERS
            ! Check environment variable `OS`.
            call get_environment_variable('OS', val, length, rc)

            if (rc == 0 .and. length > 0 .and. index(val, 'Windows_NT') > 0) then
                r = OS_WINDOWS
                return
            end if

        end function

    end subroutine finalize_plot



    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section Six: Utility and helper procedures
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    function hastitle(string)
        !..............................................................................
        ! check to see if the plot title (used as legend = key)
        !..............................................................................

        character(len=*), intent(in) :: string
        logical:: hastitle
        integer:: idx1
        integer:: idx2

        idx1=index( lcase(string),'title')     !Check if title is passed
        idx2=index(' ' // lcase(string),' t ') !Check if the abbreviated title 't' is passed. Extra space is added
        ! at the beginning of string to find starting 't'
        if (idx1 /=0 .or. idx2 /=0 ) then
            hastitle=.true.
        else
            hastitle=.false.
        end if

    end function hastitle


    function checkdim(nx,ny)
        !..............................................................................
        ! checkdim checks the equality of dimensions of two vector
        !..............................................................................

        integer, intent(in):: nx
        integer, intent(in):: ny
        logical:: checkdim
        if (nx/=ny) then
            checkdim=.false.
        else
            checkdim=.true.
        end if

    end function checkdim



    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !> Section Seven: String utility Routines
    !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



    pure function splitstr(str) result(spstr)
        !..............................................................................
        !splitstr, separate a string using ";" delimiters
        !..............................................................................

        character(len=*), intent(in)    :: str

        ! local variables
        character, parameter          :: delimiter=';'
        character(len=:), allocatable :: spstr
        integer ::  n
        integer ::  m
        integer ::  k


        k=len_trim(str) !length with removed trailing blanks
        n=scan(str,delimiter)
        if (n==0) then  ! This is a single statement
            spstr = adjustl(str) // new_line(' ')
            return
        end if

        ! for two or more statements separated by ;
        spstr = ''
        m=1
        do while (n/=0 .and. m<k)
            if (n/=1) then
                spstr = spstr // adjustl(str(m:m+n-2)) // new_line(' ')
            end if
            m=n+m
            n=scan(str(m:k),delimiter)
        end do
        if (m<k) then !write the last statement
            spstr = spstr// adjustl(str(m:k)) // new_line(' ')
        end if
    end function splitstr



    subroutine splitstring2array(strin, strarray, delimiter)
        !..............................................................................
        ! splitstring splits a string to an array of
        ! substrings based on a selected delimiter
        ! note:
        !    a. any facing space/blank in substrings will be removed
        !    b. two adjacent delimiter treats as an empty substring between them
        !    c. facing and trailing delimiter treats as empty substring at the fornt and end
        !..............................................................................

        character(len=*),  intent(in)               :: strin
        character(len=80), allocatable, intent(out) :: strarray(:)
        character(len=1),  optional,    intent(in)  :: delimiter

        ! local variables
        integer   :: m, n
        integer   :: i, idx
        character(len=len(strin)) :: strtmp
        character(len=1)  :: delimiter_

        ! 0. check the existance of delimiter
        if (present(delimiter)) then
            delimiter_ = delimiter
        else
            delimiter_ = ';'
        end if

        ! 1. remove initial blanks if any
        strtmp=trim (adjustl(strin) )

        ! 2. count the number substrings separated by delimiter
        n = count( [ (strtmp(i:i)== delimiter_, i=1, len_trim(strtmp)) ] )

        ! 3. allocate the output string array
        allocate(strarray(n+1))

        ! 4. extract substrings and store in array one by one
        m=1
        do i=1, n
            idx=index(strtmp(m:),delimiter_)
            strarray(i) = adjustl( strtmp(m:m+idx-2) )
            m = m + idx
        end do
        strarray(n+1)=adjustl(strtmp(m:) )


    end subroutine splitstring2array


    function lcase(strinput)
        !..............................................................................
        ! Return the string (strInput) in lowercase
        !..............................................................................

        character(len=*), intent(in) :: strinput
        character(len=len(strinput)):: lcase
        integer:: i
        integer:: n
        character(1):: chr

        do i=1, len(strinput)
            chr=strinput(i:i)
            n=ichar(chr)
            if (n >=65 .and. n <= 90) then
                lcase(i:i)=char(n+32)
            else
                lcase(i:i)=chr
            end if
        end do
    end function lcase


    function num2str_i4(number_in)
        !..............................................................................
        ! num2str_int: converts integer number to string
        !..............................................................................

        integer(kind=kind(1)), intent(in)     :: number_in
        character(len=:), allocatable   :: num2str_i4

        ! local variable
        character(len=range(number_in)) :: strnm
        write(unit=strnm, fmt='(I0)') number_in
        num2str_i4 = trim(strnm)

    end function num2str_i4

    function num2str_r4(number_in, strfmt)
        !..............................................................................
        ! num2str_r4: converts single precision real number to string
        ! strfmt is the optional format string
        !..............................................................................

        real(kind=sp), intent(in)                :: number_in
        character(len=*), intent(in), optional  :: strfmt
        character(len=:), allocatable           :: num2str_r4

        ! local variable
        character(len=range(number_in)) :: strnm


        if (present(strfmt)) then
            write(unit=strnm, fmt= '('//trim(strfmt)//')' ) number_in
        else
            write(unit=strnm, fmt='(G0)') number_in
        end if

        num2str_r4 = trim(strnm)

    end function num2str_r4


    function num2str_r8(number_in, strfmt)
        !..............................................................................
        ! num2str_real: converts double precision real number to string
        ! strfmt is the optional format string
        !..............................................................................

        real(kind=dp), intent(in)                :: number_in
        character(len=*), intent(in), optional  :: strfmt
        character(len=:), allocatable           :: num2str_r8

        ! local variable
        character(len=range(number_in)) :: strnm

        if (present(strfmt)) then
            write(unit=strnm, fmt= '('//trim(strfmt)//')' ) number_in
        else
            write(unit=strnm, fmt='(G0)') number_in
        end if

        num2str_r8 = trim(strnm)

    end function num2str_r8


    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    !!> Section Eight: Math helper function
    !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    function arange(xa, xb, dx)
        !..............................................................................
        !   returns a vector in the form of [xa, xa+dx, xa+2*dx, ...]
        !   the number of elements is calculated as m = n+ 1,
        !   where n= int ( (xa-xb)/dx) ).
        !   arange is similar to colon in Matlab and arange in Python!
        !
        !   NOTE:
        !    - If n calculated as zero, result is [xa]
        !    - If n calculated as Inf (dx=0), a fatal error will be raised
        !    - If n calculated as negative value (e.g xa<xb or dx<0.0), a
        !      fatal error will be raised
        !..............................................................................

        real(wp), intent(in)            :: xa
        real(wp), intent(in)            :: xb
        real(wp), intent(in), optional  :: dx
        real(wp), allocatable           :: arange(:)

        !   Local vars
        real(wp):: dxl
        integer:: i
        integer:: n
        integer:: ierr

        ! check the presence of dx and its correctness
        if (present(dx)) then
            dxl = dx
            if ( abs(dx) <= tiny(dx)) then
                print*, "arange procedure: Fatal Error: wrong dx, use a dx > 0.0 "
                stop
            end if
        else
            dxl = 1.0_wp
        end if

        if ( (xa < xb) .and. (dx < 0.0_wp) ) then
            print*, "arange procedure: Fatal Error: wrong dx, use a dx > 0.0 "
            stop
        end if

        n = int( (xb-xa)/ dxl) ! n+1 is the number of elements

        allocate(arange(n), stat=ierr)

        if (ierr /= 0) then
            print*, "arange procedure: Fatal Error, allocation failed in arange function"
            stop
        end if

        arange = [(xa + i*dxl, i=0, n)]

    end function arange


    function linspace(a,b,n_elements)
        !..............................................................................
        !   returns a linearly spaced vector with n points in [a, b]
        !   if n is omitted, 100 points will be considered
        !..............................................................................

        real(wp), intent(in)           :: a
        real(wp), intent(in)           :: b
        integer,  intent(in), optional :: n_elements
        real(wp), allocatable          :: linspace(:)

        !   Local vars
        real(wp) :: dx
        integer  :: i
        integer  :: n
        integer  :: ierr

        if (present(n_elements)) then
            if (n_elements <=1 ) then
                print*, "linspace procedure: Error: wrong value of n_elements, use an n_elements > 1"
                stop
            end if
            n=n_elements
        else
            n=100
        end if

        allocate(linspace(n), stat=ierr)
        if (ierr /= 0) then
            print*, "linspace procedure: Fatal Error, Allocation failed in linspace function"
            stop
        end if

        dx=(b-a)/real((n-1),wp)
        linspace=[(i*dx+a, i=0,n-1)]

    end function linspace



    subroutine meshgrid(x,y,xgv,ygv, ierr)
        !..............................................................................
        !meshgrid generate mesh grid over a rectangular domain of [xmin xmax, ymin, ymax]
        ! Inputs:
        !     xgv, ygv are grid vectors in form of full grid data
        ! Outputs:
        !     X and Y are matrix each of size [ny by nx] contains the grid data.
        !     The coordinates of point (i,j) is [X(i,j), Y(i,j)]
        !     ierr: The error flag
        !     """
        !     # Example
        !     # call meshgrid(X, Y, [0.,1.,2.,3.],[5.,6.,7.,8.])
        !     # X
        !     # [0.0, 1.0, 2.0, 3.0,
        !     #  0.0, 1.0, 2.0, 3.0,
        !     #  0.0, 1.0, 2.0, 3.0,
        !     #  0.0, 1.0, 2.0, 3.0]
        !     #
        !     #Y
        !     #[ 5.0, 5.0, 5.0, 5.0,
        !     #  6.0, 6.0, 6.0, 6.0,
        !     #  7.0, 7.0, 7.0, 7.0,
        !     #  8.0, 8.0, 8.0, 8.0]
        !..............................................................................
        ! Rev 0.2, Feb 2018
        ! New feature added: xgv and ygv as full grid vector are accepted now

        ! Arguments
        real(wp), intent(out), allocatable  :: x(:,:)
        real(wp), intent(out), allocatable  :: y(:,:)
        real(wp), intent(in)                :: xgv(:) ! x grid vector [start, stop, step] or [start, stop]
        real(wp), intent(in),  optional     :: ygv(:) ! y grid vector [start, stop, step] or [start, stop]
        integer,  intent(out), optional     :: ierr   ! the error value

        ! Local variables
        integer:: sv
        integer:: nx
        integer:: ny
        logical:: only_xgv_available

        ! Initial setting
        only_xgv_available  = .false.
        sv=0 !Assume no error

        nx=size(xgv, dim=1)

        if (present(ygv)) then
            ny = size(ygv, dim=1)
        else
            only_xgv_available=.true.
            ny=nx
        end if

        allocate(x(ny,nx),y(ny,nx),stat=sv)
        if (sv /=0) then
            print*, "allocataion erro in meshgrid"
            stop
        end if

        x(1,:)    = xgv
        x(2:ny,:) = spread(xgv, dim=1, ncopies=ny-1)

        if (only_xgv_available) then
            y=transpose(x)
        else
            y(:,1)    = ygv
            y(:,2:nx) = spread(ygv,dim=2,ncopies=nx-1)
        end if

        if (present(ierr)) then
            ierr=sv
        end if

    end subroutine meshgrid


    !End of ogpf
end module ogpf
Download .txt
gitextract_axg7b2oj/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── doc/
│   └── readme.txt
├── example/
│   └── demo.f90
├── fpm.toml
├── meson.build
├── revision.txt
├── sample_script.gp
└── src/
    └── ogpf.f90
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (203K chars).
[
  {
    "path": ".gitignore",
    "chars": 306,
    "preview": "# Prerequisites\n*.d\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic"
  },
  {
    "path": "LICENSE",
    "chars": 1307,
    "preview": "Copyright (c) 2012-2018 Mohammad Rahmani\n\n! Author:    Mohammad Rahmani\n!            Chem Eng Dep., Amirkabir Uni. of Te"
  },
  {
    "path": "Makefile",
    "chars": 973,
    "preview": "#\n# This Makefile was generated by Code::Blocks IDE.\n#\n\nSRCS_f90d1 = \\\nogpf.f90\n\nSRCS_f90d2 = \\\ndemo.f90\n\nOBJS_f90d1 = \\"
  },
  {
    "path": "README.md",
    "chars": 32140,
    "preview": "# ogpf\nObject Based Interface to GnuPlot from Fortran (ogpf)\n\n## Installation\n\n__Prerequisite:__ [gnuplot](http://www.gn"
  },
  {
    "path": "doc/readme.txt",
    "chars": 80,
    "preview": "This folder contains some outputs generated by demo.f90\nRev 0.2\nMarch 1st, 2018\n"
  },
  {
    "path": "example/demo.f90",
    "chars": 52952,
    "preview": "!-------------------------------------------------------------------------------\r\n!    GnuPlot Interface\r\n!-------------"
  },
  {
    "path": "fpm.toml",
    "chars": 173,
    "preview": "name=\"ogpf\"\ndescription = \"Object Based Interface to GnuPlot from Fortran\"\nversion = \"0.4.0\"\nlicense = \"MIT\"\nauthor = \"M"
  },
  {
    "path": "meson.build",
    "chars": 279,
    "preview": "project('Ogpf', 'fortran')\n\ngnuplot = find_program('gnuplot',\n  required: true)\n\nlibogpf = library('ogpf', 'src/ogpf.f90"
  },
  {
    "path": "revision.txt",
    "chars": 29,
    "preview": "Rev 0.20\r\n\r\nMarch 1st, 2018\r\n"
  },
  {
    "path": "sample_script.gp",
    "chars": 494,
    "preview": "# https://linuxgazette.net/133/luana.html\n\nset size ratio -1\n set nokey\n set noxtics\n set noytics\n set noborder\n set par"
  },
  {
    "path": "src/ogpf.f90",
    "chars": 103399,
    "preview": "!-------------------------------------------------------------------------------\r\n!    GnuPlot Interface\r\n!-------------"
  }
]

About this extraction

This page contains the full source code of the kookma/ogpf GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (187.6 KB), approximately 49.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!