5 Best Ways to Display Real-Time Graphs in a Simple UI for a Python Program

πŸ’‘ Problem Formulation: You’ve built a Python program that produces dynamic data over time, such as stock prices, sensor readouts, or performance metrics. Now you want to visualize this data in real-time through a simple user interface (UI) that displays graphs with continual updates. For instance, input could be a stream of temperature values from a sensor, and the desired output is a live graph that updates with each new value.

Method 1: Using Matplotlib with Animation

Matplotlib is a widely used library for creating static, interactive, and animated visualizations in Python. For real-time graphs, the animation functionality allows the updating of plots in a loop. You use FuncAnimation from Matplotlib’s animation module to refresh the plot at a fixed interval, which is perfect for real-time data.

Here’s an example:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random

x_vals, y_vals = [], []

def animate(i):
    x_vals.append(i)
    y_vals.append(random.randint(0, 5))
    plt.cla()
    plt.plot(x_vals, y_vals)

ani = FuncAnimation(plt.gcf(), animate, interval=1000)

plt.tight_layout()
plt.show()

The graph window displays a line graph that updates every second with a new random Y value between 0 and 5.

This code sets up a simple real-time plot using Matplotlib’s FuncAnimation, which continually calls the animate function that appends new data to our lists and clears the axes before re-plotting the updated data. The interval is set to 1000 milliseconds, meaning the graph updates every second.

Method 2: Using Pyqtgraph with PyQt5

Pyqtgraph is a graphics and user interface library for Python that is intended for use in scientific and engineering applications. It is built on PyQt5 and provides fast plotting capabilities for real-time data. This can be a powerful method when combined with the Qt framework for building GUI applications, which allows for advanced UI features and robust performance.

Here’s an example:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
import pyqtgraph as pg
import numpy as np

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.graphWidget = pg.PlotWidget()
        self.setCentralWidget(self.graphWidget)

        self.x = list(range(100)) 
        self.y = [np.sin(value) for value in self.x]
        
        self.graphWidget.setBackground('w')
        
        pen = pg.mkPen(color=(255, 0, 0))
        self.data_line = self.graphWidget.plot(self.x, self.y, pen=pen)
        
        self.timer = QtCore.QTimer()
        self.timer.setInterval(50)
        self.timer.timeout.connect(self.update_plot_data)
        self.timer.start()

    def update_plot_data(self):
        self.x = self.x[1:]  
        self.x.append(self.x[-1] + 1)
        
        self.y = self.y[1:]  
        self.y.append(np.sin(self.x[-1]))
        
        self.data_line.setData(self.x, self.y)
        
app = QApplication(sys.argv)
main = MainWindow()
main.show()

sys.exit(app.exec_())

A window opens with a smooth sine wave graph that updates in real-time.

The example shows how you can use Pyqtgraph coupled with PyQt5 to produce a real-time graph. Here, the MainWindow class creates a basic window with a plotting widget. The update_plot_data method updates the x and y datasets and redraws the graph at a set interval. The result is a real-time updating sine wave.

Method 3: Using Plotly with Dash

Plotly is an interactive graphing library for Python, and it can be combined with Dash to create a web-based data dashboards. Dash is a framework for building analytical web applications, and it’s built on top of Plotly. This combination is extremely powerful for creating complex, interactive real-time graphs and deploying them as part of a web application.

Here’s an example:

import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from collections import deque
import random

app = dash.Dash(__name__)
app.layout = html.Div([
    dcc.Graph(id='live-graph', animate=True),
    dcc.Interval(
            id='graph-update',
            interval=1*1000
    ),
])

X = deque(maxlen=20)
Y = deque(maxlen=20)
X.append(1)
Y.append(1)

@app.callback(Output('live-graph', 'figure'),
              events=[Event('graph-update', 'interval')])
def update_graph_scatter():
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1]*random.uniform(-0.1,0.1))

    data = go.Scatter(
            x=list(X),
            y=list(Y),
            name='Scatter',
            mode= 'lines+markers'
    )

    return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
                                                yaxis=dict(range=[min(Y),max(Y)]),)}

if __name__ == '__main__':
    app.run_server(debug=True)

A web page is displayed with a live-updating graph.

This snippet creates a simple dashboard using the Dash framework, showing how Plotly can be used for real-time data visualization. The @app.callback decorator updates the plot in real-time using an interval. Every second, the update_graph_scatter function gets called to update the graph with new data, and this process repeats indefinitely while the server runs.

Method 4: Using Bokeh

Bokeh is an interactive visualization library that provides elegant and versatile graphics with high-performance interactivity over very large or streaming datasets. It is well-suited for creating complex visualizations for web browsers. Bokeh abstracts the JavaScript necessary for web interactions, allowing users to create complex dashboard applications directly in Python.

Here’s an example:

from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
import random

p = figure(plot_width=400, plot_height=400)
r = p.line([], [], color="firebrick", line_width=2)

ds = r.data_source

@linear()
def update(step):
    ds.data['x'].append(step)
    ds.data['y'].append(random.randint(0, 100))
    ds.trigger('data', ds.data, ds.data)

curdoc().add_root(p)
curdoc().add_periodic_callback(update, 1000)

A web application opens showing a graph that refreshes every second with a new point.

This code utilizes the Bokeh library to create a real-time line graph. The linear decorator from Bokeh’s driving module generates a simple sequence of integer steps, and with each step, a new random point is added to the plot. The add_periodic_callback function sets the update frequency, here specified as 1000 milliseconds.

Bonus One-Liner Method 5: Using the liveplot package

For an extremely straightforward approach to live-updating graphs in Python, you can use the liveplot package. This library offers a simple API for creating real-time plots with minimal setup.

Here’s an example:

from liveplot import LivePlot
import random

plot = LivePlot()
while True:
    plot.draw(random.randint(0, 10))

A simple window opens, and you’ll see a real-time line graph showing the values updating instantaneously.

This one-liner example demonstrates the elegance of the liveplot library. By instantiating a LivePlot object and calling its draw method, we are able to create a live graph that continuously updates with the values provided within an infinite loop.

Summary/Discussion

  • Method 1: Matplotlib with Animation. Strengths: Well-suited for simple real-time plotting within a Python environment. Weaknesses: Can be less performant with very high-frequency updates or complex interactive features.
  • Method 2: Pyqtgraph with PyQt5. Strengths: Provides very efficient and fast updating for real-time graphs, ideal for applications that require high performance. Weaknesses: Might be overkill for simple plots and has a steeper learning curve.
  • Method 3: Plotly with Dash. Strengths: Perfect for web-based real-time dashboards with rich interaction and features. Weaknesses: Requires knowledge of web development, and the server setup might be complex for some users.
  • Method 4: Bokeh. Strengths: Excels at creating highly interactive and real-time streaming graphs for web applications. Weaknesses: Similar to Plotly with Dash, there is the overhead of web development knowledge and server management.
  • Method 5: liveplot package. Strengths: Extremely easy to set up for basic real-time plotting. Weaknesses: Lacks advanced customization and features found in other methods.