Added very basic LegendItem. Functional, but still missing some basic features.
Added GLImageItem and example.
This commit is contained in:
parent
1c8579d4b4
commit
65ed889a77
8
documentation/source/3dgraphics/glimageitem.rst
Normal file
8
documentation/source/3dgraphics/glimageitem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
GLImageItem
|
||||
===========
|
||||
|
||||
.. autoclass:: pyqtgraph.opengl.GLImageItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.opengl.GLImageItem.__init__
|
||||
|
8
documentation/source/graphicsItems/legenditem.rst
Normal file
8
documentation/source/graphicsItems/legenditem.rst
Normal file
@ -0,0 +1,8 @@
|
||||
LegendItem
|
||||
==========
|
||||
|
||||
.. autoclass:: pyqtgraph.LegendItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.LegendItem.__init__
|
||||
|
47
examples/GLImageItem.py
Normal file
47
examples/GLImageItem.py
Normal file
@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
## Add path to library (just for examples; you do not need this)
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
|
||||
from pyqtgraph.Qt import QtCore, QtGui
|
||||
import pyqtgraph.opengl as gl
|
||||
import pyqtgraph as pg
|
||||
import numpy as np
|
||||
import scipy.ndimage as ndi
|
||||
|
||||
app = QtGui.QApplication([])
|
||||
w = gl.GLViewWidget()
|
||||
w.opts['distance'] = 200
|
||||
w.show()
|
||||
|
||||
## create volume data set to slice three images from
|
||||
shape = (100,100,70)
|
||||
data = ndi.gaussian_filter(np.random.normal(size=shape), (4,4,4))
|
||||
data += ndi.gaussian_filter(np.random.normal(size=shape), (15,15,15))*15
|
||||
|
||||
## slice out three planes, convert to ARGB for OpenGL texture
|
||||
levels = (-0.08, 0.08)
|
||||
tex1 = pg.makeRGBA(data[shape[0]/2], levels=levels)[0] # yz plane
|
||||
tex2 = pg.makeRGBA(data[:,shape[1]/2], levels=levels)[0] # xz plane
|
||||
tex3 = pg.makeRGBA(data[:,:,shape[2]/2], levels=levels)[0] # xy plane
|
||||
|
||||
## Create three image items from textures, add to view
|
||||
v1 = gl.GLImageItem(tex1)
|
||||
v1.translate(-shape[1]/2, -shape[2]/2, 0)
|
||||
v1.rotate(90, 0,0,1)
|
||||
v1.rotate(-90, 0,1,0)
|
||||
w.addItem(v1)
|
||||
v2 = gl.GLImageItem(tex2)
|
||||
v2.translate(-shape[0]/2, -shape[2]/2, 0)
|
||||
v2.rotate(-90, 1,0,0)
|
||||
w.addItem(v2)
|
||||
v3 = gl.GLImageItem(tex3)
|
||||
v3.translate(-shape[0]/2, -shape[1]/2, 0)
|
||||
w.addItem(v3)
|
||||
|
||||
ax = gl.GLAxisItem()
|
||||
w.addItem(ax)
|
||||
|
||||
## Start Qt event loop unless running in interactive mode.
|
||||
if sys.flags.interactive != 1:
|
||||
app.exec_()
|
21
examples/Legend.py
Normal file
21
examples/Legend.py
Normal file
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import initExample ## Add path to library (just for examples; you do not need this)
|
||||
|
||||
import pyqtgraph as pg
|
||||
from pyqtgraph.Qt import QtCore, QtGui
|
||||
|
||||
plt = pg.plot()
|
||||
|
||||
l = pg.LegendItem((100,60), (60,10)) # args are (size, position)
|
||||
l.setParentItem(plt.graphicsItem()) # Note we do NOT call plt.addItem in this case
|
||||
|
||||
c1 = plt.plot([1,3,2,4], pen='r')
|
||||
c2 = plt.plot([2,1,4,3], pen='g')
|
||||
l.addItem(c1, 'red plot')
|
||||
l.addItem(c2, 'green plot')
|
||||
|
||||
|
||||
## Start Qt event loop unless running in interactive mode or using pyside.
|
||||
import sys
|
||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||
QtGui.QApplication.instance().exec_()
|
@ -31,6 +31,7 @@ examples = OrderedDict([
|
||||
('ImageItem - draw', 'Draw.py'),
|
||||
('Region-of-Interest', 'ROIExamples.py'),
|
||||
('GraphicsLayout', 'GraphicsLayout.py'),
|
||||
('LegendItem', 'Legend.py'),
|
||||
('Text Item', 'text.py'),
|
||||
('Linked Views', 'linkedViews.py'),
|
||||
('Arrow', 'Arrow.py'),
|
||||
@ -39,6 +40,8 @@ examples = OrderedDict([
|
||||
('3D Graphics', OrderedDict([
|
||||
('Volumetric', 'GLVolumeItem.py'),
|
||||
('Isosurface', 'GLMeshItem.py'),
|
||||
('Image', 'GLImageItem.py'),
|
||||
('Scatter Plot', 'GLScatterPlotItem.py'),
|
||||
])),
|
||||
('Widgets', OrderedDict([
|
||||
('PlotWidget', 'PlotWidget.py'),
|
||||
|
67
graphicsItems/LegendItem.py
Normal file
67
graphicsItems/LegendItem.py
Normal file
@ -0,0 +1,67 @@
|
||||
from .GraphicsWidget import GraphicsWidget
|
||||
from .LabelItem import LabelItem
|
||||
from ..Qt import QtGui, QtCore
|
||||
from .. import functions as fn
|
||||
|
||||
__all__ = ['LegendItem']
|
||||
|
||||
class LegendItem(GraphicsWidget):
|
||||
"""
|
||||
Displays a legend used for describing the contents of a plot.
|
||||
|
||||
Note that this item should not be added directly to a PlotItem. Instead,
|
||||
Make it a direct descendant of the PlotItem::
|
||||
|
||||
legend.setParentItem(plotItem)
|
||||
|
||||
"""
|
||||
def __init__(self, size, offset):
|
||||
GraphicsWidget.__init__(self)
|
||||
self.setFlag(self.ItemIgnoresTransformations)
|
||||
self.layout = QtGui.QGraphicsGridLayout()
|
||||
self.setLayout(self.layout)
|
||||
self.items = []
|
||||
self.size = size
|
||||
self.offset = offset
|
||||
self.setGeometry(QtCore.QRectF(self.offset[0], self.offset[1], self.size[0], self.size[1]))
|
||||
|
||||
def addItem(self, item, title):
|
||||
"""
|
||||
Add a new entry to the legend.
|
||||
=========== ========================================================
|
||||
Arguments
|
||||
item A PlotDataItem from which the line and point style
|
||||
of the item will be determined
|
||||
title The title to display for this item. Simple HTML allowed.
|
||||
=========== ========================================================
|
||||
"""
|
||||
label = LabelItem(title)
|
||||
sample = ItemSample(item)
|
||||
row = len(self.items)
|
||||
self.items.append((sample, label))
|
||||
self.layout.addItem(sample, row, 0)
|
||||
self.layout.addItem(label, row, 1)
|
||||
|
||||
def boundingRect(self):
|
||||
return QtCore.QRectF(0, 0, self.size[0], self.size[1])
|
||||
|
||||
def paint(self, p, *args):
|
||||
p.setPen(fn.mkPen(255,255,255,100))
|
||||
p.setBrush(fn.mkBrush(100,100,100,50))
|
||||
p.drawRect(self.boundingRect())
|
||||
|
||||
|
||||
class ItemSample(GraphicsWidget):
|
||||
def __init__(self, item):
|
||||
GraphicsWidget.__init__(self)
|
||||
self.item = item
|
||||
|
||||
def boundingRect(self):
|
||||
return QtCore.QRectF(0, 0, 20, 20)
|
||||
|
||||
def paint(self, p, *args):
|
||||
p.setPen(fn.mkPen(self.item.opts['pen']))
|
||||
p.drawLine(2, 18, 18, 2)
|
||||
|
||||
|
||||
|
87
opengl/items/GLImageItem.py
Normal file
87
opengl/items/GLImageItem.py
Normal file
@ -0,0 +1,87 @@
|
||||
from OpenGL.GL import *
|
||||
from .. GLGraphicsItem import GLGraphicsItem
|
||||
from pyqtgraph.Qt import QtGui
|
||||
import numpy as np
|
||||
|
||||
__all__ = ['GLImageItem']
|
||||
|
||||
class GLImageItem(GLGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||
|
||||
Displays image data as a textured quad.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, data, smooth=False):
|
||||
"""
|
||||
|
||||
============== =======================================================================================
|
||||
**Arguments:**
|
||||
data Volume data to be rendered. *Must* be 3D numpy array (x, y, RGBA) with dtype=ubyte.
|
||||
(See functions.makeRGBA)
|
||||
smooth (bool) If True, the volume slices are rendered with linear interpolation
|
||||
============== =======================================================================================
|
||||
"""
|
||||
|
||||
self.smooth = smooth
|
||||
self.data = data
|
||||
GLGraphicsItem.__init__(self)
|
||||
|
||||
def initializeGL(self):
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
self.texture = glGenTextures(1)
|
||||
glBindTexture(GL_TEXTURE_2D, self.texture)
|
||||
if self.smooth:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
||||
else:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
|
||||
#glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER)
|
||||
shape = self.data.shape
|
||||
|
||||
## Test texture dimensions first
|
||||
glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
|
||||
if glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) == 0:
|
||||
raise Exception("OpenGL failed to create 2D texture (%dx%d); too large for this hardware." % shape[:2])
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shape[0], shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, self.data.transpose((1,0,2)))
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
|
||||
#self.lists = {}
|
||||
#for ax in [0,1,2]:
|
||||
#for d in [-1, 1]:
|
||||
#l = glGenLists(1)
|
||||
#self.lists[(ax,d)] = l
|
||||
#glNewList(l, GL_COMPILE)
|
||||
#self.drawVolume(ax, d)
|
||||
#glEndList()
|
||||
|
||||
|
||||
def paint(self):
|
||||
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
glBindTexture(GL_TEXTURE_2D, self.texture)
|
||||
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
#glDisable(GL_CULL_FACE)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glEnable( GL_BLEND )
|
||||
glEnable( GL_ALPHA_TEST )
|
||||
glColor4f(1,1,1,1)
|
||||
|
||||
glBegin(GL_QUADS)
|
||||
glTexCoord2f(0,0)
|
||||
glVertex3f(0,0,0)
|
||||
glTexCoord2f(1,0)
|
||||
glVertex3f(self.data.shape[0], 0, 0)
|
||||
glTexCoord2f(1,1)
|
||||
glVertex3f(self.data.shape[0], self.data.shape[1], 0)
|
||||
glTexCoord2f(0,1)
|
||||
glVertex3f(0, self.data.shape[1], 0)
|
||||
glEnd()
|
||||
glDisable(GL_TEXTURE_3D)
|
||||
|
Loading…
Reference in New Issue
Block a user