Minor edits and bugfixes
- fixed AxisItem sometimes drawing the same tick twice (sometimes with different text) - fixed handling of record arrays in setting ScatterPlotItem point data
This commit is contained in:
parent
a4963f93b7
commit
cc94e15d1e
@ -1,13 +1,10 @@
|
||||
#!/usr/bin/python -i
|
||||
# -*- 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__), '..', '..'))
|
||||
|
||||
import initExample ## Add path to library (just for examples; you do not need this)
|
||||
|
||||
import pyqtgraph as pg
|
||||
from pyqtgraph.Qt import QtCore, QtGui
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
|
||||
|
||||
## Create image to display
|
||||
arr = np.ones((100, 100), dtype=float)
|
||||
@ -128,100 +125,10 @@ img4.setParentItem(r4)
|
||||
|
||||
|
||||
|
||||
#v = w.addViewBox(colspan=2)
|
||||
|
||||
#v.invertY(True) ## Images usually have their Y-axis pointing downward
|
||||
#v.setAspectLocked(True)
|
||||
|
||||
|
||||
|
||||
### Create image items, add to scene and set position
|
||||
#im1 = pg.ImageItem(arr)
|
||||
#im2 = pg.ImageItem(arr)
|
||||
#v.addItem(im1)
|
||||
#v.addItem(im2)
|
||||
#im2.moveBy(110, 20)
|
||||
#v.setRange(QtCore.QRectF(0, 0, 200, 120))
|
||||
|
||||
#im3 = pg.ImageItem()
|
||||
#v2 = w.addViewBox(1,0)
|
||||
#v2.addItem(im3)
|
||||
#v2.setRange(QtCore.QRectF(0, 0, 60, 60))
|
||||
#v2.invertY(True)
|
||||
#v2.setAspectLocked(True)
|
||||
##im3.moveBy(0, 130)
|
||||
#im3.setZValue(10)
|
||||
|
||||
#im4 = pg.ImageItem()
|
||||
#v3 = w.addViewBox(1,1)
|
||||
#v3.addItem(im4)
|
||||
#v3.setRange(QtCore.QRectF(0, 0, 60, 60))
|
||||
#v3.invertY(True)
|
||||
#v3.setAspectLocked(True)
|
||||
##im4.moveBy(110, 130)
|
||||
#im4.setZValue(10)
|
||||
|
||||
### create the plot
|
||||
#pi1 = w.addPlot(2,0, colspan=2)
|
||||
##pi1 = pg.PlotItem()
|
||||
##s.addItem(pi1)
|
||||
##pi1.scale(0.5, 0.5)
|
||||
##pi1.setGeometry(0, 170, 300, 100)
|
||||
|
||||
#lastRoi = None
|
||||
|
||||
#def updateRoi(roi):
|
||||
#global im1, im2, im3, im4, arr, lastRoi
|
||||
#if roi is None:
|
||||
#return
|
||||
#lastRoi = roi
|
||||
#arr1 = roi.getArrayRegion(im1.image, img=im1)
|
||||
#im3.setImage(arr1)
|
||||
#arr2 = roi.getArrayRegion(im2.image, img=im2)
|
||||
#im4.setImage(arr2)
|
||||
#updateRoiPlot(roi, arr1)
|
||||
|
||||
#def updateRoiPlot(roi, data=None):
|
||||
#if data is None:
|
||||
#data = roi.getArrayRegion(im1.image, img=im1)
|
||||
#if data is not None:
|
||||
#roi.curve.setData(data.mean(axis=1))
|
||||
|
||||
|
||||
### Create a variety of different ROI types
|
||||
#rois = []
|
||||
#rois.append(pg.TestROI([0, 0], [20, 20], maxBounds=QtCore.QRectF(-10, -10, 230, 140), pen=(0,9)))
|
||||
#rois.append(pg.LineROI([0, 0], [20, 20], width=5, pen=(1,9)))
|
||||
#rois.append(pg.MultiLineROI([[0, 50], [50, 60], [60, 30]], width=5, pen=(2,9)))
|
||||
#rois.append(pg.EllipseROI([110, 10], [30, 20], pen=(3,9)))
|
||||
#rois.append(pg.CircleROI([110, 50], [20, 20], pen=(4,9)))
|
||||
#rois.append(pg.LineSegmentROI([[110, 50], [20, 20]], pen=(5,9)))
|
||||
#rois.append(pg.PolyLineROI([[110, 60], [20, 30], [50, 10]], pen=(6,9)))
|
||||
##rois.append(pg.PolygonROI([[2,0], [2.1,0], [2,.1]], pen=(5,9)))
|
||||
##rois.append(SpiralROI([20,30], [1,1], pen=mkPen(0)))
|
||||
|
||||
### Add each ROI to the scene and link its data to a plot curve with the same color
|
||||
#for r in rois:
|
||||
#v.addItem(r)
|
||||
#c = pi1.plot(pen=r.pen)
|
||||
#r.curve = c
|
||||
#r.sigRegionChanged.connect(updateRoi)
|
||||
|
||||
#def updateImage():
|
||||
#global im1, arr, lastRoi
|
||||
#r = abs(np.random.normal(loc=0, scale=(arr.max()-arr.min())*0.1, size=arr.shape))
|
||||
#im1.updateImage(arr + r)
|
||||
#updateRoi(lastRoi)
|
||||
#for r in rois:
|
||||
#updateRoiPlot(r)
|
||||
|
||||
### Rapidly update one of the images with random noise
|
||||
#t = QtCore.QTimer()
|
||||
#t.timeout.connect(updateImage)
|
||||
#t.start(50)
|
||||
|
||||
|
||||
|
||||
## Start Qt event loop unless running in interactive mode.
|
||||
if sys.flags.interactive != 1:
|
||||
app.exec_()
|
||||
## 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_()
|
||||
|
@ -210,7 +210,7 @@ class AxisItem(GraphicsWidget):
|
||||
if scale is None:
|
||||
#if self.drawLabel: ## If there is a label, then we are free to rescale the values
|
||||
if self.label.isVisible():
|
||||
d = self.range[1] - self.range[0]
|
||||
#d = self.range[1] - self.range[0]
|
||||
#(scale, prefix) = fn.siScale(d / 2.)
|
||||
(scale, prefix) = fn.siScale(max(abs(self.range[0]), abs(self.range[1])))
|
||||
if self.labelUnits == '' and prefix in ['k', 'm']: ## If we are not showing units, wait until 1e6 before scaling.
|
||||
@ -230,7 +230,7 @@ class AxisItem(GraphicsWidget):
|
||||
def setRange(self, mn, mx):
|
||||
"""Set the range of values displayed by the axis.
|
||||
Usually this is handled automatically by linking the axis to a ViewBox with :func:`linkToView <pyqtgraph.AxisItem.linkToView>`"""
|
||||
if mn in [np.nan, np.inf, -np.inf] or mx in [np.nan, np.inf, -np.inf]:
|
||||
if any(np.isinf((mn, mx))) or any(np.isnan((mn, mx))):
|
||||
raise Exception("Not setting range to [%s, %s]" % (str(mn), str(mx)))
|
||||
self.range = [mn, mx]
|
||||
if self.autoScale:
|
||||
@ -259,6 +259,9 @@ class AxisItem(GraphicsWidget):
|
||||
view.sigXRangeChanged.connect(self.linkedViewChanged)
|
||||
|
||||
def linkedViewChanged(self, view, newRange):
|
||||
if self.orientation in ['right', 'left'] and view.yInverted():
|
||||
self.setRange(*newRange[::-1])
|
||||
else:
|
||||
self.setRange(*newRange)
|
||||
|
||||
def boundingRect(self):
|
||||
@ -365,12 +368,14 @@ class AxisItem(GraphicsWidget):
|
||||
By default, this method calls tickSpacing to determine the correct tick locations.
|
||||
This is a good method to override in subclasses.
|
||||
"""
|
||||
minVal, maxVal = sorted((minVal, maxVal))
|
||||
|
||||
if self.logMode:
|
||||
return self.logTickValues(minVal, maxVal, size)
|
||||
|
||||
ticks = []
|
||||
tickLevels = self.tickSpacing(minVal, maxVal, size)
|
||||
allValues = []
|
||||
allValues = np.array([])
|
||||
for i in range(len(tickLevels)):
|
||||
spacing, offset = tickLevels[i]
|
||||
|
||||
@ -380,8 +385,11 @@ class AxisItem(GraphicsWidget):
|
||||
## determine number of ticks
|
||||
num = int((maxVal-start) / spacing) + 1
|
||||
values = np.arange(num) * spacing + start
|
||||
values = filter(lambda x: x not in allValues, values) ## remove any ticks that were present in higher levels
|
||||
allValues.extend(values)
|
||||
## remove any ticks that were present in higher levels
|
||||
## we assume here that if the difference between a tick value and a previously seen tick value
|
||||
## is less than spacing/100, then they are 'equal' and we can ignore the new tick.
|
||||
values = filter(lambda x: all(np.abs(allValues-x) > spacing*0.01), values)
|
||||
allValues = np.concatenate([allValues, values])
|
||||
ticks.append((spacing, values))
|
||||
return ticks
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
from pyqtgraph.Qt import QtGui, QtCore
|
||||
import pyqtgraph.functions as fn
|
||||
from .GraphicsWidget import GraphicsWidget
|
||||
## Must be imported at the end to avoid cyclic-dependency hell:
|
||||
from .ViewBox import ViewBox
|
||||
from .PlotItem import PlotItem
|
||||
from .LabelItem import LabelItem
|
||||
|
||||
__all__ = ['GraphicsLayout']
|
||||
class GraphicsLayout(GraphicsWidget):
|
||||
@ -34,7 +38,7 @@ class GraphicsLayout(GraphicsWidget):
|
||||
return self.currentCol-colspan
|
||||
|
||||
def nextCol(self, *args, **kargs):
|
||||
"""Advance to next column for automatic item placement"""
|
||||
"""Alias of nextColumn"""
|
||||
return self.nextColumn(*args, **kargs)
|
||||
|
||||
def addPlot(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
|
||||
@ -131,7 +135,3 @@ class GraphicsLayout(GraphicsWidget):
|
||||
self.removeItem(i)
|
||||
|
||||
|
||||
## Must be imported at the end to avoid cyclic-dependency hell:
|
||||
from .ViewBox import ViewBox
|
||||
from .PlotItem import PlotItem
|
||||
from .LabelItem import LabelItem
|
@ -371,7 +371,6 @@ class PlotDataItem(GraphicsObject):
|
||||
#self.curves.append(curve)
|
||||
|
||||
if scatterArgs['symbol'] is not None:
|
||||
print scatterArgs
|
||||
self.scatter.setData(x=x, y=y, **scatterArgs)
|
||||
self.scatter.show()
|
||||
else:
|
||||
|
@ -330,6 +330,13 @@ class ScatterPlotItem(GraphicsObject):
|
||||
if isinstance(data, np.ndarray) or isinstance(data, list):
|
||||
if len(data) != len(dataSet):
|
||||
raise Exception("Length of meta data does not match number of points (%d != %d)" % (len(data), len(dataSet)))
|
||||
|
||||
## Bug: If data is a numpy record array, then items from that array must be copied to dataSet one at a time.
|
||||
## (otherwise they are converted to tuples and thus lose their field names.
|
||||
if isinstance(data, np.ndarray) and len(data.dtype.fields) > 1:
|
||||
for i, rec in enumerate(data):
|
||||
dataSet['data'][i] = rec
|
||||
else:
|
||||
dataSet['data'] = data
|
||||
|
||||
def setPxMode(self, mode, update=True):
|
||||
|
@ -47,9 +47,9 @@ class CheckTable(QtGui.QWidget):
|
||||
check.row = name
|
||||
self.layout.addWidget(check, row, col)
|
||||
checks.append(check)
|
||||
col += 1
|
||||
if name in self.oldRows:
|
||||
check.setChecked(self.oldRows[name])
|
||||
check.setChecked(self.oldRows[name][col])
|
||||
col += 1
|
||||
#QtCore.QObject.connect(check, QtCore.SIGNAL('stateChanged(int)'), self.checkChanged)
|
||||
check.stateChanged.connect(self.checkChanged)
|
||||
self.rowNames.append(name)
|
||||
|
@ -7,6 +7,6 @@ class GraphicsLayoutWidget(GraphicsView):
|
||||
def __init__(self, parent=None, **kargs):
|
||||
GraphicsView.__init__(self, parent)
|
||||
self.ci = GraphicsLayout(**kargs)
|
||||
for n in ['nextRow', 'nextCol', 'nextColumn', 'addPlot', 'addViewBox', 'addItem', 'getItem', 'addLabel', 'addLayout']:
|
||||
for n in ['nextRow', 'nextCol', 'nextColumn', 'addPlot', 'addViewBox', 'addItem', 'getItem', 'addLabel', 'addLayout', 'addLabel', 'addViewBox', 'removeItem', 'itemIndex', 'clear']:
|
||||
setattr(self, n, getattr(self.ci, n))
|
||||
self.setCentralItem(self.ci)
|
||||
|
Loading…
Reference in New Issue
Block a user