6

I'm trying to create a live plot which updates as more data is available.

import os,sys
import matplotlib.pyplot as plt

import time
import random

def live_plot():
    fig = plt.figure()
    ax = fig.add_subplot(111)

    ax.set_xlabel('Time (s)')
    ax.set_ylabel('Utilization (%)')
    ax.set_ylim([0, 100])
    ax.set_xlim(left=0.0)

    plt.ion()
    plt.show()

    start_time = time.time()
    traces = [0]
    timestamps = [0.0]
    # To infinity and beyond
    while True:
        # Because we want to draw a line, we need to give it at least two points
        # so, we pick the last point from the previous lists and append the
        # new point to it. This should allow us to create a continuous line.
        traces = [traces[-1]] + [random.randint(0, 100)]
        timestamps = [timestamps[-1]] + [time.time() - start_time]
        ax.set_xlim(right=timestamps[-1])
        ax.plot(timestamps, traces, 'b-')
        plt.draw()
        time.sleep(0.3)

def main(argv):
    live_plot()

if __name__ == '__main__':
    main(sys.argv)

The above code works. However, I'm unable to interact with the window generated by plt.show()

How can I plot live data while still being able to interact with the plot window?

1 Answer 1

3

Use plt.pause() instead of time.sleep().

The latter simply holds execution of the main thread and the GUI event loop does not run. Instead, plt.pause runs the event loop and allows you to interact with the figure.

From the documentation:

Pause for interval seconds.

If there is an active figure it will be updated and displayed, and the GUI event loop will run during the pause.

If there is no active figure, or if a non-interactive backend is in use, this executes time.sleep(interval).

Note

The event loop that allows you to interact with the figure only runs during the pause period. You will not be able to interact with the figure during computations. If the computations take a long time (say 0.5s or more) the interaction will feel "laggy". In that case it may make sense to let the computations run in a dedicated worker thread or process.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm confused..if the loop is running only during plt.pause(), then wouldn't I have to specify a large pause period just to make sure that it can receive and process all my commands (mouse drags - stretch/zoom/etc)? Could you maybe modify my example to describe what you mean?
Leave your example just like it is now and replace time.sleep(0.3) with plt.pause(0.3). You don't need a large pause period because you have one short pause period following another endlessly. If your code spends only little time between the pause commands everything should run smoothly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.