real-time plotting
data visualization
while loop
programming
Python

How do I plot in real-time in a while loop?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Real-time plotting in Python usually means updating an existing figure repeatedly as new data arrives. The important trick is not to create a brand-new plot inside every loop iteration. Instead, create the figure once, update the line data, and let Matplotlib process GUI events between iterations.

A Simple Real-Time Loop With Interactive Mode

Matplotlib can redraw incrementally if interactive mode is enabled.

python
1import random
2import time
3import matplotlib.pyplot as plt
4
5plt.ion()
6fig, ax = plt.subplots()
7line, = ax.plot([], [], color="tab:blue")
8ax.set_xlim(0, 50)
9ax.set_ylim(0, 100)
10ax.set_title("Real-time values")
11
12x_data = []
13y_data = []
14
15for i in range(50):
16    x_data.append(i)
17    y_data.append(random.randint(0, 100))
18
19    line.set_data(x_data, y_data)
20    ax.relim()
21    ax.autoscale_view()
22
23    fig.canvas.draw()
24    fig.canvas.flush_events()
25    time.sleep(0.1)
26
27plt.ioff()
28plt.show()

This works because the code updates the existing Line2D object instead of rebuilding the figure on every pass.

Why plt.pause Is Often Simpler

In many cases, plt.pause is the easiest way to keep the window responsive. It briefly yields to the GUI event loop and redraws the figure.

python
1import random
2import matplotlib.pyplot as plt
3
4plt.ion()
5fig, ax = plt.subplots()
6line, = ax.plot([], [], color="tab:red")
7
8x_data = []
9y_data = []
10
11for i in range(30):
12    x_data.append(i)
13    y_data.append(random.random())
14
15    line.set_data(x_data, y_data)
16    ax.relim()
17    ax.autoscale_view()
18    plt.pause(0.1)
19
20plt.ioff()
21plt.show()

For quick scripts, plt.pause is often enough and shorter than calling draw and flush_events manually.

Keeping the Plot Efficient

Real-time plotting slows down when the loop keeps adding new artists. That means code such as ax.plot(...) inside the loop is usually a bad sign. It creates a new line object every iteration and eventually clutters the figure.

Prefer this pattern:

  • create axes and artists once
  • update data with set_data
  • redraw

If you only want a moving window of the latest values, trim the stored data.

python
1from collections import deque
2import random
3import matplotlib.pyplot as plt
4
5x_data = deque(maxlen=20)
6y_data = deque(maxlen=20)
7
8plt.ion()
9fig, ax = plt.subplots()
10line, = ax.plot([], [])
11
12for i in range(100):
13    x_data.append(i)
14    y_data.append(random.randint(0, 10))
15
16    line.set_data(list(x_data), list(y_data))
17    ax.relim()
18    ax.autoscale_view()
19    plt.pause(0.05)
20
21plt.ioff()
22plt.show()

This keeps memory usage bounded and the chart focused on recent points.

When FuncAnimation Is Better

If the update loop is really a repeated render callback, matplotlib.animation.FuncAnimation is often a cleaner design than a raw while loop.

python
1import random
2import matplotlib.pyplot as plt
3from matplotlib.animation import FuncAnimation
4
5x_data = []
6y_data = []
7fig, ax = plt.subplots()
8line, = ax.plot([], [])
9
10
11def update(frame):
12    x_data.append(frame)
13    y_data.append(random.randint(0, 100))
14    line.set_data(x_data, y_data)
15    ax.relim()
16    ax.autoscale_view()
17    return line,
18
19ani = FuncAnimation(fig, update, frames=range(50), interval=100, blit=False)
20plt.show()

This integrates better with the Matplotlib event loop and is often more robust for GUI applications.

Real Data Sources

In real applications, the loop usually reads from a sensor, socket, serial port, or log file. The plotting logic should stay separate from the data acquisition logic so each piece remains easier to test.

If data arrives faster than the screen can refresh, do not redraw on every single sample. Buffer several values and redraw at a lower frequency.

Common Pitfalls

A common mistake is calling plt.plot repeatedly inside the loop. That creates new artists over and over instead of updating the existing one.

Another issue is forgetting to let the GUI event loop run. Without plt.pause, flush_events, or an animation framework, the window may freeze or never update.

Developers also sometimes set fixed axis limits once and then wonder why new data disappears off-screen. If the data range changes, update the limits or call relim and autoscale_view.

Finally, be realistic about refresh speed. Plotting every data point at sensor frequency is often unnecessary and can overwhelm the UI thread.

Summary

  • Create the figure once and update existing artists inside the loop.
  • Use plt.pause or event-loop flushing so the window stays responsive.
  • Avoid adding a new line on every iteration.
  • Use deques or trimming when only recent data should stay visible.
  • Consider FuncAnimation when the loop naturally fits an animation callback model.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.