livelossplot: an in-notebook loss plot for Keras and PyTorch training loops
Live training loss plot in Jupyter Notebook for Keras, PyTorch and others
At a glance
- What is it?
- livelossplot redraws a training loss chart inside a Jupyter output cell after every epoch. It is a small MIT-licensed Python package aimed at notebook exploration and teaching, not at long training runs that need a dashboard.
- Who is it for?
- Adopt livelossplot if your training loop runs in a Jupyter notebook and you want to see each epoch without leaving the cell, especially for short experiments and teaching. Do not adopt it for multi-day distributed runs, for headless cluster jobs, or as a replacement for an experiment-tracking service.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 52 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap livelossplot fills between a text log and TensorBoard
A Keras or PyTorch training loop already prints something. With verbose=0 there is no output at all, and with verbose=1 you get one line per epoch in which the loss is a number you have to compare against the previous number in your head. The README states the problem directly: text logs are easy, but it is easy to miss whether the model is learning, doing nothing, or overfitting. livelossplot answers that with a chart that redraws in the same Jupyter cell as training proceeds, so the shape of the curve is visible while the run is still going.
The intended user is someone working interactively. The README says the project is for training a small model in a Jupyter Notebook, and the FAQ answer to why not TensorBoard is Jupyter Notebook compatibility, for exploration and teaching, plus simplicity of use. That is a narrow, honest scope. If you already run TensorBoard or a hosted tracker, this package is not trying to replace it, and the README says so: if you want to get serious, use TensorBoard.
How the update and send cycle works
The generic API is two calls. You construct a PlotLosses object, call update with a dictionary of metric names and values, then call send, which the README describes as drawing and updating logs. In a framework callback the loop does this for you: the README's Keras example passes PlotLossesKeras() in the callbacks list of model.fit and sets verbose=0, so the notebook cell shows the plot instead of the progress bar text.
The separation between update and send is the part worth understanding, because it is what makes the package framework-agnostic. A callback adapter only has to translate whatever the framework reports per epoch (the README shows keys like acc, val_acc, loss and val_loss) into that dictionary. Everything downstream is independent of the framework. Outputs are selected at construction time, and the README shows PlotLosses(outputs=[MatplotlibPlot(), TensorboardLogger()]) as a way to draw in the notebook and write scalars elsewhere in the same run. Available outputs listed in the README are MatplotlibPlot and BokehPlot for plots, and ExtremaPrinter, TensorboardLogger and TensorboardTFLogger for logging. The naming convention is visible in the callback list: the Keras adapters are PlotLossesKeras and PlotLossesKerasTF, and there are PlotLossesPoutyne and PlotLossesIgnite for those two libraries. MainLogger is offered as a bare logger for people who want to write their own adapter.
Installing it and the supported Python floor
The README gives two equivalent install paths: uv add livelossplot or pip install livelossplot. The stated requirement is Python 3.10 or newer, which is a real constraint if your notebook kernel is still on 3.9. For throwaway scripts the README shows uv run --with livelossplot script.py, which builds an ephemeral environment without touching your project. Dependencies can also be declared inline in the script with a PEP 723 block, and the README's example pins requires-python to >=3.10 with dependencies of livelossplot and torch. For a notebook session the README suggests uv run --with livelossplot --with jupyterlab jupyter lab.
If you need unreleased changes, the README documents installing from main with uv add "livelossplot @ git+https://github.com/stared/livelossplot.git" or pip install git+https://github.com/stared/livelossplot.git. That is a moving target, so pin a commit if the notebook is something you will rerun later. The repository also ships a script.py example intended to be run directly with python script.py, which is the fastest way to check that the package imports and draws in your environment before you wire it into a real training loop.
Where the notebook-first design becomes a limitation
The redraw model assumes a live kernel and a display. A training job submitted to a scheduler, run over SSH without a notebook front end, or executed in CI has no cell to redraw, so the interactive output is simply absent. The README addresses the script case, but the value proposition there is thinner: a static chart at the end is something matplotlib already gives you.
There is a second cost that the README does not quantify: redrawing a figure every epoch is work done in the training process, and for a model with many metrics the plot can become the slowest part of a short epoch. The package offers no sampling or throttling option in the material provided, so if you train thousands of epochs you are asking for thousands of redraws. The README does not state a per-epoch overhead figure, and I have not measured one, so treat this as a design consequence rather than a benchmark. The honest reading is that livelossplot is built for runs short enough that watching every epoch is useful.
TensorBoard as the alternative, and the actual difference
The README names TensorBoard as the serious option and explains its own reason for existing as Jupyter compatibility and simplicity. The difference is architectural, not cosmetic. TensorBoard writes event files to a log directory and serves them from a separate process that you open in a browser tab; the training process never draws anything, and the chart survives the kernel dying. livelossplot inverts that: the figure lives in the notebook output cell, there is no server and no log directory to manage, and the chart is gone when the kernel is restarted unless you also attach TensorboardLogger as an output.
That inversion is exactly why the two coexist rather than compete. If your run takes hours and you want to compare several runs side by side, the event-file model wins. If you are teaching a class and want the curve to appear next to the code that produced it, a server you have to open in another tab is friction. The README's own framing, that TensorBoard is for getting serious and livelossplot is for a small model in a notebook, is a fair description of the split.
Maintenance, packaging and the MIT licence
The repository is active rather than archived, with a most recent push in July 2026 and releases v0.6.0 and v0.6.1 both dated May 2026, so the project is not in a frozen state. There is a CHANGELOG.md referenced from the README, and the badge set points at separate CI workflows for tests, external package integrations and linting, which suggests adapter breakage is at least watched for. That matters here: a package whose job is to plug into Keras, PyTorch, Poutyne and Ignite inherits the upgrade cadence of all four, and an upstream API change can break an adapter without anything changing in livelossplot itself.
The licence is MIT, which is permissive and imposes no copyleft obligation on your own code. This is not legal advice; if you redistribute the package inside a commercial product, read the licence text and your organisation's policy rather than relying on a summary. The practical upgrade cost is low for the core API, since update and send are stable-looking primitives, and higher for the callback adapters, which track other people's frameworks. Pinning a version in your notebook environment and reading CHANGELOG.md before bumping is the cheap insurance.
Who should adopt it, and what to check first
Adopt it if your training happens in a Jupyter notebook, your epochs are short enough that a redraw per epoch is not the bottleneck, and you want the curve in the same cell as the code. Adopt it too if you are teaching, where the README's own justification about exploration and teaching is the strongest case for the package. Skip it if you run on a cluster, if you need to compare many runs over time, or if you want the training process to stay free of plotting work. The README's suggestion to use TensorBoard when you want to get serious is not false modesty; it is the correct boundary.
Two things to verify before you commit. First, check that your framework has an adapter in the list the README gives (PlotLossesKeras, PlotLossesKerasTF, PlotLossesPoutyne, PlotLossesIgnite) or that you are willing to write one against the update and send API, since the generic PlotLosses path is the fallback for everything else. Second, confirm the Python version in the kernel where you will actually run, because the README states a 3.10 minimum and an old kernel will fail at install rather than at import. Running the repository's examples/script.py once with python script.py settles both questions faster than reading the source.
Editorial conclusion
Adopt livelossplot if your training loop runs in a Jupyter notebook and you want to see each epoch without leaving the cell, especially for short experiments and teaching. Do not adopt it for multi-day distributed runs, for headless cluster jobs, or as a replacement for an experiment-tracking service. Before committing, verify that your framework has a ready adapter (the README lists PlotLossesKeras, PlotLossesKerasTF, PlotLossesPoutyne and PlotLossesIgnite) and confirm that Python 3.10 or newer is available in the environment where the notebook kernel runs.
Community notes