Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.24)
project(
fplot
LANGUAGES Fortran
VERSION 1.8.12
VERSION 1.9.0
)


Expand Down
134 changes: 64 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,66 @@ This library is tailored to write script files for GNUPLOT. As such, GNUPLOT is
## Documentation
Documentation can be found [here](https://jchristopherson.github.io/fplot/)

## Building FPLOT
[CMake](https://cmake.org/)This library can be built using CMake. For instructions see [Running CMake](https://cmake.org/runningcmake/).
## Building
FPLOT requires a Fortran compiler with Fortran 2003 support and [Gnuplot](http://www.gnuplot.info/) on your `PATH` to render plots. The CMake and FPM builds retrieve the Fortran library dependencies automatically.

### CMake
Configure and build the library with CMake 3.24 or newer:
```sh
cmake -S . -B build -DBUILD_TESTING=ON -DBUILD_FPLOT_EXAMPLES=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failure
```

Install it to a prefix of your choice:
```sh
cmake --install build --prefix /path/to/install
```

To 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](https://github.com/fortran-lang/fpm) can also be used to build this library using the provided fpm.toml.
```txt
### FPM
[FPM](https://github.com/fortran-lang/fpm) can build and test the checked-out repository directly:
```sh
fpm build
fpm test
```
The FPLOT library can be used within your FPM project by adding the following to your fpm.toml file.

Add FPLOT to another FPM project with:
```toml
[dependencies]
fplot = { git = "https://github.com/jchristopherson/fplot" }
```

## Getting Started
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.

```fortran
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](examples) directory contains complete programs for 2D and 3D plots, surfaces, histograms, error bars, vector fields, and output terminals.

## External Libraries
The FPLOT library depends upon the following libraries.
- [FERROR](https://github.com/jchristopherson/ferror)
- [COLLECTIONS](https://github.com/jchristopherson/collections)
- [FSTRING](https://github.com/jchristopherson/fstring)
- [GEOMPACK](https://github.com/jchristopherson/geompack)
Expand All @@ -47,54 +91,22 @@ program example
! 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 :: leg

! Initialize the plot object
call plt%initialize()

! Define titles
call plt%show_legend(.true.)
call plt%set_title("Example Plot")
call plt%set_font_size(14)

xAxis => plt%get_x_axis()
call xAxis%set_title("X Axis")

yAxis => plt%get_y_axis()
call yAxis%set_title("Y Axis")

! Establish legend properties
leg => plt%get_legend()
call leg%set_is_visible(.true.)
call leg%set_draw_inside_axes(.false.)
call leg%set_horizontal_position(LEGEND_CENTER)
call leg%set_vertical_position(LEGEND_BOTTOM)
call leg%set_draw_border(.false.)
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 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_draw_markers(.true.)
call d1%set_marker_frequency(10)
call d1%set_marker_style(MARKER_EMPTY_CIRCLE)
call d1%set_marker_scaling(2.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)

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 program
Expand All @@ -103,10 +115,8 @@ This is the plot resulting from the above program.
![](images/example_2d_plot_1.png?raw=true)

## Example 2
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.
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.
```fortran
! fplot_2d_2.f90

program example
use, intrinsic :: iso_fortran_env
use fplot_core
Expand Down Expand Up @@ -178,7 +188,7 @@ The following example illustrates how to create a three-dimensional surface plot
program example
use fplot_core
use iso_fortran_env
use forcolormap, only : colormaps_list
use forcolormap
implicit none

! Parameters
Expand All @@ -190,8 +200,6 @@ program example
real(real64), pointer, dimension(:,:) :: x, y
real(real64), dimension(m, n) :: z
type(surface_plot) :: plt
type(surface_plot_data) :: d1
class(plot_axis), pointer :: xAxis, yAxis, zAxis
type(custom_colormap) :: map
type(cmap) :: colors

Expand All @@ -207,30 +215,21 @@ program example
! 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 titles
call plt%set_title("Example Plot")

xAxis => plt%get_x_axis()
call xAxis%set_title("X Axis")

yAxis => plt%get_y_axis()
call yAxis%set_title("Y Axis")

zAxis => plt%get_z_axis()
call zAxis%set_title("Z Axis")

! Define the function to plot
z = sqrt(x**2 + y**2) * sin(x**2 + y**2)
call d1%define_data(x, y, z)
call plt%push(d1)
call plt%push(x, y, z)

! Draw the plot
call plt%draw()
Expand Down Expand Up @@ -279,7 +278,6 @@ program example

! Create the plot
call plt%initialize()
call plt%set_font_size(14)
xAxis => plt%get_x_axis()
yAxis => plt%get_y_axis()

Expand Down Expand Up @@ -330,7 +328,6 @@ program example
real(real64), parameter :: pi = 2.0d0 * acos(0.0d0)
real(real64) :: t(npts), x(npts)
type(plot_polar) :: plt
type(plot_data_2d) :: pd

! Create a function to plot
t = linspace(-2.0d0 * pi, 2.0d0 * pi, npts)
Expand All @@ -342,10 +339,7 @@ program example
call plt%set_title("Polar Plot Example")
call plt%set_autoscale(.false.)
call plt%set_radial_limits([0.0d0, 6.0d0])

call pd%define_data(t, x)
call pd%set_line_width(2.0)
call plt%push(pd)
call plt%push(t, x, lw = 2.0)
call plt%draw()
end program
```
Expand Down
1 change: 0 additions & 1 deletion configure/template.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(ferror QUIET)
find_dependency(collections QUIET)
find_dependency(geompack QUIET)
find_dependency(fstring QUIET)
Expand Down
1 change: 0 additions & 1 deletion doc/src/fplot_colormap.f90
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module fplot_colormap
use iso_fortran_env
use fplot_plot_object
use strings
use ferror
use fplot_errors
use fplot_colors
use forcolormap, cmap => Colormap ! avoid conflict with the internally defined colormap type
Expand Down
1 change: 0 additions & 1 deletion doc/src/fplot_delaunay_tri_surface.f90
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ module fplot_delaunay_tri_surface
use ieee_arithmetic
use fplot_triangulations_delaunay_2d
use fplot_errors
use ferror
implicit none
private
public :: delaunay_tri_surface
Expand Down
25 changes: 20 additions & 5 deletions doc/src/fplot_errors.f90
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
module fplot_errors
use iso_fortran_env
use ferror
implicit none

type :: errors
contains
procedure :: report_error
end type

! ******************************************************************************
! ERROR CODES
! ------------------------------------------------------------------------------
Expand All @@ -19,6 +23,17 @@ module fplot_errors
!! Occurs if there is a GNUPLOT file error.

contains
! ------------------------------------------------------------------------------
subroutine report_error(this, fcn, msg, code)
class(errors), intent(inout) :: this
character(len = *), intent(in) :: fcn
character(len = *), intent(in) :: msg
integer(int32), intent(in) :: code

write(error_unit, '(A)') trim(fcn) // ': ' // trim(msg)
error stop code
end subroutine

! ------------------------------------------------------------------------------
subroutine report_memory_error(err, fcn, flag)
!! Reports a memory allocation error.
Expand All @@ -33,7 +48,7 @@ subroutine report_memory_error(err, fcn, flag)
character(len = 256) :: msg

! Define the error message
write(100, msg) "Memory allocation error returning flag ", flag, "."
write(msg, 100) "Memory allocation error returning flag ", flag, "."
call err%report_error(fcn, trim(msg), PLOT_OUT_OF_MEMORY_ERROR)

! Formatting
Expand All @@ -56,7 +71,7 @@ subroutine report_file_create_error(err, fcn, fname, flag)
character(len = 2048) :: msg

! Define the error message
write(100, msg) "File ", fname, " could not be created. The error flag ", &
write(msg, 100) "File ", fname, " could not be created. The error flag ", &
flag, " was returned."
call err%report_error(fcn, trim(msg), PLOT_GNUPLOT_FILE_ERROR)

Expand All @@ -82,7 +97,7 @@ subroutine report_array_size_mismatch_error(err, fcn, name, expected, actual)
character(len = 256) :: msg

! Define the message
write(100, msg) "Array ", name, " was found to be of length ", actual, &
write(msg, 100) "Array ", name, " was found to be of length ", actual, &
", but was expected to be of length ", expected, "."
call err%report_error(fcn, trim(msg), PLOT_ARRAY_SIZE_MISMATCH_ERROR)

Expand Down Expand Up @@ -113,7 +128,7 @@ subroutine report_matrix_size_mismatch_error(err, fcn, name, mexp, nexp, &
character(len = 256) :: msg

! Define the error
write(100, msg) "Matrix ", name, " was expected to be of size ", mexp, &
write(msg, 100) "Matrix ", name, " was expected to be of size ", mexp, &
"-by-", nexp, ", but was found to be of size ", mact, "-by-", nact, "."
call err%report_error(fcn, trim(msg), PLOT_ARRAY_SIZE_MISMATCH_ERROR)

Expand Down
1 change: 0 additions & 1 deletion doc/src/fplot_filled_plot_data.f90
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ module fplot_filled_plot_data
use fplot_plot_data
use fplot_errors
use fplot_colors
use ferror
use strings
implicit none
private
Expand Down
1 change: 0 additions & 1 deletion doc/src/fplot_multiplot.f90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module fplot_multiplot
use fplot_constants
use fplot_errors
use collections
use ferror
use strings
implicit none
private
Expand Down
1 change: 0 additions & 1 deletion doc/src/fplot_plot.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ module fplot_plot
use fplot_label
use fplot_arrow
use fplot_plot_data_function
use ferror
use strings
use collections
implicit none
Expand Down
2 changes: 0 additions & 2 deletions doc/src/fplot_plot_2d.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module fplot_plot_2d
use fplot_errors
use fplot_plot_axis
use fplot_legend
use ferror
use strings
implicit none
private
Expand Down Expand Up @@ -110,7 +109,6 @@ subroutine p2d_init(this, term, fname, err)
! Initialize the base class
! call plt_init(this, term, fname, errmgr)
call this%plot%initialize(term, fname, errmgr)
if (errmgr%has_error_occurred()) return

! Process
flag = 0
Expand Down
2 changes: 0 additions & 2 deletions doc/src/fplot_plot_3d.f90
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ module fplot_plot_3d
use fplot_constants
use fplot_plot_data
use fplot_legend
use ferror
use strings
implicit none
private
Expand Down Expand Up @@ -112,7 +111,6 @@ subroutine p3d_init(this, term, fname, err)
! Initialize the base class
! call plt_init(this, term, fname, errmgr)
call this%plot%initialize(term, fname, errmgr)
if (errmgr%has_error_occurred()) return

! Process
flag = 0
Expand Down
1 change: 0 additions & 1 deletion doc/src/fplot_plot_data.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module fplot_plot_data
use fplot_constants
use fplot_colors
use strings
use ferror
use fplot_errors
implicit none
private
Expand Down
Loading
Loading