diff --git a/example/test_pdf_scale_regression.f90 b/example/test_pdf_scale_regression.f90 new file mode 100644 index 00000000..62b0d2ee --- /dev/null +++ b/example/test_pdf_scale_regression.f90 @@ -0,0 +1,30 @@ +program test_pdf_scale_regression + !! Test to demonstrate PDF scale regression issue #985 + !! This test generates a simple plot that should fill the available plot area + !! but currently generates smaller plots with centering due to aspect ratio preservation + + use iso_fortran_env, only: wp => real64 + use fortplot_figure, only: figure_t + implicit none + + type(figure_t) :: fig + real(wp), parameter :: x_data(5) = [1.0_wp, 2.0_wp, 3.0_wp, 4.0_wp, 5.0_wp] + real(wp), parameter :: y_data(5) = [1.0_wp, 4.0_wp, 2.0_wp, 8.0_wp, 5.0_wp] + + ! Create figure + call fig%initialize(800, 600) + call fig%plot(x_data, y_data) + call fig%set_title("PDF Scale Regression Test - Issue #985") + call fig%set_xlabel("X values") + call fig%set_ylabel("Y values") + + ! Save PDF - this should fill the plot area but currently creates smaller plot + call fig%save("test_pdf_scale_regression.pdf") + call fig%save("test_pdf_scale_regression.png") ! For comparison + + print *, "Generated test files:" + print *, " test_pdf_scale_regression.pdf (current - smaller scale)" + print *, " test_pdf_scale_regression.png (reference - correct scale)" + print *, "Compare the scaling between PDF and PNG outputs" + +end program test_pdf_scale_regression \ No newline at end of file diff --git a/src/backends/vector/fortplot_pdf_coordinate.f90 b/src/backends/vector/fortplot_pdf_coordinate.f90 index c34911e7..f688b90f 100644 --- a/src/backends/vector/fortplot_pdf_coordinate.f90 +++ b/src/backends/vector/fortplot_pdf_coordinate.f90 @@ -47,24 +47,25 @@ subroutine normalize_to_pdf_coords(ctx, x, y, pdf_x, pdf_y) x_range = ctx%x_max - ctx%x_min y_range = ctx%y_max - ctx%y_min - ! Handle degenerate cases first (center in plot area) - left = real(ctx%plot_area%left, wp) - right = real(ctx%plot_area%left + ctx%plot_area%width, wp) + ! Frame edges + left = real(ctx%plot_area%left, wp) + right = real(ctx%plot_area%left + ctx%plot_area%width, wp) bottom = real(ctx%plot_area%bottom, wp) top = real(ctx%plot_area%bottom + ctx%plot_area%height, wp) + ! Map X using independent scale (center if degenerate) if (abs(x_range) < EPSILON) then pdf_x = left + (right - left) * 0.5_wp else x_scale = (right - left) / x_range pdf_x = (x - ctx%x_min) * x_scale + left end if - + + ! Map Y using independent scale (center if degenerate) if (abs(y_range) < EPSILON) then pdf_y = bottom + (top - bottom) * 0.5_wp else y_scale = (top - bottom) / y_range - ! PDF coordinates: Y=0 at bottom, direct mapping pdf_y = (y - ctx%y_min) * y_scale + bottom end if @@ -246,19 +247,20 @@ subroutine safe_coordinate_transform(x, y, x_min, x_max, y_min, y_max, & real(wp), parameter :: EPSILON = 1.0e-10_wp real(wp) :: x_range, y_range real(wp) :: x_scale, y_scale - + ! Calculate ranges with epsilon protection x_range = x_max - x_min y_range = y_max - y_min - - ! Handle degenerate cases by centering + + ! Map X using independent scale (center if degenerate) if (abs(x_range) < EPSILON) then pdf_x = plot_left + plot_width * 0.5_wp else x_scale = plot_width / x_range pdf_x = (x - x_min) * x_scale + plot_left end if - + + ! Map Y using independent scale (center if degenerate) if (abs(y_range) < EPSILON) then pdf_y = plot_bottom + plot_height * 0.5_wp else