Bugfixes and example for view linking

This commit is contained in:
Luke Campagnola 2012-03-20 23:38:04 -04:00
parent 97740c2376
commit 7c94b5a702
6 changed files with 80 additions and 12 deletions

View File

@ -19,6 +19,7 @@ examples = OrderedDict([
('Scatter Plot', 'ScatterPlot.py'),
('Text Item', 'text.py'),
('ViewBox', 'ViewBox.py'),
('Linked Views', 'linkedViews.py'),
('Arrow', 'Arrow.py'),
])),
('Widgets', OrderedDict([

48
examples/linkedViews.py Normal file
View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
## This example demonstrates the ability to link the axes of views together
## Views can be linked manually using the context menu, but only if they are given names.
import initExample ## Add path to library (just for examples; you do not need this)
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
#QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([])
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
x = np.linspace(-50, 50, 1000)
y = np.sin(x) / x
win = pg.GraphicsWindow(title="View Linking Examples")
win.resize(800,600)
win.addLabel("Views linked at runtime:", colspan=2)
win.nextRow()
p1 = win.addPlot(x=x, y=y, name="Plot1", title="Plot1")
p2 = win.addPlot(x=x, y=y, name="Plot2", title="Plot2 - Y linked with Plot1")
p2.setLabel('bottom', "Label to test offset")
p2.setYLink(p1)
win.nextRow()
p3 = win.addPlot(x=x, y=y, name="Plot3", title="Plot3 - X linked with Plot1")
p4 = win.addPlot(x=x, y=y, name="Plot4", title="Plot4 - X and Y linked with Plot1")
p3.setLabel('left', "Label to test offset")
QtGui.QApplication.processEvents()
p3.setXLink(p1)
p4.setXLink(p1)
p4.setYLink(p1)
## 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'):
app.exec_()

View File

@ -33,7 +33,6 @@ class GraphicsLayout(GraphicsWidget):
return self.currentCol-colspan
def addPlot(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
from PlotItem import PlotItem
plot = PlotItem(**kargs)
self.addItem(plot, row, col, rowspan, colspan)
return plot
@ -43,6 +42,11 @@ class GraphicsLayout(GraphicsWidget):
self.addItem(vb, row, col, rowspan, colspan)
return vb
def addLabel(self, text, row=None, col=None, rowspan=1, colspan=1, **kargs):
text = LabelItem(text, **kargs)
self.addItem(text, row, col, rowspan, colspan)
return text
def addItem(self, item, row=None, col=None, rowspan=1, colspan=1):
if row is None:
@ -95,3 +99,4 @@ class GraphicsLayout(GraphicsWidget):
## Must be imported at the end to avoid cyclic-dependency hell:
from ViewBox import ViewBox
from PlotItem import PlotItem
from LabelItem import LabelItem

View File

@ -10,12 +10,11 @@ class LabelItem(GraphicsWidget):
GraphicsWidget displaying text.
Used mainly as axis labels, titles, etc.
Note: To display text inside a scaled view (ViewBox, PlotWidget, etc) use QGraphicsTextItem
with the flag ItemIgnoresTransformations set.
Note: To display text inside a scaled view (ViewBox, PlotWidget, etc) use TextItem
"""
def __init__(self, text, parent=None, **args):
def __init__(self, text, parent=None, angle=0, **args):
GraphicsWidget.__init__(self, parent)
self.item = QtGui.QGraphicsTextItem(self)
self.opts = args
@ -26,6 +25,7 @@ class LabelItem(GraphicsWidget):
self.opts['color'] = fn.colorStr(args['color'])[:6]
self.sizeHint = {}
self.setText(text)
self.setAngle(angle)
def setAttr(self, attr, value):

View File

@ -480,11 +480,13 @@ class ViewBox(GraphicsWidget):
self.linksBlocked = b ## prevents recursive plot-change propagation
def linkedXChanged(self):
## called when x range of linked view has changed
view = self.state['linkedViews'][0]
self.linkedViewChanged(view, ViewBox.XAxis)
def linkedYChanged(self):
view = self.state['linkedViews'][0]
## called when y range of linked view has changed
view = self.state['linkedViews'][1]
self.linkedViewChanged(view, ViewBox.YAxis)
@ -502,15 +504,27 @@ class ViewBox(GraphicsWidget):
view.blockLink(True)
try:
if axis == ViewBox.XAxis:
upp = float(vr.width()) / vg.width()
x1 = vr.left() + (sg.x()-vg.x()) * upp
x2 = x1 + sg.width() * upp
overlap = min(sg.right(), vg.right()) - max(sg.left(), vg.left())
if overlap < min(vg.width()/3, sg.width()/3): ## if less than 1/3 of views overlap,
## then just replicate the view
x1 = vr.left()
x2 = vr.right()
else: ## views overlap; line them up
upp = float(vr.width()) / vg.width()
x1 = vr.left() + (sg.x()-vg.x()) * upp
x2 = x1 + sg.width() * upp
self.enableAutoRange(ViewBox.XAxis, False)
self.setXRange(x1, x2, padding=0)
else:
upp = float(vr.height()) / vg.height()
x1 = vr.bottom() + (sg.y()-vg.y()) * upp
x2 = x1 + sg.height() * upp
overlap = min(sg.bottom(), vg.bottom()) - max(sg.top(), vg.top())
if overlap < min(vg.height()/3, sg.height()/3): ## if less than 1/3 of views overlap,
## then just replicate the view
x1 = vr.top()
x2 = vr.bottom()
else: ## views overlap; line them up
upp = float(vr.height()) / vg.height()
x1 = vr.top() + (sg.y()-vg.y()) * upp
x2 = x1 + sg.height() * upp
self.enableAutoRange(ViewBox.YAxis, False)
self.setYRange(x1, x2, padding=0)
finally:

View File

@ -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', 'addPlot', 'addViewBox', 'addItem', 'getItem']:
for n in ['nextRow', 'nextCol', 'addPlot', 'addViewBox', 'addItem', 'getItem', 'addLabel']:
setattr(self, n, getattr(self.ci, n))
self.setCentralItem(self.ci)