fortplot_polar_text_layout Module

Text-backend polar layout policy (issue #2072).

Character terminals cannot overlay labels, spokes, and dense curve data the way a raster backend can, so the text backend needs a deterministic cell layout for polar plots. This module owns the geometry that keeps angular/radial labels and legend text off the plotted glyphs:

  • polar_to_text_cell maps a (theta, r) sample to an integer canvas cell, keeping Matplotlib's orientation (0 rad at east, angle increasing counter-clockwise) as the geometry oracle.
  • inside_polar_frame clips samples to the drawn circular frame so the rose never spills into the label ring outside the boundary.
  • reserve_label_cells/can_place_data mark and query cells that labels own, so curve glyphs are suppressed there rather than crowding the labels (gnuplot dumb and plotext do the same for terminals).


Derived Types

type, public ::  polar_frame_t

Circular frame expressed in canvas cells. radius_cols and radius_rows differ because a character cell is taller than wide.

Components

Type Visibility Attributes Name Initial
integer, public :: center_row = 0
integer, public :: center_col = 0
integer, public :: radius_rows = 0
integer, public :: radius_cols = 0

Functions

public pure function inside_polar_frame(frame, row, col) result(inside)

True when the cell lies within the circular frame (elliptical in cell space because of the character aspect ratio).

Arguments

Type IntentOptional Attributes Name
type(polar_frame_t), intent(in) :: frame
integer, intent(in) :: row
integer, intent(in) :: col

Return Value logical

public pure function can_place_data(reserved, row, col) result(ok)

True when a data glyph may occupy the cell (in bounds and not reserved for a label).

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: reserved(:,:)
integer, intent(in) :: row
integer, intent(in) :: col

Return Value logical


Subroutines

public pure subroutine polar_to_text_cell(frame, theta, r, r_max, theta_offset, clockwise, row, col)

Map a polar sample to a canvas cell. r_max is the shared radial axis maximum so r == r_max lands on the circular boundary.

Arguments

Type IntentOptional Attributes Name
type(polar_frame_t), intent(in) :: frame
real(kind=wp), intent(in) :: theta
real(kind=wp), intent(in) :: r
real(kind=wp), intent(in) :: r_max
real(kind=wp), intent(in) :: theta_offset
logical, intent(in) :: clockwise
integer, intent(out) :: row
integer, intent(out) :: col

public pure subroutine reserve_label_cells(reserved, row, col, span, halo)

Reserve a label footprint of span cells starting at (row, col) plus a halo border, so plotted data is kept clear of the label.

Arguments

Type IntentOptional Attributes Name
logical, intent(inout) :: reserved(:,:)
integer, intent(in) :: row
integer, intent(in) :: col
integer, intent(in) :: span
integer, intent(in) :: halo