Gnuplot

gnuplot
Fig. 1: Gnuplot called from Fortran

Gnuplot is a free plotting tool that can be run from the command-line or invoked by third-party applications. The plotting commands and the input data are read from files or stdin. Plots can either be displayed inside a window (fig. 1) or exported in various image formats. The development of Gnuplot started already in 1986.

The Fortran example below writes the processed data to a text file data.txt and then uses the intrinsic Fortran 2008 routine execute_command_line() to call Gnuplot. Additional Fortran modules are not required.

! example.f90
program main
    implicit none
    character(len=*), parameter :: FILE_NAME = 'data.txt'   ! File name.
    integer,          parameter :: N         = 10           ! Number of values.

    real, dimension(N) :: x, y
    integer            :: i, fu

    x(1) = 0.0
    y(1) = 0.0

    do i = 2, N
        x(i) = 0.1 * i
        y(i) = x(i) * x(i)
    end do

    open (newunit=fu, action='write', file=FILE_NAME, status='replace')

    do i = 1, N
        write (fu, *) x(i), y(i)
    end do

    close (fu)

    call execute_command_line('gnuplot -p plot.plt')
end program main

The Gnuplot commands to display the plot are stored in file plot.plt:

# plot.plt
set terminal x11 0
set title "Fortran Example"
set nokey
set grid
set xlabel "x"
set ylabel "y"
m="data.txt"
plot m using 1:2 with linespoints

The file will then be read by Gnuplot to perform the actual plotting:

$ gfortran10 -o example example.f90
$ ./example

Unix Pipes

Instead of transfering the output data to Gnuplot by file, we can feed plotting options and data values directly by connecting both applications with Unix pipes. The output of the Fortran program will become the input of Gnuplot.

An example shows how to plot a shaded height map based on Perlin noise with Gnuplot (fig. 2). The Fortran program will simple print the height map to stdout. If we set the dgrid3d option followed by the correct dimensions of the matrix, Gnuplot will map a non-grid input to the internal grid format automatically. We could then output single coordinates (x, y, z) line by line instead of the matrix as a whole.

gnuplot matrix
Fig. 2: Perlin noise generated in Fortran visualised by Gnuplot

The Fortran module perlin.f90 contains a simple Perlin noise implementation called by the example. The plotted surface is interpolated by Gnuplot.

! example.f90
program main
    use :: perlin
    implicit none
    integer, parameter :: WIDTH  = 128
    integer, parameter :: HEIGHT = 64
    integer            :: x, y
    real               :: r
    real               :: matrix(HEIGHT, WIDTH)

    ! Set Perlin noise seed.
    call random_seed()
    call random_number(r)
    call perlin_noise_seed(int(r * 10**6))

    ! Set Gnuplot options.
    print '(a)', 'unset key'                           ! Disable legend.
    print '(a)', 'set cbtics scale 0'                  ! Disable colourbar tics.
    print '(a)', 'set title "Perlin Noise in Fortran"' ! Set title.
    print '(a)', 'set pm3d interpolate 2, 2'           ! Draw 3d data as colour map.
    print '(a)', 'splot "-" matrix with pm3d'          ! Plot matrix data in 3d.

    ! Calculate matrix values and print them to stdout.
    do y = 1, HEIGHT
        do x = 1, WIDTH
            matrix(y, x) = perlin_noise(real(x * .1), real(y * .1), 0.4, 8) * 100
            write (*, '(f8.5, " ")', advance='no') matrix(y, x)
        end do
        write (*, '(a)')
    end do
end program main

The example can be compiled and run with:

$ gfortran10 -c perlin.f90
$ gfortran10 -o example example.f90 perlin.o
$ ./example | gnuplot -p

Fortran Libraries

Additionally, several Gnuplot libraries are available for Fortran:

References