Skip to content

Commit f97b376

Browse files
Jammy2211claude
authored andcommitted
Add auto log10 contours to plot_array
Log10 plots now draw log-spaced contour lines by default. Linear plots still require explicit contours= argument. Config: contour.total_contours (default 10), contour.include_values (default false). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f40be78 commit f97b376

File tree

3 files changed

+75
-10
lines changed

3 files changed

+75
-10
lines changed

autoarray/config/visualize/general.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ colormap: autoarray # Default colormap for 2D plots. Use any matpl
1919
ticks:
2020
extent_factor_2d: 0.75 # Fraction of half-extent used for 2D tick positions (< 1.0 pulls ticks inward from edges).
2121
number_of_ticks_2d: 3 # Number of ticks on each spatial axis of 2D plots.
22+
contour:
23+
total_contours: 10 # Number of contour levels drawn over log10 (and explicit linear) plots.
24+
include_values: false # Whether to label each contour line with its value.
2225
colorbar:
2326
fraction: 0.047 # Fraction of original axes to use for the colorbar.
2427
pad: 0.01 # Padding between colorbar and axes.

autoarray/plot/array.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
numpy_grid,
2020
numpy_lines,
2121
numpy_positions,
22+
_apply_contours,
2223
)
2324

2425
_zoom_array_2d = zoom_array
@@ -270,16 +271,13 @@ def plot_array(
270271
x_fill = np.arange(len(y1))
271272
ax.fill_between(x_fill, y1, y2, alpha=0.3)
272273

273-
if contours is not None and contours > 0:
274-
try:
275-
levels = np.linspace(np.nanmin(array), np.nanmax(array), contours)
276-
cs = ax.contour(array[::-1], levels=levels, extent=extent, colors="k")
277-
try:
278-
ax.clabel(cs, levels=levels, inline=True, fontsize=8)
279-
except (ValueError, IndexError):
280-
pass
281-
except Exception:
282-
pass
274+
# Contours: auto-enabled for log10 plots; explicit int enables linear contours.
275+
if use_log10 or (contours is not None and contours > 0):
276+
_apply_contours(
277+
ax, array, extent,
278+
use_log10=use_log10,
279+
n=contours if (contours is not None and contours > 0) else None,
280+
)
283281

284282
# --- labels / ticks --------------------------------------------------------
285283
apply_labels(ax, title=title, xlabel=xlabel, ylabel=ylabel, is_subplot=not owns_figure)

autoarray/plot/utils.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,70 @@ def _apply_colorbar(
572572
)
573573

574574

575+
def _apply_contours(
576+
ax: plt.Axes,
577+
array: np.ndarray,
578+
extent,
579+
use_log10: bool = False,
580+
n: Optional[int] = None,
581+
) -> None:
582+
"""Draw contour lines over a 2D image panel.
583+
584+
For log10 plots contours are drawn automatically with log-spaced levels.
585+
For linear plots contours are only drawn when *n* is given explicitly.
586+
587+
Level count and label visibility are read from the ``contour`` section of
588+
``visualize/general.yaml`` (keys ``total_contours`` and
589+
``include_values``). The *n* argument overrides ``total_contours`` when
590+
provided.
591+
592+
Parameters
593+
----------
594+
ax
595+
The axes to draw on.
596+
array
597+
2D numpy array of the plotted data (after any clipping/normalisation).
598+
extent
599+
``[xmin, xmax, ymin, ymax]`` passed to ``ax.contour``.
600+
use_log10
601+
When ``True`` levels are log-spaced between the positive minimum and
602+
maximum of *array*.
603+
n
604+
Explicit number of contour levels (overrides config). When ``None``
605+
the config value is used.
606+
"""
607+
try:
608+
from autoconf import conf
609+
_c = conf.instance["visualize"]["general"]["contour"]
610+
total = int(n if n is not None else _c.get("total_contours", 10))
611+
include_values = bool(_c.get("include_values", False))
612+
except Exception:
613+
total = int(n) if n is not None else 10
614+
include_values = False
615+
616+
try:
617+
if use_log10:
618+
positive = array[array > 0]
619+
if positive.size == 0:
620+
return
621+
levels = np.logspace(
622+
np.log10(float(np.nanmin(positive))),
623+
np.log10(float(np.nanmax(array))),
624+
total,
625+
)
626+
else:
627+
levels = np.linspace(float(np.nanmin(array)), float(np.nanmax(array)), total)
628+
629+
cs = ax.contour(array[::-1], levels=levels, extent=extent, colors="k", alpha=0.5)
630+
if include_values:
631+
try:
632+
ax.clabel(cs, levels=levels, inline=True, fontsize=8)
633+
except (ValueError, IndexError):
634+
pass
635+
except Exception:
636+
pass
637+
638+
575639
def hide_unused_axes(axes) -> None:
576640
"""Turn off any axes in the flattened *axes* array that have no plotted data."""
577641
for ax in axes:

0 commit comments

Comments
 (0)