doc updates

ViewBox: made padding more consistent for all auto-ranging methods, deprecated autoRange(item=) in favor of autoRange(items=)
This commit is contained in:
Luke Campagnola 2013-02-20 11:13:50 -05:00
parent 86861b5a06
commit 412e1d2ec8
6 changed files with 62 additions and 24 deletions

View File

@ -17,7 +17,7 @@ Pyqtgraph makes it very easy to visualize data from the command line. Observe::
import pyqtgraph as pg
pg.plot(data) # data can be a list of values or a numpy array
The example above would open a window displaying a line plot of the data given. The call to :func:`pg.plot <pyqtgraph.plot>` returns a handle to the :class:`plot widget <pyqtgraph.PlotWidget>` that is created, allowing more data to be added to the same window.
The example above would open a window displaying a line plot of the data given. The call to :func:`pg.plot <pyqtgraph.plot>` returns a handle to the :class:`plot widget <pyqtgraph.PlotWidget>` that is created, allowing more data to be added to the same window. **Note:** interactive plotting from the python prompt is only available with PyQt; PySide does not run the Qt event loop while the interactive prompt is running. If you wish to use pyqtgraph interactively with PySide, see the 'console' :ref:`example <examples>`.
Further examples::

View File

@ -66,6 +66,12 @@ Signals, Slots, and Events
[ to be continued.. please post a request on the pyqtgraph forum if you'd like to read more ]
Qt detects and reacts to user interaction by executing its *event loop*.
- what happens in the event loop?
- when do I need to use QApplication.exec_() ?
- what control do I have over event loop execution? (QApplication.processEvents)
GraphicsView and GraphicsItems
------------------------------
@ -79,8 +85,8 @@ Mouse and Keyboard Input
------------------------
QTimer, the Event Loop, and Multi-Threading
-------------------------------------------
QTimer, Multi-Threading
-----------------------
Multi-threading vs Multi-processing in Qt

View File

@ -1,4 +1,15 @@
# -*- coding: utf-8 -*-
"""
This example demonstrates the use of ImageView, which is a high-level widget for
displaying and analyzing 2D and 3D data. ImageView provides:
1. A zoomable region (ViewBox) for displaying the image
2. A combination histogram and gradient editor (HistogramLUTItem) for
controlling the visual appearance of the image
3. A timeline for selecting the currently displayed frame (for 3D data only).
4. Tools for very basic analysis of image data (see ROI and Norm buttons)
"""
## Add path to library (just for examples; you do not need this)
import initExample
@ -22,9 +33,6 @@ img = img[np.newaxis,:,:]
decay = np.exp(-np.linspace(0,0.3,100))[:,np.newaxis,np.newaxis]
data = np.random.normal(size=(100, 200, 200))
data += img * decay
#for i in range(data.shape[0]):
#data[i] += 10*exp(-(2.*i)/data.shape[0])
data += 2
## Add time-varying signal
@ -37,7 +45,7 @@ sig = sig[:,np.newaxis,np.newaxis] * 3
data[:,50:60,50:60] += sig
## Display the data
## Display the data and assign each frame a time value from 1.0 to 3.0
imv.setImage(data, xvals=np.linspace(1., 3., data.shape[0]))
## Start Qt event loop unless running in interactive mode.

View File

@ -66,6 +66,7 @@ for i in range(0, 5):
## Test large numbers
curve = pw3.plot(np.random.normal(size=100)*1e0, clickable=True)
curve.curve.setClickable(True)
curve.setPen('w') ## white pen
curve.setShadowPen(pg.mkPen((70,70,30), width=6, cosmetic=True))

View File

@ -22,7 +22,7 @@ class PlotData(object):
self.maxVals = {} ## cache for max/min
self.minVals = {}
def addFields(self, fields):
def addFields(self, **fields):
for f in fields:
if f not in self.fields:
self.fields[f] = None

View File

@ -336,7 +336,7 @@ class ViewBox(GraphicsWidget):
print("make qrectf failed:", self.state['targetRange'])
raise
def setRange(self, rect=None, xRange=None, yRange=None, padding=0.02, update=True, disableAutoRange=True):
def setRange(self, rect=None, xRange=None, yRange=None, padding=None, update=True, disableAutoRange=True):
"""
Set the visible range of the ViewBox.
Must specify at least one of *range*, *xRange*, or *yRange*.
@ -347,7 +347,8 @@ class ViewBox(GraphicsWidget):
*xRange* (min,max) The range that should be visible along the x-axis.
*yRange* (min,max) The range that should be visible along the y-axis.
*padding* (float) Expand the view by a fraction of the requested range.
By default, this value is 0.02 (2%)
By default, this value is set between 0.02 and 0.1 depending on
the size of the ViewBox.
============= =====================================================================
"""
@ -367,6 +368,10 @@ class ViewBox(GraphicsWidget):
changed = [False, False]
for ax, range in changes.items():
if padding is None:
xpad = self.suggestPadding(ax)
else:
xpad = padding
mn = min(range)
mx = max(range)
if mn == mx: ## If we requested 0 range, try to preserve previous scale. Otherwise just pick an arbitrary scale.
@ -375,11 +380,11 @@ class ViewBox(GraphicsWidget):
dy = 1
mn -= dy*0.5
mx += dy*0.5
padding = 0.0
xpad = 0.0
if any(np.isnan([mn, mx])) or any(np.isinf([mn, mx])):
raise Exception("Not setting range [%s, %s]" % (str(mn), str(mx)))
p = (mx-mn) * padding
p = (mx-mn) * xpad
mn -= p
mx += p
@ -412,34 +417,53 @@ class ViewBox(GraphicsWidget):
elif changed[1] and self.state['autoVisibleOnly'][0]:
self.updateAutoRange()
def setYRange(self, min, max, padding=0.02, update=True):
def setYRange(self, min, max, padding=None, update=True):
"""
Set the visible Y range of the view to [*min*, *max*].
The *padding* argument causes the range to be set larger by the fraction specified.
(by default, this value is between 0.02 and 0.1 depending on the size of the ViewBox)
"""
self.setRange(yRange=[min, max], update=update, padding=padding)
def setXRange(self, min, max, padding=0.02, update=True):
def setXRange(self, min, max, padding=None, update=True):
"""
Set the visible X range of the view to [*min*, *max*].
The *padding* argument causes the range to be set larger by the fraction specified.
(by default, this value is between 0.02 and 0.1 depending on the size of the ViewBox)
"""
self.setRange(xRange=[min, max], update=update, padding=padding)
def autoRange(self, padding=0.02, item=None):
def autoRange(self, padding=None, items=None, item=None):
"""
Set the range of the view box to make all children visible.
Note that this is not the same as enableAutoRange, which causes the view to
automatically auto-range whenever its contents are changed.
=========== ============================================================
Arguments
padding The fraction of the total data range to add on to the final
visible range. By default, this value is set between 0.02
and 0.1 depending on the size of the ViewBox.
items If specified, this is a list of items to consider when
determining the visible range.
=========== ============================================================
"""
if item is None:
bounds = self.childrenBoundingRect()
bounds = self.childrenBoundingRect(items=items)
else:
print "Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead."
bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
if bounds is not None:
self.setRange(bounds, padding=padding)
def suggestPadding(self, axis):
l = self.width() if axis==0 else self.height()
if l > 0:
padding = np.clip(1./(l**0.5), 0.02, 0.1)
else:
padding = 0.02
return padding
def scaleBy(self, s, center=None):
"""
@ -577,12 +601,10 @@ class ViewBox(GraphicsWidget):
w2 = (targetRect[ax][1]-targetRect[ax][0]) / 2.
childRange[ax] = [x-w2, x+w2]
else:
l = self.width() if ax==0 else self.height()
if l > 0:
padding = np.clip(1./(l**0.5), 0.02, 0.1)
wp = (xr[1] - xr[0]) * padding
childRange[ax][0] -= wp
childRange[ax][1] += wp
padding = self.suggestPadding(ax)
wp = (xr[1] - xr[0]) * padding
childRange[ax][0] -= wp
childRange[ax][1] += wp
targetRect[ax] = childRange[ax]
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
if len(args) == 0:
@ -995,13 +1017,14 @@ class ViewBox(GraphicsWidget):
def childrenBounds(self, frac=None, orthoRange=(None,None)):
def childrenBounds(self, frac=None, orthoRange=(None,None), items=None):
"""Return the bounding range of all children.
[[xmin, xmax], [ymin, ymax]]
Values may be None if there are no specific bounds for an axis.
"""
prof = debug.Profiler('updateAutoRange', disabled=True)
items = self.addedItems
if items is None:
items = self.addedItems
## measure pixel dimensions in view box
px, py = [v.length() if v is not None else 0 for v in self.childGroup.pixelVectors()]