Skip to content

Commit d99ec2b

Browse files
author
James Nightingale
authored
Merge pull request #653 from PyAutoLabs/feature/point-fit-source-plane-panel
fix: adaptive tick significant figures so apply_extent ticks never collapse
2 parents 086c727 + 883acc7 commit d99ec2b

2 files changed

Lines changed: 53 additions & 9 deletions

File tree

‎autoarray/plot/utils.py‎

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,20 +1143,32 @@ def _inward_ticks(lo: float, hi: float, factor: float, n: int) -> np.ndarray:
11431143
)
11441144

11451145

1146-
def _round_ticks(values: np.ndarray, sig: int = 2) -> np.ndarray:
1147-
"""Round *values* to *sig* significant figures.
1146+
def _round_ticks(values: np.ndarray, sig: int = 2, max_sig: int = 10) -> np.ndarray:
1147+
"""Round *values* to *sig* significant figures, adding figures until distinct ticks stay distinct.
1148+
1149+
Two significant figures suit an extent that spans its own magnitude (e.g. -2" to 2"), but on a
1150+
narrow extent far from zero (a few milli-arcseconds at 1.2") every tick rounds to the same value
1151+
and the labels collapse to one repeated number. The significant figures are therefore raised, up
1152+
to *max_sig*, until the rounded ticks are as distinct as the input ticks.
11481153
11491154
After rounding, values smaller than 1e-10 of the overall tick scale are
11501155
clamped to zero so that floating-point noise (e.g. 1e-16 centre ticks on
11511156
symmetric extents) does not appear as scientific notation in labels.
11521157
"""
1153-
with np.errstate(divide="ignore", invalid="ignore"):
1154-
nonzero = np.where(values != 0, np.abs(values), 1.0)
1155-
mags = np.where(values != 0, 10 ** (sig - 1 - np.floor(np.log10(nonzero))), 1.0)
1156-
rounded = np.round(values * mags) / mags
1157-
scale = float(np.max(np.abs(rounded))) if len(rounded) > 0 else 1.0
1158-
if scale > 0:
1159-
rounded[np.abs(rounded) < scale * 1e-10] = 0.0
1158+
values = np.asarray(values, dtype=float)
1159+
n_distinct = len(np.unique(values))
1160+
for n_sig in range(sig, max(sig, max_sig) + 1):
1161+
with np.errstate(divide="ignore", invalid="ignore"):
1162+
nonzero = np.where(values != 0, np.abs(values), 1.0)
1163+
mags = np.where(
1164+
values != 0, 10 ** (n_sig - 1 - np.floor(np.log10(nonzero))), 1.0
1165+
)
1166+
rounded = np.round(values * mags) / mags
1167+
scale = float(np.max(np.abs(rounded))) if len(rounded) > 0 else 1.0
1168+
if scale > 0:
1169+
rounded[np.abs(rounded) < scale * 1e-10] = 0.0
1170+
if len(np.unique(rounded)) == n_distinct:
1171+
break
11601172
return rounded
11611173

11621174

‎test_autoarray/plot/test_utils.py‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,35 @@ def test__plot_regions__single_polygon_region_is_labelled_once():
619619
)
620620
finally:
621621
plt.close(figure)
622+
623+
624+
def test__round_ticks__two_significant_figures_by_default():
625+
from autoarray.plot.utils import _round_ticks
626+
627+
assert list(_round_ticks(np.array([-1.875, 0.0, 1.875]))) == [-1.9, 0.0, 1.9]
628+
629+
630+
def test__round_ticks__adds_significant_figures_until_ticks_are_distinct():
631+
from autoarray.plot.utils import _round_ticks
632+
633+
# A few milli-arcseconds at 1.2": two (and three) significant figures collapse every tick to 1.2.
634+
ticks = _round_ticks(np.array([1.19655, 1.2, 1.20345]))
635+
636+
assert len(np.unique(ticks)) == 3
637+
assert list(ticks) == [1.197, 1.2, 1.203]
638+
639+
640+
def test__apply_extent__narrow_extent_far_from_zero_has_distinct_tick_labels():
641+
import matplotlib.pyplot as plt
642+
643+
from autoarray.plot.utils import apply_extent
644+
645+
fig, ax = plt.subplots()
646+
apply_extent(ax, [1.1954, 1.2046, -0.8046, -0.7954])
647+
648+
xlabels = [label.get_text() for label in ax.get_xticklabels()]
649+
ylabels = [label.get_text() for label in ax.get_yticklabels()]
650+
plt.close(fig)
651+
652+
assert len(set(xlabels)) == len(xlabels) == 3
653+
assert len(set(ylabels)) == len(ylabels) == 3

0 commit comments

Comments
 (0)