- Fixed issue with numpy.concatenate wrapper
- ConsoleWidget now correctly catches its own exceptions - Fixed ViewBox auto-scaling bug - Fixed functions.siEval not parsing units correctly - Fixed bug caused when opengl GL_VERSION_STR is None
This commit is contained in:
parent
844dbb20a5
commit
1d05656a73
@ -217,6 +217,7 @@ class ConsoleWidget(QtGui.QWidget):
|
|||||||
for l in tb.split('\n'):
|
for l in tb.split('\n'):
|
||||||
lines.append(" "*indent + prefix + l)
|
lines.append(" "*indent + prefix + l)
|
||||||
self.write('\n'.join(lines))
|
self.write('\n'.join(lines))
|
||||||
|
self.exceptionHandler(*sys.exc_info())
|
||||||
|
|
||||||
def cmdSelected(self, item):
|
def cmdSelected(self, item):
|
||||||
index = -(self.ui.historyList.row(item)+1)
|
index = -(self.ui.historyList.row(item)+1)
|
||||||
@ -314,6 +315,8 @@ class ConsoleWidget(QtGui.QWidget):
|
|||||||
def exceptionHandler(self, excType, exc, tb):
|
def exceptionHandler(self, excType, exc, tb):
|
||||||
if self.ui.catchNextExceptionBtn.isChecked():
|
if self.ui.catchNextExceptionBtn.isChecked():
|
||||||
self.ui.catchNextExceptionBtn.setChecked(False)
|
self.ui.catchNextExceptionBtn.setChecked(False)
|
||||||
|
elif not self.ui.catchAllExceptionsBtn.isChecked():
|
||||||
|
return
|
||||||
|
|
||||||
self.ui.clearExceptionBtn.setEnabled(True)
|
self.ui.clearExceptionBtn.setEnabled(True)
|
||||||
self.currentTraceback = tb
|
self.currentTraceback = tb
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
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)
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import scipy.ndimage as ndi
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from pyqtgraph.Qt import QtGui, QtCore
|
from pyqtgraph.Qt import QtGui, QtCore
|
||||||
from pyqtgraph.Point import Point
|
from pyqtgraph.Point import Point
|
||||||
@ -11,22 +12,38 @@ label = pg.LabelItem(justify='right')
|
|||||||
win.addItem(label)
|
win.addItem(label)
|
||||||
p1 = win.addPlot(row=1, col=0)
|
p1 = win.addPlot(row=1, col=0)
|
||||||
p2 = win.addPlot(row=2, col=0)
|
p2 = win.addPlot(row=2, col=0)
|
||||||
|
|
||||||
region = pg.LinearRegionItem()
|
region = pg.LinearRegionItem()
|
||||||
region.setZValue(10)
|
region.setZValue(10)
|
||||||
p2.addItem(region)
|
p2.addItem(region)
|
||||||
|
|
||||||
|
#pg.dbg()
|
||||||
|
p1.setAutoVisible(y=True)
|
||||||
|
|
||||||
|
|
||||||
#create numpy arrays
|
#create numpy arrays
|
||||||
#make the numbers large to show that the xrange shows data from 10000 to all the way 0
|
#make the numbers large to show that the xrange shows data from 10000 to all the way 0
|
||||||
data1 = 10000 + 3000 * np.random.random(size=10000)
|
data1 = 10000 + 15000 * ndi.gaussian_filter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
|
||||||
data2 = 15000 + 3000 * np.random.random(size=10000)
|
data2 = 15000 + 15000 * ndi.gaussian_filter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
|
||||||
|
|
||||||
p1.plot(data1, pen="r")
|
p1.plot(data1, pen="r")
|
||||||
p1.plot(data2, pen="g")
|
p1.plot(data2, pen="g")
|
||||||
|
|
||||||
p2.plot(data1, pen="w")
|
p2.plot(data1, pen="w")
|
||||||
|
|
||||||
def update():
|
def update():
|
||||||
p1.setXRange(*region.getRegion())
|
region.setZValue(10)
|
||||||
|
minX, maxX = region.getRegion()
|
||||||
|
p1.setXRange(minX, maxX, padding=0)
|
||||||
|
|
||||||
region.sigRegionChanged.connect(update)
|
region.sigRegionChanged.connect(update)
|
||||||
|
|
||||||
|
def updateRegion(window, viewRange):
|
||||||
|
rgn = viewRange[0]
|
||||||
|
region.setRegion(rgn)
|
||||||
|
|
||||||
|
p1.sigRangeChanged.connect(updateRegion)
|
||||||
|
|
||||||
region.setRegion([1000, 2000])
|
region.setRegion([1000, 2000])
|
||||||
|
|
||||||
#cross hair
|
#cross hair
|
||||||
@ -34,6 +51,8 @@ vLine = pg.InfiniteLine(angle=90, movable=False)
|
|||||||
hLine = pg.InfiniteLine(angle=0, movable=False)
|
hLine = pg.InfiniteLine(angle=0, movable=False)
|
||||||
p1.addItem(vLine, ignoreBounds=True)
|
p1.addItem(vLine, ignoreBounds=True)
|
||||||
p1.addItem(hLine, ignoreBounds=True)
|
p1.addItem(hLine, ignoreBounds=True)
|
||||||
|
|
||||||
|
|
||||||
vb = p1.vb
|
vb = p1.vb
|
||||||
|
|
||||||
def mouseMoved(evt):
|
def mouseMoved(evt):
|
||||||
@ -45,6 +64,9 @@ def mouseMoved(evt):
|
|||||||
label.setText("<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y1=%0.1f</span>, <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), data1[index], data2[index]))
|
label.setText("<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y1=%0.1f</span>, <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), data1[index], data2[index]))
|
||||||
vLine.setPos(mousePoint.x())
|
vLine.setPos(mousePoint.x())
|
||||||
hLine.setPos(mousePoint.y())
|
hLine.setPos(mousePoint.y())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)
|
proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)
|
||||||
#p1.scene().sigMouseMoved.connect(mouseMoved)
|
#p1.scene().sigMouseMoved.connect(mouseMoved)
|
||||||
|
|
||||||
@ -52,4 +74,4 @@ proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)
|
|||||||
## Start Qt event loop unless running in interactive mode or using pyside.
|
## Start Qt event loop unless running in interactive mode or using pyside.
|
||||||
import sys
|
import sys
|
||||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||||
app.exec_()
|
app.exec_()
|
||||||
|
@ -116,7 +116,7 @@ def siEval(s):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
s = asUnicode(s)
|
s = asUnicode(s)
|
||||||
m = re.match(r'(-?((\d+(\.\d*)?)|(\.\d+))([eE]-?\d+)?)\s*([u' + SI_PREFIXES + r']?)$', s)
|
m = re.match(r'(-?((\d+(\.\d*)?)|(\.\d+))([eE]-?\d+)?)\s*([u' + SI_PREFIXES + r']?).*$', s)
|
||||||
if m is None:
|
if m is None:
|
||||||
raise Exception("Can't convert string '%s' to number." % s)
|
raise Exception("Can't convert string '%s' to number." % s)
|
||||||
v = float(m.groups()[0])
|
v = float(m.groups()[0])
|
||||||
|
@ -532,7 +532,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
if type(fractionVisible[i]) is bool:
|
if type(fractionVisible[i]) is bool:
|
||||||
fractionVisible[i] = 1.0
|
fractionVisible[i] = 1.0
|
||||||
|
|
||||||
childRect = None
|
childRange = None
|
||||||
|
|
||||||
order = [0,1]
|
order = [0,1]
|
||||||
if self.state['autoVisibleOnly'][0] is True:
|
if self.state['autoVisibleOnly'][0] is True:
|
||||||
@ -545,40 +545,48 @@ class ViewBox(GraphicsWidget):
|
|||||||
if self.state['autoVisibleOnly'][ax]:
|
if self.state['autoVisibleOnly'][ax]:
|
||||||
oRange = [None, None]
|
oRange = [None, None]
|
||||||
oRange[ax] = targetRect[1-ax]
|
oRange[ax] = targetRect[1-ax]
|
||||||
childRect = self.childrenBoundingRect(frac=fractionVisible, orthoRange=oRange)
|
childRange = self.childrenBounds(frac=fractionVisible, orthoRange=oRange)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if childRect is None:
|
if childRange is None:
|
||||||
childRect = self.childrenBoundingRect(frac=fractionVisible)
|
childRange = self.childrenBounds(frac=fractionVisible)
|
||||||
|
|
||||||
if ax == 0:
|
## Make corrections to range
|
||||||
## Make corrections to X range
|
xr = childRange[ax]
|
||||||
|
if xr is not None:
|
||||||
if self.state['autoPan'][0]:
|
if self.state['autoPan'][0]:
|
||||||
x = childRect.center().x()
|
x = sum(xr) * 0.5
|
||||||
|
#x = childRect.center().x()
|
||||||
w2 = (targetRect[0][1]-targetRect[0][0]) / 2.
|
w2 = (targetRect[0][1]-targetRect[0][0]) / 2.
|
||||||
childRect.setLeft(x-w2)
|
#childRect.setLeft(x-w2)
|
||||||
childRect.setRight(x+w2)
|
#childRect.setRight(x+w2)
|
||||||
|
childRange[ax] = [x-w2, x+w2]
|
||||||
else:
|
else:
|
||||||
wp = childRect.width() * 0.02
|
#wp = childRect.width() * 0.02
|
||||||
childRect = childRect.adjusted(-wp, 0, wp, 0)
|
wp = (xr[1] - xr[0]) * 0.02
|
||||||
|
#childRect = childRect.adjusted(-wp, 0, wp, 0)
|
||||||
|
childRange[ax][0] -= wp
|
||||||
|
childRange[ax][1] += wp
|
||||||
|
#targetRect[ax][0] = childRect.left()
|
||||||
|
#targetRect[ax][1] = childRect.right()
|
||||||
|
targetRect[ax] = childRange[ax]
|
||||||
|
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
|
||||||
|
#else:
|
||||||
|
### Make corrections to Y range
|
||||||
|
#if self.state['autoPan'][1]:
|
||||||
|
#y = childRect.center().y()
|
||||||
|
#h2 = (targetRect[1][1]-targetRect[1][0]) / 2.
|
||||||
|
#childRect.setTop(y-h2)
|
||||||
|
#childRect.setBottom(y+h2)
|
||||||
|
#else:
|
||||||
|
#hp = childRect.height() * 0.02
|
||||||
|
#childRect = childRect.adjusted(0, -hp, 0, hp)
|
||||||
|
|
||||||
targetRect[0][0] = childRect.left()
|
#targetRect[1][0] = childRect.top()
|
||||||
targetRect[0][1] = childRect.right()
|
#targetRect[1][1] = childRect.bottom()
|
||||||
args['xRange'] = targetRect[0]
|
#args['yRange'] = targetRect[1]
|
||||||
else:
|
if len(args) == 0:
|
||||||
## Make corrections to Y range
|
return
|
||||||
if self.state['autoPan'][1]:
|
|
||||||
y = childRect.center().y()
|
|
||||||
h2 = (targetRect[1][1]-targetRect[1][0]) / 2.
|
|
||||||
childRect.setTop(y-h2)
|
|
||||||
childRect.setBottom(y+h2)
|
|
||||||
else:
|
|
||||||
hp = childRect.height() * 0.02
|
|
||||||
childRect = childRect.adjusted(0, -hp, 0, hp)
|
|
||||||
|
|
||||||
targetRect[1][0] = childRect.top()
|
|
||||||
targetRect[1][1] = childRect.bottom()
|
|
||||||
args['yRange'] = targetRect[1]
|
|
||||||
args['padding'] = 0
|
args['padding'] = 0
|
||||||
args['disableAutoRange'] = False
|
args['disableAutoRange'] = False
|
||||||
#self.setRange(xRange=targetRect[0], yRange=targetRect[1], padding=0, disableAutoRange=False)
|
#self.setRange(xRange=targetRect[0], yRange=targetRect[1], padding=0, disableAutoRange=False)
|
||||||
@ -689,14 +697,14 @@ class ViewBox(GraphicsWidget):
|
|||||||
overlap = min(sg.bottom(), vg.bottom()) - max(sg.top(), vg.top())
|
overlap = min(sg.bottom(), vg.bottom()) - max(sg.top(), vg.top())
|
||||||
if overlap < min(vg.height()/3, sg.height()/3): ## if less than 1/3 of views overlap,
|
if overlap < min(vg.height()/3, sg.height()/3): ## if less than 1/3 of views overlap,
|
||||||
## then just replicate the view
|
## then just replicate the view
|
||||||
x1 = vr.top()
|
y1 = vr.top()
|
||||||
x2 = vr.bottom()
|
y2 = vr.bottom()
|
||||||
else: ## views overlap; line them up
|
else: ## views overlap; line them up
|
||||||
upp = float(vr.height()) / vg.height()
|
upp = float(vr.height()) / vg.height()
|
||||||
x1 = vr.top() + (sg.y()-vg.y()) * upp
|
y2 = vr.bottom() - (sg.y()-vg.y()) * upp
|
||||||
x2 = x1 + sg.height() * upp
|
y1 = y2 - sg.height() * upp
|
||||||
self.enableAutoRange(ViewBox.YAxis, False)
|
self.enableAutoRange(ViewBox.YAxis, False)
|
||||||
self.setYRange(x1, x2, padding=0)
|
self.setYRange(y1, y2, padding=0)
|
||||||
finally:
|
finally:
|
||||||
view.blockLink(False)
|
view.blockLink(False)
|
||||||
|
|
||||||
@ -984,8 +992,8 @@ class ViewBox(GraphicsWidget):
|
|||||||
return children
|
return children
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def childrenBoundingRect(self, frac=None, orthoRange=(None,None)):
|
def childrenBounds(self, frac=None, orthoRange=(None,None)):
|
||||||
"""Return the bounding range of all children.
|
"""Return the bounding range of all children.
|
||||||
[[xmin, xmax], [ymin, ymax]]
|
[[xmin, xmax], [ymin, ymax]]
|
||||||
Values may be None if there are no specific bounds for an axis.
|
Values may be None if there are no specific bounds for an axis.
|
||||||
@ -1052,22 +1060,18 @@ class ViewBox(GraphicsWidget):
|
|||||||
if useY:
|
if useY:
|
||||||
if range[1] is not None:
|
if range[1] is not None:
|
||||||
range[1] = [min(bounds.top(), range[1][0]), max(bounds.bottom(), range[1][1])]
|
range[1] = [min(bounds.top(), range[1][0]), max(bounds.bottom(), range[1][1])]
|
||||||
#bounds.setTop(min(bounds.top(), chb.top()))
|
|
||||||
#bounds.setBottom(max(bounds.bottom(), chb.bottom()))
|
|
||||||
else:
|
else:
|
||||||
range[1] = [bounds.top(), bounds.bottom()]
|
range[1] = [bounds.top(), bounds.bottom()]
|
||||||
#bounds.setTop(chb.top())
|
|
||||||
#bounds.setBottom(chb.bottom())
|
|
||||||
if useX:
|
if useX:
|
||||||
if range[0] is not None:
|
if range[0] is not None:
|
||||||
range[0] = [min(bounds.left(), range[0][0]), max(bounds.right(), range[0][1])]
|
range[0] = [min(bounds.left(), range[0][0]), max(bounds.right(), range[0][1])]
|
||||||
#bounds.setLeft(min(bounds.left(), chb.left()))
|
|
||||||
#bounds.setRight(max(bounds.right(), chb.right()))
|
|
||||||
else:
|
else:
|
||||||
range[0] = [bounds.left(), bounds.right()]
|
range[0] = [bounds.left(), bounds.right()]
|
||||||
#bounds.setLeft(chb.left())
|
|
||||||
#bounds.setRight(chb.right())
|
|
||||||
|
|
||||||
|
return range
|
||||||
|
|
||||||
|
def childrenBoundingRect(self, *args, **kwds):
|
||||||
|
range = self.childrenBounds(*args, **kwds)
|
||||||
tr = self.targetRange()
|
tr = self.targetRange()
|
||||||
if range[0] is None:
|
if range[0] is None:
|
||||||
range[0] = tr[0]
|
range[0] = tr[0]
|
||||||
|
@ -5,15 +5,15 @@ try:
|
|||||||
## (numpy trac issue #2084)
|
## (numpy trac issue #2084)
|
||||||
if not hasattr(np, 'concatenate_orig'):
|
if not hasattr(np, 'concatenate_orig'):
|
||||||
np.concatenate_orig = np.concatenate
|
np.concatenate_orig = np.concatenate
|
||||||
def concatenate(vals, **kwds):
|
def concatenate(vals, *args, **kwds):
|
||||||
"""Wrapper around numpy.concatenate (see pyqtgraph/numpy_fix.py)"""
|
"""Wrapper around numpy.concatenate (see pyqtgraph/numpy_fix.py)"""
|
||||||
dtypes = [getattr(v, 'dtype', None) for v in vals]
|
dtypes = [getattr(v, 'dtype', None) for v in vals]
|
||||||
names = [getattr(dt, 'names', None) for dt in dtypes]
|
names = [getattr(dt, 'names', None) for dt in dtypes]
|
||||||
if len(dtypes) < 2 or all([n is None for n in names]):
|
if len(dtypes) < 2 or all([n is None for n in names]):
|
||||||
return np.concatenate_orig(vals, **kwds)
|
return np.concatenate_orig(vals, *args, **kwds)
|
||||||
if any([dt != dtypes[0] for dt in dtypes[1:]]):
|
if any([dt != dtypes[0] for dt in dtypes[1:]]):
|
||||||
raise TypeError("Cannot concatenate structured arrays of different dtype.")
|
raise TypeError("Cannot concatenate structured arrays of different dtype.")
|
||||||
return np.concatenate_orig(vals, **kwds)
|
return np.concatenate_orig(vals, *args, **kwds)
|
||||||
|
|
||||||
np.concatenate = concatenate
|
np.concatenate = concatenate
|
||||||
|
|
||||||
|
@ -109,11 +109,13 @@ class GLViewWidget(QtOpenGL.QGLWidget):
|
|||||||
import pyqtgraph.debug
|
import pyqtgraph.debug
|
||||||
pyqtgraph.debug.printExc()
|
pyqtgraph.debug.printExc()
|
||||||
msg = "Error while drawing item %s." % str(item)
|
msg = "Error while drawing item %s." % str(item)
|
||||||
ver = glGetString(GL_VERSION).split()[0]
|
ver = glGetString(GL_VERSION)
|
||||||
if int(ver.split('.')[0]) < 2:
|
if ver is not None:
|
||||||
print(msg + " The original exception is printed above; however, pyqtgraph requires OpenGL version 2.0 or greater for many of its 3D features and your OpenGL version is %s. Installing updated display drivers may resolve this issue." % ver)
|
ver = ver.split()[0]
|
||||||
else:
|
if int(ver.split('.')[0]) < 2:
|
||||||
print(msg)
|
print(msg + " The original exception is printed above; however, pyqtgraph requires OpenGL version 2.0 or greater for many of its 3D features and your OpenGL version is %s. Installing updated display drivers may resolve this issue." % ver)
|
||||||
|
else:
|
||||||
|
print(msg)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
glPopAttrib()
|
glPopAttrib()
|
||||||
|
Loading…
Reference in New Issue
Block a user