Merge branch 'develop' into scatterplotwidget-updates

This commit is contained in:
Luke Campagnola 2018-04-25 11:16:17 -07:00
commit 434d2b8c71
11 changed files with 58 additions and 48 deletions

View File

@ -12,32 +12,27 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.ptime import time from pyqtgraph.ptime import time
#QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([]) app = QtGui.QApplication([])
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
p = pg.plot() plot = pg.plot()
p.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest') plot.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest')
#p.setRange(QtCore.QRectF(0, -10, 5000, 20)) plot.setLabel('bottom', 'Index', units='B')
p.setLabel('bottom', 'Index', units='B')
nPlots = 100 nPlots = 100
nSamples = 500 nSamples = 500
#curves = [p.plot(pen=(i,nPlots*1.3)) for i in range(nPlots)]
curves = [] curves = []
for i in range(nPlots): for idx in range(nPlots):
c = pg.PlotCurveItem(pen=(i,nPlots*1.3)) curve = pg.PlotCurveItem(pen=(idx,nPlots*1.3))
p.addItem(c) plot.addItem(curve)
c.setPos(0,i*6) curve.setPos(0,idx*6)
curves.append(c) curves.append(curve)
p.setYRange(0, nPlots*6) plot.setYRange(0, nPlots*6)
p.setXRange(0, nSamples) plot.setXRange(0, nSamples)
p.resize(600,900) plot.resize(600,900)
rgn = pg.LinearRegionItem([nSamples/5.,nSamples/3.]) rgn = pg.LinearRegionItem([nSamples/5.,nSamples/3.])
p.addItem(rgn) plot.addItem(rgn)
data = np.random.normal(size=(nPlots*23,nSamples)) data = np.random.normal(size=(nPlots*23,nSamples))
@ -46,13 +41,12 @@ lastTime = time()
fps = None fps = None
count = 0 count = 0
def update(): def update():
global curve, data, ptr, p, lastTime, fps, nPlots, count global curve, data, ptr, plot, lastTime, fps, nPlots, count
count += 1 count += 1
#print "---------", count
for i in range(nPlots): for i in range(nPlots):
curves[i].setData(data[(ptr+i)%data.shape[0]]) curves[i].setData(data[(ptr+i)%data.shape[0]])
#print " setData done."
ptr += nPlots ptr += nPlots
now = time() now = time()
dt = now - lastTime dt = now - lastTime
@ -62,14 +56,12 @@ def update():
else: else:
s = np.clip(dt*3., 0, 1) s = np.clip(dt*3., 0, 1)
fps = fps * (1-s) + (1.0/dt) * s fps = fps * (1-s) + (1.0/dt) * s
p.setTitle('%0.2f fps' % fps) plot.setTitle('%0.2f fps' % fps)
#app.processEvents() ## force complete redraw for every plot #app.processEvents() ## force complete redraw for every plot
timer = QtCore.QTimer() timer = QtCore.QTimer()
timer.timeout.connect(update) timer.timeout.connect(update)
timer.start(0) timer.start(0)
## Start Qt event loop unless running in interactive mode. ## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys

View File

@ -26,6 +26,7 @@ class ExampleLoader(QtGui.QMainWindow):
self.cw = QtGui.QWidget() self.cw = QtGui.QWidget()
self.setCentralWidget(self.cw) self.setCentralWidget(self.cw)
self.ui.setupUi(self.cw) self.ui.setupUi(self.cw)
self.setWindowTitle("PyQtGraph Examples")
self.codeBtn = QtGui.QPushButton('Run Edited Code') self.codeBtn = QtGui.QPushButton('Run Edited Code')
self.codeLayout = QtGui.QGridLayout() self.codeLayout = QtGui.QGridLayout()

View File

@ -4,6 +4,7 @@ Displays an interactive Koch fractal
""" """
import initExample ## Add path to library (just for examples; you do not need this) import initExample ## Add path to library (just for examples; you do not need this)
from functools import reduce
import pyqtgraph as pg import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui from pyqtgraph.Qt import QtCore, QtGui
import numpy as np import numpy as np
@ -112,11 +113,3 @@ if __name__ == '__main__':
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_() QtGui.QApplication.instance().exec_()

View File

@ -359,7 +359,6 @@ class ConsoleWidget(QtGui.QWidget):
for index, line in enumerate(traceback.extract_stack(frame)): for index, line in enumerate(traceback.extract_stack(frame)):
# extract_stack return value changed in python 3.5 # extract_stack return value changed in python 3.5
if 'FrameSummary' in str(type(line)): if 'FrameSummary' in str(type(line)):
print(dir(line))
line = (line.filename, line.lineno, line.name, line._line) line = (line.filename, line.lineno, line.name, line._line)
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line) self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
@ -380,7 +379,6 @@ class ConsoleWidget(QtGui.QWidget):
for index, line in enumerate(traceback.extract_tb(tb)): for index, line in enumerate(traceback.extract_tb(tb)):
# extract_stack return value changed in python 3.5 # extract_stack return value changed in python 3.5
if 'FrameSummary' in str(type(line)): if 'FrameSummary' in str(type(line)):
print(dir(line))
line = (line.filename, line.lineno, line.name, line._line) line = (line.filename, line.lineno, line.name, line._line)
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line) self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)

View File

@ -169,7 +169,7 @@ def _generateItemSvg(item, nodes=None, root=None):
buf = QtCore.QBuffer(arr) buf = QtCore.QBuffer(arr)
svg = QtSvg.QSvgGenerator() svg = QtSvg.QSvgGenerator()
svg.setOutputDevice(buf) svg.setOutputDevice(buf)
dpi = QtGui.QDesktopWidget().physicalDpiX() dpi = QtGui.QDesktopWidget().logicalDpiX()
svg.setResolution(dpi) svg.setResolution(dpi)
p = QtGui.QPainter() p = QtGui.QPainter()
@ -372,7 +372,7 @@ def correctCoordinates(node, defs, item):
ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families])) ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families]))
## correct line widths if needed ## correct line widths if needed
if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke': if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke' and grp.getAttribute('stroke-width') != '':
w = float(grp.getAttribute('stroke-width')) w = float(grp.getAttribute('stroke-width'))
s = fn.transformCoordinates(tr, np.array([[w,0], [0,0]]), transpose=True) s = fn.transformCoordinates(tr, np.array([[w,0], [0,0]]), transpose=True)
w = ((s[0]-s[1])**2).sum()**0.5 w = ((s[0]-s[1])**2).sum()**0.5

View File

@ -110,7 +110,8 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
#print("-------") #print("-------")
for sample, label in self.items: for sample, label in self.items:
height += max(sample.height(), label.height()) + 3 height += max(sample.height(), label.height()) + 3
width = max(width, sample.width()+label.width()) width = max(width, (sample.sizeHint(QtCore.Qt.MinimumSize, sample.size()).width() +
label.sizeHint(QtCore.Qt.MinimumSize, label.size()).width()))
#print(width, height) #print(width, height)
#print width, height #print width, height
self.setGeometry(0, 0, width+25, height) self.setGeometry(0, 0, width+25, height)

View File

@ -849,8 +849,15 @@ class SpotItem(object):
def __init__(self, data, plot, index): def __init__(self, data, plot, index):
self._data = data self._data = data
self._plot = plot
self._index = index self._index = index
# SpotItems are kept in plot.data["items"] numpy object array which
# does not support cyclic garbage collection (numpy issue 6581).
# Keeping a strong ref to plot here would leak the cycle
self.__plot_ref = weakref.ref(plot)
@property
def _plot(self):
return self.__plot_ref()
def data(self): def data(self):
"""Return the user data associated with this spot.""" """Return the user data associated with this spot."""

View File

@ -16,9 +16,13 @@ class GLViewWidget(QtOpenGL.QGLWidget):
- Axis/grid display - Axis/grid display
- Export options - Export options
High-DPI displays: Qt5 should automatically detect the correct resolution.
For Qt4, specify the ``devicePixelRatio`` argument when initializing the
widget (usually this value is 1-2).
""" """
def __init__(self, parent=None): def __init__(self, parent=None, devicePixelRatio=None):
global ShareWidget global ShareWidget
if ShareWidget is None: if ShareWidget is None:
@ -37,6 +41,7 @@ class GLViewWidget(QtOpenGL.QGLWidget):
'azimuth': 45, ## camera's azimuthal angle in degrees 'azimuth': 45, ## camera's azimuthal angle in degrees
## (rotation around z-axis 0 points along x-axis) ## (rotation around z-axis 0 points along x-axis)
'viewport': None, ## glViewport params; None == whole widget 'viewport': None, ## glViewport params; None == whole widget
'devicePixelRatio': devicePixelRatio,
} }
self.setBackgroundColor('k') self.setBackgroundColor('k')
self.items = [] self.items = []
@ -79,10 +84,21 @@ class GLViewWidget(QtOpenGL.QGLWidget):
def getViewport(self): def getViewport(self):
vp = self.opts['viewport'] vp = self.opts['viewport']
dpr = self.devicePixelRatio()
if vp is None: if vp is None:
return (0, 0, self.width(), self.height()) return (0, 0, int(self.width() * dpr), int(self.height() * dpr))
else: else:
return vp return tuple([int(x * dpr) for x in vp])
def devicePixelRatio(self):
dpr = self.opts['devicePixelRatio']
if dpr is not None:
return dpr
if hasattr(QtOpenGL.QGLWidget, 'devicePixelRatio'):
return QtOpenGL.QGLWidget.devicePixelRatio(self)
else:
return 1.0
def resizeGL(self, w, h): def resizeGL(self, w, h):
pass pass
@ -99,7 +115,8 @@ class GLViewWidget(QtOpenGL.QGLWidget):
def projectionMatrix(self, region=None): def projectionMatrix(self, region=None):
# Xw = (Xnd + 1) * width/2 + X # Xw = (Xnd + 1) * width/2 + X
if region is None: if region is None:
region = (0, 0, self.width(), self.height()) dpr = self.devicePixelRatio()
region = (0, 0, self.width() * dpr, self.height() * dpr)
x0, y0, w, h = self.getViewport() x0, y0, w, h = self.getViewport()
dist = self.opts['distance'] dist = self.opts['distance']

View File

@ -485,7 +485,7 @@ class MeshData(object):
if isinstance(radius, int): if isinstance(radius, int):
radius = [radius, radius] # convert to list radius = [radius, radius] # convert to list
## compute vertexes ## compute vertexes
th = np.linspace(2 * np.pi, 0, cols).reshape(1, cols) th = np.linspace(2 * np.pi, (2 * np.pi)/cols, cols).reshape(1, cols)
r = np.linspace(radius[0],radius[1],num=rows+1, endpoint=True).reshape(rows+1, 1) # radius as a function of z r = np.linspace(radius[0],radius[1],num=rows+1, endpoint=True).reshape(rows+1, 1) # radius as a function of z
verts[...,2] = np.linspace(0, length, num=rows+1, endpoint=True).reshape(rows+1, 1) # z verts[...,2] = np.linspace(0, length, num=rows+1, endpoint=True).reshape(rows+1, 1) # z
if offset: if offset:

View File

@ -10,10 +10,10 @@ class GLGridItem(GLGraphicsItem):
""" """
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>` **Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
Displays a wire-grame grid. Displays a wire-frame grid.
""" """
def __init__(self, size=None, color=None, antialias=True, glOptions='translucent'): def __init__(self, size=None, color=(1, 1, 1, .3), antialias=True, glOptions='translucent'):
GLGraphicsItem.__init__(self) GLGraphicsItem.__init__(self)
self.setGLOptions(glOptions) self.setGLOptions(glOptions)
self.antialias = antialias self.antialias = antialias
@ -21,6 +21,7 @@ class GLGridItem(GLGraphicsItem):
size = QtGui.QVector3D(20,20,1) size = QtGui.QVector3D(20,20,1)
self.setSize(size=size) self.setSize(size=size)
self.setSpacing(1, 1, 1) self.setSpacing(1, 1, 1)
self.color = color
def setSize(self, x=None, y=None, z=None, size=None): def setSize(self, x=None, y=None, z=None, size=None):
""" """
@ -67,7 +68,7 @@ class GLGridItem(GLGraphicsItem):
xs,ys,zs = self.spacing() xs,ys,zs = self.spacing()
xvals = np.arange(-x/2., x/2. + xs*0.001, xs) xvals = np.arange(-x/2., x/2. + xs*0.001, xs)
yvals = np.arange(-y/2., y/2. + ys*0.001, ys) yvals = np.arange(-y/2., y/2. + ys*0.001, ys)
glColor4f(1, 1, 1, .3) glColor4f(*self.color)
for x in xvals: for x in xvals:
glVertex3f(x, yvals[0], 0) glVertex3f(x, yvals[0], 0)
glVertex3f(x, yvals[-1], 0) glVertex3f(x, yvals[-1], 0)

View File

@ -122,7 +122,7 @@ if HAVE_OPENGL:
if not self.uploaded: if not self.uploaded:
self.uploadTexture() self.uploadTexture()
glViewport(0, 0, self.width(), self.height()) glViewport(0, 0, self.width() * self.devicePixelRatio(), self.height() * self.devicePixelRatio())
glEnable(GL_TEXTURE_2D) glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture) glBindTexture(GL_TEXTURE_2D, self.texture)
glColor4f(1,1,1,1) glColor4f(1,1,1,1)