diff --git a/docs/api.md b/docs/api.md index 8671cb5..69a281d 100644 --- a/docs/api.md +++ b/docs/api.md @@ -15,7 +15,7 @@ LivePlot([iterable,] *panels, total=None, initial=0, unit="step", unit_scale=1, | `iterable` | anything you would wrap with tqdm: a range, a DataLoader, an existing tqdm bar. Iterating the plot yields its items, shows a tqdm bar under the plot, and finishes the plot when the loop ends. Leave it out for nested loops and use `plot(inner)` instead. | | `*panels` | layout strings, one per panel: `"loss"`, `"return | entropy"`, `"lossD lossG | acc"`. Names separated by spaces share the left y-axis; names after `|` go on a right-hand axis. With no strings, every metric shares one panel. Metrics no string mentions get a panel of their own. | | `total`, `initial`, `unit`, `unit_scale` | tqdm's arguments, with tqdm's meaning. They define the x-axis: `x = initial + n * unit_scale`, where `n` counts items consumed. `total` is in items and fixes the x range; the single-loop form takes it from `len(iterable)`. | -| `refresh_seconds` | minimum time between redraws. `0` redraws on every arrival, as fast as rendering allows, and costs nothing while idle. | +| `refresh_seconds` | minimum time between redraws, default 0.2 s. `0` redraws on every arrival, as fast as rendering allows, and costs nothing while idle. | | `smooth` | default smoothing weight for every panel, wandb's time-weighted EMA in `[0, 1)`. | | `max_cols`, `rows`, `cols` | grid shape. `max_cols=None` gives a near-square grid. | | `progress`, `desc` | switch the tqdm bars off, or give the single-loop form's bar a description. | diff --git a/docs/guide.md b/docs/guide.md index 6190ab9..b7b70e1 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -54,7 +54,7 @@ It follows tqdm: the plot counts items consumed and never looks at their values. ## How it works -The training thread only appends numbers (about 40 µs per `log`). A separate render process owns the matplotlib figure, redraws it at most once per `refresh_seconds` (default 1; `0` means on every arrival), and sends back PNG bytes that get swapped into a fixed output cell. The output is a plain image, so it behaves identically in Jupyter, Colab, VS Code and Cursor: no widgets, no JavaScript, no CDN. +The training thread only appends numbers (about 40 µs per `log`). A separate render process owns the matplotlib figure, redraws it at most once per `refresh_seconds` (default 0.2 s; `0` means on every arrival), and sends back PNG bytes that get swapped into a fixed output cell. The output is a plain image, so it behaves identically in Jupyter, Colab, VS Code and Cursor: no widgets, no JavaScript, no CDN. Interrupting the cell is safe. Jupyter sends its interrupt to every process the kernel started; the render process ignores it, so you get a frozen plot with `plot.data` intact. A plot that is dropped without `finish()` shuts its process down when garbage collected, and the process exits by itself if the notebook kernel dies. @@ -63,7 +63,7 @@ Interrupting the cell is safe. Jupyter sends its interrupt to every process the | | | |---|---| | `total`, `initial`, `unit`, `unit_scale` | tqdm's arguments, with tqdm's meaning; they define the x-axis (see above) | -| `refresh_seconds` | minimum time between redraws (default 1.0). Points arriving in between are batched into the next frame. `0` redraws whenever new data arrives, as fast as rendering allows (roughly 0.15 s per frame at a few thousand points), and costs nothing while idle. | +| `refresh_seconds` | minimum time between redraws (default 0.2, the same interval fastprogress uses for its live bars). Points arriving in between are batched into the next frame. A frame itself takes about 0.15 s to render, so going lower mostly just keeps the renderer busy. `0` redraws whenever new data arrives, as fast as rendering allows (roughly 0.15 s per frame at a few thousand points), and costs nothing while idle. | | `max_cols`, `rows`, `cols` | grid shape; `max_cols=None` gives a near-square grid | | `progress`, `desc` | disable the bundled tqdm bars, or give the single-loop form's bar a description | | `cell_size`, `dpi` | size of each panel in inches, and PNG resolution | diff --git a/liveplot/liveplot.py b/liveplot/liveplot.py index 7a687a6..f64fdd9 100644 --- a/liveplot/liveplot.py +++ b/liveplot/liveplot.py @@ -66,7 +66,7 @@ How it works: the training thread only appends numbers (~40 us per `log`). A separate *render process* owns the matplotlib figure, redraws it at most once per -`refresh_seconds` (default 1.0; points arriving in between are batched into the +`refresh_seconds` (default 0.2; points arriving in between are batched into the next frame; 0 means redraw on every arrival, as fast as rendering allows), and sends back PNG bytes that get swapped into a fixed output cell. The output is a plain image, so it behaves the same in Jupyter, Colab, VS Code and Cursor: no widgets, no CDN, no JavaScript. The progress bar is tqdm @@ -598,7 +598,7 @@ def __init__( initial: int | float = 0, unit: str = "step", unit_scale: int | float = 1, - refresh_seconds: float = 1.0, + refresh_seconds: float = 0.2, max_cols: int | None = 3, rows: int | None = None, cols: int | None = None,