Question: I'm trying to continuously plot data received via network using matplotlib. On the y-axis, I want to plot a particular entity, while the x-axis is the current time. The x-axis should cover a fixed period of time, ending with the current time. Here's my current test code, which simulates the data received via network with random numbers. import threading import random import time import signal import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as md class NPData(): def __init__(self, size): self.data = np.zeros((size,2)) # size rows, 2 cols self.size = size self.head = 0 def __len__(self): return self.data.__len__() def __str__(self): return str(self.data) def append(self, data): self.data[self.head] = data self.head = (self.head + 1) % self.size def get_x_range(self): return (self.data.min(axis=0)[0], self.data.max(axis=0)[0]) class Producer(threading.Thread): def __init__(self): super().__init__() random.seed() self.running = True self.data = NPData(100) def get_data(self): return self.data.data def stop(self): self.running = False def run(self): while self.running: now_ms = md.date2num(int(time.time() * 1000)) # ms sample = np.array([now_ms, np.random.randint(0,999)]) self.data.append(sample) time.sleep(0.1) prog_do_run = True def signal_handler(sig, frame): global prog_do_run prog_do_run = False def main(): signal.signal(signal.SIGINT, signal_handler) p = Producer() p.start() fig, ax = plt.subplots() xfmt = md.DateFormatter('%H:%M:%S.%f') ax.xaxis.set_major_formatter(xfmt) #ax.plot(p.get_data()) #ax.set_ylim(0,999) plt.show(block=False) while prog_do_run: x_range = p.data.get_x_range() ax.set_xlim(x_range) #ax.set_ylim(0,999) print(p.get_data()) #ax.plot(p.get_data()) plt.draw() plt.pause(0.05) p.stop()  Notes: The Producer class is supposed to emulate data received via network. I've encountered two main issues:  I'm struggling to find out what actually needs to be called inside an endless loop in order for matplotlib to continuously update a plot (efficiently). Is it draw(), plot(), pause() or a combination of those?  I've been generating milliseconds timestamps and matplotlib seems to not like them at all. The official docs say to use date2num(), which does not work. If I just use int(time.time() * 1000) or round(time.time() * 1000), I get OverflowError: int too big to convert from the formatter.  

Answer: Basically there are small errors. For example don't call ax.plot() in the loop because it adds a new line each time, which is inefficient and causes multiples lines to be drawn. I would suggest to use a single line2D object by creating it once and then update its data with set_data() insde your loop. Additionally, use fig.canvas.draw_idle() or plt.pause() to refresh; plt.pause() is the simplest for interactive updates. Another error is the date, matplotlib expects dates in "days since 0001-01-01 UTC" as floats. I would say to use datetime.datetime.now() and md.date2num() to convert to the correct format. Take in cosideration that milliseconds are not directly supported in the tick labels, but you can format them. import threading import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as md import datetime import time import signal class NPData(): def __init__(self, size): self.data = np.zeros((size,2)) self.size = size self.head = 0 self.full = False def append(self, data): self.data[self.head] = data self.head = (self.head + 1) % self.size if self.head == 0: self.full = True def get_data(self): if self.full: return np.vstack((self.data[self.head:], self.data[:self.head])) else: return self.data[:self.head] def get_x_range(self, window_seconds=10): data = self.get_data() if len(data) == 0: now = md.date2num(datetime.datetime.now()) return (now - window_seconds/86400, now) latest = data[-1,0] return (latest - window_seconds/86400, latest) class Producer(threading.Thread): def __init__(self): super().__init__() self.running = True self.data = NPData(1000) def stop(self): self.running = False def run(self): while self.running: now = datetime.datetime.now() now_num = md.date2num(now) sample = np.array([now_num, np.random.randint(0,999)]) self.data.append(sample) time.sleep(0.1) prog_do_run = True def signal_handler(sig, frame): global prog_do_run prog_do_run = False def main(): signal.signal(signal.SIGINT, signal_handler) p = Producer() p.start() fig, ax = plt.subplots() xfmt = md.DateFormatter('%H:%M:%S.%f') ax.xaxis.set_major_formatter(xfmt) line, = ax.plot([], [], 'b-') ax.set_ylim(0, 999) plt.show(block=False) while prog_do_run: data = p.data.get_data() if len(data) > 0: line.set_data(data[:,0], data[:,1]) x_range = p.data.get_x_range(window_seconds=10) ax.set_xlim(x_range) #Keep window fixed to recent data ax.figure.canvas.draw_idle() plt.pause(0.05) p.stop()