From 8e1c3856ea5885ee226c85591d6d1c8974881802 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 1 Mar 2015 16:52:15 -0500 Subject: [PATCH] Added more examples to menu Minor edits --- CHANGELOG | 3 + README.md | 3 +- examples/ScatterPlotWidget.py | 80 ++++++++++++++++---------- examples/__main__.py | 7 ++- pyqtgraph/multiprocess/processes.py | 11 ++-- pyqtgraph/widgets/ScatterPlotWidget.py | 9 +-- 6 files changed, 68 insertions(+), 45 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 89e6fdca..1c5ee97e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ pyqtgraph-0.9.11 [unreleased] - Fixed git version string generation on python3 - Fixed setting default values for out-of-bound points in pg.interpolateArray + New Features: + - PyQt5 support + pyqtgraph-0.9.10 Fixed installation issues with more recent pip versions. diff --git a/README.md b/README.md index 83327089..642d70e7 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,12 @@ Contributors * Nicholas TJ * John David Reaver * David Kaplan + * Martin Fitzpatrick Requirements ------------ - * PyQt 4.7+ or PySide + * PyQt 4.7+, PySide, or PyQt5 * python 2.6, 2.7, or 3.x * NumPy * For 3D graphics: pyopengl and qt-opengl diff --git a/examples/ScatterPlotWidget.py b/examples/ScatterPlotWidget.py index 563667bd..33503cab 100644 --- a/examples/ScatterPlotWidget.py +++ b/examples/ScatterPlotWidget.py @@ -1,4 +1,22 @@ # -*- coding: utf-8 -*- +""" +Demonstration of ScatterPlotWidget for exploring structure in tabular data. + +The widget consists of four components: + +1) A list of column names from which the user may select 1 or 2 columns + to plot. If one column is selected, the data for that column will be + plotted in a histogram-like manner by using pg.pseudoScatter(). + If two columns are selected, then the + scatter plot will be generated with x determined by the first column + that was selected and y by the second. +2) A DataFilter that allows the user to select a subset of the data by + specifying multiple selection criteria. +3) A ColorMap that allows the user to determine how points are colored by + specifying multiple criteria. +4) A PlotWidget for displaying the data. + +""" import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg @@ -7,42 +25,42 @@ import numpy as np pg.mkQApp() +# Make up some tabular data with structure +data = np.empty(1000, dtype=[('x_pos', float), ('y_pos', float), + ('count', int), ('amplitude', float), + ('decay', float), ('type', 'S10')]) +strings = ['Type-A', 'Type-B', 'Type-C', 'Type-D', 'Type-E'] +typeInds = np.random.randint(5, size=1000) +data['type'] = np.array(strings)[typeInds] +data['x_pos'] = np.random.normal(size=1000) +data['x_pos'][data['type'] == 'Type-A'] -= 1 +data['x_pos'][data['type'] == 'Type-B'] -= 1 +data['x_pos'][data['type'] == 'Type-C'] += 2 +data['x_pos'][data['type'] == 'Type-D'] += 2 +data['x_pos'][data['type'] == 'Type-E'] += 2 +data['y_pos'] = np.random.normal(size=1000) + data['x_pos']*0.1 +data['y_pos'][data['type'] == 'Type-A'] += 3 +data['y_pos'][data['type'] == 'Type-B'] += 3 +data['amplitude'] = data['x_pos'] * 1.4 + data['y_pos'] + np.random.normal(size=1000, scale=0.4) +data['count'] = (np.random.exponential(size=1000, scale=100) * data['x_pos']).astype(int) +data['decay'] = np.random.normal(size=1000, scale=1e-3) + data['amplitude'] * 1e-4 +data['decay'][data['type'] == 'Type-A'] /= 2 +data['decay'][data['type'] == 'Type-E'] *= 3 + + +# Create ScatterPlotWidget and configure its fields spw = pg.ScatterPlotWidget() -spw.show() - -data = np.array([ - (1, 1, 3, 4, 'x'), - (2, 3, 3, 7, 'y'), - (3, 2, 5, 2, 'z'), - (4, 4, 6, 9, 'z'), - (5, 3, 6, 7, 'x'), - (6, 5, 4, 6, 'x'), - (7, 5, 8, 2, 'z'), - (8, 1, 2, 4, 'x'), - (9, 2, 3, 7, 'z'), - (0, 6, 0, 2, 'z'), - (1, 3, 1, 2, 'z'), - (2, 5, 4, 6, 'y'), - (3, 4, 8, 1, 'y'), - (4, 7, 6, 8, 'z'), - (5, 8, 7, 4, 'y'), - (6, 1, 2, 3, 'y'), - (7, 5, 3, 9, 'z'), - (8, 9, 3, 1, 'x'), - (9, 2, 6, 2, 'z'), - (0, 3, 4, 6, 'x'), - (1, 5, 9, 3, 'y'), - ], dtype=[('col1', float), ('col2', float), ('col3', int), ('col4', int), ('col5', 'S10')]) - spw.setFields([ - ('col1', {'units': 'm'}), - ('col2', {'units': 'm'}), - ('col3', {}), - ('col4', {}), - ('col5', {'mode': 'enum', 'values': ['x', 'y', 'z']}), + ('x_pos', {'units': 'm'}), + ('y_pos', {'units': 'm'}), + ('count', {}), + ('amplitude', {'units': 'V'}), + ('decay', {'units': 's'}), + ('type', {'mode': 'enum', 'values': strings}), ]) spw.setData(data) +spw.show() ## Start Qt event loop unless running in interactive mode or using pyside. diff --git a/examples/__main__.py b/examples/__main__.py index 9ef2df28..192742f7 100644 --- a/examples/__main__.py +++ b/examples/__main__.py @@ -32,6 +32,7 @@ examples = OrderedDict([ ('Dock widgets', 'dockarea.py'), ('Console', 'ConsoleWidget.py'), ('Histograms', 'histogram.py'), + ('Beeswarm plot', 'beeswarm.py'), ('Auto-range', 'PlotAutoRange.py'), ('Remote Plotting', 'RemoteSpeedTest.py'), ('Scrolling plots', 'scrollingPlots.py'), @@ -51,6 +52,7 @@ examples = OrderedDict([ ('ImageItem - video', 'ImageItem.py'), ('ImageItem - draw', 'Draw.py'), ('Region-of-Interest', 'ROIExamples.py'), + ('Bar Graph', 'BarGraphItem.py'), ('GraphicsLayout', 'GraphicsLayout.py'), ('LegendItem', 'Legend.py'), ('Text Item', 'text.py'), @@ -58,6 +60,7 @@ examples = OrderedDict([ ('Arrow', 'Arrow.py'), ('ViewBox', 'ViewBox.py'), ('Custom Graphics', 'customGraphicsItem.py'), + ('Labeled Graph', 'CustomGraphItem.py'), ])), ('Benchmarks', OrderedDict([ ('Video speed test', 'VideoSpeedTest.py'), @@ -81,6 +84,7 @@ examples = OrderedDict([ ('ConsoleWidget', 'ConsoleWidget.py'), ('Histogram / lookup table', 'HistogramLUT.py'), ('TreeWidget', 'TreeWidget.py'), + ('ScatterPlotWidget', 'ScatterPlotWidget.py'), ('DataTreeWidget', 'DataTreeWidget.py'), ('GradientWidget', 'GradientWidget.py'), ('TableWidget', 'TableWidget.py'), @@ -90,11 +94,8 @@ examples = OrderedDict([ ('JoystickButton', 'JoystickButton.py'), ])), - #('GraphicsScene', 'GraphicsScene.py'), ('Flowcharts', 'Flowchart.py'), ('Custom Flowchart Nodes', 'FlowchartCustomNode.py'), - #('Canvas', '../canvas'), - #('MultiPlotWidget', 'MultiPlotWidget.py'), ]) path = os.path.abspath(os.path.dirname(__file__)) diff --git a/pyqtgraph/multiprocess/processes.py b/pyqtgraph/multiprocess/processes.py index 0dfb80b9..a121487b 100644 --- a/pyqtgraph/multiprocess/processes.py +++ b/pyqtgraph/multiprocess/processes.py @@ -267,10 +267,11 @@ class ForkedProcess(RemoteEventHandler): sys.excepthook = excepthook ## Make it harder to access QApplication instance - if 'PyQt4.QtGui' in sys.modules: - sys.modules['PyQt4.QtGui'].QApplication = None - sys.modules.pop('PyQt4.QtGui', None) - sys.modules.pop('PyQt4.QtCore', None) + for qtlib in ('PyQt4', 'PySide', 'PyQt5'): + if qtlib in sys.modules: + sys.modules[qtlib+'.QtGui'].QApplication = None + sys.modules.pop(qtlib+'.QtGui', None) + sys.modules.pop(qtlib+'.QtCore', None) ## sabotage atexit callbacks atexit._exithandlers = [] @@ -420,7 +421,6 @@ def startQtEventLoop(name, port, authkey, ppid, debug=False): if debug: cprint.cout(debug, '[%d] connected; starting remote proxy.\n' % os.getpid(), -1) from ..Qt import QtGui, QtCore - #from PyQt4 import QtGui, QtCore app = QtGui.QApplication.instance() #print app if app is None: @@ -429,7 +429,6 @@ def startQtEventLoop(name, port, authkey, ppid, debug=False): ## until it is explicitly closed by the parent process. global HANDLER - #ppid = 0 if not hasattr(os, 'getppid') else os.getppid() HANDLER = RemoteQtEventHandler(conn, name, ppid, debug=debug) HANDLER.startEventTimer() app.exec_() diff --git a/pyqtgraph/widgets/ScatterPlotWidget.py b/pyqtgraph/widgets/ScatterPlotWidget.py index 02f260ca..cca40e65 100644 --- a/pyqtgraph/widgets/ScatterPlotWidget.py +++ b/pyqtgraph/widgets/ScatterPlotWidget.py @@ -13,10 +13,11 @@ __all__ = ['ScatterPlotWidget'] class ScatterPlotWidget(QtGui.QSplitter): """ - Given a record array, display a scatter plot of a specific set of data. - This widget includes controls for selecting the columns to plot, - filtering data, and determining symbol color and shape. This widget allows - the user to explore relationships between columns in a record array. + This is a high-level widget for exploring relationships in tabular data. + + Given a multi-column record array, the widget displays a scatter plot of a + specific subset of the data. Includes controls for selecting the columns to + plot, filtering data, and determining symbol color and shape. The widget consists of four components: