A Fortran library providing a convenient interface for plotting with Gnuplot.
This library is tailored to write script files for GNUPLOT. As such, GNUPLOT is required to make use of the output of this library. GNUPLOT can be found here.
Documentation can be found here
FPLOT requires a Fortran compiler with Fortran 2003 support and Gnuplot on your PATH to render plots. The CMake and FPM builds retrieve the Fortran library dependencies automatically.
Configure and build the library with CMake 3.24 or newer:
cmake -S . -B build -DBUILD_TESTING=ON -DBUILD_FPLOT_EXAMPLES=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failureInstall it to a prefix of your choice:
cmake --install build --prefix /path/to/installTo build a shared library, add -DBUILD_SHARED_LIBS=ON to the configure command. Set BUILD_TESTING or BUILD_FPLOT_EXAMPLES to OFF when those targets are not needed.
FPM can build and test the checked-out repository directly:
fpm build
fpm testAdd FPLOT to another FPM project with:
[dependencies]
fplot = { git = "https://github.com/jchristopherson/fplot" }Import fplot_core for the primary types, styling constants, and helper routines such as linspace and meshgrid. A basic 2D plot follows four steps: initialize a plot object, configure its appearance, add one or more data series, and draw it.
use, intrinsic :: iso_fortran_env
use fplot_core
type(plot_2d) :: plt
real(real64) :: x(100), y(100)
x = linspace(0.0_real64, 10.0_real64, size(x))
y = sin(x)
call plt%initialize()
call plt%set_title("Sine wave")
call plt%set_x_axis_title("x")
call plt%set_y_axis_title("sin(x)")
call plt%push(x, y, lw = 2.0, name = "sin(x)")
call plt%draw()plot_2d%push creates a line data series directly from x and y. For more control, create a plot_data_2d object, call define_data, set properties such as its name, line style, markers, or color, and then pass it to plot_2d%push.
Use plot_3d for 3D curves and scatter data, surface_plot for gridded surfaces, and plot_polar for polar coordinates. plot_data_error_bars, plot_data_histogram, plot_data_bar, and vector_field_plot_data provide specialized series types. Axis and legend objects are available through get_x_axis, get_y_axis, and get_legend for detailed layout control. Invalid input and allocation failures print a diagnostic and terminate with an fplot_errors error code.
The examples directory contains complete programs for 2D and 3D plots, surfaces, histograms, error bars, vector fields, and output terminals.
The FPLOT library depends upon the following libraries.
This example illustrates how to plot two-dimensional data.
program example
use, intrinsic :: iso_fortran_env
use fplot_core
implicit none
! Parameters
integer(int32), parameter :: n = 1000
! Local Variables
real(real64), dimension(n) :: x, y1, y2
type(plot_2d) :: plt
! Initialize the plot object
call plt%initialize()
call plt%show_legend(.true.)
call plt%set_title("Example Plot")
call plt%set_x_axis_title("X Axis")
call plt%set_y_axis_title("Y Axis")
! Define the data, and then add it to the plot
x = linspace(0.0d0, 10.0d0, n)
y1 = sin(5.0d0 * x)
y2 = 2.0d0 * cos(2.0d0 * x)
call plt%push(x, y1, lw = 2.0, name = "Data Set 1")
call plt%push(x, y2, lw = 2.0, ls = LINE_DASHED, name = "Data Set 2")
! Let GNUPLOT draw the plot
call plt%draw()
end programThis is the plot resulting from the above program.

Another example of a similar two-dimensional plot to the plot in example 1 is given below. This plot shifts the x-axis to the zero point along the y-axis. Additionally, this example highlights the use of the plot_axis, legend, and plot_data_2d types to gain more control over the plot.
program example
use, intrinsic :: iso_fortran_env
use fplot_core
implicit none
! Parameters
integer(int32), parameter :: n = 1000
! Local Variables
real(real64), dimension(n) :: x, y1, y2
type(plot_2d) :: plt
type(plot_data_2d) :: d1, d2
class(plot_axis), pointer :: xAxis, yAxis
type(legend), pointer :: lgnd
! Initialize the plot object
call plt%initialize()
! Set plot properties
call plt%set_draw_border(.false.)
call plt%set_show_gridlines(.false.)
! Define the legend location
lgnd => plt%get_legend()
call lgnd%set_is_visible(.true.)
call lgnd%set_draw_inside_axes(.false.)
! Define titles
call plt%set_title("2D Example Plot 2")
xAxis => plt%get_x_axis()
call xAxis%set_title("X Axis")
call xAxis%set_zero_axis(.true.)
call xAxis%set_zero_axis_line_width(1.0)
yAxis => plt%get_y_axis()
call yAxis%set_title("Y Axis")
! Define the data, and then add it to the plot
x = linspace(0.0d0, 10.d0, n)
y1 = sin(5.0d0 * x)
y2 = 2.0d0 * cos(2.0d0 * x)
call d1%define_data(x, y1)
call d2%define_data(x, y2)
! Define properties for each data set
call d1%set_name("Data Set 1")
call d1%set_line_width(1.0)
call d2%set_name("Data Set 2")
call d2%set_line_style(LINE_DASHED)
call d2%set_line_width(2.0)
! Add the data sets to the plot
call plt%push(d1)
call plt%push(d2)
! Let GNUPLOT draw the plot
call plt%draw()
end programThis is the plot resulting from the above program.

The following example illustrates how to create a three-dimensional surface plot. The plot also leverages the FORCOLORMAP library to provide the colormap.
program example
use fplot_core
use iso_fortran_env
use forcolormap
implicit none
! Parameters
integer(int32), parameter :: m = 50
integer(int32), parameter :: n = 50
! Local Variables
real(real64), dimension(m, n, 2), target :: xy
real(real64), pointer, dimension(:,:) :: x, y
real(real64), dimension(m, n) :: z
type(surface_plot) :: plt
type(custom_colormap) :: map
type(cmap) :: colors
! Set up the colormap
call colors%set("glasgow", -8.0d0, 8.0d0)
call map%set_colormap(colors)
! Define the data
xy = meshgrid(linspace(-5.0d0, 5.0d0, n), linspace(-5.0d0, 5.0d0, m))
x => xy(:,:,1)
y => xy(:,:,2)
! Initialize the plot
call plt%initialize()
call plt%set_colormap(map)
call plt%set_x_axis_title("X Axis")
call plt%set_y_axis_title("Y Axis")
call plt%set_z_axis_title("Z Axis")
call plt%set_title("Custom Colormap")
! Establish lighting
call plt%set_use_lighting(.true.)
! Set the orientation of the plot
call plt%set_elevation(20.0d0)
call plt%set_azimuth(30.0d0)
! Define the function to plot
z = sqrt(x**2 + y**2) * sin(x**2 + y**2)
call plt%push(x, y, z)
! Draw the plot
call plt%draw()
end programThis is the plot resulting from the above program.

The following example illustrates how to create a vector-field plot. This example illustrates using one of the built-in colormaps to to help illustrate vector magnitude.
program example
use iso_fortran_env
use fplot_core
implicit none
! Local Variables
type(plot_2d) :: plt
type(vector_field_plot_data) :: ds1
class(plot_axis), pointer :: xAxis, yAxis
type(rainbow_colormap) :: cmap
real(real64), allocatable, dimension(:,:,:) :: pts
real(real64), allocatable, dimension(:,:) :: dx, dy
real(real64) :: dxdt(2)
integer(int32) :: i, j
! Create a grid of points defining the vector locations
pts = meshgrid( &
linspace(-2.0d0, 2.0d0, 20), &
linspace(-5.0d0, 5.0d0, 20))
! Compute the values of each derivative
allocate(dx(size(pts, 1), size(pts, 2)))
allocate(dy(size(pts, 1), size(pts, 2)))
do j = 1, size(pts, 2)
do i = 1, size(pts, 1)
call eqn([pts(i,j,1), pts(i,j,2)], dxdt)
dx(i,j) = dxdt(1)
dy(i,j) = dxdt(2)
end do
end do
! Define arrow properties
call ds1%set_arrow_size(0.1d0) ! 1.0 by default
call ds1%set_fill_arrow(.true.) ! .false. by default
! Create the plot
call plt%initialize()
xAxis => plt%get_x_axis()
yAxis => plt%get_y_axis()
! Define axis labels
call xAxis%set_title("x(t)")
call yAxis%set_title("dx/dt")
! Set plot style information
call xAxis%set_zero_axis(.true.)
call yAxis%set_zero_axis(.true.)
call plt%set_draw_border(.false.)
call plt%set_show_gridlines(.false.)
! Define the colormap
call plt%set_colormap(cmap)
! Add the data to the plot - color by the magnitude of gradient
call ds1%define_data(pts(:,:,1), pts(:,:,2), dx, dy, sqrt(dx**2 + dy**2))
call plt%push(ds1)
call plt%draw()
contains
! Van der Pol Equation
! x" - mu * (1 - x^2) * x' + x = 0
subroutine eqn(x, dxdt)
real(real64), intent(in) :: x(2)
real(real64), intent(out) :: dxdt(2)
real(real64), parameter :: mu = 2.0d0
dxdt(1) = x(2)
dxdt(2) = mu * (1.0d0 - x(1)**2) * x(2) - x(1)
end subroutine
end programThis is the plot resulting from the above program.

The following example illustrates how to create a polar plot.
program example
use iso_fortran_env
use fplot_core
! Local Variables
integer(int32), parameter :: npts = 1000
real(real64), parameter :: pi = 2.0d0 * acos(0.0d0)
real(real64) :: t(npts), x(npts)
type(plot_polar) :: plt
! Create a function to plot
t = linspace(-2.0d0 * pi, 2.0d0 * pi, npts)
x = t * sin(t)
! Plot the function
call plt%initialize()
call plt%set_font_size(14)
call plt%set_title("Polar Plot Example")
call plt%set_autoscale(.false.)
call plt%set_radial_limits([0.0d0, 6.0d0])
call plt%push(t, x, lw = 2.0)
call plt%draw()
end program