Skip to content

Commit 690b983

Browse files
krystophnyclaude
andauthored
feat: Add subplot support with grid layouts (#62)
* feat: Add subplot support with grid layouts and independent axes - Implement subplot_t type to manage individual subplot properties - Add subplots() method to create grid layouts (rows x cols) - Add subplot_plot() to add plots to specific subplots - Add subplot_set_title/xlabel/ylabel for subplot labeling - Add subplot rendering with independent coordinate systems - Create comprehensive test suite covering all subplot features - Add demo showing 2x2 and 1x3 subplot layouts Each subplot maintains its own: - Data ranges and axis limits - Title and axis labels - Plot collection - Pixel boundaries for rendering 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Address critical subplot rendering issues - Fix critical bug: Check allocation before linestyle comparison to prevent crashes - Implement proper coordinate transformation for subplot rendering - Fix empty subplot handling with default ranges - Add transform_subplot_coordinates function for proper data-to-screen mapping - Ensure all subplots render with axes even when empty This addresses the critical allocation bug flagged in PR review. * fix: Implement proper subplot coordinate transformation - Set backend coordinate system for each subplot - Use proper apply_scale_transform for subplot rendering - Remove unused transform_subplot_coordinates function - Fix coordinate mapping to work with existing backend system This addresses the rendering shortcut that caused blank subplot images. * Rebrand from fortplotlib to fortplot - Renamed all occurrences of 'fortplotlib' to 'fortplot' throughout codebase - Updated package name in fpm.toml, pyproject.toml, and CMakeLists.txt - Renamed Python package directory from python/fortplotlib to python/fortplot - Updated all documentation, README files, and examples - Updated GitHub repository URLs in documentation - Maintained consistency with existing module name 'fortplot' 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Update subplot demo output paths for FORD documentation compatibility - Change output paths from plots/ to build/example/subplot_demo/ - Add subplot_demo directory to Makefile build targets - Ensure FORD can discover subplot demo plots in expected location 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Update fpm example dependency to use local path - Change dependency from git URL to local path reference - Fixes test_system_fpm_example failure - All tests now pass 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Fix subplot rendering to properly isolate plot regions - Update backend plot_area for each subplot to constrain drawing - Save and restore plot_area when switching between subplots - Add proper subplot coordinate system setup for PNG and PDF backends - Fix subplot rendering so plots appear in correct regions - Add debug_subplot app for testing subplot functionality Previously all subplot plots were rendered in the same space. Now each subplot is properly isolated to its designated region. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Complete subplot rendering with proper axes and titles - Fixed subplot isolation by updating backend plot_area for each subplot - Replaced simple rectangle drawing with proper axes functions (draw_axes_and_labels) - Implemented separate subplot title rendering positioned above each subplot - Increased vertical gap between subplots from 0.05 to 0.08 for better title spacing - Titles now properly positioned: first row at y=25px (like main title), other rows centered in gap - All subplots now render with independent axes, tick marks, labels, and titles 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Improve subplot title positioning with proper margins - Simplified title positioning to use consistent 20px padding above subplot top - Increased top margin from 5% to 10% when using subplots to accommodate titles - Removed complex conditional positioning logic - Ensures titles stay within image bounds (minimum y=15px) - Follows matplotlib's approach of consistent padding above axes This fixes the issue where subplot titles were not visible or were being clipped due to insufficient top margin space. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Render subplot titles directly to image buffer for PNG backend - Fixed subplot title rendering by using render_text_to_image directly - Bypassed coordinate transformation that was causing incorrect positioning - Titles now render properly in screen coordinates above each subplot - Simplified implementation by removing unused LaTeX processing for now The issue was that the text() method applies data-to-screen transformation, but subplot titles need to be positioned in screen coordinates directly. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Clean up subplot title rendering implementation - Removed debug print statements and boxes - Simplified implementation for production use - Subplot titles now render correctly above each subplot - Using render_text_to_image directly for PNG backend 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Use old library name in CMake example until rename is merged The main branch still uses 'fortplotlib' as the library name, so the CMake example needs to use that name when fetching from main. This will be updated back to 'fortplot' once the rename is merged to main. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Clean up debug print statements and TODOs - Removed debug print statements from debug_subplot.f90 - Removed unnecessary print statements from subplot_demo.f90 - Cleaned up TODO comment about LaTeX processing - Kept error handling print statements (consistent with codebase pattern) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 13b1e48 commit 690b983

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1157
-227
lines changed

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ These are not suggestions - they are strict requirements that MUST be followed i
2929

3030
## Project Overview
3131

32-
**fortplotlib** is a modern Fortran plotting library providing scientific visualization with PNG, PDF, and ASCII backends.
32+
**fortplot** is a modern Fortran plotting library providing scientific visualization with PNG, PDF, and ASCII backends.
3333

3434
## API Usage
3535

CMakeLists.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.20)
2-
project(fortplotlib VERSION 2025.06.25 LANGUAGES Fortran C)
2+
project(fortplot VERSION 2025.06.25 LANGUAGES Fortran C)
33

44
# Set default build type
55
if(NOT CMAKE_BUILD_TYPE)
@@ -12,39 +12,39 @@ set(CMAKE_Fortran_FLAGS_DEBUG "-g -O0 -fcheck=all")
1212
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
1313

1414
# Automatically collect all source files from src directory
15-
file(GLOB_RECURSE FORTPLOTLIB_SOURCES "src/*.f90" "src/*.c")
15+
file(GLOB_RECURSE FORTPLOT_SOURCES "src/*.f90" "src/*.c")
1616

1717
# Create static library
18-
add_library(fortplotlib STATIC ${FORTPLOTLIB_SOURCES})
18+
add_library(fortplot STATIC ${FORTPLOT_SOURCES})
1919

2020
# Set module directory and enable position-independent code for shared library usage
21-
set_target_properties(fortplotlib PROPERTIES
21+
set_target_properties(fortplot PROPERTIES
2222
Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include
2323
POSITION_INDEPENDENT_CODE ON
2424
)
2525

2626
# Make modules available to consumers
27-
target_include_directories(fortplotlib
27+
target_include_directories(fortplot
2828
PUBLIC
2929
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
3030
$<INSTALL_INTERFACE:include>
3131
)
3232

3333
# Create alias for FetchContent compatibility
34-
add_library(fortplotlib::fortplotlib ALIAS fortplotlib)
34+
add_library(fortplot::fortplot ALIAS fortplot)
3535

3636
# Export targets for FetchContent
37-
export(TARGETS fortplotlib
38-
NAMESPACE fortplotlib::
39-
FILE ${CMAKE_CURRENT_BINARY_DIR}/fortplotlibTargets.cmake
37+
export(TARGETS fortplot
38+
NAMESPACE fortplot::
39+
FILE ${CMAKE_CURRENT_BINARY_DIR}/fortplotTargets.cmake
4040
)
4141

4242
# Check if Python interface should be built
4343
if (ENABLE_PYTHON)
4444
include(cmake/PythonHelpers.cmake)
4545
add_f90wrap_wrapper(
4646
fortplot_wrapper
47-
fortplotlib
47+
fortplot
4848
src/fortplot.f90
4949
)
5050
# After f90wrap generates files, fix the imports

Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ debug:
2525
test:
2626
fpm test $(FPM_FLAGS) $(ARGS)
2727

28-
# Run Python examples with fortplotlib (default mode)
28+
# Run Python examples with fortplot (default mode)
2929
example_python:
30-
@echo "Running Python examples with fortplotlib..."
30+
@echo "Running Python examples with fortplot..."
3131
@for dir in example/python/*/; do \
3232
if [ -f "$$dir"*.py ]; then \
3333
echo "Running $$dir"; \
@@ -104,13 +104,14 @@ create_build_dirs:
104104
@mkdir -p build/example/smart_show_demo
105105
@mkdir -p build/example/animation
106106
@mkdir -p build/example/stateful_streamplot
107+
@mkdir -p build/example/subplot_demo
107108

108109
# Help target
109110
help:
110111
@echo "Available targets:"
111112
@echo " build - Compile the project"
112113
@echo " example - Build and run all Fortran examples"
113-
@echo " example_python - Run Python examples with fortplotlib"
114+
@echo " example_python - Run Python examples with fortplot"
114115
@echo " example_matplotlib - Run Python examples with matplotlib (comparison)"
115116
@echo " debug - Build and run apps for debugging"
116117
@echo " test - Run all tests"

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# ![fortplotlib logo](media/logo.jpg)
1+
# ![fortplot logo](media/logo.jpg)
22

3-
[![codecov](https://codecov.io/gh/krystophny/fortplotlib/branch/main/graph/badge.svg)](https://codecov.io/gh/krystophny/fortplotlib)
4-
[![Documentation](https://img.shields.io/badge/docs-FORD-blue.svg)](https://krystophny.github.io/fortplotlib/)
3+
[![codecov](https://codecov.io/gh/krystophny/fortplot/branch/main/graph/badge.svg)](https://codecov.io/gh/krystophny/fortplot)
4+
[![Documentation](https://img.shields.io/badge/docs-FORD-blue.svg)](https://krystophny.github.io/fortplot/)
55

6-
Fortran-native plotting inspired by Python's `matplotlib.pyplot` and https://github.com/jacobwilliams/pyplot-fortran . This library is under active development and API still subject to change. There are no external dependencies. Ironically, it has also Python interface installable via `pip` (see below) `fortplotlib.fortplot` that can be used as a drop-in replacement for `matplotlib.pyplot` for a limited set of features.
6+
Fortran-native plotting inspired by Python's `matplotlib.pyplot` and https://github.com/jacobwilliams/pyplot-fortran . This library is under active development and API still subject to change. There are no external dependencies. Ironically, it has also Python interface installable via `pip` (see below) `fortplot.fortplot` that can be used as a drop-in replacement for `matplotlib.pyplot` for a limited set of features.
77

88
## Usage
99

@@ -111,7 +111,7 @@ to build and run them.
111111
Add to your `fpm.toml`:
112112
```toml
113113
[[dependencies]]
114-
fortplotlib = { git = "https://github.com/krystophny/fortplotlib" }
114+
fortplot = { git = "https://github.com/krystophny/fortplot" }
115115
```
116116

117117
### For CMake projects
@@ -121,20 +121,20 @@ Add to your `CMakeLists.txt`:
121121
include(FetchContent)
122122
123123
FetchContent_Declare(
124-
fortplotlib
125-
GIT_REPOSITORY https://github.com/krystophny/fortplotlib
124+
fortplot
125+
GIT_REPOSITORY https://github.com/krystophny/fortplot
126126
GIT_TAG main
127127
)
128-
FetchContent_MakeAvailable(fortplotlib)
128+
FetchContent_MakeAvailable(fortplot)
129129
130-
target_link_libraries(your_target fortplotlib::fortplotlib)
130+
target_link_libraries(your_target fortplot::fortplot)
131131
```
132132

133133
### For Python projects
134134
Install the Python package with pip:
135135

136136
```bash
137-
pip install git+https://github.com/krystophny/fortplotlib.git
137+
pip install git+https://github.com/krystophny/fortplot.git
138138
```
139139

140140
## Features

app/debug_subplot.f90

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
program debug_subplot
2+
use iso_fortran_env, only: real64, wp => real64
3+
use fortplot, only: figure_t
4+
implicit none
5+
6+
type(figure_t) :: fig
7+
real(wp) :: x(10), y(10)
8+
integer :: i, j
9+
10+
! Simple test data
11+
do i = 1, 10
12+
x(i) = real(i, wp)
13+
y(i) = real(i, wp)
14+
end do
15+
16+
! Test 1: Simple 2x1 subplot
17+
call fig%initialize(800, 400)
18+
call fig%subplots(1, 2)
19+
20+
! Add plot to first subplot
21+
call fig%subplot_plot(1, 1, x, y, label='Linear')
22+
call fig%subplot_set_title(1, 1, 'First Plot')
23+
24+
! Add plot to second subplot
25+
call fig%subplot_plot(1, 2, x, y**2, label='Quadratic')
26+
call fig%subplot_set_title(1, 2, 'Second Plot')
27+
28+
! Save the figure
29+
call fig%savefig('debug_subplot_test.png')
30+
31+
! Test 2: 2x2 subplot
32+
call fig%initialize(800, 800)
33+
call fig%subplots(2, 2)
34+
35+
do i = 1, 2
36+
do j = 1, 2
37+
call fig%subplot_plot(i, j, x, x**(real(i+j-1, wp)), label='Power')
38+
call fig%subplot_set_title(i, j, 'Subplot ' // char(48+i) // ',' // char(48+j))
39+
end do
40+
end do
41+
42+
call fig%savefig('debug_subplot_2x2.png')
43+
44+
end program debug_subplot

doc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Welcome to the fortplotlib documentation. This library provides a modern, matplotlib-inspired plotting interface for Fortran with multiple backends including PNG, PDF, and ASCII.
1+
Welcome to the fortplot documentation. This library provides a modern, matplotlib-inspired plotting interface for Fortran with multiple backends including PNG, PDF, and ASCII.
22

33
## Features
44

doc/cmake_example/CMakeLists.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.20)
2-
project(fortplotlib_cmake_example Fortran)
2+
project(fortplot_cmake_example Fortran)
33

44
# Enable Fortran
55
enable_language(Fortran)
@@ -10,16 +10,16 @@ include(FetchContent)
1010
# Fetch and build fortplotlib using CMake
1111
FetchContent_Declare(
1212
fortplotlib
13-
GIT_REPOSITORY https://github.com/krystophny/fortplotlib
13+
GIT_REPOSITORY https://github.com/krystophny/fortplot
1414
GIT_TAG main
1515
)
1616
FetchContent_MakeAvailable(fortplotlib)
1717

1818
# Create a simple test program
19-
add_executable(fortplotlib_test main.f90)
19+
add_executable(fortplot_test main.f90)
2020

21-
# Link against fortplotlib
22-
target_link_libraries(fortplotlib_test fortplotlib::fortplotlib)
21+
# Link against fortplotlib (using old name until rename is merged to main)
22+
target_link_libraries(fortplot_test fortplotlib::fortplotlib)
2323

2424
# Set Fortran compiler flags
2525
set(CMAKE_Fortran_FLAGS "-Wall -Wextra -fimplicit-none")

doc/design/axes_layout.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
This document describes the matplotlib-compatible axes and layout management system in fortplotlib, covering coordinate systems, axis scaling, tick generation, spine rendering, and layout optimization. The implementation follows matplotlib's Axes class architecture and transform system patterns while maintaining Fortran's performance characteristics.
5+
This document describes the matplotlib-compatible axes and layout management system in fortplot, covering coordinate systems, axis scaling, tick generation, spine rendering, and layout optimization. The implementation follows matplotlib's Axes class architecture and transform system patterns while maintaining Fortran's performance characteristics.
66

77
## Problem Statement
88

@@ -461,4 +461,4 @@ end subroutine
461461
- **`test/test_transforms.f90`** - Coordinate transformation verification
462462
- **`test/test_tight_layout.f90`** - Layout optimization algorithm tests
463463

464-
This implementation ensures fortplotlib provides matplotlib-compatible axes and layout management with professional coordinate systems, flexible spine positioning, automatic layout optimization, and complete multi-axes support for complex scientific visualization workflows.
464+
This implementation ensures fortplot provides matplotlib-compatible axes and layout management with professional coordinate systems, flexible spine positioning, automatic layout optimization, and complete multi-axes support for complex scientific visualization workflows.

doc/design/backends.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
This document describes the matplotlib-compatible backend architecture in fortplotlib, covering rendering systems, output formats, and drawing primitives. The implementation follows matplotlib's three-layer backend architecture while leveraging Fortran's polymorphism and type safety for high-performance scientific visualization.
5+
This document describes the matplotlib-compatible backend architecture in fortplot, covering rendering systems, output formats, and drawing primitives. The implementation follows matplotlib's three-layer backend architecture while leveraging Fortran's polymorphism and type safety for high-performance scientific visualization.
66

77
## Problem Statement
88

@@ -490,4 +490,4 @@ end subroutine
490490
- **`test/test_drawing_primitives.f90`** - Drawing API compliance tests
491491
- **`test/test_performance_backends.f90`** - Backend performance benchmarks
492492

493-
This implementation ensures fortplotlib provides matplotlib-compatible backend architecture with professional rendering capabilities, flexible output format support, sophisticated graphics state management, and high-performance optimization for scientific visualization workflows.
493+
This implementation ensures fortplot provides matplotlib-compatible backend architecture with professional rendering capabilities, flexible output format support, sophisticated graphics state management, and high-performance optimization for scientific visualization workflows.

doc/design/basic_plots.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
This document describes the matplotlib-compatible basic plotting implementation in fortplotlib, covering line plots, scatter plots, and bar charts. The implementation follows matplotlib's API and behavior exactly to ensure drop-in compatibility and familiar user experience.
5+
This document describes the matplotlib-compatible basic plotting implementation in fortplot, covering line plots, scatter plots, and bar charts. The implementation follows matplotlib's API and behavior exactly to ensure drop-in compatibility and familiar user experience.
66

77
## Problem Statement
88

@@ -294,8 +294,8 @@ end function
294294
- **`src/fortplot_markers.f90`** - Extended marker support and rendering
295295
- **`src/fortplot_linestyles.f90`** - Complete line style implementations
296296
- **`src/fortplot_colors.f90`** - Color cycle and named color support
297-
- **`python/fortplotlib/fortplot.py`** - Updated Python interface
297+
- **`python/fortplot/fortplot.py`** - Updated Python interface
298298
- **`test/test_basic_plots.f90`** - Comprehensive plotting tests
299299
- **`test/test_format_parser.f90`** - Format string parsing verification
300300

301-
This implementation ensures fortplotlib provides matplotlib-compatible basic plotting functionality with professional rendering quality and complete API compatibility for seamless migration from matplotlib-based workflows.
301+
This implementation ensures fortplot provides matplotlib-compatible basic plotting functionality with professional rendering quality and complete API compatibility for seamless migration from matplotlib-based workflows.

0 commit comments

Comments
 (0)