Skip to main content

live_plotter

Plot live data that updates in real time using matplotlib backend

Installing

Install:

pip install live_plotter

Usage

In this library, we have two axes of variation:

  • The first axis of variation is using either LivePlotter or LiveImagePlotter. LivePlotter create line plots. LiveImagePlotter creates image plots.

  • The second axis of variation is using either LivePlotter or FastLivePlotter. LivePlotter is more flexible and dynamic, but this results in slower updates. FastLivePlotter requires that the user specify the number of plots in the figure from the beginning, but this allows it to update faster by modifying an existing plot rather than creating a new plot from scratch.

Additionally, we have a wrapper SeparateProcessLivePlotter that takes in any of the above plotters and creates a separate process to update the plot. The above plotters run on the same process as the main process, but SeparateProcessLivePlotter is run on another process so there is much less performance overhead on the main process from plotting. Plotting takes time, so running the plotting code in the same process as the main process can significantly slow things down, especially as plots get larger. This must be done on a new process instead of a new thread because the GUI does not work on non-main threads.

Please refer to the associated example code for more details.

Options:

  • LivePlotter

  • FastLivePlotter

  • LiveImagePlotter

  • FastLiveImagePlotter

  • SeparateProcessLivePlotter

TODO: Compare with https://igitugraz.github.io/live-plotter/liveplotter.html

Live Plotter

2023-11-23_16-55-40_live_plot

Fast Live Plotter

2023-11-23_16-55-46_fast_live_plot

Live Image Plotter

2023-11-23_16-55-54_live_image_plot

Example Usage of LivePlotter

import numpy as np
from live_plotter import LivePlotter

live_plotter = LivePlotter()
x_data = []
for i in range(25):
    x_data.append(i)
    live_plotter.plot(
        y_data_list=[np.sin(x_data), np.cos(x_data)],
        titles=["sin", "cos"],
    )

Example Usage of LivePlotter (mult-line plot)

import numpy as np
from live_plotter import LivePlotter

live_plotter = LivePlotter()

new_x_data = []
for i in range(25):
    new_x_data.append(i)
    y_data = np.stack([np.sin(new_x_data), np.cos(new_x_data)], axis=1)
    live_plotter.plot(
        y_data_list=[y_data],
        titles=["sin and cos"],
        xlabels=["x"],
        ylabels=["y"],
        ylims=[(-2, 2)],
        legends=[["sin", "cos"]],
    )

Example Usage of FastLivePlotter

import numpy as np
from live_plotter import FastLivePlotter

live_plotter = FastLivePlotter(titles=["sin", "cos"], n_plots=2, n_rows=2, n_cols=1)
x_data = []
for i in range(25):
    x_data.append(i)
    live_plotter.plot(
        y_data_list=[np.sin(x_data), np.cos(x_data)],
    )

Example Usage of FastLivePlotter (multi-line plot)

import numpy as np

from live_plotter import FastLivePlotter

new_x_data = []
live_plotter = FastLivePlotter(
    n_plots=1,
    titles=["sin and cos"],
    xlabels=["x"],
    ylabels=["y"],
    ylims=[(-2, 2)],
    legends=[["sin", "cos"]],
)
for i in range(25):
    new_x_data.append(i)
    y_data = np.stack([np.sin(new_x_data), np.cos(new_x_data)], axis=1)
    live_plotter.plot(
        y_data_list=[y_data],
    )

Example Usage of FastLivePlotter (complex example)

import numpy as np

from live_plotter import FastLivePlotter

y_data_dict = {
    "exp(-x/10)": [],
    "ln(x + 1)": [],
    "x^2": [],
    "4x^4": [],
    "ln(2^x)": [],
}
plot_names = list(y_data_dict.keys())
live_plotter = FastLivePlotter(
    titles=plot_names, n_plots=len(plot_names)
)
for i in range(25):
    y_data_dict["exp(-x/10)"].append(np.exp(-i / 10))
    y_data_dict["ln(x + 1)"].append(np.log(i + 1))
    y_data_dict["x^2"].append(np.power(i, 2))
    y_data_dict["4x^4"].append(4 * np.power(i, 4))
    y_data_dict["ln(2^x)"].append(np.log(np.power(2, i)))

    live_plotter.plot(
        y_data_list=[np.array(y_data_dict[plot_name]) for plot_name in plot_names],
    )
import numpy as np
import time

from live_plotter import SeparateProcessLivePlotter, FastLivePlotter

N_ITERS = 100
SIMULATED_COMPUTATION_TIME_S = 0.1
OPTIMAL_TIME_S = N_ITERS * SIMULATED_COMPUTATION_TIME_S

# Slower when plotting is on same process
live_plotter = FastLivePlotter(
    n_plots=2, titles=["sin", "cos"]
)
x_data = []
start_time_same_process = time.time()
for i in range(N_ITERS):
    x_data.append(i)
    time.sleep(SIMULATED_COMPUTATION_TIME_S)
    live_plotter.plot(
        y_data_list=[np.sin(x_data), np.cos(x_data)],
    )
time_taken_same_process = time.time() - start_time_same_process

# Faster when plotting is on separate process
live_plotter_separate_process = SeparateProcessLivePlotter(
    live_plotter=live_plotter, plot_names=["sin", "cos"]
)
live_plotter_separate_process.start()
start_time_separate_process = time.time()
for i in range(N_ITERS):
    time.sleep(SIMULATED_COMPUTATION_TIME_S)
    live_plotter_separate_process.data_dict["sin"].append(np.sin(i))
    live_plotter_separate_process.data_dict["cos"].append(np.cos(i))
    live_plotter_separate_process.update()
time_taken_separate_process = time.time() - start_time_separate_process

print(f"Time taken same process: {round(time_taken_same_process, 1)} s")
print(f"Time taken separate process: {round(time_taken_separate_process, 1)} s")
print(f"OPTIMAL_TIME_S: {round(OPTIMAL_TIME_S, 1)} s")

assert time_taken_separate_process < time_taken_same_process

Output:

Time taken same process: 19.0 s
Time taken separate process: 10.4 s
OPTIMAL_TIME_S: 10.0 s

Note how this runs much faster than the same process code

Example Usage of LiveImagePlotter

Note:

  • images must be (M, N) or (M, N, 3) or (M, N, 4)

  • Typically images must either be floats in [0, 1] or ints in [0, 255]. If not in this range, we will automatically scale it and print a warning. We recommend using the scale_image function as shown below.

import numpy as np
from live_plotter import LiveImagePlotter, scale_image

N = 25
DEFAULT_IMAGE_HEIGHT = 100
DEFAULT_IMAGE_WIDTH = 100

live_plotter = LiveImagePlotter()

x_data = []
for i in range(N):
    x_data.append(0.5 * i)
    image_data = (
        np.sin(x_data)[None, ...]
        .repeat(DEFAULT_IMAGE_HEIGHT, 0)
        .repeat(DEFAULT_IMAGE_WIDTH // N, 1)
    )
    live_plotter.plot(image_data_list=[scale_image(image_data, min_val=-1.0, max_val=1.0)])

Example Usage of FastLiveImagePlotter

import numpy as np
from live_plotter import FastLiveImagePlotter, scale_image

N = 25
DEFAULT_IMAGE_HEIGHT = 100
DEFAULT_IMAGE_WIDTH = 100

live_plotter = FastLiveImagePlotter(
    titles=["sin", "cos"], n_plots=2, n_rows=2, n_cols=1
)
x_data = []
for i in range(N):
    x_data.append(i)
    image_data_1 = (
        np.sin(x_data)[None, ...]
        .repeat(DEFAULT_IMAGE_HEIGHT, 0)
        .repeat(DEFAULT_IMAGE_WIDTH // N, 1)
    )
    image_data_2 = (
        np.cos(x_data)[None, ...]
        .repeat(DEFAULT_IMAGE_HEIGHT, 0)
        .repeat(DEFAULT_IMAGE_WIDTH // N, 1)
    )
    live_plotter.plot(
        image_data_list=[
            scale_image(image_data_1, min_val=-1.0, max_val=1.0),
            scale_image(image_data_2),
        ],
    )

Metadata

Release files for live-plotter 4.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for live-plotter 4.1.0
File Size Uploaded Provenance
live_plotter-4.1.0.tar.gz 11.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for live-plotter 4.1.0
File Interpreter ABI Platform
live_plotter-4.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 36.1 kB

Release files / live_plotter-4.1.0.tar.gz

Download URL live_plotter-4.1.0.tar.gz
Size 11.6 kB
Tags Source
SHA-256 checksum
How to use checksums
46a8c1c722975f5f891516fcc163e884abecc27251d8d92d995c9a6fed79a0dd
BLAKE2b-256 checksum
How to use checksums
88984595aeab97b38a2e28c78b4e1ad142d2dcb48725430addc47018d04e5829
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.5

Release files / live_plotter-4.1.0-py3-none-any.whl

Download URL live_plotter-4.1.0-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c39c22ba809155fcb20191e7ebec66801817ce1b84225d3ae4b1e4ddf802b8f
BLAKE2b-256 checksum
How to use checksums
9f04b89f42b784e97942233c379035f34c2b9d6d0cab870601160e12ca79433c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.5

Security for live-plotter 4.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page