Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Native plotting in modern Fortran

License

NotificationsYou must be signed in to change notification settings

lazy-fortran/fortplot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fortplot logo

Documentation

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).

Usage

use fortplot

Stateful API

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")

Note: Subplot Grids (Not Yet Implemented)

! 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

Object-Oriented API

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")

Advanced Examples

3D plotting

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")

Multiple plots with legend

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")

Unicode and Greek letters in scientific plots

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

Enhanced scatter plots with size/color mapping

! 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")

Surface plots (3D visualization)

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")

Contour plot with colorbar

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")

Streamplot with arrows

! 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)

Error bars for scientific data

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")

Log scale plot

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, Test, and Artifact Verification

  • Build:make build orfpm build
  • Tests:make test (full) ormake test-ci (fast subset)
  • Examples:make example (Fortran),make example_python,make example_matplotlib,make example_python_dual

Artifact Verification (required for rendering changes)

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.

Python Example Outputs

  • All Python examples now accept an optional--outdir to override output location.
  • By default, outputs are consolidated under:
    • output/example/python/fortplot/<example>/ for fortplot backend
    • output/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 annotations with coordinate systems

! 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")

Animation example

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 ffmpeg or 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.

Setup

Dependencies

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 viachoco 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

For fpm (Fortran Package Manager) projects

Add to yourfpm.toml:

[[dependencies]]fortplot = {git ="https://github.com/lazy-fortran/fortplot" }

For CMake projects

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)

Security Features

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.

Verify 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

Security Build Flags

# 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

For Python projects

Install the Python package with pip:

pip install git+https://github.com/lazy-fortran/fortplot.git

Features

Plot types

  • 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)

Backends

  • PNG (raster graphics)
  • PDF (vector graphics)
  • ASCII (terminal display)
  • Interactive display via system viewer (show())

Features

  • 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 withshow() (GUI detection for X11, Wayland, macOS, Windows)
  • Animation support withFuncAnimation (requiresffmpeg for 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

Module Architecture

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.

Testing

Run Tests

maketest

Complexity Budgets (Issue #937)

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

Control Warning Output

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

Documentation Generation

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

Branch Naming & Lifecycle

  • Naming: usefix/<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 intomain.

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.

Why though?

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

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors2

  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp