Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion autoarray/plot/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def plot_array(
cb_unit: Optional[str] = None,
line_colors: Optional[List] = None,
origin_imshow: Optional[str] = None,
arcsec_after_decimal: Optional[bool] = None,
# --- figure control (used only when ax is None) -----------------------------
figsize: Optional[Tuple[int, int]] = None,
output_path: Optional[str] = None,
Expand Down Expand Up @@ -126,6 +127,11 @@ def plot_array(
When ``True`` a ``LogNorm`` is applied.
origin_imshow
Passed directly to ``imshow`` (``"upper"`` or ``"lower"``).
arcsec_after_decimal
Per-call override of the ``ticks.symbol_over_decimal`` config flag.
When ``True`` the arcsecond tick labels place the ``″`` symbol over the
decimal point (``3.″8``) instead of suffixing it (``3.8"``); when ``False``
the suffix form is forced. ``None`` (the default) reads the config.
figsize
Figure size in inches.
output_path
Expand Down Expand Up @@ -320,7 +326,7 @@ def plot_array(
)

if extent is not None:
apply_extent(ax, extent)
apply_extent(ax, extent, symbol_over_decimal=arcsec_after_decimal)

# --- output ----------------------------------------------------------------
if owns_figure:
Expand Down
8 changes: 7 additions & 1 deletion autoarray/plot/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def plot_grid(
buffer: float = 0.1,
extent: Optional[Tuple[float, float, float, float]] = None,
force_symmetric_extent: bool = True,
arcsec_after_decimal: Optional[bool] = None,
# --- figure control (used only when ax is None) -----------------------------
figsize: Optional[Tuple[int, int]] = None,
output_path: Optional[str] = None,
Expand Down Expand Up @@ -77,6 +78,11 @@ def plot_grid(
force_symmetric_extent
When ``True`` (and *extent* is auto-computed) the limits are made
symmetric about the origin so the plot is centred.
arcsec_after_decimal
Per-call override of the ``ticks.symbol_over_decimal`` config flag.
When ``True`` the arcsecond tick labels place the ``″`` symbol over the
decimal point (``3.″8``) instead of suffixing it (``3.8"``); when ``False``
the suffix form is forced. ``None`` (the default) reads the config.
figsize
Figure size in inches ``(width, height)``.
output_path
Expand Down Expand Up @@ -178,7 +184,7 @@ def plot_grid(
y_abs = max(abs(extent[2]), abs(extent[3]))
extent = [-x_abs, x_abs, -y_abs, y_abs]

apply_extent(ax, extent)
apply_extent(ax, extent, symbol_over_decimal=arcsec_after_decimal)

# --- output ----------------------------------------------------------------
if owns_figure:
Expand Down
8 changes: 7 additions & 1 deletion autoarray/plot/inversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def plot_inversion_reconstruction(
use_log10: bool = False,
zoom_to_brightest: bool = True,
zoom_extent_scale: float = 1.0,
arcsec_after_decimal: Optional[bool] = None,
# --- overlays ---------------------------------------------------------------
lines: Optional[List[np.ndarray]] = None,
line_colors: Optional[List] = None,
Expand Down Expand Up @@ -73,6 +74,11 @@ def plot_inversion_reconstruction(
Apply ``LogNorm``.
zoom_to_brightest
Pass through to ``mapper.extent_from``.
arcsec_after_decimal
Per-call override of the ``ticks.symbol_over_decimal`` config flag.
When ``True`` the arcsecond tick labels place the ``″`` symbol over the
decimal point (``3.″8``) instead of suffixing it (``3.8"``); when ``False``
the suffix form is forced. ``None`` (the default) reads the config.
lines
Line overlays (e.g. critical curves).
grid
Expand Down Expand Up @@ -163,7 +169,7 @@ def plot_inversion_reconstruction(
if grid is not None:
ax.scatter(grid[:, 1], grid[:, 0], s=1, c="w", alpha=0.5)

apply_extent(ax, extent)
apply_extent(ax, extent, symbol_over_decimal=arcsec_after_decimal)

apply_labels(
ax,
Expand Down
25 changes: 21 additions & 4 deletions autoarray/plot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ def _round_ticks(values: np.ndarray, sig: int = 2) -> np.ndarray:
return rounded


def _arcsec_labels(ticks) -> List[str]:
def _arcsec_labels(ticks, symbol_over_decimal: Optional[bool] = None) -> List[str]:
"""Format tick values as arcsecond coordinate strings.

Whole-number tick sets render without a decimal point, so
Expand All @@ -1117,6 +1117,16 @@ def _arcsec_labels(ticks) -> List[str]:
decimal labels keep the suffix form ``3.8"``. When
``ticks.symbol_over_decimal`` is true, labels use the double-prime arcsecond
symbol and decimal labels place it over the decimal point, e.g. ``3.″8``.

Parameters
----------
ticks
The tick values to label.
symbol_over_decimal
Per-call override of the ``ticks.symbol_over_decimal`` config flag.
``True`` forces the symbol-over-decimal form and ``False`` forces the
suffix form, whatever the config says. ``None`` (the default) reads
the config, so callers that do not pass it behave exactly as before.
"""
minus_in_math = _conf_ticks_flag("minus_in_math", False)

Expand All @@ -1132,7 +1142,9 @@ def _fmt_minus(label: str) -> str:
label if "." in label else f"{float(v):.1f}"
for label, v in zip(labels, ticks)
]
if _conf_ticks_flag("symbol_over_decimal", False):
if symbol_over_decimal is None:
symbol_over_decimal = _conf_ticks_flag("symbol_over_decimal", False)
if symbol_over_decimal:
symbol_labels = []
for label in labels:
if "." in label:
Expand All @@ -1147,13 +1159,18 @@ def _fmt_minus(label: str) -> str:
def apply_extent(
ax,
extent: Tuple[float, float, float, float],
symbol_over_decimal: Optional[bool] = None,
) -> None:
"""
Apply axis limits and inward-pulled, rounded, arcsecond-labelled ticks to *ax*.

Tick count and inward factor are read from ``visualize/general.yaml``
(``ticks.number_of_ticks_2d`` and ``ticks.extent_factor_2d``), defaulting
to 3 ticks and factor 0.75.

``symbol_over_decimal`` is a per-call override of the
``ticks.symbol_over_decimal`` config flag, forwarded to
:func:`_arcsec_labels`; ``None`` (the default) reads the config.
"""
factor = _conf_ticks("extent_factor_2d", 0.75)
n = int(_conf_ticks("number_of_ticks_2d", 3))
Expand All @@ -1166,8 +1183,8 @@ def apply_extent(
yticks = _round_ticks(_inward_ticks(ymin, ymax, factor, n))
ax.set_xticks(xticks)
ax.set_yticks(yticks)
ax.set_xticklabels(_arcsec_labels(xticks))
ax.set_yticklabels(_arcsec_labels(yticks))
ax.set_xticklabels(_arcsec_labels(xticks, symbol_over_decimal=symbol_over_decimal))
ax.set_yticklabels(_arcsec_labels(yticks, symbol_over_decimal=symbol_over_decimal))

# The y-tick labels are rotated 90 degrees elsewhere; without an explicit
# centre alignment a rotated label anchors at its right edge and visually
Expand Down
59 changes: 59 additions & 0 deletions test_autoarray/plot/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,65 @@ def test_arcsec_labels_minus_in_math():
ticks["minus_in_math"] = original_minus


def test_arcsec_labels_symbol_over_decimal_argument_overrides_config():
# The per-call argument alone switches the format on, with the config flag
# left at its default (false) and `conf.instance` never mutated.
assert _arcsec_labels([-2.1, -0.044, 2.0], symbol_over_decimal=True) == [
"-2.″1",
"-0.″044",
"2.″0",
]
assert _arcsec_labels([3.8], symbol_over_decimal=True) == ["3.″8"]
assert _arcsec_labels([-1.0, 0.0, 1.0], symbol_over_decimal=True) == [
"-1″",
"0″",
"1″",
]


def test_arcsec_labels_symbol_over_decimal_argument_false_beats_config():
# The override wins in both directions: an explicit False forces the suffix
# form even when the config flag is on.
ticks = conf.instance["visualize"]["general"]["ticks"]
original = ticks.get("symbol_over_decimal", False)
try:
ticks["symbol_over_decimal"] = True

assert _arcsec_labels([-2.1, -0.044, 2.0], symbol_over_decimal=False) == [
'-2.1"',
'-0.044"',
'2.0"',
]
assert _arcsec_labels([3.8], symbol_over_decimal=False) == ['3.8"']
finally:
ticks["symbol_over_decimal"] = original


def test_arcsec_labels_symbol_over_decimal_none_reads_config():
# None (the default) leaves the config in charge, so every existing caller
# is unchanged.
ticks = conf.instance["visualize"]["general"]["ticks"]
original = ticks.get("symbol_over_decimal", False)
try:
ticks["symbol_over_decimal"] = True

assert _arcsec_labels([-2.1, -0.044, 2.0], symbol_over_decimal=None) == [
"-2.″1",
"-0.″044",
"2.″0",
]

ticks["symbol_over_decimal"] = False

assert _arcsec_labels([-2.1, -0.044, 2.0], symbol_over_decimal=None) == [
'-2.1"',
'-0.044"',
'2.0"',
]
finally:
ticks["symbol_over_decimal"] = original


class TestNormFrom:
"""The one colour-norm helper `plot_array`, `plot_inversion_reconstruction`
and `autogalaxy.util.plot_utils.norm_from` all build their norms with.
Expand Down
Loading