Pglive - Pglive package adds support for thread-safe live plotting to pyqtgraph

Overview

Live pyqtgraph plot

Pglive package adds support for thread-safe live plotting to pyqtgraph.
It supports PyQt5 and PyQt6.

Description

By default, pyqtgraph doesn't support live plotting. Aim of this package is to provide easy implementation of Line, Scatter and Bar Live plot. Every plot is connected with it's DataConnector, which sole purpose is to consume data points and manage data re-plotting. DataConnector interface provides Pause and Resume method, update rate and maximum number of plotted points. Each time data point is collected, call DataConnector.cb_set_data or DataConnector.cb_append_data_point callback. That's all You need to update plot with new data. Callbacks are Thread safe, so it works nicely in applications with multiple data collection Threads.

Focus on data collection and leave plotting to pglive.

To make firsts steps easy, package comes with many examples implemented in PyQt5 or PyQt6.

Code examples

import sys
from math import sin
from threading import Thread
from time import sleep

from PyQt6.QtWidgets import QApplication

from pglive.sources.data_connector import DataConnector
from pglive.sources.live_plot import LiveLinePlot
from pglive.sources.live_plot_widget import LivePlotWidget

"""
In this example Line plot is displayed.
"""
app = QApplication(sys.argv)
running = True

plot_widget = LivePlotWidget(title="Line Plot @ 100Hz")
plot_curve = LiveLinePlot()
plot_widget.addItem(plot_curve)
# DataConnector holding 600 points and plots @ 100Hz
data_connector = DataConnector(plot_curve, max_points=600, update_rate=100)


def sin_wave_generator(connector):
    """Sinus wave generator"""
    x = 0
    while running:
        x += 1
        data_point = sin(x * 0.01)
        # Callback to plot new data point
        connector.cb_append_data_point(data_point, x)

        sleep(0.01)


plot_widget.show()
Thread(target=sin_wave_generator, args=(data_connector,)).start()
app.exec()
running = False

Output:

Plot example

To run built-in examples, use python3 -m parameter like:
python3 -m pglive.examples_pyqt6.all_plot_types
python3 -m pglive.examples_pyqt6.crosshair

Available plot types

Pglive supports four plot types: LiveLinePlot, LiveScatterPlot, LiveHBarPlot (horizontal bar plot) and LiveVBarPlot (vertical bar plot).

All plot types

Crosshair

Pglive comes with built-in Crosshair as well.

Crosshair

Axis

To make life easier, pglive includes few axis improvements:

  • Colored axis line using new axisPen attribute
  • Time and DateTime tick format, converting timestamp into human readable format

Crosshair

Summary

  • With Pglive You've got easy Thread-safe implementation of fast Live plots
  • You can use all kwargs specified in pyqtgraph
  • Focus on Data Handling, not Data Plotting
Comments
  • version 0.4.4 - after cb_set_data, x,y view range is not auto set. whereas it works perfectly in 0.3.3

    version 0.4.4 - after cb_set_data, x,y view range is not auto set. whereas it works perfectly in 0.3.3

    Dear Sir, I have been using pglive 0.3.3 and very much impressed with your work. Thank you very much for developing the module, it really simplifies the development effort to making pyqtgraph live. I use pglive for plotting live stock quote (just a live line plot, i have also tested candleplot too).

    problem : I have recently updated the version to 0.4.4 and my previously working code is not usable now. I use livelineplot, and cb_set_data and cb_append_data_point to load initial data and append live data respectively. In the ver0.3.3, when the initial set of historical data is loaded using cb_set_data, the x,y axis view is is properly set and can see the plot (even if live data is unavailable). Whereas in the ver0.4.4, possibly because of introducing the x and y live axis controller, once initial data is set using cb_set_data , the plot view is blank. Note,I use datetime axis on X. Once cb_set_data command is issued, the x axis defaults to epoch (1970) and y axis is 0 to1. I am unable to autorange even by clicking the 'A' button of pyqtgraph which is on the bottom left.

    However, once the live data arrives, the plot shows up in the view box. Please let me know the method to enable x,y auto range during normal conditions (i.e, prior to the arrival of live data). I need to view historical data sometimes, when the live tick is not available. Actually, I would like to know the autorange command just like we use for pg.PlotWidget so that i can enable it as and when the view changes. I do not want to use pg.PlotWidget commands like setXrange, setLimits etc beacuse it interferes with pglive auto range features during live tick plotting.

    opened by vvdigitaal 9
  • Horizontal Bar chart with categories

    Horizontal Bar chart with categories

    Hello,

    I have successfully been using PGlive for awhile now and love it.

    Can PGlive do Horizontal Bar chart with categories like below?

    Barchart

    If so can you add some details to accomplish this? Categories on the Y-axis and keep the time on the X-axis.

    Thanks for a great charting app!

    opened by optio50 9
  • Append data and set data difference

    Append data and set data difference

    Hi, I am a little confused with cb_set_data and cb_append_data_point. Source code says, it "replaces current data" for cb_set_data, and "appends new data point" for cb_append_data_point. My understanding is that, when using cb_append_data_point, we can retain old data. For instance, if the plot widget is set to max_points of 600, the plot will start scrolling when it reaches max_points, but we will be able to pan and look at the past data if cb_append_data_point is used. Whereas, if we use cb_set_data, points in the view box will be replaced by a new set of data points when max_point is reached. Please let me know if this is correct. Thanks.

    opened by sreekarreddy21 8
  • "cb_append_data_point" leads to runtime error if no existing points are present

    I initialize a LiveLinePlot, which is passed to a DataConnector for later updating. On the first iteration where I try to add a datapoint through the connecter via cb_append_data_point I receive the following error:

    /home/user/.local/lib/python3.10/site-packages/pyqtgraph/debug.py:128: RuntimeWarning: Ignored exception:
    Traceback (most recent call last):
      File "/home/user/path/pysideGUI.py", line 1101, in <module>
        app.exec()
      File "/home/user/.local/lib/python3.10/site-packages/pglive/sources/live_plot_widget.py", line 165, in paintEvent
        return super().paintEvent(ev)
      File "/home/user/.local/lib/python3.10/site-packages/pyqtgraph/widgets/GraphicsView.py", line 137, in paintEvent
        return super().paintEvent(ev)
      File "/home/user/.local/lib/python3.10/site-packages/pyqtgraph/debug.py", line 128, in w
        printExc('Ignored exception:')
      --- exception caught here ---
      File "/home/user/.local/lib/python3.10/site-packages/pyqtgraph/debug.py", line 126, in w
        func(*args, **kwds)
      File "/home/user/.local/lib/python3.10/site-packages/pyqtgraph/graphicsItems/PlotCurveItem.py", line 905, in paint
        p.drawLines(*self._getLineSegments())
    TypeError: QPainter.drawLines() takes exactly one argument (0 given)
      printExc('Ignored exception:')
    

    I've found that checking for the presence of data in the x or y variable in the DataConnector and adding the first datapoint twice if there is none prevents the error from appearing. E.g.:

    if len(connector.x) < 1:
      *add extra datapoint*
    *add datapoint like normal*
    

    It seems like there just needs to be an additional check somewhere(?)

    Using: Python 3.10 pglive 0.5.5

    opened by Obliman 7
  • Crosshair label not formatted

    Crosshair label not formatted

    Not sure if its a bug or simply requires proper formatting on my part. Using bottom_axis = LiveAxis("bottom", **{Axis.TICK_FORMAT: Axis.TIME}) the X crosshair is displayed in raw unformatted epoch time.

    Can you suggest a way to format the X crosshair label when using tick format Time?

    thank you

    opened by optio50 5
  • LiveAxisRange Multiple Plots Auto range if plot turned off.

    LiveAxisRange Multiple Plots Auto range if plot turned off.

    Is LiveAxisRange supposed to work with multiple plots? if you turn one of the plots off with the legend the "A" autorange breaks and plots disappear.

        PV1watts_plot = LiveLinePlot(pen='orange',name='PV-1',fillLevel=0, brush=(213,129,44,100))
        PV2watts_plot = LiveLinePlot(pen='cyan',name='PV-2', fillLevel=0, brush=(102,102,255,100))
    
        # Data connectors for each plot with dequeue of max_points
        self.PV1watts_connector = DataConnector(PV1watts_plot, max_points=48000) 
        self.PV2watts_connector = DataConnector(PV2watts_plot, max_points=48000) 
    
    
        # Setup bottom axis with TIME tick format
        # use Axis.DATETIME to show date
        pv1_watts_bottom_axis = LiveAxis("bottom", **{Axis.TICK_FORMAT: Axis.TIME})
    
        # Create plot
        self.PV1_graph_Widget = LivePlotWidget(title="Charger 1 & 2 Watts 1 Hour of 24",
        axisItems={'bottom': pv1_watts_bottom_axis},
        x_range_controller=LiveAxisRange(roll_on_tick=1800, offset_left=1), **kwargs)
    
        self.PV1_graph_Widget.x_range_controller.crop_left_offset_to_data = True
        
      
        # Show grid
        self.PV1_graph_Widget.showGrid(x=True, y=True, alpha=0.3)
    
        # Set labels
        self.PV1_graph_Widget.setLabel('bottom')
        self.PV1_graph_Widget.setLabel('left', 'Watts')
    
        self.PV1_graph_Widget.addLegend() # If plot is named, auto add name to legend
    
        # Add Line
        self.PV1_graph_Widget.addItem(PV1watts_plot)
        self.PV1_graph_Widget.addItem(PV2watts_plot)
    
        # Add chart to Layout in Qt Designer
        self.PV1_Watts_Layout.addWidget(self.PV1_graph_Widget)
    
    opened by optio50 4
  • Placing the widget into an existing window

    Placing the widget into an existing window

    Thanks for making this. Using your examples I can make a stand alone window with my live data and it looks and works great.

    I am having difficulty placing the widget into an existing window made with PYQT designer. I have promoted a Qwidget to a PlotWidget class but cannot figure out how to embed it into the promoted widget.

    Can you include an example how this might be achieved?

    Thank you.

    opened by optio50 4
  • Support for

    Support for "connect" attribute of pyqtgraph PlotDataItem/PlotCurveItem?

    Per the pyqtgraph documentation it's possible to specify the connectivity of data points on a line plot via the PlotDataItem:

    connect supports the following arguments:
    
    - ‘all’ connects all points.- 
    - ‘pairs’ generates lines between every other point.- 
    - ‘finite’ creates a break when a nonfinite points is encountered.- 
    - If an ndarray is passed, it should contain N int32 values of 0 or 1. Values of 1 indicate that the respective point will be connected to the next.- 
    - In the default ‘auto’ mode, PlotDataItem will normally use ‘all’, but if any nonfinite data points are detected, it will automatically switch to ‘finite’.
    

    The connect arg is also found in the PlotCurveItem.setData() function.

    Is this supported in pglive? I haven't found anything for it so far.

    opened by Obliman 2
  • Question: If using

    Question: If using "Promoted Widget", How to add LivePlotWidget(title=...., axisItems=......, **kwargs)

    I don't normally use a promoted widget but thought I would try it out in QT Designer. Normally I create the widget manually. If it's promoted and created in the QT Designer how do I add, LivePlotWidget(title="Chart Title", axisItems={'bottom': bottom_axis}, **kwargs)

    I can add title with .setLabels I can add axisItems with .setAxisItems

    Those are done with pyqtgraph options. How do I add ** kwargs that recognize the pglive crosshairs?

    Can it all be done with a one liner like I normally do with a widget created manually?

    I know you're busy. Thanks for looking.

    opened by optio50 2
  • Question: Autoscale plots when legend item is turned off

    Question: Autoscale plots when legend item is turned off

    I cant determine if this is a pyqtgraph function or PGlive.

    A graph with multiple plots and a legend. If you click an item in the legend box its plot is turned off in the graph. (its still collecting data)

    What I have is three plots with what can be large variations in Y axis values. I was hoping to autorange the remaining plots when a plot is turned off from the legend. For example below. Turn off Watts and have Volts and Amps auto scale for best viewable resolution. legend-plots

    opened by optio50 2
  • Question: Are Crosshairs expected to work with the Categorized Bar Chart?

    Question: Are Crosshairs expected to work with the Categorized Bar Chart?

    Are Crosshairs expected to work with the Categorized Bar Chart?

    I think I would only need it for the Date Time Axis to see preciously when the state changed happened.

    opened by optio50 2
Releases(v0.5.6)
Owner
Martin Domaracký
Martin Domaracký
📊 Extensions for Matplotlib

📊 Extensions for Matplotlib

Nico Schlömer 519 Dec 30, 2022
A site that displays up to date COVID-19 stats, powered by fastpages.

https://covid19dashboards.com This project was built with fastpages Background This project showcases how you can use fastpages to create a static das

GitHub 1.6k Jan 07, 2023
GDSHelpers is an open-source package for automatized pattern generation for nano-structuring.

GDSHelpers GDSHelpers in an open-source package for automatized pattern generation for nano-structuring. It allows exporting the pattern in the GDSII-

Helge Gehring 76 Dec 16, 2022
A dashboard built using Plotly-Dash for interactive visualization of Dex-connected individuals across the country.

Dashboard For The DexConnect Platform of Dexterity Global Working prototype submission for internship at Dexterity Global Group. Dashboard for real ti

Yashasvi Misra 2 Jun 15, 2021
a plottling library for python, based on D3

Hello August 2013 Hello! Maybe you're looking for a nice Python interface to build interactive, javascript based plots that look as nice as all those

Mike Dewar 1.4k Dec 28, 2022
Interactive Data Visualization in the browser, from Python

Bokeh is an interactive visualization library for modern web browsers. It provides elegant, concise construction of versatile graphics, and affords hi

Bokeh 17.1k Dec 31, 2022
Mattia Ficarelli 2 Mar 29, 2022
The windML framework provides an easy-to-use access to wind data sources within the Python world, building upon numpy, scipy, sklearn, and matplotlib. Renewable Wind Energy, Forecasting, Prediction

windml Build status : The importance of wind in smart grids with a large number of renewable energy resources is increasing. With the growing infrastr

Computational Intelligence Group 125 Dec 24, 2022
Active Transport Analytics Model (ATAM) is a new strategic transport modelling and data visualization framework for Active Transport as well as emerging micro-mobility modes

{ATAM} Active Transport Analytics Model Active Transport Analytics Model (“ATAM”) is a new strategic transport modelling and data visualization framew

Peter Stephan 0 Jan 12, 2022
Generate graphs with NetworkX, natively visualize with D3.js and pywebview

webview_d3 This is some PoC code to render graphs created with NetworkX natively using D3.js and pywebview. The main benifit of this approac

byt3bl33d3r 68 Aug 18, 2022
Calendar heatmaps from Pandas time series data

Note: See MarvinT/calmap for the maintained version of the project. That is also the version that gets published to PyPI and it has received several f

Martijn Vermaat 195 Dec 22, 2022
Simple addon for snapping active object to mesh ground

Snap to Ground Simple addon for snapping active object to mesh ground How to install: install the Python file as an addon use shortcut "D" in 3D view

Iyad Ahmed 12 Nov 07, 2022
Moscow DEG 2021 elections plots

Построение графиков на основе публичных данных о ДЭГ в Москве в 2021г. Описание Скрипты в данном репозитории позволяют собственноручно построить графи

9 Jul 15, 2022
A small timeseries transformation API built on Flask and Pandas

#Mcflyin ###A timeseries transformation API built on Pandas and Flask This is a small demo of an API to do timeseries transformations built on Flask a

Rob Story 84 Mar 25, 2022
Python script to generate a visualization of various sorting algorithms, image or video.

sorting_algo_visualizer Python script to generate a visualization of various sorting algorithms, image or video.

146 Nov 12, 2022
DrawBot lets you draw images taken from the internet on Skribbl.io, Gartic Phone and Paint

DrawBot You don't speak french? No worries, english translation is over here. C'est quoi ? DrawBot est un logiciel codé par V2F qui va prendre possess

V2F 205 Jan 01, 2023
FairLens is an open source Python library for automatically discovering bias and measuring fairness in data

FairLens FairLens is an open source Python library for automatically discovering bias and measuring fairness in data. The package can be used to quick

Synthesized 69 Dec 15, 2022
A python script editor for napari based on PyQode.

napari-script-editor A python script editor for napari based on PyQode. This napari plugin was generated with Cookiecutter using with @napari's cookie

Robert Haase 9 Sep 20, 2022
Define fortify and autoplot functions to allow ggplot2 to handle some popular R packages.

ggfortify This package offers fortify and autoplot functions to allow automatic ggplot2 to visualize statistical result of popular R packages. Check o

Sinhrks 504 Dec 23, 2022
HW_02 Data visualisation task

HW_02 Data visualisation and Matplotlib practice Instructions for HW_02 Idea for data analysis As I was brainstorming ideas and running through databa

9 Dec 13, 2022