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
22 changes: 22 additions & 0 deletions autofit/non_linear/plot/samples_plotters.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@
logger = logging.getLogger(__name__)


def _corner_range_from(data):
"""Per-column ``(min, max)`` plot ranges for a corner figure.

``corner`` raises "no dynamic range" if any column has zero spread (every
sample equal). That is a legitimate input — a reduced-iteration run (e.g.
``PYAUTO_TEST_MODE=1``) or a parameter that has converged flat — so we hand
it an explicit per-column range rather than let it crash. Columns with real
spread keep their ``(min, max)``; degenerate columns are widened to a small
non-zero window centred on the value so the plot still renders.
"""
mins = np.asarray(data).min(axis=0)
maxs = np.asarray(data).max(axis=0)
plot_range = []
for lower, upper in zip(mins, maxs):
if lower == upper:
pad = max(abs(lower) * 1e-4, 1e-8)
lower, upper = lower - pad, upper + pad
plot_range.append((lower, upper))
return plot_range


@skip_in_test_mode
def corner_cornerpy(samples, path=None, filename="corner", format="show", **kwargs):
data = np.asarray(samples.parameter_lists)
Expand All @@ -34,6 +55,7 @@ def corner_cornerpy(samples, path=None, filename="corner", format="show", **kwar
data=data,
weight_list=samples.weight_list,
labels=samples.model.parameter_labels_with_superscripts_latex,
range=_corner_range_from(data),
)

output_figure(path=path, filename=filename, format=format)
Empty file.
43 changes: 43 additions & 0 deletions test_autofit/non_linear/plot/test_samples_plotters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import numpy as np

from autofit.non_linear.plot.samples_plotters import _corner_range_from


def test__corner_range__real_spread_columns_preserved():
data = np.array(
[
[1.0, 10.0],
[2.0, 20.0],
[3.0, 30.0],
]
)

plot_range = _corner_range_from(data)

assert plot_range == [(1.0, 3.0), (10.0, 30.0)]


def test__corner_range__degenerate_columns_widened_to_nonzero_span():
# Columns 0, 1, 2 have no dynamic range (all samples equal) — the input
# that made `corner` raise "no dynamic range". Column 3 has real spread.
data = np.array(
[
[0.0, 5.0, -2.0, 1.0],
[0.0, 5.0, -2.0, 2.0],
[0.0, 5.0, -2.0, 3.0],
]
)

plot_range = _corner_range_from(data)

# Every column ends up with a strictly positive width, so `corner` gets a
# valid range for all of them and does not raise.
for lower, upper in plot_range:
assert upper > lower

# Degenerate windows stay centred on the constant value.
for (lower, upper), value in zip(plot_range[:3], [0.0, 5.0, -2.0]):
assert lower < value < upper

# The real-spread column is left untouched.
assert plot_range[3] == (1.0, 3.0)
Loading