Loading...

DearPyGui

GPU-accelerated Python GUI framework for high-performance interactive applications

Interactive Visualization & Exploration Advanced GUI Framework
Quick Info
  • Category: Interactive Visualization & Exploration
  • Level: Advanced
  • Type: GUI Framework

Why We Recommend DearPyGui

DearPyGui excels at real-time visualization and interactive applications requiring high performance. Built on Dear ImGui, it provides immediate-mode GUI rendering with GPU acceleration, making it ideal for live data streaming, real-time signal processing, and interactive scientific visualizations.

Common Use Cases

  • Real-time data visualization and monitoring
  • Interactive signal processing applications
  • Live neural data streaming and display
  • Hardware control interfaces

Getting Started

DearPyGui is a Python GUI framework built on Dear ImGui (Immediate Mode Graphical User Interface). Unlike traditional retained-mode frameworks, DearPyGui rebuilds the UI every frame, enabling smooth real-time updates and GPU-accelerated rendering for high-performance applications.

Key Features

  • GPU acceleration: Hardware-accelerated rendering via OpenGL
  • Real-time performance: Handles thousands of data points at 60+ FPS
  • Immediate mode: Simplified state management
  • Built-in plotting: Fast line plots, scatter plots, heatmaps
  • Cross-platform: Windows, macOS, Linux
  • Pure Python: No compilation or external dependencies

When to Choose DearPyGui vs Streamlit

Use DearPyGui for:

  • Real-time data streaming (>10 Hz updates)
  • Hardware control interfaces
  • Complex interactive visualizations
  • Desktop applications requiring high performance

Use Streamlit for:

  • Web-based dashboards
  • Sharing with non-technical users
  • Rapid prototyping
  • Periodic data updates (<1 Hz)

Getting Started

import dearpygui.dearpygui as dpg
import numpy as np

dpg.create_context()

# Create window
with dpg.window(label="Neural Data Viewer", width=800, height=600):
    dpg.add_text("Live spike rate monitor")

    # Add plot
    with dpg.plot(label="Firing Rate", height=300, width=-1):
        dpg.add_plot_legend()
        dpg.add_plot_axis(dpg.mvXAxis, label="Time (s)")
        dpg.add_plot_axis(dpg.mvYAxis, label="Rate (Hz)", tag="y_axis")

        # Create data series
        dpg.add_line_series([], [], label="Neuron 1", parent="y_axis", tag="series1")

# Setup viewport
dpg.create_viewport(title="Neural Monitor", width=900, height=700)
dpg.setup_dearpygui()
dpg.show_viewport()

# Main loop
dpg.start_dearpygui()
dpg.destroy_context()

Real-Time Data Streaming

import dearpygui.dearpygui as dpg
import numpy as np
from collections import deque
import time

# Buffer for streaming data
BUFFER_SIZE = 1000
time_buffer = deque(maxlen=BUFFER_SIZE)
data_buffer = deque(maxlen=BUFFER_SIZE)
start_time = time.time()

def update_data():
    """Callback to update data stream."""
    current_time = time.time() - start_time
    # Simulate incoming neural data
    new_value = np.random.randn() + 5 * np.sin(2 * np.pi * 0.5 * current_time)

    time_buffer.append(current_time)
    data_buffer.append(new_value)

    # Update plot
    dpg.set_value("series", [list(time_buffer), list(data_buffer)])
    dpg.set_axis_limits("x_axis", current_time - 10, current_time)

dpg.create_context()

# Create window with controls
with dpg.window(label="Real-Time Neural Recording", width=1000, height=700, tag="main"):

    # Controls
    with dpg.group(horizontal=True):
        dpg.add_button(label="Start", callback=lambda: dpg.set_value("recording", True))
        dpg.add_button(label="Stop", callback=lambda: dpg.set_value("recording", False))
        dpg.add_button(label="Clear", callback=lambda: [time_buffer.clear(), data_buffer.clear()])

    dpg.add_checkbox(label="Recording", tag="recording", default_value=True)
    dpg.add_slider_float(label="Threshold", default_value=0.0, min_value=-5.0, max_value=5.0, tag="threshold")

    # Plot
    with dpg.plot(label="Neural Signal", height=500, width=-1):
        dpg.add_plot_legend()
        dpg.add_plot_axis(dpg.mvXAxis, label="Time (s)", tag="x_axis")

        with dpg.plot_axis(dpg.mvYAxis, label="Voltage (μV)", tag="y_axis"):
            dpg.add_line_series([], [], label="Signal", tag="series")
            dpg.add_hline_series([0], label="Threshold", tag="threshold_line")

    # Statistics
    with dpg.group(horizontal=True):
        dpg.add_text("Mean: ", tag="mean_text")
        dpg.add_text("Std: ", tag="std_text")
        dpg.add_text("Peaks: ", tag="peaks_text")

def update_loop():
    """Main update loop."""
    while dpg.is_dearpygui_running():
        if dpg.get_value("recording"):
            update_data()

            # Update threshold line
            threshold = dpg.get_value("threshold")
            dpg.set_value("threshold_line", [[0], [threshold]])

            # Update statistics
            if len(data_buffer) > 0:
                data_array = np.array(data_buffer)
                mean_val = np.mean(data_array)
                std_val = np.std(data_array)
                peaks = np.sum(data_array > threshold)

                dpg.set_value("mean_text", f"Mean: {mean_val:.2f}")
                dpg.set_value("std_text", f"Std: {std_val:.2f}")
                dpg.set_value("peaks_text", f"Peaks: {peaks}")

        dpg.render_dearpygui_frame()
        time.sleep(0.016)  # ~60 FPS

dpg.create_viewport(title="Neural Monitor", width=1100, height=800)
dpg.setup_dearpygui()
dpg.show_viewport()

update_loop()
dpg.destroy_context()

Multi-Channel Visualization

import dearpygui.dearpygui as dpg
import numpy as np

N_CHANNELS = 8
SAMPLE_RATE = 30000
DISPLAY_DURATION = 1.0  # seconds

def create_multichannel_viewer():
    dpg.create_context()

    with dpg.window(label="Multi-Channel Recording", width=1200, height=800, tag="main"):

        # Channel plots
        for ch in range(N_CHANNELS):
            with dpg.plot(label=f"Channel {ch}", height=80, width=-1):
                dpg.add_plot_axis(dpg.mvXAxis, label="", no_tick_labels=True, tag=f"x_axis_{ch}")
                with dpg.plot_axis(dpg.mvYAxis, label="", tag=f"y_axis_{ch}"):
                    dpg.add_line_series([], [], tag=f"series_{ch}")

                dpg.set_axis_limits(f"x_axis_{ch}", 0, DISPLAY_DURATION)
                dpg.set_axis_limits(f"y_axis_{ch}", -100, 100)

    dpg.create_viewport(title="Multi-Channel Viewer", width=1300, height=900)
    dpg.setup_dearpygui()
    dpg.show_viewport()

    # Simulate data streaming
    t = np.linspace(0, DISPLAY_DURATION, int(SAMPLE_RATE * DISPLAY_DURATION))

    while dpg.is_dearpygui_running():
        for ch in range(N_CHANNELS):
            # Generate synthetic neural-like signal
            signal = (np.random.randn(len(t)) * 10 +
                     30 * np.sin(2 * np.pi * (ch + 1) * 0.5 * t))
            dpg.set_value(f"series_{ch}", [list(t), list(signal)])

        dpg.render_dearpygui_frame()
        time.sleep(0.1)

    dpg.destroy_context()

create_multichannel_viewer()

Hardware Control Interface

import dearpygui.dearpygui as dpg

def create_control_panel():
    dpg.create_context()

    with dpg.window(label="Experiment Control", width=600, height=400):

        dpg.add_text("Stimulation Parameters")
        dpg.add_separator()

        with dpg.group():
            dpg.add_slider_float(label="Frequency (Hz)", default_value=10.0,
                                min_value=0.1, max_value=100.0, tag="freq")
            dpg.add_slider_float(label="Amplitude (V)", default_value=5.0,
                                min_value=0.0, max_value=10.0, tag="amp")
            dpg.add_slider_float(label="Duration (ms)", default_value=100.0,
                                min_value=1.0, max_value=1000.0, tag="dur")

        dpg.add_separator()

        with dpg.group(horizontal=True):
            dpg.add_button(label="Start Stimulation", callback=start_stim, width=200)
            dpg.add_button(label="Stop", callback=stop_stim, width=200)

        dpg.add_separator()
        dpg.add_text("Status: Idle", tag="status")

    dpg.create_viewport(title="Control Panel", width=700, height=500)
    dpg.setup_dearpygui()
    dpg.show_viewport()
    dpg.start_dearpygui()
    dpg.destroy_context()

def start_stim():
    freq = dpg.get_value("freq")
    amp = dpg.get_value("amp")
    dur = dpg.get_value("dur")
    dpg.set_value("status", f"Status: Running at {freq} Hz, {amp} V")
    # Send to hardware...

def stop_stim():
    dpg.set_value("status", "Status: Stopped")
    # Stop hardware...

create_control_panel()

Performance Considerations

DearPyGui can handle:

  • 1000+ data points per series at 60 FPS
  • Multiple plots simultaneously
  • Real-time updates with minimal latency

Optimization tips:

  • Use deque with maxlen for rolling buffers
  • Update only visible data ranges
  • Batch multiple series updates
  • Use appropriate sleep times in render loop

When to Use DearPyGui

Best for:

  • Closed-loop experimental control
  • Real-time neural data monitoring
  • Signal processing applications
  • Hardware interfaces
  • Desktop-only applications

Not ideal for:

  • Web deployment
  • Mobile applications
  • Non-technical end users
  • Simple static dashboards
Top