An x axis whose extent isn’t known up front

Sometimes the sweep range itself is the unknown – a search that keeps extending until a stopping condition is met, rather than a pre-planned grid. Here x grows one column at a time and the axes limits grow with it, while y and the colour scale stay fixed throughout.

The code below is exactly what you’d write against the real plotpress.qt.LiveArtist: a callback that receives one finished column at a time and pushes it to the plot, fed by a loop simulating a sweep controller that doesn’t know its own stopping point yet. Only read_next_column() is meant to be replaced, with your own instrument call.

plot 03 growing xaxis
import numpy as np
import plotpress


NY = 18
Y = np.arange(NY + 1, dtype=float)
VMIN, VMAX = 0.0, 10.0   # the instrument's own known reading range
N_STEPS_EXPECTED = 26    # only used to size the fixed x window below

fig, ax = plotpress.subplots(figsize=(7, 4.5))
mesh = LiveArtist(ax, cmap="plasma", vmin=VMIN, vmax=VMAX)
cols_collected = []

# One-time colorbar: the scale is fixed, so it never needs a per-frame
# refresh the way plot_02_systematic_fill's autoscaled one does.
m0 = ax.pcolormesh(np.array([0.0, 1.0]), Y, np.zeros((NY, 1)), cmap="plasma",
                   vmin=VMIN, vmax=VMAX)
fig.colorbar(m0, ax=ax)


def on_new_column(x0, values):
    """Called once per column the sweep finishes -- append it and redraw
    with one more column of x extent than before.
    """
    cols_collected.append(values)
    X = np.arange(len(cols_collected) + 1, dtype=float)
    C = np.column_stack(cols_collected)
    mesh.update(X, Y, C)
    ax.set_xlim(0, N_STEPS_EXPECTED)   # cla() wiped this -- fixed frame, shows how far there is to go
    ax.set_xlabel("x (sweep step)"); ax.set_ylabel("y index")
    ax.set_title(f"Growing x axis: {len(cols_collected)}/{N_STEPS_EXPECTED} columns collected")
    fig.tight_layout()


# ---------------------------------------------------------------------------
# Data acquisition -- replace this with your own sweep controller. Every-
# thing above only needs an x value and its column of readings handed to
# on_new_column() as each one finishes.
# ---------------------------------------------------------------------------
rng = np.random.default_rng(11)
rows = np.arange(NY)


def read_next_column(x0):
    """Stand-in for the sweep controller reporting a finished column at
    sweep position x0.
    """
    return (np.exp(-((rows - 9) ** 2) / 22.0) * 8.0 * np.cos(x0 / 4.0) ** 2
            + 0.15 * rng.standard_normal(NY))


for step in range(N_STEPS_EXPECTED):
    on_new_column(float(step), read_next_column(float(step)))

Total running time of the script: (0 minutes 3.040 seconds)

Gallery generated by Sphinx-Gallery