merged with dev
This commit is contained in:
commit
2e9440d927
48
documentation/source/3dgraphics.rst
Normal file
48
documentation/source/3dgraphics.rst
Normal file
@ -0,0 +1,48 @@
|
||||
3D Graphics
|
||||
===========
|
||||
|
||||
Pyqtgraph uses OpenGL to provide a 3D scenegraph system. This system is functional but still early in development.
|
||||
Current capabilities include:
|
||||
|
||||
* 3D view widget with zoom/rotate controls (mouse drag and wheel)
|
||||
* Scenegraph allowing items to be added/removed from scene with per-item transformations and parent/child relationships.
|
||||
* Triangular meshes
|
||||
* Basic mesh computation functions: isosurfaces, per-vertex normals
|
||||
* Volumetric rendering item
|
||||
* Grid/axis items
|
||||
|
||||
See the :doc:`API Reference </3dgraphics/index>` and the Volumetric (GLVolumeItem.py) and Isosurface (GLMeshItem.py) examples for more information.
|
||||
|
||||
Basic usage example::
|
||||
|
||||
## build a QApplication before building other widgets
|
||||
import pyqtgraph as pg
|
||||
pg.mkQApp()
|
||||
|
||||
## make a widget for displaying 3D objects
|
||||
import pyqtgraph.opengl as gl
|
||||
view = gl.GLViewWidget()
|
||||
view.show()
|
||||
|
||||
## create three grids, add each to the view
|
||||
xgrid = gl.GLGridItem()
|
||||
ygrid = gl.GLGridItem()
|
||||
zgrid = gl.GLGridItem()
|
||||
view.addItem(xgrid)
|
||||
view.addItem(ygrid)
|
||||
view.addItem(zgrid)
|
||||
|
||||
## rotate x and y grids to face the correct direction
|
||||
xgrid.rotate(90, 0, 1, 0)
|
||||
ygrid.rotate(90, 1, 0, 0)
|
||||
|
||||
## scale each grid differently
|
||||
xgrid.scale(0.2, 0.1, 0.1)
|
||||
ygrid.scale(0.2, 0.1, 0.1)
|
||||
zgrid.scale(0.1, 0.2, 0.1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
8
documentation/source/3dgraphics/glaxisitem.rst
Normal file
8
documentation/source/3dgraphics/glaxisitem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLAxisItem
|
||||
==========
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLAxisItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.GLAxisItem.__init__
|
||||
|
8
documentation/source/3dgraphics/glgraphicsitem.rst
Normal file
8
documentation/source/3dgraphics/glgraphicsitem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLGraphicsItem
|
||||
==============
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLGraphicsItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.GLGraphicsItem.__init__
|
||||
|
8
documentation/source/3dgraphics/glgriditem.rst
Normal file
8
documentation/source/3dgraphics/glgriditem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLGridItem
|
||||
==========
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLGridItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.GLGridItem.__init__
|
||||
|
8
documentation/source/3dgraphics/glmeshitem.rst
Normal file
8
documentation/source/3dgraphics/glmeshitem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLMeshItem
|
||||
==========
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLMeshItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.GLMeshItem.__init__
|
||||
|
8
documentation/source/3dgraphics/glviewwidget.rst
Normal file
8
documentation/source/3dgraphics/glviewwidget.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLViewWidget
|
||||
============
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLViewWidget
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.GLViewWidget.__init__
|
||||
|
8
documentation/source/3dgraphics/glvolumeitem.rst
Normal file
8
documentation/source/3dgraphics/glvolumeitem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLVolumeItem
|
||||
============
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLVolumeItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.GLVolumeItem.__init__
|
||||
|
24
documentation/source/3dgraphics/index.rst
Normal file
24
documentation/source/3dgraphics/index.rst
Normal file
@ -0,0 +1,24 @@
|
||||
Pyqtgraph's 3D Graphics System
|
||||
==============================
|
||||
|
||||
The 3D graphics system in pyqtgraph is composed of a :class:`view widget <pyqtgraph.opengl.GLViewWidget>` and
|
||||
several graphics items (all subclasses of :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`) which
|
||||
can be added to a view widget.
|
||||
|
||||
**Note:** use of this system requires python-opengl bindings. Linux users should install the python-opengl
|
||||
packages from their distribution. Windows/OSX users can download from `<http://pyopengl.sourceforge.net>`_.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
glviewwidget
|
||||
|
||||
glgriditem
|
||||
glmeshitem
|
||||
glvolumeitem
|
||||
glaxisitem
|
||||
glgraphicsitem
|
||||
meshdata
|
||||
|
9
documentation/source/3dgraphics/meshdata.rst
Normal file
9
documentation/source/3dgraphics/meshdata.rst
Normal file
@ -0,0 +1,9 @@
|
||||
MeshData
|
||||
========
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.MeshData.MeshData
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.MeshData.MeshData.__init__
|
||||
.. automethod:: pyqtgraph.opengl.MeshData.MeshData.__iter__
|
||||
|
@ -9,4 +9,5 @@ Contents:
|
||||
functions
|
||||
graphicsItems/index
|
||||
widgets/index
|
||||
graphicsscene/index
|
||||
3dgraphics/index
|
||||
graphicsscene/index
|
||||
|
@ -16,6 +16,7 @@ Contents:
|
||||
how_to_use
|
||||
plotting
|
||||
images
|
||||
3dgraphics
|
||||
style
|
||||
region_of_interest
|
||||
parametertree
|
||||
|
@ -34,59 +34,39 @@ class PlotCurveItem(GraphicsObject):
|
||||
sigPlotChanged = QtCore.Signal(object)
|
||||
sigClicked = QtCore.Signal(object)
|
||||
|
||||
def __init__(self, y=None, x=None, fillLevel=None, copy=False, pen=None, shadowPen=None, brush=None, parent=None, clickable=False):
|
||||
def __init__(self, *args, **kargs):
|
||||
"""
|
||||
Forwards all arguments to :func:`setData <pyqtgraph.PlotCurveItem.setData>`.
|
||||
|
||||
Some extra arguments are accepted as well:
|
||||
|
||||
============== =======================================================
|
||||
**Arguments:**
|
||||
x, y (numpy arrays) Data to show
|
||||
pen Pen to use when drawing. Any single argument accepted by
|
||||
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
||||
shadowPen Pen for drawing behind the primary pen. Usually this
|
||||
is used to emphasize the curve by providing a
|
||||
high-contrast border. Any single argument accepted by
|
||||
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
||||
fillLevel (float or None) Fill the area 'under' the curve to
|
||||
*fillLevel*
|
||||
brush QBrush to use when filling. Any single argument accepted
|
||||
by :func:`mkBrush <pyqtgraph.mkBrush>` is allowed.
|
||||
parent The parent GraphicsObject (optional)
|
||||
clickable If True, the item will emit sigClicked when it is
|
||||
clicked on.
|
||||
clicked on. Defaults to False.
|
||||
============== =======================================================
|
||||
|
||||
|
||||
|
||||
"""
|
||||
GraphicsObject.__init__(self, parent)
|
||||
GraphicsObject.__init__(self, kargs.get('parent', None))
|
||||
self.clear()
|
||||
self.path = None
|
||||
self.fillPath = None
|
||||
self.exportOpts = False
|
||||
self.antialias = False
|
||||
|
||||
if y is not None:
|
||||
self.updateData(y, x)
|
||||
|
||||
## this is disastrous for performance.
|
||||
#self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
|
||||
|
||||
self.metaData = {}
|
||||
self.opts = {
|
||||
#'spectrumMode': False,
|
||||
#'logMode': [False, False],
|
||||
#'downsample': False,
|
||||
#'alphaHint': 1.0,
|
||||
#'alphaMode': False,
|
||||
'pen': 'w',
|
||||
'pen': fn.mkPen('w'),
|
||||
'shadowPen': None,
|
||||
'fillLevel': fillLevel,
|
||||
'brush': brush,
|
||||
'fillLevel': None,
|
||||
'brush': None,
|
||||
}
|
||||
self.setPen(pen)
|
||||
self.setShadowPen(shadowPen)
|
||||
self.setFillLevel(fillLevel)
|
||||
self.setBrush(brush)
|
||||
self.setClickable(clickable)
|
||||
#self.fps = None
|
||||
self.setClickable(kargs.get('clickable', False))
|
||||
self.setData(*args, **kargs)
|
||||
|
||||
def implements(self, interface=None):
|
||||
ints = ['plotData']
|
||||
@ -101,41 +81,6 @@ class PlotCurveItem(GraphicsObject):
|
||||
|
||||
def getData(self):
|
||||
return self.xData, self.yData
|
||||
#if self.xData is None:
|
||||
#return (None, None)
|
||||
#if self.xDisp is None:
|
||||
#nanMask = np.isnan(self.xData) | np.isnan(self.yData)
|
||||
#if any(nanMask):
|
||||
#x = self.xData[~nanMask]
|
||||
#y = self.yData[~nanMask]
|
||||
#else:
|
||||
#x = self.xData
|
||||
#y = self.yData
|
||||
#ds = self.opts['downsample']
|
||||
#if ds > 1:
|
||||
#x = x[::ds]
|
||||
##y = resample(y[:len(x)*ds], len(x)) ## scipy.signal.resample causes nasty ringing
|
||||
#y = y[::ds]
|
||||
#if self.opts['spectrumMode']:
|
||||
#f = fft(y) / len(y)
|
||||
#y = abs(f[1:len(f)/2])
|
||||
#dt = x[-1] - x[0]
|
||||
#x = np.linspace(0, 0.5*len(x)/dt, len(y))
|
||||
#if self.opts['logMode'][0]:
|
||||
#x = np.log10(x)
|
||||
#if self.opts['logMode'][1]:
|
||||
#y = np.log10(y)
|
||||
#self.xDisp = x
|
||||
#self.yDisp = y
|
||||
##print self.yDisp.shape, self.yDisp.min(), self.yDisp.max()
|
||||
##print self.xDisp.shape, self.xDisp.min(), self.xDisp.max()
|
||||
#return self.xDisp, self.yDisp
|
||||
|
||||
#def generateSpecData(self):
|
||||
#f = fft(self.yData) / len(self.yData)
|
||||
#self.ySpec = abs(f[1:len(f)/2])
|
||||
#dt = self.xData[-1] - self.xData[0]
|
||||
#self.xSpec = linspace(0, 0.5*len(self.xData)/dt, len(self.ySpec))
|
||||
|
||||
def dataBounds(self, ax, frac=1.0):
|
||||
(x, y) = self.getData()
|
||||
@ -154,12 +99,6 @@ class PlotCurveItem(GraphicsObject):
|
||||
else:
|
||||
return (scipy.stats.scoreatpercentile(d, 50 - (frac * 50)), scipy.stats.scoreatpercentile(d, 50 + (frac * 50)))
|
||||
|
||||
#def setMeta(self, data):
|
||||
#self.metaData = data
|
||||
|
||||
#def meta(self):
|
||||
#return self.metaData
|
||||
|
||||
def setPen(self, *args, **kargs):
|
||||
"""Set the pen used to draw the curve."""
|
||||
self.opts['pen'] = fn.mkPen(*args, **kargs)
|
||||
@ -219,7 +158,26 @@ class PlotCurveItem(GraphicsObject):
|
||||
|
||||
def setData(self, *args, **kargs):
|
||||
"""
|
||||
Accepts most of the same arguments as __init__.
|
||||
============== =======================================================
|
||||
**Arguments:**
|
||||
x, y (numpy arrays) Data to show
|
||||
pen Pen to use when drawing. Any single argument accepted by
|
||||
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
||||
shadowPen Pen for drawing behind the primary pen. Usually this
|
||||
is used to emphasize the curve by providing a
|
||||
high-contrast border. Any single argument accepted by
|
||||
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
|
||||
fillLevel (float or None) Fill the area 'under' the curve to
|
||||
*fillLevel*
|
||||
brush QBrush to use when filling. Any single argument accepted
|
||||
by :func:`mkBrush <pyqtgraph.mkBrush>` is allowed.
|
||||
============== =======================================================
|
||||
|
||||
If non-keyword arguments are used, they will be interpreted as
|
||||
setData(y) for a single argument and setData(x, y) for two
|
||||
arguments.
|
||||
|
||||
|
||||
"""
|
||||
self.updateData(*args, **kargs)
|
||||
|
||||
|
@ -3,12 +3,13 @@ import pyqtgraph.functions as fn
|
||||
|
||||
class MeshData(object):
|
||||
"""
|
||||
Class for storing 3D mesh data. May contain:
|
||||
- list of vertex locations
|
||||
- list of edges
|
||||
- list of triangles
|
||||
- colors per vertex, edge, or tri
|
||||
- normals per vertex or tri
|
||||
Class for storing and operating on 3D mesh data. May contain:
|
||||
|
||||
- list of vertex locations
|
||||
- list of edges
|
||||
- list of triangles
|
||||
- colors per vertex, edge, or tri
|
||||
- normals per vertex or tri
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@ -26,11 +27,15 @@ class MeshData(object):
|
||||
def setFaces(self, faces, vertexes=None):
|
||||
"""
|
||||
Set the faces in this data set.
|
||||
Data may be provided either as an Nx3x3 list of floats (9 float coordinate values per face)
|
||||
*faces* = [ [(x, y, z), (x, y, z), (x, y, z)], ... ]
|
||||
or as an Nx3 list of ints (vertex integers) AND an Mx3 list of floats (3 float coordinate values per vertex)
|
||||
*faces* = [ (p1, p2, p3), ... ]
|
||||
*vertexes* = [ (x, y, z), ... ]
|
||||
Data may be provided either as an Nx3x3 list of floats (9 float coordinate values per face)::
|
||||
|
||||
faces = [ [(x, y, z), (x, y, z), (x, y, z)], ... ]
|
||||
|
||||
or as an Nx3 list of ints (vertex integers) AND an Mx3 list of floats (3 float coordinate values per vertex)::
|
||||
|
||||
faces = [ (p1, p2, p3), ... ]
|
||||
vertexes = [ (x, y, z), ... ]
|
||||
|
||||
"""
|
||||
|
||||
if vertexes is None:
|
||||
@ -147,18 +152,18 @@ class MeshData(object):
|
||||
def edgeColors(self):
|
||||
return self._edgeColors
|
||||
|
||||
def reverseNormals(self):
|
||||
"""
|
||||
Reverses the direction of all normal vectors.
|
||||
"""
|
||||
pass
|
||||
#def reverseNormals(self):
|
||||
#"""
|
||||
#Reverses the direction of all normal vectors.
|
||||
#"""
|
||||
#pass
|
||||
|
||||
def generateEdgesFromFaces(self):
|
||||
"""
|
||||
Generate a set of edges by listing all the edges of faces and removing any duplicates.
|
||||
Useful for displaying wireframe meshes.
|
||||
"""
|
||||
pass
|
||||
#def generateEdgesFromFaces(self):
|
||||
#"""
|
||||
#Generate a set of edges by listing all the edges of faces and removing any duplicates.
|
||||
#Useful for displaying wireframe meshes.
|
||||
#"""
|
||||
#pass
|
||||
|
||||
def save(self):
|
||||
"""Serialize this mesh to a string appropriate for disk storage"""
|
||||
|
@ -5,6 +5,13 @@ from pyqtgraph import QtGui
|
||||
__all__ = ['GLAxisItem']
|
||||
|
||||
class GLAxisItem(GLGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||
|
||||
Displays three lines indicating origin and orientation of local coordinate system.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, size=None):
|
||||
GLGraphicsItem.__init__(self)
|
||||
if size is None:
|
||||
|
@ -6,6 +6,11 @@ import pyqtgraph as pg
|
||||
__all__ = ['GLBoxItem']
|
||||
|
||||
class GLBoxItem(GLGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||
|
||||
Displays a wire-frame box.
|
||||
"""
|
||||
def __init__(self, size=None, color=None):
|
||||
GLGraphicsItem.__init__(self)
|
||||
if size is None:
|
||||
|
@ -5,6 +5,12 @@ from pyqtgraph import QtGui
|
||||
__all__ = ['GLGridItem']
|
||||
|
||||
class GLGridItem(GLGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||
|
||||
Displays a wire-grame grid.
|
||||
"""
|
||||
|
||||
def __init__(self, size=None, color=None):
|
||||
GLGraphicsItem.__init__(self)
|
||||
if size is None:
|
||||
|
@ -12,13 +12,13 @@ __all__ = ['GLMeshItem']
|
||||
|
||||
class GLMeshItem(GLGraphicsItem):
|
||||
"""
|
||||
Displays a 3D triangle mesh.
|
||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||
|
||||
Displays a 3D triangle mesh.
|
||||
"""
|
||||
def __init__(self, faces, vertexes=None):
|
||||
|
||||
"""
|
||||
See MeshData for initialization arguments.
|
||||
See :class:`MeshData <pyqtgraph.opengl.MeshData>` for initialization arguments.
|
||||
"""
|
||||
if isinstance(faces, MeshData):
|
||||
self.data = faces
|
||||
|
@ -6,7 +6,23 @@ import numpy as np
|
||||
__all__ = ['GLVolumeItem']
|
||||
|
||||
class GLVolumeItem(GLGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||
|
||||
Displays volumetric data.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, data, sliceDensity=1, smooth=True):
|
||||
"""
|
||||
============== =======================================================================================
|
||||
**Arguments:**
|
||||
data Volume data to be rendered. *Must* be 4D numpy array (x, y, z, RGBA) with dtype=ubyte.
|
||||
sliceDensity Density of slices to render through the volume. A value of 1 means one slice per voxel.
|
||||
smooth (bool) If True, the volume slices are rendered with linear interpolation
|
||||
============== =======================================================================================
|
||||
"""
|
||||
|
||||
self.sliceDensity = sliceDensity
|
||||
self.smooth = smooth
|
||||
self.data = data
|
||||
|
Loading…
Reference in New Issue
Block a user