- Notifications
You must be signed in to change notification settings - Fork1
Native plotting in modern Fortran
License
lazy-fortran/fortplot
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Fortran-native plotting inspired by Python'smatplotlib.pyplot andhttps://github.com/jacobwilliams/pyplot-fortran. This library is under active development, and the API is still subject to change. There are no external dependencies for building the library itself. For verifying PDF/PNG outputs, optional tooling is recommended (see Artifact Verification).
use fortplot
use fortplot ! Provides wp=> real64 for precisionreal(wp),dimension(50):: x, y! Generate sampledatax= [(real(i-1, wp)*0.2_wp, i=1,50)]y=sin(x)call figure()call plot(x, y)call title("Function Plot")call xlabel("x")call ylabel("y")call xlim(0.0_wp,10.0_wp) ! Set x-axis limitscall ylim(-1.0_wp,1.0_wp) ! Set y-axis limitscall savefig("plot.png")
! Multiple subplots are not yet implemented.! Calling subplot(...) currently emits a warning ("subplot: Multiple! subplots not yet implemented") and only the first panel is! rendered/saved. This feature is planned for a future release.call figure(figsize=[8.0_wp,6.0_wp])call subplot(2,2,1) ! Will show warningcall plot(x,sin(x))call title("Sine Wave")call savefig("single_plot.png") ! Only first subplot will be saved
use fortplot ! Imports wp=> real64 for precisiontype(figure_t):: figreal(wp),dimension(50):: x, yfinteger:: i! Generate testdatax= [(real(i-1, wp)*0.1_wp, i=1,50)]yf=sin(x)call fig%initialize()call fig%set_title("Function Plot")call fig%set_xlabel("x")call fig%set_ylabel("y")call fig%add_plot(x, yf)call fig%savefig("plot_oo.png")
call figure(figsize=[8.0_wp,6.0_wp])call add_3d_plot(x, y, z, label="3D curve")call title("3D Line Plot")call savefig("3d_plot.png")
call figure(figsize=[8.0_wp,6.0_wp])call plot(x,sin(x), label="sin(x)", linestyle="b-")call plot(x,cos(x), label="cos(x)", linestyle="r--")call plot(x,sin(2*x), label="sin(2x)", linestyle="g:")call legend()call savefig("trig_functions.pdf")
call figure(figsize=[8.0_wp,6.0_wp])call title("Wave Functions: \psi(\omega t) = A e^{-\lambda t} sin(\omega t)")call xlabel("Time \tau (normalized)")call ylabel("Amplitude \Psi (V)")call plot(t, damped_sine, label="\alpha decay")call plot(t, damped_cosine, label="\beta oscillation")call legend()call savefig("unicode_demo.png") ! Worksin PNG, PDF, and ASCII
! Basic scatter plotcall figure()call scatter(x, y, label="Data Points")call savefig("basic_scatter.png")! Object-oriented scatter plottype(figure_t):: figreal(wp),dimension(20):: x, y, sizescall fig%initialize()call fig%scatter(x, y, label='Bubble Chart')call fig%savefig("bubble_chart.pdf")
use fortplotimplicit nonereal(wp),dimension(50):: x, y, zinteger:: i! Generate3D curvedatax= [(real(i-1, wp)*0.1_wp, i=1,50)]y=sin(x)z=cos(x)!3D surface visualizationcall figure(figsize=[8.0_wp,6.0_wp])call add_3d_plot(x, y, z, label="3D Surface Curve")call title("3D Surface Plot")call savefig("surface_3d.png")! pcolormesh for2D heatmaps is available and working! Array dimensions: z(ny,nx) with x(nx+1), y(ny+1) is the! standard scientificformat and does NOT emit warnings.! C-style z(nx,ny) is also accepted; it is transposed internally.real(wp),dimension(10,10):: z_data ! ny=10, nx=10call pcolormesh(x_grid, y_grid, z_data, colormap="viridis")
call figure()call contour_filled(x_grid, y_grid, z_data, colormap="viridis", show_colorbar=.true.)call title("Temperature Distribution")call xlabel("X Position")call ylabel("Y Position")call savefig("temperature.png")
! Basic streamplot with default arrowscall figure()call streamplot(x_grid, y_grid, u_field, v_field)call savefig("flow_field.png")! Streamplot with custom arrow size and stylecall streamplot(x_grid, y_grid, u_field, v_field, arrowsize=1.5_real64, arrowstyle='<->')! Streamlines without arrowscall streamplot(x_grid, y_grid, u_field, v_field, arrowsize=0.0_real64)
use fortplot ! Imports wp=> real64 automaticallyimplicit none! Use functional API for errorbar plots (currently supported)real(wp),dimension(20):: x, y, yerr, y_theorycall figure(figsize=[8.0_wp,6.0_wp])call errorbar(x, y, yerr=yerr, marker='o', label='Experimental data')call plot(x, y_theory, label='Theory', linestyle='-')call legend()call savefig("scientific_plot.png")
call figure()call plot(x, y)call set_xscale("log")call set_yscale("symlog", threshold=0.01_wp)call xlim(1.0e-3_wp,1.0e3_wp)call ylim(-100.0_wp,100.0_wp)call savefig("log_plot.pdf")
- Build:
make buildorfpm build - Tests:
make test(full) ormake test-ci(fast subset) - Examples:
make example(Fortran),make example_python,make example_matplotlib,make example_python_dual
Usemake verify-artifacts to run key examples and validate generated PDF/PNG/txt artifacts with strict checks.
Dependencies for verification tools:
- Arch Linux:
sudo pacman -S poppler ghostscript - Ubuntu/Debian:
sudo apt-get install -y poppler-utils ghostscript - macOS (Homebrew):
brew install poppler ghostscript
In PRs and issues for output-affecting fixes, include the exact commands run, artifact paths, and short excerpts from tools (e.g.,pdftotext) as evidence.
- All Python examples now accept an optional
--outdirto override output location. - By default, outputs are consolidated under:
output/example/python/fortplot/<example>/for fortplot backendoutput/example/python/pyplot/<example>/for matplotlib backend
- Run both backends back-to-back for quick comparisons:
make example_python_dual# or per-examplepython3 example/python/basic_plots/basic_plots.py# fortplotpython3 example/python/basic_plots/basic_plots.py --matplotlib# matplotlib
! Text annotation system is FULLY IMPLEMENTEDuse fortplottype(figure_t):: figreal(wp),dimension(50):: x, yinteger:: i! Generate sampledatax= [(real(i-1, wp)*0.1_wp, i=1,50)]y=sin(x)call figure(figsize=[8.0_wp,6.0_wp])call add_plot(x, y, label="Scientific Data", linestyle="b-")call set_title("Annotated Scientific Plot")call set_xlabel("X Variable")call set_ylabel("Y Variable")! Add text annotations with different coordinate systemscall add_text_annotation("Maximum",1.57_wp,1.0_wp, coord_type=COORD_DATA)call add_arrow_annotation("Peak→",1.2_wp,0.8_wp,1.57_wp,1.0_wp, coord_type=COORD_DATA)call add_text_annotation("Title Area",0.5_wp,0.95_wp, coord_type=COORD_FIGURE)call savefig("annotated_plot.png")
use fortplot_animationtype(figure_t):: figtype(animation_t):: animinteger:: statusreal(wp),dimension(100):: x_data, y_data! Setup figure and initial plotcall figure(figsize=[8.0_wp,6.0_wp])call add_plot(x_data, y_data, label='animated data')call title('Animation Demo')! Create animation with update functionanim= FuncAnimation(update_frame, frames=100, interval=50, fig=fig)call save_animation(anim,"animation.mp4",24, status)if (status/=0)thenprint*,"ERROR: Animation save failed. Check ffmpeg installation."print*,"Windows: choco install ffmpeg"print*,"Linux: sudo apt install ffmpeg"end ifcontainssubroutineupdate_frame(frame)integer,intent(in):: frame ! Update plotdata based on frame numbercall set_ydata(sin(x_data+real(frame, wp)*0.1_wp))endsubroutine update_frame
Windows Support (Issue #189 Fixed): Binary pipe handling and path escaping now work correctly on Windows.
Cross-Platform FFmpeg Setup:
- Windows:
choco install ffmpegor download from ffmpeg.org - Linux:
sudo apt install ffmpeg(Ubuntu/Debian) or equivalent - macOS:
brew install ffmpeg
File Validation: Useffprobe -v error -show_format filename.mp4 to verify video integrity.
For more examples, see theexample directory and run
make example
to build and run them.
Required:
- Modern Fortran compiler (gfortran-11 or newer)
- FPM (Fortran Package Manager) or CMake
Optional:
ffmpeg- Required for saving animations in compressed video formats (MP4, AVI, MKV)- Windows Support: Issue #189 fixed - binary pipes and path escaping work correctly
- Cross-platform: Install via
choco install ffmpeg(Windows),brew install ffmpeg(macOS), or package manager (Linux) - Setup Guide: SeeWindows FFmpeg Setup for Windows-specific installation
- Validation: FFprobe integration for format verification
Add to yourfpm.toml:
[[dependencies]]fortplot = {git ="https://github.com/lazy-fortran/fortplot" }
Add to yourCMakeLists.txt:
include(FetchContent)FetchContent_Declare( fortplot GIT_REPOSITORY https://github.com/lazy-fortran/fortplot GIT_TAG main)FetchContent_MakeAvailable(fortplot)target_link_libraries(your_target fortplot::fortplot)
Executable Stack Protection: fortplot prevents creation of executable stack segments which could be exploited for code injection attacks.
Trampoline Detection: The build system automatically detects and prevents nested functions that generate trampolines. All library code is trampoline-free for security compliance.
# Build with trampoline detection enabled# Requires Ninja generator (install package: ninja or ninja-build)cmake -S. -B build -G Ninja&& cmake --build build -j# Library builds successfully = trampoline-free core code# Verify no executable stack segmentsreadelf -W -l build/libfortplot.a| grep -i stack# Should return empty (no executable stack)# Test trampoline detection (should fail on example with nested function)fpm build --flag"-Werror=trampolines"2>/dev/null||echo"Trampoline detection working"# Error confirms security validation is active
# FPM: Manual security flags (as documented in fpm.toml)fpm build --flag"-Wtrampolines -Werror=trampolines"# CMake: Automatic security flags (see CMakeLists.txt lines 36-47)cmake -S. -B build -G Ninja&& cmake --build build -j# Standard development (FPM default)make build# Uses fpm.toml configuration
Install the Python package with pip:
pip install git+https://github.com/lazy-fortran/fortplot.git
- Line plots (
plot) with customizable line styles and markers - Error bars (
errorbar) with symmetric/asymmetric X/Y errors and customization - 3D line plots (
add_3d_plot) with automatic projection - 3D surface plots (
add_surface) with automatic dimension validation - Contour plots (
contour,contourf) with custom levels and colormaps - Pseudocolor mesh (
pcolormesh) with color limits and edge colors - Streamplots (
streamplot) for vector field visualization with arrows - Enhanced scatter plots (
scatter) with size/color mapping and multiple marker shapes - Bar charts (
bar,barh) - Histograms (
hist,histogram) - Images (
imshow)
- PNG (raster graphics)
- PDF (vector graphics)
- ASCII (terminal display)
- Interactive display via system viewer (
show())
- Line styles: solid (
-), dashed (--), dotted (:), dashdot (-.) - Markers: circle (
o), cross (x), square (s), diamond (D), plus (+), star (*), triangle, pentagon, hexagon - Format strings (
'r-o','b--','g:') for matplotlib compatibility - Colormaps: viridis, plasma, inferno, crest, coolwarm, jet, rocket, mako, flare
- Colorbars for contour and pcolormesh plots
- Legends with automatic positioning
- Scales: linear, log, symlog (with configurable threshold)
- Axis limits (
xlim,ylim) - Subplot grids (
subplot) - Not yet implemented (shows warning) - Interactive display with
show()(GUI detection for X11, Wayland, macOS, Windows) - Animation support with
FuncAnimation(requiresffmpegfor video formats)- 5-Layer Validation: Comprehensive framework with size, header, semantic, and external tool checks
- False Positive Prevention: Multi-criteria validation framework
- Unicode and LaTeX-style Greek letters (
\alpha,\beta,\gamma, etc.) in all backends - Security features: Executable stack protection, trampoline detection, path validation
- Text annotations (
add_text_annotation,add_arrow_annotation) with multi-coordinate systems and typography
Fortplot uses a modular architecture with focused modules under 1,000 lines each. The facade pattern maintains 100% backward compatibility:
! Your existing code works unchangeduse fortplot_pdf, only: pdf_context, create_pdf_canvastype(pdf_context):: ctxcall create_pdf_canvas(ctx,"plot.pdf",800,600)
SeeModule Architecture Guide for developer guidelines and refactoring details.
maketest# Verify heuristic procedure count budgetsmake verify-complexity# Optional: override budgetsMAX_TOTAL_PROCS=1800 MAX_PROCS_PER_FILE=50 make verify-complexity
Requiresripgrep (rg) to be installed and available on PATH.
# Suppress warnings for clean test outputFORTPLOT_SUPPRESS_WARNINGS=1 maketest# Force warnings even in CI environmentsFORTPLOT_FORCE_WARNINGS=1 maketest
SeeTesting Guide for complete testing documentation.
Generate HTML documentation using FORD:
make doc
The documentation is generated inbuild/doc/index.html and includes:
- API reference with full procedure documentation
- Source code cross-references
- Example gallery with working code
Browse documentation: Openfile:///path/to/fortplot/build/doc/index.html
- Naming: use
fix/<topic>,feat/<topic>,docs/<topic>,refactor/<topic>. - Scope: keep branches focused; one unit of change per branch.
- Lifecycle: delete branches after merge; avoid long-lived topic branches.
- Hygiene: regularly prune remote-tracking branches and local branches fully merged into
main.
Pruning helper:
# Dry-run: see what would be prunedmake git-prune# Apply pruning (removes merged local branches older than 30 days)make git-prune FORCE=1
This keeps the repository navigable and avoids metadata bloat.
Mostly for the lulz and to help make Fortran great again. In addition,there is a need for high-quality high-performance plotting directly from Fortranwith the side-effect of a higher-performance limited-feature version ofmatplotlib.pyplot.
Timing comparison
time make example_matplotlib5.13s user 0.52s system 91% cpu 6.159 totaltime make example_python1.35s user 0.17s system 97% cpu 1.562 total
About
Native plotting in modern Fortran
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Contributors2
Uh oh!
There was an error while loading.Please reload this page.
