Add GLGradientLegendItem to pyqtgraph
Huge thank you to @feketeimre for the initial PR for this feature Thank you to @pijyoi for re-implementing with no changes needed to GLViewWidget and supporting QOpenGLWidget vs. QGLWidget.
This commit is contained in:
parent
d3755520d0
commit
0cfc9cd440
43
examples/GLGradientLegendItem.py
Normal file
43
examples/GLGradientLegendItem.py
Normal file
@ -0,0 +1,43 @@
|
||||
import initExample
|
||||
|
||||
import pyqtgraph as pg
|
||||
import pyqtgraph.opengl as gl
|
||||
import numpy
|
||||
|
||||
app = pg.mkQApp()
|
||||
w = gl.GLViewWidget()
|
||||
w.show()
|
||||
w.setWindowTitle("pyqtgraph example: GLGradientLegendItem")
|
||||
w.setCameraPosition(distance=60)
|
||||
|
||||
gx = gl.GLGridItem()
|
||||
gx.rotate(90, 0, 1, 0)
|
||||
w.addItem(gx)
|
||||
|
||||
md = gl.MeshData.cylinder(rows=10, cols=20, radius=[5.0, 5], length=20.0)
|
||||
md._vertexes[:, 2] = md._vertexes[:, 2] - 10
|
||||
|
||||
# set color based on z coordinates
|
||||
color_map = pg.colormap.get("CET-L10")
|
||||
|
||||
h = md.vertexes()[:, 2]
|
||||
# remember these
|
||||
h_max, h_min = h.max(), h.min()
|
||||
h = (h - h_min) / (h_max - h_min)
|
||||
colors = color_map.map(h, mode="float")
|
||||
md.setFaceColors(colors)
|
||||
m = gl.GLMeshItem(meshdata=md, smooth=True)
|
||||
w.addItem(m)
|
||||
|
||||
legendLabels = numpy.linspace(h_max, h_min, 5)
|
||||
legendPos = numpy.linspace(1, 0, 5)
|
||||
legend = dict(zip(map(str, legendLabels), legendPos))
|
||||
|
||||
gll = gl.GLGradientLegendItem(
|
||||
pos=(10, 10), size=(50, 300), gradient=color_map, labels=legend
|
||||
)
|
||||
w.addItem(gll)
|
||||
|
||||
## Start Qt event loop unless running in interactive mode.
|
||||
if __name__ == "__main__":
|
||||
pg.exec()
|
@ -76,6 +76,7 @@ examples_ = OrderedDict([
|
||||
('Text', 'GLTextItem.py'),
|
||||
('BarGraph', 'GLBarGraphItem.py'),
|
||||
('Painter', 'GLPainterItem.py'),
|
||||
('Gradient Legend', 'GLGradientLegendItem.py')
|
||||
])),
|
||||
('Widgets', OrderedDict([
|
||||
('PlotWidget', 'PlotWidget.py'),
|
||||
|
@ -4,17 +4,18 @@ from .GLViewWidget import GLViewWidget
|
||||
#from .. import importAll
|
||||
#importAll('items', globals(), locals())
|
||||
|
||||
from .items.GLGridItem import *
|
||||
from .items.GLBarGraphItem import *
|
||||
from .items.GLScatterPlotItem import *
|
||||
from .items.GLMeshItem import *
|
||||
from .items.GLLinePlotItem import *
|
||||
from .items.GLAxisItem import *
|
||||
from .items.GLImageItem import *
|
||||
from .items.GLSurfacePlotItem import *
|
||||
from .items.GLBoxItem import *
|
||||
from .items.GLVolumeItem import *
|
||||
from .items.GLGridItem import *
|
||||
from .items.GLBarGraphItem import *
|
||||
from .items.GLScatterPlotItem import *
|
||||
from .items.GLMeshItem import *
|
||||
from .items.GLLinePlotItem import *
|
||||
from .items.GLAxisItem import *
|
||||
from .items.GLImageItem import *
|
||||
from .items.GLSurfacePlotItem import *
|
||||
from .items.GLBoxItem import *
|
||||
from .items.GLVolumeItem import *
|
||||
from .items.GLTextItem import *
|
||||
from .items.GLGradientLegendItem import *
|
||||
|
||||
from .MeshData import MeshData
|
||||
## for backward compatibility:
|
||||
|
107
pyqtgraph/opengl/items/GLGradientLegendItem.py
Normal file
107
pyqtgraph/opengl/items/GLGradientLegendItem.py
Normal file
@ -0,0 +1,107 @@
|
||||
from ... Qt import QtCore, QtGui
|
||||
from ... import functions as fn
|
||||
from OpenGL.GL import *
|
||||
from ..GLGraphicsItem import GLGraphicsItem
|
||||
|
||||
__all__ = ['GLGradientLegendItem']
|
||||
|
||||
class GLGradientLegendItem(GLGraphicsItem):
|
||||
"""
|
||||
Displays legend colorbar on the screen.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwds):
|
||||
"""
|
||||
Arguments:
|
||||
pos: position of the colorbar on the screen, from the top left corner, in pixels
|
||||
size: size of the colorbar without the text, in pixels
|
||||
gradient: a pg.ColorMap used to color the colorbar
|
||||
labels: a dict of "text":value to display next to the colorbar.
|
||||
The value corresponds to a position in the gradient from 0 to 1.
|
||||
fontColor: sets the color of the texts
|
||||
#Todo:
|
||||
size as percentage
|
||||
legend title
|
||||
"""
|
||||
GLGraphicsItem.__init__(self)
|
||||
glopts = kwds.pop("glOptions", "additive")
|
||||
self.setGLOptions(glopts)
|
||||
self.pos = (10, 10)
|
||||
self.size = (10, 100)
|
||||
self.fontColor = (1.0, 1.0, 1.0, 1.0)
|
||||
self.stops = None
|
||||
self.colors = None
|
||||
self.gradient = None
|
||||
self.setData(**kwds)
|
||||
|
||||
def setData(self, **kwds):
|
||||
args = ["size", "pos", "gradient", "labels", "fontColor"]
|
||||
for k in kwds.keys():
|
||||
if k not in args:
|
||||
raise Exception(
|
||||
"Invalid keyword argument: %s (allowed arguments are %s)"
|
||||
% (k, str(args))
|
||||
)
|
||||
|
||||
self.antialias = False
|
||||
|
||||
for arg in args:
|
||||
if arg in kwds:
|
||||
setattr(self, arg, kwds[arg])
|
||||
|
||||
##todo: add title
|
||||
##todo: take more gradient types
|
||||
if self.gradient is not None and hasattr(self.gradient, "getStops"):
|
||||
self.stops, self.colors = self.gradient.getStops("float")
|
||||
self.qgradient = self.gradient.getGradient()
|
||||
self.update()
|
||||
|
||||
def paint(self):
|
||||
if self.pos is None or self.stops is None:
|
||||
return
|
||||
self.setupGLState()
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glPushMatrix()
|
||||
glLoadIdentity()
|
||||
glOrtho(0.0, self.view().width(), self.view().height(), 0.0, -1.0, 10.0)
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
glDisable(GL_CULL_FACE)
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT)
|
||||
|
||||
# draw the colorbar
|
||||
glTranslate(self.pos[0], self.pos[1], 0)
|
||||
glScale(self.size[0], self.size[1], 0)
|
||||
glBegin(GL_QUAD_STRIP)
|
||||
for p, c in zip(self.stops, self.colors):
|
||||
glColor4f(*c)
|
||||
glVertex2d(0, 1 - p)
|
||||
glColor4f(*c)
|
||||
glVertex2d(1, 1 - p)
|
||||
glEnd()
|
||||
|
||||
# draw labels
|
||||
# scaling and translate doesnt work on rendertext
|
||||
fontColor = QtGui.QColor(*[x * 255 for x in self.fontColor])
|
||||
|
||||
# could also draw the gradient using QPainter
|
||||
barRect = QtCore.QRectF(self.view().width() - 60, self.pos[1], self.size[0], self.size[1])
|
||||
self.qgradient.setStart(barRect.bottomLeft())
|
||||
self.qgradient.setFinalStop(barRect.topLeft())
|
||||
|
||||
painter = QtGui.QPainter(self.view())
|
||||
painter.fillRect(barRect, self.qgradient)
|
||||
painter.setPen(fn.mkPen(fontColor))
|
||||
for labelText, labelPosition in self.labels.items():
|
||||
## todo: draw ticks, position text properly
|
||||
x = 1.1 * self.size[0] + self.pos[0]
|
||||
y = self.size[1] - labelPosition * self.size[1] + self.pos[1] + 8
|
||||
##todo: fonts
|
||||
painter.drawText(x, y, labelText)
|
||||
painter.end()
|
||||
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glPopMatrix()
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
|
Loading…
Reference in New Issue
Block a user