fsleyes.views.plotpanel
¶
This module provides the PlotPanel
and OverlayPlotPanel
classes. The PlotPanel
class is the base class for all FSLeyes views
which display some sort of data plot. The OverlayPlotPanel
is a
PlotPanel
which contains some extra logic for displaying plots related to
the currently selected overlay.
-
class
fsleyes.views.plotpanel.
PlotPanel
(parent, overlayList, displayCtx, frame)¶ Bases:
fsleyes.views.viewpanel.ViewPanel
The
PlotPanel
class is the base class for all FSLeyes views which display some sort of 2D data plot, such as theTimeSeriesPanel
, and theHistogramPanel
. See also theOverlayPlotPanel
, which contains extra logic for displaying plots related to the currently selected overlay.PlotPanel
usesmatplotlib
for its plotting. Thematplotlib
Figure
,Axis
, andCanvas
instances can be accessed via thegetFigure()
,getAxis()
, andgetCanvas()
methods, if they are needed. Various display settings can be configured throughPlotPanel
properties, includinglegend
,smooth
, etc.Sub-class requirements
Sub-class implementations of
PlotPanel
must do the following:Call the
PlotPanel
constructor.Define a
DataSeries
sub-class.Override the
draw()
method, so it calls thedrawDataSeries()
method.If necessary, override the
prepareDataSeries()
method to perform any preprocessing onextraSeries
passed to thedrawDataSeries()
method (but not applied toDataSeries
that have been added to thedataSeries
list).If necessary, override the
destroy()
method, but make sure that the base-class implementation is called.
Data series
A
PlotPanel
instance plots data contained in one or moreDataSeries
instances; allDataSeries
classes are defined in theplotting
sub-package. Therefore,PlotPanel
sub-classes also need to define a sub-class of theDataSeries
base class.DataSeries
objects can be plotted by passing them to thedrawDataSeries()
method.Or, if you want one or more
DataSeries
to be held, i.e. plotted every time, you can add them to thedataSeries
list. TheDataSeries
in thedataSeries
list will be plotted on every call todrawDataSeries()
(in addition to anyDataSeries
passed directly todrawDataSeries()
) until they are removed from thedataSeries
list.The draw queue
The
PlotPanel
uses aasync.TaskThread
to asynchronously extract and prepare data for plotting, This is because data preparation may take a long time for largeImage
overlays, and the main application thread should not be blocked while this is occurring. TheTaskThread
instance is accessible through thegetDrawQueue()
method, in case anything needs to be scheduled on it.Plot panel actions
A number of
actions
are also provided by thePlotPanel
class:Prompts the user to select a file name, then saves a screenshot of the current plot.
Imports data series from a text file.
Exports displayed data series to a text file.
-
dataSeries
= <MagicMock name='mock.List()' id='140735845975376'>¶ This list contains
DataSeries
instances which are plotted on every call todrawDataSeries()
.DataSeries
instances can be added/removed directly to/from this list.
-
artists
= <MagicMock name='mock.List()' id='140735845975376'>¶ This list contains any
matplotlib.Artist
instances which are plotted every call todrawArtists()
.
-
legend
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ If
True
, a legend is added to the plot, with an entry for everyDataSeries
instance in thedataSeries
list.
-
xAutoScale
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ If
True
, the plotlimits
for the X axis are automatically updated to fit all plotted data.
-
yAutoScale
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ If
True
, the plotlimits
for the Y axis are automatically updated to fit all plotted data.
-
xLogScale
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ Toggle a \(log_{10}\) x axis scale.
-
yLogScale
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ Toggle a \(log_{10}\) y axis scale.
-
invertX
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ Invert the plot along the X axis.
-
invertY
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ Invert the plot along the Y axis.
-
xScale
= <MagicMock name='mock.Real()' id='140735894843600'>¶ Scale to apply to the X axis data.
-
yScale
= <MagicMock name='mock.Real()' id='140735894843600'>¶ Scale to apply to the Y axis data.
-
xOffset
= <MagicMock name='mock.Real()' id='140735894843600'>¶ Offset to apply to the X axis data.
-
yOffset
= <MagicMock name='mock.Real()' id='140735894843600'>¶ Offset to apply to the Y axis data.
-
ticks
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ Toggle axis ticks and tick labels on/off.
-
grid
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ Toggle an axis grid on/off.
-
bgColour
= <MagicMock name='mock.Colour()' id='140735848816272'>¶ Plot background colour.
-
smooth
= <MagicMock name='mock.Boolean()' id='140735851538640'>¶ If
True
all plotted data is up-sampled, and smoothed using spline interpolation.
-
xlabel
= <MagicMock name='mock.String()' id='140735848727888'>¶ A label to show on the x axis.
-
ylabel
= <MagicMock name='mock.String()' id='140735848727888'>¶ A label to show on the y axis.
-
limits
= <MagicMock name='mock.Bounds()' id='140735846157520'>¶ The x/y axis limits. If
xAutoScale
andyAutoScale
areTrue
, these limit values are automatically updated on every call todrawDataSeries()
.
-
__init__
(parent, overlayList, displayCtx, frame)¶ Create a
PlotPanel
.- Parameters
parent – The
wx
parent object.overlayList – An
OverlayList
instance.displayCtx – A
DisplayContext
instance.frame – The
FSLeyesFrame
instance.
-
getFigure
()¶ Returns the
matplotlib
Figure
instance.
-
getAxis
()¶ Returns the
matplotlib
Axis
instance.
-
getCanvas
()¶ Returns the
matplotlib
Canvas
instance.
-
getDrawQueue
()¶ Returns the :class`.idle.TaskThread` instance used for data preparation.
-
draw
(*a)¶ This method must be overridden by
PlotPanel
sub-classes.It is called whenever a
DataSeries
is added to thedataSeries
list, or when any plot display properties change.Sub-class implementations should call the
drawDataSeries()
and meth:drawArtists methods.
-
asyncDraw
(*a)¶ Schedules
draw()
to be run asynchronously. This method should be used in preference to callingdraw()
directly in most cases, particularly where the call occurs within a property callback function.
-
destroy
()¶ Removes some property listeners, and then calls
ViewPanel.destroy()
.
-
screenshot
(*a)¶ Prompts the user to select a file name, then saves a screenshot of the current plot.
See the
ScreenshotAction
.
-
importDataSeries
(*a)¶ Imports data series from a text file.
See the
ImportDataSeriesAction
.
-
exportDataSeries
(*args, **kwargs)¶ Exports displayed data series to a text file.
See the
ExportDataSeriesAction
.
-
message
(msg, clear=True, border=False)¶ Displays the given message in the centre of the figure.
This is a convenience method provided for use by subclasses.
-
getArtist
(ds)¶ Returns the
matplotlib.Artist
(typically aLine2D
instance) associated with the givenDataSeries
instance. AKeyError
is raised if there is no such artist.
-
getDrawnDataSeries
()¶ Returns a list of tuples, each tuple containing the
(DataSeries, x, y)
data for oneDataSeries
instance as it is shown on the plot.
-
prepareDataSeries
(ds)¶ Prepares the data from the given
DataSeries
so it is ready to be plotted. Called by the__drawOneDataSeries()
method for anyextraSeries
passed to thedrawDataSeries()
method (but not applied toDataSeries
that have been added to thedataSeries
list).This implementation just returns
DataSeries.getData
- override it to perform any custom preprocessing.
-
drawArtists
(refresh=True, immediate=False)¶ Draw all
matplotlib.Artist
instances in theartists
list, then refresh the canvas.- Parameters
refresh – If
True
(default), the canvas is refreshed.
-
drawDataSeries
(extraSeries=None, refresh=False, **plotArgs)¶ Queues a request to plot all of the
DataSeries
instances in thedataSeries
list.This method does not do the actual plotting - it is performed asynchronously, to avoid locking up the GUI:
The data for each
DataSeries
instance is prepared on separate threads (usingidle.run()
).A call to
idle.wait()
is enqueued on aTaskThread
.This
wait
function waits until all of the data preparation threads have completed, and then passes all of the data to the__drawDataSeries()
method.
- Parameters
extraSeries – A sequence of additional
DataSeries
to be plotted. These series are passed through theprepareDataSeries()
method before being plotted.refresh – If
True
, the canvas is refreshed. Otherwise, you must callgetCanvas().draw()
manually. Defaults toFalse
- thedrawArtists()
method will refresh the canvas, so if you calldrawArtists()
immediately after calling this method (which you should), then you don’t need to manually refresh the canvas.plotArgs – Passed through to the
__drawDataSeries()
method.
Note
This method must only be called from the main application thread (the
wx
event loop).
-
_PlotPanel__artistsChanged
(*a)¶ Called when the
artists
list changes. CallsasyncDraw()
.
-
_PlotPanel__calcLimits
(dataxlims, dataylims, axisxlims, axisylims, axWidth, axHeight)¶ Calculates and returns suitable axis limits for the current plot. Also updates the
limits
property. This method is called by thedrawDataSeries()
method.If
xAutoScale
oryAutoScale
are enabled, the limits are calculated from the data range, using the canvas width and height to maintain consistent padding around the plotted data, irrespective of the canvas size.. Otherwise, the existing axis limits are retained.
- Parameters
dataxlims – A tuple containing the (min, max) x data range.
dataylims – A tuple containing the (min, max) y data range.
axisxlims – A tuple containing the current (min, max) x axis limits.
axisylims – A tuple containing the current (min, max) y axis limits.
axWidth – Canvas width in pixels
axHeight – Canvas height in pixels
-
_PlotPanel__dataSeriesChanged
(*a)¶ Called when the
dataSeries
list changes. Adds listeners to any newDataSeries
instances, and then callsasyncDraw()
.
-
_PlotPanel__drawDataSeries
(dataSeries, allXdata, allYdata, oldxlim, oldylim, refresh, xlabel=None, ylabel=None, **plotArgs)¶ Called by
__drawDataSeries()
. Plots all of the data associated with the givendataSeries
.- Parameters
dataSeries – The list of
DataSeries
instances to plot.allXdata – A list of arrays containing X axis data, one for each
DataSeries
.allYdata – A list of arrays containing Y axis data, one for each
DataSeries
.oldxlim – X plot limits from the previous draw. If
xAutoScale
is disabled, this limit is preserved.oldylim – Y plot limits from the previous draw. If
yAutoScale
is disabled, this limit is preserved.refresh – Refresh the canvas - see
drawDataSeries()
.xlabel – If provided, overrides the value of the
xlabel
property.ylabel – If provided, overrides the value of the
ylabel
property.plotArgs – Remaining arguments passed to the
__drawOneDataSeries()
method.
-
_PlotPanel__drawOneDataSeries
(ds, xdata, ydata, **plotArgs)¶ Plots a single
DataSeries
instance. This method is called by thedrawDataSeries()
method.- Parameters
ds – The
DataSeries
instance.xdata – X axis data.
ydata – Y axis data.
plotArgs – May be used to customise the plot - these arguments are all passed through to the
Axis.plot
function.
-
__module__
= 'fsleyes.views.plotpanel'¶
-
class
fsleyes.views.plotpanel.
OverlayPlotPanel
(*args, **kwargs)¶ Bases:
fsleyes.views.plotpanel.PlotPanel
The
OverlayPlotPanel
is aPlotPanel
which contains some extra logic for creating, storing, and drawingDataSeries
instances for each overlay in theOverlayList
.Subclass requirements
Sub-classes must:
Implement the
createDataSeries()
method, so it creates aDataSeries
instance for a specified overlay.Implement the
PlotPanel.draw()
method so it calls thePlotPanel.drawDataSeries()
, passingDataSeries
instances for all overlays whereDisplay.enabled
isTrue
.Optionally implement the
prepareDataSeries()
method to perform any custom preprocessing.
The internal data series store
The
OverlayPlotPanel
maintains a store ofDataSeries
instances, one for each compatible overlay in theOverlayList
. TheOverlayPlotPanel
manages the property listeners that must be registered with each of theseDataSeries
to refresh the plot. These instances are created by thecreateDataSeries()
method, which is implemented by sub-classes. The following methods are available to sub-classes, for managing the internal store ofDataSeries
instances:Returns the
DataSeries
instance associated with the specified overlay, orNone
if there is noDataSeries
instance.Convenience method which returns a list of overlays which have
DataSeries
that should be plotted.Destroys the internally cached
DataSeries
for the given overlay.Makes sure that a
DataSeries
instance has been created for every compatible overlay, and that property listeners are correctly registered, so the plot can be refreshed when needed.Every
DataSeries
which is currently plotted, and has not been added to thePlotPanel.dataSeries
list, is added to said list.Removes the most recently added
DataSeries
from thisOverlayPlotPanel
.Proxy images
The
OverlayPlotPanel
will replace allProxyImage
instances with their base images. This functionality was originally added to support theHistogramSeries.showOverlay
functionality - it adds a mask image to theOverlayList
to display the histogram range. Sub-classes may wish to adhere to the same logic (replacingProxyImage
instances with their bases)Control panels
The
PlotControlPanel
,PlotListPanel
, andOverlayListPanel
are FSLeyes control panels which work with theOverlayPlotPanel
. ThePlotControlPanel
is not intended to be used directly - plot-specific sub-classes are used instead. The following actions can be used to toggle control panels on anOverlayPlotPanel
:Shows/hides an
OverlayListPanel
.Shows/hides a
PlotListPanel
.Sub-classes
The
OverlayPlotPanel
is the base class for:The
TimeSeriesPanel
is anOverlayPlotPanel
which plots time series data from overlays.An
OverlayPlotPanel
which plots histograms fromImage
overlay data.The
PowerSpectrumPanel
class is anOverlayPlotPanel
which plots power spectra of overlay data.-
_OverlayPlotPanel__dataSeriesChanged
(*a)¶ Called when the
dataSeries
list changes. Enables/disables theremoveDataSeries()
action accordingly.
-
_OverlayPlotPanel__overlayListChanged
(*a, **kwa)¶ Called when the
OverlayList
changes. Makes sure that there are noDataSeries
instances in thePlotPanel.dataSeries
list, or in the internal cache, which refer to overlays that no longer exist.- Parameters
initialState – Must be passed as a keyword argument. If provided, passed through to the
updateDataSeries()
method.
-
__module__
= 'fsleyes.views.plotpanel'¶
-
plotColours
= {}¶ This dictionary is used to store a collection of
{overlay : colour}
mappings. It is shared across allOverlayPlotPanel
instances, so that the same (initial) colour is used for the same overlay, across multiple plots.Sub-classes should use the
getOverlayPlotColour()
method to retrieve the initial colour to use for a given overlay.
-
__init__
(*args, **kwargs)¶ Create an
OverlayPlotPanel
.- Parameters
initialState – Must be passed as a keyword argument. Allows you to specify the initial enabled/disabled state for each overlay. See
updateDataSeries()
. If not provided, only the data series for the currently selected overlay is shown (if possible).
All other argumenst are passed through to
PlotPanel.__init__()
.
-
destroy
()¶ Must be called when this
OverlayPlotPanel
is no longer needed. Removes some property listeners, and callsPlotPanel.destroy()
.
-
getDataSeriesToPlot
()¶ Convenience method which returns a list of overlays which have
DataSeries
that should be plotted.
-
getDataSeries
(overlay)¶ Returns the
DataSeries
instance associated with the specified overlay, orNone
if there is noDataSeries
instance.
-
getOverlayPlotColour
(overlay)¶ Returns an initial colour to use for plots associated with the given overlay. If a colour is present in the
plotColours
dictionary, it is returned. Otherwise a random colour is generated, added toplotColours
, and returned.
-
addDataSeries
()¶ Every
DataSeries
which is currently plotted, and has not been added to thePlotPanel.dataSeries
list, is added to said list.
-
removeDataSeries
(*a)¶ Removes the most recently added
DataSeries
from thisOverlayPlotPanel
.
-
createDataSeries
(overlay)¶ This method must be implemented by sub-classes. It must create and return a
DataSeries
instance for the specified overlay.Note
Sub-class implementations should set the
DataSeries.colour
property to that returned by thegetOverlayPlotColour()
method.Different
DataSeries
types need to be re-drawn when different properties change. For example, aVoxelTimeSeries`
instance needs to be redrawn when theDisplayContext.location
property changes, whereas aMelodicTimeSeries
instance needs to be redrawn when theVolumeOpts.volume
property changes.Therefore, in addition to creating and returning a
DataSeries
instance for the given overlay, sub-class implementations must also specify the properties which affect the state of theDataSeries
instance. These must be specified as two lists:the targets list, a list of objects which own the dependant properties (e.g. the
DisplayContext
orVolumeOpts
instance).The properties list, a list of names, each specifying the property on the corresponding target.
This method must therefore return a tuple containing:
A
DataSeries
instance, orNone
if the overlay is incompatible.A list of target instances.
A list of property names.
The target and property name lists must have the same length.
-
clearDataSeries
(overlay)¶ Destroys the internally cached
DataSeries
for the given overlay.
-
updateDataSeries
(initialState=None)¶ Makes sure that a
DataSeries
instance has been created for every compatible overlay, and that property listeners are correctly registered, so the plot can be refreshed when needed.- Parameters
initialState – If provided, must be a
dict
of{ overlay : bool }
mappings, specifying the initial value of theDataSeries.enabled
property for newly created instances. If not provided, only the data series for the currently selected overlay (if it has been newly added) is initially enabled.
-
toggleOverlayList
()¶ Shows/hides an
OverlayListPanel
. SeeViewPanel.togglePanel()
.
-
togglePlotList
(floatPane=False)¶ Shows/hides a
PlotListPanel
. SeeViewPanel.togglePanel()
.