Browse Source

Added support for pyqtgraph

Alfio Puglisi 1 year ago
parent
commit
93c8008f78
6 changed files with 94 additions and 6 deletions
  1. 1 1
      README.md
  2. 1 1
      docs/index.rst
  3. 6 3
      docs/reference.rst
  4. 36 0
      docs/tutorial.rst
  5. 22 0
      guietta/examples/plot_pyqtgraph.py
  6. 28 1
      guietta/guietta.py

+ 1 - 1
README.md

@@ -22,7 +22,7 @@ And here it is:
 ![Example GUI](http://guietta.com/_images/example.png)
 
 Also featuring:
- * matplotlib integration, for easy event-driven plots
+ * matplotlib and pyqtgraph integration, for easy event-driven plots
  * easily display columns of data in labels using lists and dicts
  * multiple windows
  * customizable behaviour in case of exceptions

+ 1 - 1
docs/index.rst

@@ -13,7 +13,7 @@ And here it is:
 
 
 Also featuring:
- - matplotlib integration, for easy event-driven plots
+ - matplotlib and pyqtgraph integration, for easy event-driven plots
  - easily display columns of data in labels using lists and dicts
  - multiple windows
  - customizable behaviour in case of exceptions

+ 6 - 3
docs/reference.rst

@@ -82,14 +82,17 @@ Here is the complete widget set::
 +-----------------+---------------------------------------+-------------+
 | M('name')       |   Matplotlib FigureCanvas*            |             |
 +-----------------+---------------------------------------+-------------+
+| PG('name')      |   pyqtgraph PlotWidget*               |             |
++-----------------+---------------------------------------+-------------+
 | widget          |   any valid QT widget                 | none        |
 +-----------------+---------------------------------------+-------------+
 | (widget, 'name')|   any valid QT widget                 | 'name'      |
 +-----------------+---------------------------------------+-------------+
 
-* Matplotlib will only be imported if the M() widget is used. Matplotlib
-  is not installed automatically toegher with guietta. If the M() widget
-  is used, the user must install matplotlib manually.
+* Matplotlib or pyqtraph will only be imported if the M() or PG() widgets
+  are used. Matplotlib and pyqtgraph are not is not installed automatically
+  together with guietta. If the M() widget  is used, the user must install
+  matplotlib manually, same for PG() and pyqtgraph.
 
 Buttons support both images and texts at the same time:
 

+ 36 - 0
docs/tutorial.rst

@@ -605,5 +605,41 @@ and run the GUI::
 Notice how we first call the callback ourselves, giving it a default
 value, in order to have a plot ready when the GUI is displayed.
 
+Pyqtgraph
+---------
+
+*pyqtgraph* is a plotting module with less features than matplotlib, but
+much faster. It is ideal if the graph must be updated frequently. Guietta
+wraps it into its *PG()* widget::
+
+    import numpy as np
+    from guietta import Gui, PG, ___, III, _, VS
+    
+    gui = Gui(
+      [  PG('plot'),  ___, ___, VS('slider') ],
+      [     III     , III, III,     III      ],
+      [     III     , III, III,     III      ],
+      [     III     , III, III,  '^^^ Move the slider'  ],
+     )
+
+Replotting in pyqtgraph is much simpler than in matplotlib: we just have
+to call the widget's *plot()* method, setting *clear=True* to ensure that
+the previous plot is erased::
+
+    with gui.slider:
+        t = np.linspace(0, 1+gui.slider/10, 500)
+        gui.plot.plot(t, np.tan(t), clear=True)
+
+Now we initialize the plot with a default one, and run the gui::
+
+    gui.slider = 1
+    gui.run()
+
+If something more complex is needed, remember that pyqtgraph are full-featured
+QT widgets, so they can be instantiated and dropped into Guietta without
+the need to use the PG() wrapper.
+
+.. note: minimum version for pyqtgrap is 0.11.0. This is the first version
+         to support PySide2, used by Guietta.
 
 Next topic: the `reference guide <reference.html>`_.

+ 22 - 0
guietta/examples/plot_pyqtgraph.py

@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+
+import numpy as np
+from guietta import Gui, PG, ___, III, _, VS
+
+gui = Gui(
+  [  PG('plot'),  ___, ___, VS('slider') ],
+  [     III     , III, III,     III      ],
+  [     III     , III, III,     III      ],
+  [     III     , III, III,  '^^^ Move the slider'  ],
+ )
+
+with gui.slider:
+    t = np.linspace(0, 1+gui.slider/10, 500)
+    gui.plot.plot(t, np.tan(t), clear=True)
+
+gui.slider = 1
+
+gui.run()
+
+    

+ 28 - 1
guietta/guietta.py

@@ -949,6 +949,9 @@ class MatplotlibWidget:
     '''Dummy definition to avoid importing matplotlib when it is not used.'''
     pass
 
+class PyQtGraphPlotWidget:
+    '''Dummy definition to avoid importing pyqtgraph when it is not used.'''
+    pass
 
 @contextlib.contextmanager
 def Ax(widget):
@@ -1010,7 +1013,31 @@ class M(_DeferredCreationWidget):
         widget = MatplotlibWidget(self._width, self._height, self._dpi)
         return (widget, self._name)
 
-        
+
+class PG(_DeferredCreationWidget):
+    '''A pyqtgraph PlotWidget'''
+
+    def __init__(self, name):
+        self._name = name
+
+    def create(self, gui):
+        if globals()['PyQtGraphPlotWidget'].__name__ == 'PyQtGraphPlotWidget':
+
+            import pyqtgraph
+            if pyqtgraph.__version__ < '0.11.0':
+                raise Exception('Minimum version for pyqtgraph is 0.11.0,'
+                                'you have '+pyqtgraph.__version__)
+
+            class RealPyQtGraphPlotWidget(pyqtgraph.PlotWidget):
+                def __init__(self):
+                    super().__init__()
+
+            globals()['PyQtGraphPlotWidget'] = RealPyQtGraphPlotWidget
+
+        widget = PyQtGraphPlotWidget()
+        return (widget, self._name)
+      
+
 #####################
 # Stdout redirection