- PlotItem can now be constructed with customized ViewBox and AxisItems
- Text spacing fix for AxisItem
This commit is contained in:
parent
f178919bee
commit
662b319d7b
@ -505,18 +505,19 @@ class GraphicsScene(QtGui.QGraphicsScene):
|
|||||||
menusToAdd = []
|
menusToAdd = []
|
||||||
while item is not self:
|
while item is not self:
|
||||||
item = item.parentItem()
|
item = item.parentItem()
|
||||||
|
|
||||||
if item is None:
|
if item is None:
|
||||||
item = self
|
item = self
|
||||||
|
|
||||||
if not hasattr(item, "getContextMenus"):
|
if not hasattr(item, "getContextMenus"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
subMenus = item.getContextMenus(event)
|
subMenus = item.getContextMenus(event)
|
||||||
|
if subMenus is None:
|
||||||
|
continue
|
||||||
if type(subMenus) is not list: ## so that some items (like FlowchartViewBox) can return multiple menus
|
if type(subMenus) is not list: ## so that some items (like FlowchartViewBox) can return multiple menus
|
||||||
subMenus = [subMenus]
|
subMenus = [subMenus]
|
||||||
|
|
||||||
for sm in subMenus:
|
for sm in subMenus:
|
||||||
menusToAdd.append(sm)
|
menusToAdd.append(sm)
|
||||||
|
|
||||||
|
12
__init__.py
12
__init__.py
@ -49,10 +49,10 @@ def getConfigOption(opt):
|
|||||||
|
|
||||||
|
|
||||||
def systemInfo():
|
def systemInfo():
|
||||||
print "sys.platform:", sys.platform
|
print("sys.platform: %s" % sys.platform)
|
||||||
print "sys.version:", sys.version
|
print("sys.version: %s" % sys.version)
|
||||||
from .Qt import VERSION_INFO
|
from .Qt import VERSION_INFO
|
||||||
print "qt bindings:", VERSION_INFO
|
print("qt bindings: %s" % VERSION_INFO)
|
||||||
|
|
||||||
global REVISION
|
global REVISION
|
||||||
if REVISION is None: ## this code was probably checked out from bzr; look up the last-revision file
|
if REVISION is None: ## this code was probably checked out from bzr; look up the last-revision file
|
||||||
@ -60,8 +60,8 @@ def systemInfo():
|
|||||||
if os.path.exists(lastRevFile):
|
if os.path.exists(lastRevFile):
|
||||||
REVISION = open(lastRevFile, 'r').read().strip()
|
REVISION = open(lastRevFile, 'r').read().strip()
|
||||||
|
|
||||||
print "pyqtgraph:", REVISION
|
print("pyqtgraph: %s" % REVISION)
|
||||||
print "config:"
|
print("config:")
|
||||||
import pprint
|
import pprint
|
||||||
pprint.pprint(CONFIG_OPTIONS)
|
pprint.pprint(CONFIG_OPTIONS)
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ def importAll(path, excludes=()):
|
|||||||
globals()[k] = getattr(mod, k)
|
globals()[k] = getattr(mod, k)
|
||||||
|
|
||||||
importAll('graphicsItems')
|
importAll('graphicsItems')
|
||||||
importAll('widgets', excludes=['MatplotlibWidget'])
|
importAll('widgets', excludes=['MatplotlibWidget', 'RemoteGraphicsView'])
|
||||||
|
|
||||||
from .imageview import *
|
from .imageview import *
|
||||||
from .WidgetGroup import *
|
from .WidgetGroup import *
|
||||||
|
@ -16,6 +16,7 @@ examples = OrderedDict([
|
|||||||
('Video speed test', 'VideoSpeedTest.py'),
|
('Video speed test', 'VideoSpeedTest.py'),
|
||||||
('Plot speed test', 'PlotSpeedTest.py'),
|
('Plot speed test', 'PlotSpeedTest.py'),
|
||||||
('Data Slicing', 'DataSlicing.py'),
|
('Data Slicing', 'DataSlicing.py'),
|
||||||
|
('Plot Customization', 'customPlot.py'),
|
||||||
('GraphicsItems', OrderedDict([
|
('GraphicsItems', OrderedDict([
|
||||||
('Scatter Plot', 'ScatterPlot.py'),
|
('Scatter Plot', 'ScatterPlot.py'),
|
||||||
#('PlotItem', 'PlotItem.py'),
|
#('PlotItem', 'PlotItem.py'),
|
||||||
@ -45,7 +46,7 @@ examples = OrderedDict([
|
|||||||
#('VerticalLabel', '../widgets/VerticalLabel.py'),
|
#('VerticalLabel', '../widgets/VerticalLabel.py'),
|
||||||
('JoystickButton', 'JoystickButton.py'),
|
('JoystickButton', 'JoystickButton.py'),
|
||||||
])),
|
])),
|
||||||
|
|
||||||
('GraphicsScene', 'GraphicsScene.py'),
|
('GraphicsScene', 'GraphicsScene.py'),
|
||||||
('Flowcharts', 'Flowchart.py'),
|
('Flowcharts', 'Flowchart.py'),
|
||||||
#('Canvas', '../canvas'),
|
#('Canvas', '../canvas'),
|
||||||
|
52
examples/customPlot.py
Normal file
52
examples/customPlot.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##
|
||||||
|
## This example demonstrates the creation of a plot with a customized
|
||||||
|
## AxisItem and ViewBox.
|
||||||
|
##
|
||||||
|
|
||||||
|
|
||||||
|
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 time
|
||||||
|
|
||||||
|
class DateAxis(pg.AxisItem):
|
||||||
|
def tickStrings(self, values, scale, spacing):
|
||||||
|
return [time.strftime('%b %Y', time.localtime(x)) for x in values]
|
||||||
|
|
||||||
|
class CustomViewBox(pg.ViewBox):
|
||||||
|
def __init__(self, *args, **kwds):
|
||||||
|
pg.ViewBox.__init__(self, *args, **kwds)
|
||||||
|
self.setMouseMode(self.RectMode)
|
||||||
|
|
||||||
|
## reimplement right-click to zoom out
|
||||||
|
def mouseClickEvent(self, ev):
|
||||||
|
if ev.button() == QtCore.Qt.RightButton:
|
||||||
|
self.autoRange()
|
||||||
|
|
||||||
|
def mouseDragEvent(self, ev):
|
||||||
|
if ev.button() == QtCore.Qt.RightButton:
|
||||||
|
ev.ignore()
|
||||||
|
else:
|
||||||
|
pg.ViewBox.mouseDragEvent(self, ev)
|
||||||
|
|
||||||
|
|
||||||
|
app = pg.mkQApp()
|
||||||
|
|
||||||
|
axis = DateAxis(orientation='bottom')
|
||||||
|
vb = CustomViewBox()
|
||||||
|
|
||||||
|
pw = pg.PlotWidget(viewBox=vb, axisItems={'bottom': axis}, enableMenu=False, title="PlotItem with custom axis and ViewBox<br>Menu disabled, mouse behavior changed: left-drag to zoom, right-click to reset zoom")
|
||||||
|
dates = np.arange(8) * (3600*24*356)
|
||||||
|
pw.plot(x=dates, y=[1,6,2,4,3,5,6,8], symbol='o')
|
||||||
|
pw.show()
|
||||||
|
|
||||||
|
r = pg.PolyLineROI([(0,0), (10, 10)])
|
||||||
|
pw.addItem(r)
|
||||||
|
|
||||||
|
## 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_()
|
@ -363,6 +363,29 @@ class AxisItem(GraphicsWidget):
|
|||||||
(intervals[minorIndex], 0)
|
(intervals[minorIndex], 0)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
##### This does not work -- switching between 2/5 confuses the automatic text-level-selection
|
||||||
|
### Determine major/minor tick spacings which flank the optimal spacing.
|
||||||
|
#intervals = np.array([1., 2., 5., 10., 20., 50., 100.]) * p10unit
|
||||||
|
#minorIndex = 0
|
||||||
|
#while intervals[minorIndex+1] <= optimalSpacing:
|
||||||
|
#minorIndex += 1
|
||||||
|
|
||||||
|
### make sure we never see 5 and 2 at the same time
|
||||||
|
#intIndexes = [
|
||||||
|
#[0,1,3],
|
||||||
|
#[0,2,3],
|
||||||
|
#[2,3,4],
|
||||||
|
#[3,4,6],
|
||||||
|
#[3,5,6],
|
||||||
|
#][minorIndex]
|
||||||
|
|
||||||
|
#return [
|
||||||
|
#(intervals[intIndexes[2]], 0),
|
||||||
|
#(intervals[intIndexes[1]], 0),
|
||||||
|
#(intervals[intIndexes[0]], 0)
|
||||||
|
#]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def tickValues(self, minVal, maxVal, size):
|
def tickValues(self, minVal, maxVal, size):
|
||||||
"""
|
"""
|
||||||
@ -395,7 +418,7 @@ class AxisItem(GraphicsWidget):
|
|||||||
## remove any ticks that were present in higher levels
|
## 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
|
## 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.
|
## 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)
|
values = list(filter(lambda x: all(np.abs(allValues-x) > spacing*0.01), values) )
|
||||||
allValues = np.concatenate([allValues, values])
|
allValues = np.concatenate([allValues, values])
|
||||||
ticks.append((spacing, values))
|
ticks.append((spacing, values))
|
||||||
|
|
||||||
@ -601,9 +624,9 @@ class AxisItem(GraphicsWidget):
|
|||||||
if tickPositions[i][j] is None:
|
if tickPositions[i][j] is None:
|
||||||
strings[j] = None
|
strings[j] = None
|
||||||
|
|
||||||
|
textRects.extend([p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, s) for s in strings if s is not None])
|
||||||
if i > 0: ## always draw top level
|
if i > 0: ## always draw top level
|
||||||
## measure all text, make sure there's enough room
|
## measure all text, make sure there's enough room
|
||||||
textRects.extend([p.boundingRect(QtCore.QRectF(0, 0, 100, 100), QtCore.Qt.AlignCenter, s) for s in strings if s is not None])
|
|
||||||
if axis == 0:
|
if axis == 0:
|
||||||
textSize = np.sum([r.height() for r in textRects])
|
textSize = np.sum([r.height() for r in textRects])
|
||||||
else:
|
else:
|
||||||
@ -613,7 +636,6 @@ class AxisItem(GraphicsWidget):
|
|||||||
textFillRatio = float(textSize) / lengthInPixels
|
textFillRatio = float(textSize) / lengthInPixels
|
||||||
if textFillRatio > 0.7:
|
if textFillRatio > 0.7:
|
||||||
break
|
break
|
||||||
|
|
||||||
#spacing, values = tickLevels[best]
|
#spacing, values = tickLevels[best]
|
||||||
#strings = self.tickStrings(values, self.scale, spacing)
|
#strings = self.tickStrings(values, self.scale, spacing)
|
||||||
for j in range(len(strings)):
|
for j in range(len(strings)):
|
||||||
|
@ -33,17 +33,12 @@ from .. AxisItem import AxisItem
|
|||||||
from .. LabelItem import LabelItem
|
from .. LabelItem import LabelItem
|
||||||
from .. GraphicsWidget import GraphicsWidget
|
from .. GraphicsWidget import GraphicsWidget
|
||||||
from .. ButtonItem import ButtonItem
|
from .. ButtonItem import ButtonItem
|
||||||
|
#from .. GraphicsLayout import GraphicsLayout
|
||||||
from pyqtgraph.WidgetGroup import WidgetGroup
|
from pyqtgraph.WidgetGroup import WidgetGroup
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
__all__ = ['PlotItem']
|
__all__ = ['PlotItem']
|
||||||
|
|
||||||
#try:
|
|
||||||
#from WidgetGroup import *
|
|
||||||
#HAVE_WIDGETGROUP = True
|
|
||||||
#except:
|
|
||||||
#HAVE_WIDGETGROUP = False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from metaarray import *
|
from metaarray import *
|
||||||
HAVE_METAARRAY = True
|
HAVE_METAARRAY = True
|
||||||
@ -99,26 +94,28 @@ class PlotItem(GraphicsWidget):
|
|||||||
lastFileDir = None
|
lastFileDir = None
|
||||||
managers = {}
|
managers = {}
|
||||||
|
|
||||||
def __init__(self, parent=None, name=None, labels=None, title=None, **kargs):
|
def __init__(self, parent=None, name=None, labels=None, title=None, viewBox=None, axisItems=None, enableMenu=True, **kargs):
|
||||||
"""
|
"""
|
||||||
Create a new PlotItem. All arguments are optional.
|
Create a new PlotItem. All arguments are optional.
|
||||||
Any extra keyword arguments are passed to PlotItem.plot().
|
Any extra keyword arguments are passed to PlotItem.plot().
|
||||||
|
|
||||||
============= ==========================================================================================
|
============== ==========================================================================================
|
||||||
**Arguments**
|
**Arguments**
|
||||||
*title* Title to display at the top of the item. Html is allowed.
|
*title* Title to display at the top of the item. Html is allowed.
|
||||||
*labels* A dictionary specifying the axis labels to display::
|
*labels* A dictionary specifying the axis labels to display::
|
||||||
|
|
||||||
{'left': (args), 'bottom': (args), ...}
|
{'left': (args), 'bottom': (args), ...}
|
||||||
|
|
||||||
The name of each axis and the corresponding arguments are passed to
|
The name of each axis and the corresponding arguments are passed to
|
||||||
:func:`PlotItem.setLabel() <pyqtgraph.PlotItem.setLabel>`
|
:func:`PlotItem.setLabel() <pyqtgraph.PlotItem.setLabel>`
|
||||||
Optionally, PlotItem my also be initialized with the keyword arguments left,
|
Optionally, PlotItem my also be initialized with the keyword arguments left,
|
||||||
right, top, or bottom to achieve the same effect.
|
right, top, or bottom to achieve the same effect.
|
||||||
*name* Registers a name for this view so that others may link to it
|
*name* Registers a name for this view so that others may link to it
|
||||||
============= ==========================================================================================
|
*viewBox* If specified, the PlotItem will be constructed with this as its ViewBox.
|
||||||
|
*axisItems* Optional dictionary instructing the PlotItem to use pre-constructed items
|
||||||
|
for its axes. The dict keys must be axis names ('left', 'bottom', 'right', 'top')
|
||||||
|
and the values must be instances of AxisItem (or at least compatible with AxisItem).
|
||||||
|
============== ==========================================================================================
|
||||||
"""
|
"""
|
||||||
|
|
||||||
GraphicsWidget.__init__(self, parent)
|
GraphicsWidget.__init__(self, parent)
|
||||||
@ -127,8 +124,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
|
|
||||||
## Set up control buttons
|
## Set up control buttons
|
||||||
path = os.path.dirname(__file__)
|
path = os.path.dirname(__file__)
|
||||||
#self.ctrlBtn = ButtonItem(os.path.join(path, 'ctrl.png'), 14, self)
|
|
||||||
#self.ctrlBtn.clicked.connect(self.ctrlBtnClicked)
|
|
||||||
self.autoImageFile = os.path.join(path, 'auto.png')
|
self.autoImageFile = os.path.join(path, 'auto.png')
|
||||||
self.lockImageFile = os.path.join(path, 'lock.png')
|
self.lockImageFile = os.path.join(path, 'lock.png')
|
||||||
self.autoBtn = ButtonItem(self.autoImageFile, 14, self)
|
self.autoBtn = ButtonItem(self.autoImageFile, 14, self)
|
||||||
@ -141,32 +136,33 @@ class PlotItem(GraphicsWidget):
|
|||||||
self.layout.setHorizontalSpacing(0)
|
self.layout.setHorizontalSpacing(0)
|
||||||
self.layout.setVerticalSpacing(0)
|
self.layout.setVerticalSpacing(0)
|
||||||
|
|
||||||
self.vb = ViewBox(name=name)
|
if viewBox is None:
|
||||||
|
viewBox = ViewBox()
|
||||||
|
self.vb = viewBox
|
||||||
|
self.setMenuEnabled(enableMenu, enableMenu) ## en/disable plotitem and viewbox menus
|
||||||
|
|
||||||
|
if name is not None:
|
||||||
|
self.vb.register(name)
|
||||||
self.vb.sigRangeChanged.connect(self.sigRangeChanged)
|
self.vb.sigRangeChanged.connect(self.sigRangeChanged)
|
||||||
self.vb.sigXRangeChanged.connect(self.sigXRangeChanged)
|
self.vb.sigXRangeChanged.connect(self.sigXRangeChanged)
|
||||||
self.vb.sigYRangeChanged.connect(self.sigYRangeChanged)
|
self.vb.sigYRangeChanged.connect(self.sigYRangeChanged)
|
||||||
#self.vb.sigRangeChangedManually.connect(self.enableManualScale)
|
|
||||||
#self.vb.sigRangeChanged.connect(self.viewRangeChanged)
|
|
||||||
|
|
||||||
self.layout.addItem(self.vb, 2, 1)
|
self.layout.addItem(self.vb, 2, 1)
|
||||||
self.alpha = 1.0
|
self.alpha = 1.0
|
||||||
self.autoAlpha = True
|
self.autoAlpha = True
|
||||||
self.spectrumMode = False
|
self.spectrumMode = False
|
||||||
|
|
||||||
#self.autoScale = [True, True]
|
## Create and place axis items
|
||||||
|
if axisItems is None:
|
||||||
## Create and place scale items
|
axisItems = {}
|
||||||
self.scales = {
|
self.axes = {}
|
||||||
'top': {'item': AxisItem(orientation='top', linkView=self.vb), 'pos': (1, 1)},
|
for k, pos in (('top', (1,1)), ('bottom', (3,1)), ('left', (2,0)), ('right', (2,2))):
|
||||||
'bottom': {'item': AxisItem(orientation='bottom', linkView=self.vb), 'pos': (3, 1)},
|
axis = axisItems.get(k, AxisItem(orientation=k))
|
||||||
'left': {'item': AxisItem(orientation='left', linkView=self.vb), 'pos': (2, 0)},
|
axis.linkToView(self.vb)
|
||||||
'right': {'item': AxisItem(orientation='right', linkView=self.vb), 'pos': (2, 2)}
|
self.axes[k] = {'item': axis, 'pos': pos}
|
||||||
}
|
self.layout.addItem(axis, *pos)
|
||||||
for k in self.scales:
|
axis.setZValue(-1000)
|
||||||
item = self.scales[k]['item']
|
axis.setFlag(axis.ItemNegativeZStacksBehindParent)
|
||||||
self.layout.addItem(item, *self.scales[k]['pos'])
|
|
||||||
item.setZValue(-1000)
|
|
||||||
item.setFlag(item.ItemNegativeZStacksBehindParent)
|
|
||||||
|
|
||||||
self.titleLabel = LabelItem('', size='11pt')
|
self.titleLabel = LabelItem('', size='11pt')
|
||||||
self.layout.addItem(self.titleLabel, 0, 1)
|
self.layout.addItem(self.titleLabel, 0, 1)
|
||||||
@ -193,7 +189,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
'setXRange', 'setYRange', 'setXLink', 'setYLink', 'setAutoPan', 'setAutoVisible',
|
'setXRange', 'setYRange', 'setXLink', 'setYLink', 'setAutoPan', 'setAutoVisible',
|
||||||
'setRange', 'autoRange', 'viewRect', 'viewRange', 'setMouseEnabled',
|
'setRange', 'autoRange', 'viewRect', 'viewRange', 'setMouseEnabled',
|
||||||
'enableAutoRange', 'disableAutoRange', 'setAspectLocked',
|
'enableAutoRange', 'disableAutoRange', 'setAspectLocked',
|
||||||
'setMenuEnabled', 'menuEnabled',
|
|
||||||
'register', 'unregister']: ## NOTE: If you update this list, please update the class docstring as well.
|
'register', 'unregister']: ## NOTE: If you update this list, please update the class docstring as well.
|
||||||
setattr(self, m, getattr(self.vb, m))
|
setattr(self, m, getattr(self.vb, m))
|
||||||
|
|
||||||
@ -233,45 +228,12 @@ class PlotItem(GraphicsWidget):
|
|||||||
self.subMenus.append(sm)
|
self.subMenus.append(sm)
|
||||||
self.ctrlMenu.addMenu(sm)
|
self.ctrlMenu.addMenu(sm)
|
||||||
|
|
||||||
## exporting is handled by GraphicsScene now
|
|
||||||
#exportOpts = collections.OrderedDict([
|
|
||||||
#('SVG - Full Plot', self.saveSvgClicked),
|
|
||||||
#('SVG - Curves Only', self.saveSvgCurvesClicked),
|
|
||||||
#('Image', self.saveImgClicked),
|
|
||||||
#('CSV', self.saveCsvClicked),
|
|
||||||
#])
|
|
||||||
|
|
||||||
#self.vb.menu.setExportMethods(exportOpts)
|
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_WIDGETGROUP:
|
|
||||||
self.stateGroup = WidgetGroup()
|
self.stateGroup = WidgetGroup()
|
||||||
for name, w in menuItems:
|
for name, w in menuItems:
|
||||||
self.stateGroup.autoAdd(w)
|
self.stateGroup.autoAdd(w)
|
||||||
|
|
||||||
self.fileDialog = None
|
self.fileDialog = None
|
||||||
|
|
||||||
#self.xLinkPlot = None
|
|
||||||
#self.yLinkPlot = None
|
|
||||||
#self.linksBlocked = False
|
|
||||||
|
|
||||||
#self.setAcceptHoverEvents(True)
|
|
||||||
|
|
||||||
## Connect control widgets
|
|
||||||
#c.xMinText.editingFinished.connect(self.setManualXScale)
|
|
||||||
#c.xMaxText.editingFinished.connect(self.setManualXScale)
|
|
||||||
#c.yMinText.editingFinished.connect(self.setManualYScale)
|
|
||||||
#c.yMaxText.editingFinished.connect(self.setManualYScale)
|
|
||||||
|
|
||||||
#c.xManualRadio.clicked.connect(lambda: self.updateXScale())
|
|
||||||
#c.yManualRadio.clicked.connect(lambda: self.updateYScale())
|
|
||||||
|
|
||||||
#c.xAutoRadio.clicked.connect(self.updateXScale)
|
|
||||||
#c.yAutoRadio.clicked.connect(self.updateYScale)
|
|
||||||
|
|
||||||
#c.xAutoPercentSpin.valueChanged.connect(self.replot)
|
|
||||||
#c.yAutoPercentSpin.valueChanged.connect(self.replot)
|
|
||||||
|
|
||||||
c.alphaGroup.toggled.connect(self.updateAlpha)
|
c.alphaGroup.toggled.connect(self.updateAlpha)
|
||||||
c.alphaSlider.valueChanged.connect(self.updateAlpha)
|
c.alphaSlider.valueChanged.connect(self.updateAlpha)
|
||||||
c.autoAlphaCheck.toggled.connect(self.updateAlpha)
|
c.autoAlphaCheck.toggled.connect(self.updateAlpha)
|
||||||
@ -283,13 +245,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
c.fftCheck.toggled.connect(self.updateSpectrumMode)
|
c.fftCheck.toggled.connect(self.updateSpectrumMode)
|
||||||
c.logXCheck.toggled.connect(self.updateLogMode)
|
c.logXCheck.toggled.connect(self.updateLogMode)
|
||||||
c.logYCheck.toggled.connect(self.updateLogMode)
|
c.logYCheck.toggled.connect(self.updateLogMode)
|
||||||
#c.saveSvgBtn.clicked.connect(self.saveSvgClicked)
|
|
||||||
#c.saveSvgCurvesBtn.clicked.connect(self.saveSvgCurvesClicked)
|
|
||||||
#c.saveImgBtn.clicked.connect(self.saveImgClicked)
|
|
||||||
#c.saveCsvBtn.clicked.connect(self.saveCsvClicked)
|
|
||||||
|
|
||||||
#self.ctrl.xLinkCombo.currentIndexChanged.connect(self.xLinkComboChanged)
|
|
||||||
#self.ctrl.yLinkCombo.currentIndexChanged.connect(self.yLinkComboChanged)
|
|
||||||
|
|
||||||
c.downsampleSpin.valueChanged.connect(self.updateDownsampling)
|
c.downsampleSpin.valueChanged.connect(self.updateDownsampling)
|
||||||
|
|
||||||
@ -298,24 +253,15 @@ class PlotItem(GraphicsWidget):
|
|||||||
|
|
||||||
self.ctrl.maxTracesCheck.toggled.connect(self.updateDecimation)
|
self.ctrl.maxTracesCheck.toggled.connect(self.updateDecimation)
|
||||||
self.ctrl.maxTracesSpin.valueChanged.connect(self.updateDecimation)
|
self.ctrl.maxTracesSpin.valueChanged.connect(self.updateDecimation)
|
||||||
#c.xMouseCheck.toggled.connect(self.mouseCheckChanged)
|
|
||||||
#c.yMouseCheck.toggled.connect(self.mouseCheckChanged)
|
|
||||||
|
|
||||||
#self.xLinkPlot = None
|
|
||||||
#self.yLinkPlot = None
|
|
||||||
#self.linksBlocked = False
|
|
||||||
self.manager = None
|
|
||||||
|
|
||||||
self.hideAxis('right')
|
self.hideAxis('right')
|
||||||
self.hideAxis('top')
|
self.hideAxis('top')
|
||||||
self.showAxis('left')
|
self.showAxis('left')
|
||||||
self.showAxis('bottom')
|
self.showAxis('bottom')
|
||||||
|
|
||||||
#if name is not None:
|
|
||||||
#self.registerPlot(name)
|
|
||||||
if labels is None:
|
if labels is None:
|
||||||
labels = {}
|
labels = {}
|
||||||
for label in list(self.scales.keys()):
|
for label in list(self.axes.keys()):
|
||||||
if label in kargs:
|
if label in kargs:
|
||||||
labels[label] = kargs[label]
|
labels[label] = kargs[label]
|
||||||
del kargs[label]
|
del kargs[label]
|
||||||
@ -330,15 +276,16 @@ class PlotItem(GraphicsWidget):
|
|||||||
if len(kargs) > 0:
|
if len(kargs) > 0:
|
||||||
self.plot(**kargs)
|
self.plot(**kargs)
|
||||||
|
|
||||||
#self.enableAutoRange()
|
|
||||||
|
|
||||||
def implements(self, interface=None):
|
def implements(self, interface=None):
|
||||||
return interface in ['ViewBoxWrapper']
|
return interface in ['ViewBoxWrapper']
|
||||||
|
|
||||||
def getViewBox(self):
|
def getViewBox(self):
|
||||||
"""Return the ViewBox within."""
|
"""Return the :class:`ViewBox <pyqtgraph.ViewBox>` contained within."""
|
||||||
return self.vb
|
return self.vb
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setLogMode(self, x, y):
|
def setLogMode(self, x, y):
|
||||||
"""
|
"""
|
||||||
Set log scaling for x and y axes.
|
Set log scaling for x and y axes.
|
||||||
@ -399,11 +346,11 @@ class PlotItem(GraphicsWidget):
|
|||||||
#self.autoBtn.setParent(None)
|
#self.autoBtn.setParent(None)
|
||||||
#self.autoBtn = None
|
#self.autoBtn = None
|
||||||
|
|
||||||
for k in self.scales:
|
for k in self.axes:
|
||||||
i = self.scales[k]['item']
|
i = self.axes[k]['item']
|
||||||
i.close()
|
i.close()
|
||||||
|
|
||||||
self.scales = None
|
self.axes = None
|
||||||
self.scene().removeItem(self.vb)
|
self.scene().removeItem(self.vb)
|
||||||
self.vb = None
|
self.vb = None
|
||||||
|
|
||||||
@ -431,47 +378,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
|
|
||||||
def registerPlot(self, name): ## for backward compatibility
|
def registerPlot(self, name): ## for backward compatibility
|
||||||
self.vb.register(name)
|
self.vb.register(name)
|
||||||
#self.name = name
|
|
||||||
#win = str(self.window())
|
|
||||||
##print "register", name, win
|
|
||||||
#if win not in PlotItem.managers:
|
|
||||||
#PlotItem.managers[win] = PlotWidgetManager()
|
|
||||||
#self.manager = PlotItem.managers[win]
|
|
||||||
#self.manager.addWidget(self, name)
|
|
||||||
##QtCore.QObject.connect(self.manager, QtCore.SIGNAL('widgetListChanged'), self.updatePlotList)
|
|
||||||
#self.manager.sigWidgetListChanged.connect(self.updatePlotList)
|
|
||||||
#self.updatePlotList()
|
|
||||||
|
|
||||||
#def updatePlotList(self):
|
|
||||||
#"""Update the list of all plotWidgets in the "link" combos"""
|
|
||||||
##print "update plot list", self
|
|
||||||
#try:
|
|
||||||
#for sc in [self.ctrl.xLinkCombo, self.ctrl.yLinkCombo]:
|
|
||||||
#current = unicode(sc.currentText())
|
|
||||||
#sc.blockSignals(True)
|
|
||||||
#try:
|
|
||||||
#sc.clear()
|
|
||||||
#sc.addItem("")
|
|
||||||
#if self.manager is not None:
|
|
||||||
#for w in self.manager.listWidgets():
|
|
||||||
##print w
|
|
||||||
#if w == self.name:
|
|
||||||
#continue
|
|
||||||
#sc.addItem(w)
|
|
||||||
#if w == current:
|
|
||||||
#sc.setCurrentIndex(sc.count()-1)
|
|
||||||
#finally:
|
|
||||||
#sc.blockSignals(False)
|
|
||||||
#if unicode(sc.currentText()) != current:
|
|
||||||
#sc.currentItemChanged.emit()
|
|
||||||
#except:
|
|
||||||
#import gc
|
|
||||||
#refs= gc.get_referrers(self)
|
|
||||||
#print " error during update of", self
|
|
||||||
#print " Referrers are:", refs
|
|
||||||
#raise
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def updateGrid(self, *args):
|
def updateGrid(self, *args):
|
||||||
alpha = self.ctrl.gridAlphaSlider.value()
|
alpha = self.ctrl.gridAlphaSlider.value()
|
||||||
@ -492,91 +398,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
return wr
|
return wr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#def viewRangeChanged(self, vb, range):
|
|
||||||
##self.emit(QtCore.SIGNAL('viewChanged'), *args)
|
|
||||||
#self.sigRangeChanged.emit(self, range)
|
|
||||||
|
|
||||||
#def blockLink(self, b):
|
|
||||||
#self.linksBlocked = b
|
|
||||||
|
|
||||||
#def xLinkComboChanged(self):
|
|
||||||
#self.setXLink(str(self.ctrl.xLinkCombo.currentText()))
|
|
||||||
|
|
||||||
#def yLinkComboChanged(self):
|
|
||||||
#self.setYLink(str(self.ctrl.yLinkCombo.currentText()))
|
|
||||||
|
|
||||||
#def setXLink(self, plot=None):
|
|
||||||
#"""Link this plot's X axis to another plot (pass either the PlotItem/PlotWidget or the registered name of the plot)"""
|
|
||||||
#if isinstance(plot, basestring):
|
|
||||||
#if self.manager is None:
|
|
||||||
#return
|
|
||||||
#if self.xLinkPlot is not None:
|
|
||||||
#self.manager.unlinkX(self, self.xLinkPlot)
|
|
||||||
#plot = self.manager.getWidget(plot)
|
|
||||||
#if not isinstance(plot, PlotItem) and hasattr(plot, 'getPlotItem'):
|
|
||||||
#plot = plot.getPlotItem()
|
|
||||||
#self.xLinkPlot = plot
|
|
||||||
#if plot is not None:
|
|
||||||
#self.setManualXScale()
|
|
||||||
#self.manager.linkX(self, plot)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#def setYLink(self, plot=None):
|
|
||||||
#"""Link this plot's Y axis to another plot (pass either the PlotItem/PlotWidget or the registered name of the plot)"""
|
|
||||||
#if isinstance(plot, basestring):
|
|
||||||
#if self.manager is None:
|
|
||||||
#return
|
|
||||||
#if self.yLinkPlot is not None:
|
|
||||||
#self.manager.unlinkY(self, self.yLinkPlot)
|
|
||||||
#plot = self.manager.getWidget(plot)
|
|
||||||
#if not isinstance(plot, PlotItem) and hasattr(plot, 'getPlotItem'):
|
|
||||||
#plot = plot.getPlotItem()
|
|
||||||
#self.yLinkPlot = plot
|
|
||||||
#if plot is not None:
|
|
||||||
#self.setManualYScale()
|
|
||||||
#self.manager.linkY(self, plot)
|
|
||||||
|
|
||||||
#def linkXChanged(self, plot):
|
|
||||||
#"""Called when a linked plot has changed its X scale"""
|
|
||||||
##print "update from", plot
|
|
||||||
#if self.linksBlocked:
|
|
||||||
#return
|
|
||||||
#pr = plot.vb.viewRect()
|
|
||||||
#pg = plot.viewGeometry()
|
|
||||||
#if pg is None:
|
|
||||||
##print " return early"
|
|
||||||
#return
|
|
||||||
#sg = self.viewGeometry()
|
|
||||||
#upp = float(pr.width()) / pg.width()
|
|
||||||
#x1 = pr.left() + (sg.x()-pg.x()) * upp
|
|
||||||
#x2 = x1 + sg.width() * upp
|
|
||||||
#plot.blockLink(True)
|
|
||||||
#self.setManualXScale()
|
|
||||||
#self.setXRange(x1, x2, padding=0)
|
|
||||||
#plot.blockLink(False)
|
|
||||||
#self.replot()
|
|
||||||
|
|
||||||
#def linkYChanged(self, plot):
|
|
||||||
#"""Called when a linked plot has changed its Y scale"""
|
|
||||||
#if self.linksBlocked:
|
|
||||||
#return
|
|
||||||
#pr = plot.vb.viewRect()
|
|
||||||
#pg = plot.vb.boundingRect()
|
|
||||||
#sg = self.vb.boundingRect()
|
|
||||||
#upp = float(pr.height()) / pg.height()
|
|
||||||
#y1 = pr.bottom() + (sg.y()-pg.y()) * upp
|
|
||||||
#y2 = y1 + sg.height() * upp
|
|
||||||
#plot.blockLink(True)
|
|
||||||
#self.setManualYScale()
|
|
||||||
#self.setYRange(y1, y2, padding=0)
|
|
||||||
#plot.blockLink(False)
|
|
||||||
#self.replot()
|
|
||||||
|
|
||||||
|
|
||||||
def avgToggled(self, b):
|
def avgToggled(self, b):
|
||||||
if b:
|
if b:
|
||||||
self.recomputeAverages()
|
self.recomputeAverages()
|
||||||
@ -650,50 +471,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
else:
|
else:
|
||||||
plot.setData(x, y)
|
plot.setData(x, y)
|
||||||
|
|
||||||
|
|
||||||
#def mouseCheckChanged(self):
|
|
||||||
#state = [self.ctrl.xMouseCheck.isChecked(), self.ctrl.yMouseCheck.isChecked()]
|
|
||||||
#self.vb.setMouseEnabled(*state)
|
|
||||||
|
|
||||||
#def xRangeChanged(self, _, range):
|
|
||||||
#if any(np.isnan(range)) or any(np.isinf(range)):
|
|
||||||
#raise Exception("yRange invalid: %s. Signal came from %s" % (str(range), str(self.sender())))
|
|
||||||
#self.ctrl.xMinText.setText('%0.5g' % range[0])
|
|
||||||
#self.ctrl.xMaxText.setText('%0.5g' % range[1])
|
|
||||||
|
|
||||||
### automatically change unit scale
|
|
||||||
#maxVal = max(abs(range[0]), abs(range[1]))
|
|
||||||
#(scale, prefix) = fn.siScale(maxVal)
|
|
||||||
##for l in ['top', 'bottom']:
|
|
||||||
##if self.getLabel(l).isVisible():
|
|
||||||
##self.setLabel(l, unitPrefix=prefix)
|
|
||||||
##self.getScale(l).setScale(scale)
|
|
||||||
##else:
|
|
||||||
##self.setLabel(l, unitPrefix='')
|
|
||||||
##self.getScale(l).setScale(1.0)
|
|
||||||
|
|
||||||
##self.emit(QtCore.SIGNAL('xRangeChanged'), self, range)
|
|
||||||
#self.sigXRangeChanged.emit(self, range)
|
|
||||||
|
|
||||||
#def yRangeChanged(self, _, range):
|
|
||||||
#if any(np.isnan(range)) or any(np.isinf(range)):
|
|
||||||
#raise Exception("yRange invalid: %s. Signal came from %s" % (str(range), str(self.sender())))
|
|
||||||
#self.ctrl.yMinText.setText('%0.5g' % range[0])
|
|
||||||
#self.ctrl.yMaxText.setText('%0.5g' % range[1])
|
|
||||||
|
|
||||||
### automatically change unit scale
|
|
||||||
#maxVal = max(abs(range[0]), abs(range[1]))
|
|
||||||
#(scale, prefix) = fn.siScale(maxVal)
|
|
||||||
##for l in ['left', 'right']:
|
|
||||||
##if self.getLabel(l).isVisible():
|
|
||||||
##self.setLabel(l, unitPrefix=prefix)
|
|
||||||
##self.getScale(l).setScale(scale)
|
|
||||||
##else:
|
|
||||||
##self.setLabel(l, unitPrefix='')
|
|
||||||
##self.getScale(l).setScale(1.0)
|
|
||||||
##self.emit(QtCore.SIGNAL('yRangeChanged'), self, range)
|
|
||||||
#self.sigYRangeChanged.emit(self, range)
|
|
||||||
|
|
||||||
def autoBtnClicked(self):
|
def autoBtnClicked(self):
|
||||||
if self.autoBtn.mode == 'auto':
|
if self.autoBtn.mode == 'auto':
|
||||||
self.enableAutoRange()
|
self.enableAutoRange()
|
||||||
@ -706,72 +483,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
"""
|
"""
|
||||||
print("Warning: enableAutoScale is deprecated. Use enableAutoRange(axis, enable) instead.")
|
print("Warning: enableAutoScale is deprecated. Use enableAutoRange(axis, enable) instead.")
|
||||||
self.vb.enableAutoRange(self.vb.XYAxes)
|
self.vb.enableAutoRange(self.vb.XYAxes)
|
||||||
#self.ctrl.xAutoRadio.setChecked(True)
|
|
||||||
#self.ctrl.yAutoRadio.setChecked(True)
|
|
||||||
|
|
||||||
#self.autoBtn.setImageFile(self.lockImageFile)
|
|
||||||
#self.autoBtn.mode = 'lock'
|
|
||||||
#self.updateXScale()
|
|
||||||
#self.updateYScale()
|
|
||||||
#self.replot()
|
|
||||||
|
|
||||||
#def updateXScale(self):
|
|
||||||
#"""Set plot to autoscale or not depending on state of radio buttons"""
|
|
||||||
#if self.ctrl.xManualRadio.isChecked():
|
|
||||||
#self.setManualXScale()
|
|
||||||
#else:
|
|
||||||
#self.setAutoXScale()
|
|
||||||
#self.replot()
|
|
||||||
|
|
||||||
#def updateYScale(self, b=False):
|
|
||||||
#"""Set plot to autoscale or not depending on state of radio buttons"""
|
|
||||||
#if self.ctrl.yManualRadio.isChecked():
|
|
||||||
#self.setManualYScale()
|
|
||||||
#else:
|
|
||||||
#self.setAutoYScale()
|
|
||||||
#self.replot()
|
|
||||||
|
|
||||||
#def enableManualScale(self, v=[True, True]):
|
|
||||||
#if v[0]:
|
|
||||||
#self.autoScale[0] = False
|
|
||||||
#self.ctrl.xManualRadio.setChecked(True)
|
|
||||||
##self.setManualXScale()
|
|
||||||
#if v[1]:
|
|
||||||
#self.autoScale[1] = False
|
|
||||||
#self.ctrl.yManualRadio.setChecked(True)
|
|
||||||
##self.setManualYScale()
|
|
||||||
##self.autoBtn.enable()
|
|
||||||
#self.autoBtn.setImageFile(self.autoImageFile)
|
|
||||||
#self.autoBtn.mode = 'auto'
|
|
||||||
##self.replot()
|
|
||||||
|
|
||||||
#def setManualXScale(self):
|
|
||||||
#self.autoScale[0] = False
|
|
||||||
#x1 = float(self.ctrl.xMinText.text())
|
|
||||||
#x2 = float(self.ctrl.xMaxText.text())
|
|
||||||
#self.ctrl.xManualRadio.setChecked(True)
|
|
||||||
#self.setXRange(x1, x2, padding=0)
|
|
||||||
#self.autoBtn.show()
|
|
||||||
##self.replot()
|
|
||||||
|
|
||||||
#def setManualYScale(self):
|
|
||||||
#self.autoScale[1] = False
|
|
||||||
#y1 = float(self.ctrl.yMinText.text())
|
|
||||||
#y2 = float(self.ctrl.yMaxText.text())
|
|
||||||
#self.ctrl.yManualRadio.setChecked(True)
|
|
||||||
#self.setYRange(y1, y2, padding=0)
|
|
||||||
#self.autoBtn.show()
|
|
||||||
##self.replot()
|
|
||||||
|
|
||||||
#def setAutoXScale(self):
|
|
||||||
#self.autoScale[0] = True
|
|
||||||
#self.ctrl.xAutoRadio.setChecked(True)
|
|
||||||
##self.replot()
|
|
||||||
|
|
||||||
#def setAutoYScale(self):
|
|
||||||
#self.autoScale[1] = True
|
|
||||||
#self.ctrl.yAutoRadio.setChecked(True)
|
|
||||||
##self.replot()
|
|
||||||
|
|
||||||
def addItem(self, item, *args, **kargs):
|
def addItem(self, item, *args, **kargs):
|
||||||
"""
|
"""
|
||||||
@ -867,17 +578,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if y is not None:
|
|
||||||
#data = y
|
|
||||||
#if data2 is not None:
|
|
||||||
#x = data
|
|
||||||
#data = data2
|
|
||||||
#if decimate is not None and decimate > 1:
|
|
||||||
#data = data[::decimate]
|
|
||||||
#if x is not None:
|
|
||||||
#x = x[::decimate]
|
|
||||||
## print 'plot with decimate = %d' % (decimate)
|
|
||||||
clear = kargs.get('clear', False)
|
clear = kargs.get('clear', False)
|
||||||
params = kargs.get('params', None)
|
params = kargs.get('params', None)
|
||||||
|
|
||||||
@ -888,23 +588,7 @@ class PlotItem(GraphicsWidget):
|
|||||||
|
|
||||||
if params is None:
|
if params is None:
|
||||||
params = {}
|
params = {}
|
||||||
#if HAVE_METAARRAY and (hasattr(data, 'implements') and data.implements('MetaArray')):
|
|
||||||
#curve = self._plotMetaArray(data, x=x, **kargs)
|
|
||||||
#elif isinstance(data, np.ndarray):
|
|
||||||
#curve = self._plotArray(data, x=x, **kargs)
|
|
||||||
#elif isinstance(data, list):
|
|
||||||
#if x is not None:
|
|
||||||
#x = np.array(x)
|
|
||||||
#curve = self._plotArray(np.array(data), x=x, **kargs)
|
|
||||||
#elif data is None:
|
|
||||||
#curve = PlotCurveItem(**kargs)
|
|
||||||
#else:
|
|
||||||
#raise Exception('Not sure how to plot object of type %s' % type(data))
|
|
||||||
|
|
||||||
#print data, curve
|
|
||||||
self.addItem(item, params=params)
|
self.addItem(item, params=params)
|
||||||
#if pen is not None:
|
|
||||||
#curve.setPen(fn.mkPen(pen))
|
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
@ -922,80 +606,34 @@ class PlotItem(GraphicsWidget):
|
|||||||
del kargs['size']
|
del kargs['size']
|
||||||
|
|
||||||
return self.plot(*args, **kargs)
|
return self.plot(*args, **kargs)
|
||||||
#sp = ScatterPlotItem(*args, **kargs)
|
|
||||||
#self.addItem(sp)
|
|
||||||
#return sp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#def plotChanged(self, curve=None):
|
|
||||||
## Recompute auto range if needed
|
|
||||||
#args = {}
|
|
||||||
#for ax in [0, 1]:
|
|
||||||
#print "range", ax
|
|
||||||
#if self.autoScale[ax]:
|
|
||||||
#percentScale = [self.ctrl.xAutoPercentSpin.value(), self.ctrl.yAutoPercentSpin.value()][ax] * 0.01
|
|
||||||
#mn = None
|
|
||||||
#mx = None
|
|
||||||
#for c in self.curves + [c[1] for c in self.avgCurves.values()] + self.dataItems:
|
|
||||||
#if not c.isVisible():
|
|
||||||
#continue
|
|
||||||
#cmn, cmx = c.getRange(ax, percentScale)
|
|
||||||
##print " ", c, cmn, cmx
|
|
||||||
#if mn is None or cmn < mn:
|
|
||||||
#mn = cmn
|
|
||||||
#if mx is None or cmx > mx:
|
|
||||||
#mx = cmx
|
|
||||||
#if mn is None or mx is None or any(np.isnan([mn, mx])) or any(np.isinf([mn, mx])):
|
|
||||||
#continue
|
|
||||||
#if mn == mx:
|
|
||||||
#mn -= 1
|
|
||||||
#mx += 1
|
|
||||||
#if ax == 0:
|
|
||||||
#args['xRange'] = [mn, mx]
|
|
||||||
#else:
|
|
||||||
#args['yRange'] = [mn, mx]
|
|
||||||
|
|
||||||
#if len(args) > 0:
|
|
||||||
##print args
|
|
||||||
#self.setRange(**args)
|
|
||||||
|
|
||||||
def replot(self):
|
def replot(self):
|
||||||
#self.plotChanged()
|
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def updateParamList(self):
|
def updateParamList(self):
|
||||||
self.ctrl.avgParamList.clear()
|
self.ctrl.avgParamList.clear()
|
||||||
## Check to see that each parameter for each curve is present in the list
|
## Check to see that each parameter for each curve is present in the list
|
||||||
#print "\nUpdate param list", self
|
|
||||||
#print "paramList:", self.paramList
|
|
||||||
for c in self.curves:
|
for c in self.curves:
|
||||||
#print " curve:", c
|
|
||||||
for p in list(self.itemMeta.get(c, {}).keys()):
|
for p in list(self.itemMeta.get(c, {}).keys()):
|
||||||
#print " param:", p
|
|
||||||
if type(p) is tuple:
|
if type(p) is tuple:
|
||||||
p = '.'.join(p)
|
p = '.'.join(p)
|
||||||
|
|
||||||
## If the parameter is not in the list, add it.
|
## If the parameter is not in the list, add it.
|
||||||
matches = self.ctrl.avgParamList.findItems(p, QtCore.Qt.MatchExactly)
|
matches = self.ctrl.avgParamList.findItems(p, QtCore.Qt.MatchExactly)
|
||||||
#print " matches:", matches
|
|
||||||
if len(matches) == 0:
|
if len(matches) == 0:
|
||||||
i = QtGui.QListWidgetItem(p)
|
i = QtGui.QListWidgetItem(p)
|
||||||
if p in self.paramList and self.paramList[p] is True:
|
if p in self.paramList and self.paramList[p] is True:
|
||||||
#print " set checked"
|
|
||||||
i.setCheckState(QtCore.Qt.Checked)
|
i.setCheckState(QtCore.Qt.Checked)
|
||||||
else:
|
else:
|
||||||
#print " set unchecked"
|
|
||||||
i.setCheckState(QtCore.Qt.Unchecked)
|
i.setCheckState(QtCore.Qt.Unchecked)
|
||||||
self.ctrl.avgParamList.addItem(i)
|
self.ctrl.avgParamList.addItem(i)
|
||||||
else:
|
else:
|
||||||
i = matches[0]
|
i = matches[0]
|
||||||
|
|
||||||
self.paramList[p] = (i.checkState() == QtCore.Qt.Checked)
|
self.paramList[p] = (i.checkState() == QtCore.Qt.Checked)
|
||||||
#print "paramList:", self.paramList
|
|
||||||
|
|
||||||
|
|
||||||
## This is bullshit.
|
## Qt's SVG-writing capabilities are pretty terrible.
|
||||||
def writeSvgCurves(self, fileName=None):
|
def writeSvgCurves(self, fileName=None):
|
||||||
if fileName is None:
|
if fileName is None:
|
||||||
self.fileDialog = FileDialog()
|
self.fileDialog = FileDialog()
|
||||||
@ -1190,18 +828,12 @@ class PlotItem(GraphicsWidget):
|
|||||||
|
|
||||||
|
|
||||||
def saveState(self):
|
def saveState(self):
|
||||||
#if not HAVE_WIDGETGROUP:
|
|
||||||
#raise Exception("State save/restore requires WidgetGroup class.")
|
|
||||||
state = self.stateGroup.state()
|
state = self.stateGroup.state()
|
||||||
state['paramList'] = self.paramList.copy()
|
state['paramList'] = self.paramList.copy()
|
||||||
state['view'] = self.vb.getState()
|
state['view'] = self.vb.getState()
|
||||||
#print "\nSAVE %s:\n" % str(self.name), state
|
|
||||||
#print "Saving state. averageGroup.isChecked(): %s state: %s" % (str(self.ctrl.averageGroup.isChecked()), str(state['averageGroup']))
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def restoreState(self, state):
|
def restoreState(self, state):
|
||||||
#if not HAVE_WIDGETGROUP:
|
|
||||||
#raise Exception("State save/restore requires WidgetGroup class.")
|
|
||||||
if 'paramList' in state:
|
if 'paramList' in state:
|
||||||
self.paramList = state['paramList'].copy()
|
self.paramList = state['paramList'].copy()
|
||||||
|
|
||||||
@ -1218,8 +850,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
state['yGridCheck'] = state['gridGroup']
|
state['yGridCheck'] = state['gridGroup']
|
||||||
|
|
||||||
self.stateGroup.setState(state)
|
self.stateGroup.setState(state)
|
||||||
#self.updateXScale()
|
|
||||||
#self.updateYScale()
|
|
||||||
self.updateParamList()
|
self.updateParamList()
|
||||||
|
|
||||||
if 'view' not in state:
|
if 'view' not in state:
|
||||||
@ -1232,13 +862,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
}
|
}
|
||||||
self.vb.setState(state['view'])
|
self.vb.setState(state['view'])
|
||||||
|
|
||||||
|
|
||||||
#print "\nRESTORE %s:\n" % str(self.name), state
|
|
||||||
#print "Restoring state. averageGroup.isChecked(): %s state: %s" % (str(self.ctrl.averageGroup.isChecked()), str(state['averageGroup']))
|
|
||||||
#avg = self.ctrl.averageGroup.isChecked()
|
|
||||||
#if avg != state['averageGroup']:
|
|
||||||
#print " WARNING: avgGroup is %s, should be %s" % (str(avg), str(state['averageGroup']))
|
|
||||||
|
|
||||||
|
|
||||||
def widgetGroupInterface(self):
|
def widgetGroupInterface(self):
|
||||||
return (None, PlotItem.saveState, PlotItem.restoreState)
|
return (None, PlotItem.saveState, PlotItem.restoreState)
|
||||||
@ -1269,8 +892,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
for c in self.curves:
|
for c in self.curves:
|
||||||
c.setDownsampling(ds)
|
c.setDownsampling(ds)
|
||||||
self.recomputeAverages()
|
self.recomputeAverages()
|
||||||
#for c in self.avgCurves.values():
|
|
||||||
#c[1].setDownsampling(ds)
|
|
||||||
|
|
||||||
|
|
||||||
def downsampleMode(self):
|
def downsampleMode(self):
|
||||||
@ -1306,8 +927,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
(alpha, auto) = self.alphaState()
|
(alpha, auto) = self.alphaState()
|
||||||
for c in self.curves:
|
for c in self.curves:
|
||||||
c.setAlpha(alpha**2, auto)
|
c.setAlpha(alpha**2, auto)
|
||||||
|
|
||||||
#self.replot(autoRange=False)
|
|
||||||
|
|
||||||
def alphaState(self):
|
def alphaState(self):
|
||||||
enabled = self.ctrl.alphaGroup.isChecked()
|
enabled = self.ctrl.alphaGroup.isChecked()
|
||||||
@ -1330,9 +949,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
mode = False
|
mode = False
|
||||||
return mode
|
return mode
|
||||||
|
|
||||||
#def wheelEvent(self, ev):
|
|
||||||
## disables default panning the whole scene by mousewheel
|
|
||||||
#ev.accept()
|
|
||||||
|
|
||||||
def resizeEvent(self, ev):
|
def resizeEvent(self, ev):
|
||||||
if self.autoBtn is None: ## already closed down
|
if self.autoBtn is None: ## already closed down
|
||||||
@ -1340,29 +956,42 @@ class PlotItem(GraphicsWidget):
|
|||||||
btnRect = self.mapRectFromItem(self.autoBtn, self.autoBtn.boundingRect())
|
btnRect = self.mapRectFromItem(self.autoBtn, self.autoBtn.boundingRect())
|
||||||
y = self.size().height() - btnRect.height()
|
y = self.size().height() - btnRect.height()
|
||||||
self.autoBtn.setPos(0, y)
|
self.autoBtn.setPos(0, y)
|
||||||
|
|
||||||
#def hoverMoveEvent(self, ev):
|
|
||||||
#self.mousePos = ev.pos()
|
|
||||||
#self.mouseScreenPos = ev.screenPos()
|
|
||||||
|
|
||||||
|
|
||||||
#def ctrlBtnClicked(self):
|
|
||||||
#self.ctrlMenu.popup(self.mouseScreenPos)
|
|
||||||
|
|
||||||
def getMenu(self):
|
def getMenu(self):
|
||||||
return self.ctrlMenu
|
return self.ctrlMenu
|
||||||
|
|
||||||
def getContextMenus(self, event):
|
def getContextMenus(self, event):
|
||||||
## called when another item is displaying its context menu; we get to add extras to the end of the menu.
|
## called when another item is displaying its context menu; we get to add extras to the end of the menu.
|
||||||
return self.ctrlMenu
|
if self.menuEnabled():
|
||||||
|
return self.ctrlMenu
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def setMenuEnabled(self, enableMenu=True, enableViewBoxMenu='same'):
|
||||||
|
"""
|
||||||
|
Enable or disable the context menu for this PlotItem.
|
||||||
|
By default, the ViewBox's context menu will also be affected.
|
||||||
|
(use enableViewBoxMenu=None to leave the ViewBox unchanged)
|
||||||
|
"""
|
||||||
|
self._menuEnabled = enableMenu
|
||||||
|
if enableViewBoxMenu is None:
|
||||||
|
return
|
||||||
|
if enableViewBoxMenu is 'same':
|
||||||
|
enableViewBoxMenu = enableMenu
|
||||||
|
self.vb.setMenuEnabled(enableViewBoxMenu)
|
||||||
|
|
||||||
|
def menuEnabled(self):
|
||||||
|
return self._menuEnabled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getLabel(self, key):
|
def getLabel(self, key):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _checkScaleKey(self, key):
|
def _checkScaleKey(self, key):
|
||||||
if key not in self.scales:
|
if key not in self.axes:
|
||||||
raise Exception("Scale '%s' not found. Scales are: %s" % (key, str(list(self.scales.keys()))))
|
raise Exception("Scale '%s' not found. Scales are: %s" % (key, str(list(self.axes.keys()))))
|
||||||
|
|
||||||
def getScale(self, key):
|
def getScale(self, key):
|
||||||
return self.getAxis(key)
|
return self.getAxis(key)
|
||||||
@ -1371,7 +1000,7 @@ class PlotItem(GraphicsWidget):
|
|||||||
"""Return the specified AxisItem.
|
"""Return the specified AxisItem.
|
||||||
*name* should be 'left', 'bottom', 'top', or 'right'."""
|
*name* should be 'left', 'bottom', 'top', or 'right'."""
|
||||||
self._checkScaleKey(name)
|
self._checkScaleKey(name)
|
||||||
return self.scales[name]['item']
|
return self.axes[name]['item']
|
||||||
|
|
||||||
def setLabel(self, axis, text=None, units=None, unitPrefix=None, **args):
|
def setLabel(self, axis, text=None, units=None, unitPrefix=None, **args):
|
||||||
"""
|
"""
|
||||||
@ -1417,7 +1046,7 @@ class PlotItem(GraphicsWidget):
|
|||||||
axis must be one of 'left', 'bottom', 'right', or 'top'
|
axis must be one of 'left', 'bottom', 'right', or 'top'
|
||||||
"""
|
"""
|
||||||
s = self.getScale(axis)
|
s = self.getScale(axis)
|
||||||
p = self.scales[axis]['pos']
|
p = self.axes[axis]['pos']
|
||||||
if show:
|
if show:
|
||||||
s.show()
|
s.show()
|
||||||
else:
|
else:
|
||||||
@ -1454,7 +1083,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
## create curve
|
## create curve
|
||||||
try:
|
try:
|
||||||
xv = arr.xvals(0)
|
xv = arr.xvals(0)
|
||||||
#print 'xvals:', xv
|
|
||||||
except:
|
except:
|
||||||
if x is None:
|
if x is None:
|
||||||
xv = np.arange(arr.shape[0])
|
xv = np.arange(arr.shape[0])
|
||||||
@ -1474,17 +1102,6 @@ class PlotItem(GraphicsWidget):
|
|||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
||||||
#def saveSvgClicked(self):
|
|
||||||
#self.writeSvg()
|
|
||||||
|
|
||||||
#def saveSvgCurvesClicked(self):
|
|
||||||
#self.writeSvgCurves()
|
|
||||||
|
|
||||||
#def saveImgClicked(self):
|
|
||||||
#self.writeImage()
|
|
||||||
|
|
||||||
#def saveCsvClicked(self):
|
|
||||||
#self.writeCsv()
|
|
||||||
|
|
||||||
def setExportMode(self, export, opts):
|
def setExportMode(self, export, opts):
|
||||||
if export:
|
if export:
|
||||||
@ -1492,63 +1109,3 @@ class PlotItem(GraphicsWidget):
|
|||||||
else:
|
else:
|
||||||
self.autoBtn.show()
|
self.autoBtn.show()
|
||||||
|
|
||||||
|
|
||||||
#class PlotWidgetManager(QtCore.QObject):
|
|
||||||
|
|
||||||
#sigWidgetListChanged = QtCore.Signal(object)
|
|
||||||
|
|
||||||
#"""Used for managing communication between PlotWidgets"""
|
|
||||||
#def __init__(self):
|
|
||||||
#QtCore.QObject.__init__(self)
|
|
||||||
#self.widgets = weakref.WeakValueDictionary() # Don't keep PlotWidgets around just because they are listed here
|
|
||||||
|
|
||||||
#def addWidget(self, w, name):
|
|
||||||
#self.widgets[name] = w
|
|
||||||
##self.emit(QtCore.SIGNAL('widgetListChanged'), self.widgets.keys())
|
|
||||||
#self.sigWidgetListChanged.emit(self.widgets.keys())
|
|
||||||
|
|
||||||
#def removeWidget(self, name):
|
|
||||||
#if name in self.widgets:
|
|
||||||
#del self.widgets[name]
|
|
||||||
##self.emit(QtCore.SIGNAL('widgetListChanged'), self.widgets.keys())
|
|
||||||
#self.sigWidgetListChanged.emit(self.widgets.keys())
|
|
||||||
#else:
|
|
||||||
#print "plot %s not managed" % name
|
|
||||||
|
|
||||||
|
|
||||||
#def listWidgets(self):
|
|
||||||
#return self.widgets.keys()
|
|
||||||
|
|
||||||
#def getWidget(self, name):
|
|
||||||
#if name not in self.widgets:
|
|
||||||
#return None
|
|
||||||
#else:
|
|
||||||
#return self.widgets[name]
|
|
||||||
|
|
||||||
#def linkX(self, p1, p2):
|
|
||||||
##QtCore.QObject.connect(p1, QtCore.SIGNAL('xRangeChanged'), p2.linkXChanged)
|
|
||||||
#p1.sigXRangeChanged.connect(p2.linkXChanged)
|
|
||||||
##QtCore.QObject.connect(p2, QtCore.SIGNAL('xRangeChanged'), p1.linkXChanged)
|
|
||||||
#p2.sigXRangeChanged.connect(p1.linkXChanged)
|
|
||||||
#p1.linkXChanged(p2)
|
|
||||||
##p2.setManualXScale()
|
|
||||||
|
|
||||||
#def unlinkX(self, p1, p2):
|
|
||||||
##QtCore.QObject.disconnect(p1, QtCore.SIGNAL('xRangeChanged'), p2.linkXChanged)
|
|
||||||
#p1.sigXRangeChanged.disconnect(p2.linkXChanged)
|
|
||||||
##QtCore.QObject.disconnect(p2, QtCore.SIGNAL('xRangeChanged'), p1.linkXChanged)
|
|
||||||
#p2.sigXRangeChanged.disconnect(p1.linkXChanged)
|
|
||||||
|
|
||||||
#def linkY(self, p1, p2):
|
|
||||||
##QtCore.QObject.connect(p1, QtCore.SIGNAL('yRangeChanged'), p2.linkYChanged)
|
|
||||||
#p1.sigYRangeChanged.connect(p2.linkYChanged)
|
|
||||||
##QtCore.QObject.connect(p2, QtCore.SIGNAL('yRangeChanged'), p1.linkYChanged)
|
|
||||||
#p2.sigYRangeChanged.connect(p1.linkYChanged)
|
|
||||||
#p1.linkYChanged(p2)
|
|
||||||
##p2.setManualYScale()
|
|
||||||
|
|
||||||
#def unlinkY(self, p1, p2):
|
|
||||||
##QtCore.QObject.disconnect(p1, QtCore.SIGNAL('yRangeChanged'), p2.linkYChanged)
|
|
||||||
#p1.sigYRangeChanged.disconnect(p2.linkYChanged)
|
|
||||||
##QtCore.QObject.disconnect(p2, QtCore.SIGNAL('yRangeChanged'), p1.linkYChanged)
|
|
||||||
#p2.sigYRangeChanged.disconnect(p1.linkYChanged)
|
|
||||||
|
@ -62,7 +62,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
NamedViews = weakref.WeakValueDictionary() # name: ViewBox
|
NamedViews = weakref.WeakValueDictionary() # name: ViewBox
|
||||||
AllViews = weakref.WeakKeyDictionary() # ViewBox: None
|
AllViews = weakref.WeakKeyDictionary() # ViewBox: None
|
||||||
|
|
||||||
def __init__(self, parent=None, border=None, lockAspect=False, enableMouse=True, invertY=False, enableMenu = True, name=None):
|
def __init__(self, parent=None, border=None, lockAspect=False, enableMouse=True, invertY=False, enableMenu=True, name=None):
|
||||||
"""
|
"""
|
||||||
============= =============================================================
|
============= =============================================================
|
||||||
**Arguments**
|
**Arguments**
|
||||||
@ -136,7 +136,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
|
|
||||||
## Make scale box that is shown when dragging on the view
|
## Make scale box that is shown when dragging on the view
|
||||||
self.rbScaleBox = QtGui.QGraphicsRectItem(0, 0, 1, 1)
|
self.rbScaleBox = QtGui.QGraphicsRectItem(0, 0, 1, 1)
|
||||||
self.rbScaleBox.setPen(fn.mkPen((255,0,0), width=1))
|
self.rbScaleBox.setPen(fn.mkPen((255,255,100), width=1))
|
||||||
self.rbScaleBox.setBrush(fn.mkBrush(255,255,0,100))
|
self.rbScaleBox.setBrush(fn.mkBrush(255,255,0,100))
|
||||||
self.rbScaleBox.hide()
|
self.rbScaleBox.hide()
|
||||||
self.addItem(self.rbScaleBox)
|
self.addItem(self.rbScaleBox)
|
||||||
@ -358,7 +358,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
changes[1] = yRange
|
changes[1] = yRange
|
||||||
|
|
||||||
if len(changes) == 0:
|
if len(changes) == 0:
|
||||||
print rect
|
print(rect)
|
||||||
raise Exception("Must specify at least one of rect, xRange, or yRange. (gave rect=%s)" % str(type(rect)))
|
raise Exception("Must specify at least one of rect, xRange, or yRange. (gave rect=%s)" % str(type(rect)))
|
||||||
|
|
||||||
changed = [False, False]
|
changed = [False, False]
|
||||||
@ -863,7 +863,10 @@ class ViewBox(GraphicsWidget):
|
|||||||
return self._menuCopy
|
return self._menuCopy
|
||||||
|
|
||||||
def getContextMenus(self, event):
|
def getContextMenus(self, event):
|
||||||
return self.menu.subMenus()
|
if self.menuEnabled():
|
||||||
|
return self.menu.subMenus()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
#return [self.getMenu(event)]
|
#return [self.getMenu(event)]
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ class PlotWidget(GraphicsView):
|
|||||||
other methods, use :func:`getPlotItem <pyqtgraph.PlotWidget.getPlotItem>`.
|
other methods, use :func:`getPlotItem <pyqtgraph.PlotWidget.getPlotItem>`.
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent=None, **kargs):
|
def __init__(self, parent=None, **kargs):
|
||||||
|
"""When initializing PlotWidget, all keyword arguments except *parent* are passed
|
||||||
|
to :func:`PlotItem.__init__() <pyqtgraph.PlotItem.__init__>`."""
|
||||||
GraphicsView.__init__(self, parent)
|
GraphicsView.__init__(self, parent)
|
||||||
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||||
self.enableMouse(False)
|
self.enableMouse(False)
|
||||||
|
Loading…
Reference in New Issue
Block a user