Skip to content

liveplot.warm(): keep a render process ready so plots appear immediately - #12

Merged
davidquarel merged 1 commit into
readme-minimalfrom
warm
Sep 20, 2026
Merged

davidquarel merged 1 commit into
readme-minimalfrom
warm

Conversation

@davidquarel

Copy link
Copy Markdown
Collaborator

Example

import liveplot
from liveplot import LivePlot

liveplot.warm()        # once, in a setup cell: a render process is kept ready in the background

plot = LivePlot(loader, "loss | acc")     # ... so this plot's first frame appears right away
for batch in plot:
    plot.log(loss=train_step(batch))

What

A plot's first frame used to wait ~0.75 s for its render process, and nearly all of that is a fresh Python importing matplotlib (process start 0.04 s, import and figure 0.55 s, first draw 0.05 s). The render worker now does that warm-up first and then waits for its configuration, so a process can be started before any plot exists.

liveplot.warm() starts one. Each LivePlot adopts the waiting process and a replacement starts in the background, so every later plot is fast too. It's opt-in: without warm() nothing changes and no process is kept. The spare ignores interrupts and exits when the kernel dies, like the renderer always has.

The tour's setup cell (examples/demo.py) now calls it, and the guide and API pages document it.

Measured

In a real kernel via nbclient, three plots in a row with a 2 s gap between cells (someone reading the notebook):

plot 1 plot 2 plot 3
without warm() 0.76 s 0.72 s 0.78 s
with warm() 0.21 s 0.24 s 0.21 s

If cells run back to back with no gap, a plot can adopt a replacement that is still warming up and gets part of the benefit (measured 0.59 s).

No demo GIF: a recording starts at the first frame, so the wait this removes can't be seen in one; the table is the evidence.

Verified

tests/test_warm.py: warm() is exported and idempotent; a plot adopts the spare and a replacement starts; the warm first frame is under 0.4 s; a dead spare is replaced rather than used; an unused spare exits when its parent dies; and without warm() plots leave no process behind. Full suite: 39 passed. The tour runs end to end as a script; the site builds strict-clean.

Stacked on #11.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G9zs684RFxHvW6cNWqTPSF

@info-arena
info-arena added this pull request to stack #13 September 17, 2026 18:52
Base automatically changed from refresh-default to readme-minimal September 17, 2026 18:53
A plot's first frame waited ~0.75 s for its render process, almost all of
it a fresh Python importing matplotlib. The render worker now does that
warm-up first and then waits for its configuration, so a process can be
started before any plot exists. warm() starts one; each LivePlot adopts
the waiting process and a replacement starts in the background. Opt-in:
without warm() nothing changes and no process is left behind.

Measured in a real kernel, three plots in a row with a 2 s gap between
cells: first frame 0.72-0.78 s cold, 0.21-0.24 s with warm().

The demo's setup cell calls it; the guide and API pages document it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9zs684RFxHvW6cNWqTPSF
@davidquarel
davidquarel merged commit 29fdd09 into readme-minimal Sep 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant