bugfix: ignore inf and nan when auto-ranging

added experimental opengl line-drawing code
This commit is contained in:
Luke Campagnola 2013-03-04 19:43:51 -05:00
parent 83812ad5b8
commit 2980f8335c
4 changed files with 76 additions and 9 deletions

View File

@ -54,6 +54,7 @@ CONFIG_OPTIONS = {
'editorCommand': None, ## command used to invoke code editor from ConsoleWidgets
'useWeave': True, ## Use weave to speed up some operations, if it is available
'weaveDebug': False, ## Print full error message if weave compile fails
'enableExperimental': False, ## Enable experimental features (the curious can search for this key in the code)
}

View File

@ -1,4 +1,10 @@
from pyqtgraph.Qt import QtGui, QtCore
try:
from pyqtgraph.Qt import QtOpenGL
HAVE_OPENGL = True
except:
HAVE_OPENGL = False
from scipy.fftpack import fft
import numpy as np
import scipy.stats
@ -370,12 +376,11 @@ class PlotCurveItem(GraphicsObject):
prof = debug.Profiler('PlotCurveItem.paint '+str(id(self)), disabled=True)
if self.xData is None:
return
#if self.opts['spectrumMode']:
#if self.specPath is None:
#self.specPath = self.generatePath(*self.getData())
#path = self.specPath
#else:
if HAVE_OPENGL and pg.getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget):
self.paintGL(p, opt, widget)
return
x = None
y = None
if self.path is None:
@ -385,7 +390,6 @@ class PlotCurveItem(GraphicsObject):
self.path = self.generatePath(x,y)
self.fillPath = None
path = self.path
prof.mark('generate path')
@ -440,6 +444,65 @@ class PlotCurveItem(GraphicsObject):
#p.setPen(QtGui.QPen(QtGui.QColor(255,0,0)))
#p.drawRect(self.boundingRect())
def paintGL(self, p, opt, widget):
p.beginNativePainting()
import OpenGL.GL as gl
## set clipping viewport
view = self.getViewBox()
if view is not None:
rect = view.mapRectToItem(self, view.boundingRect())
#gl.glViewport(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
#gl.glTranslate(-rect.x(), -rect.y(), 0)
gl.glEnable(gl.GL_STENCIL_TEST)
gl.glColorMask(gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE) # disable drawing to frame buffer
gl.glDepthMask(gl.GL_FALSE) # disable drawing to depth buffer
gl.glStencilFunc(gl.GL_NEVER, 1, 0xFF)
gl.glStencilOp(gl.GL_REPLACE, gl.GL_KEEP, gl.GL_KEEP)
## draw stencil pattern
gl.glStencilMask(0xFF);
gl.glClear(gl.GL_STENCIL_BUFFER_BIT)
gl.glBegin(gl.GL_TRIANGLES)
gl.glVertex2f(rect.x(), rect.y())
gl.glVertex2f(rect.x()+rect.width(), rect.y())
gl.glVertex2f(rect.x(), rect.y()+rect.height())
gl.glVertex2f(rect.x()+rect.width(), rect.y()+rect.height())
gl.glVertex2f(rect.x()+rect.width(), rect.y())
gl.glVertex2f(rect.x(), rect.y()+rect.height())
gl.glEnd()
gl.glColorMask(gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
gl.glDepthMask(gl.GL_TRUE)
gl.glStencilMask(0x00)
gl.glStencilFunc(gl.GL_EQUAL, 1, 0xFF)
try:
x, y = self.getData()
pos = np.empty((len(x), 2))
pos[:,0] = x
pos[:,1] = y
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
try:
gl.glVertexPointerf(pos)
pen = fn.mkPen(self.opts['pen'])
color = pen.color()
gl.glColor4f(color.red()/255., color.green()/255., color.blue()/255., color.alpha()/255.)
width = pen.width()
if pen.isCosmetic() and width < 1:
width = 1
gl.glPointSize(width)
gl.glEnable(gl.GL_LINE_SMOOTH)
gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glHint(gl.GL_LINE_SMOOTH_HINT, gl.GL_NICEST);
gl.glDrawArrays(gl.GL_LINE_STRIP, 0, pos.size / pos.shape[-1])
finally:
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
finally:
p.endNativePainting()
def clear(self):
self.xData = None ## raw values

View File

@ -683,6 +683,9 @@ class ScatterPlotItem(GraphicsObject):
rec = self.data[i]
pos = QtCore.QPointF(pts[0,i], pts[1,i])
x,y,w,h = rec['fragCoords']
if abs(w) > 10000 or abs(h) > 10000:
print self.data
raise Exception("fragment corrupt")
rect = QtCore.QRectF(y, x, h, w)
self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))

View File

@ -1048,10 +1048,10 @@ class ViewBox(GraphicsWidget):
xr = item.dataBounds(0, frac=frac[0], orthoRange=orthoRange[0])
yr = item.dataBounds(1, frac=frac[1], orthoRange=orthoRange[1])
pxPad = 0 if not hasattr(item, 'pixelPadding') else item.pixelPadding()
if xr is None or xr == (None, None):
if xr is None or xr == (None, None) or np.isnan(xr).any() or np.isinf(xr).any():
useX = False
xr = (0,0)
if yr is None or yr == (None, None):
if yr is None or yr == (None, None) or np.isnan(yr).any() or np.isinf(yr).any():
useY = False
yr = (0,0)