Skip to content
Snippets Groups Projects
Commit ee993e1d authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Improved log scale plotting, and added neato option to apply smoothing

to time courses. Improved time series control panel layout too.
parent b63336bc
No related branches found
No related tags found
No related merge requests found
...@@ -203,8 +203,9 @@ labels = TypeDict({ ...@@ -203,8 +203,9 @@ labels = TypeDict({
'TimeSeriesControlPanel.xlim' : 'X limits', 'TimeSeriesControlPanel.xlim' : 'X limits',
'TimeSeriesControlPanel.ylim' : 'Y limits', 'TimeSeriesControlPanel.ylim' : 'Y limits',
'TimeSeriesControlPanel.xlabel' : 'X label', 'TimeSeriesControlPanel.labels' : 'Labels',
'TimeSeriesControlPanel.ylabel' : 'Y label', 'TimeSeriesControlPanel.xlabel' : 'X',
'TimeSeriesControlPanel.ylabel' : 'Y',
}) })
...@@ -247,6 +248,7 @@ properties = TypeDict({ ...@@ -247,6 +248,7 @@ properties = TypeDict({
'TimeSeriesPanel.legend' : 'Show legend', 'TimeSeriesPanel.legend' : 'Show legend',
'TimeSeriesPanel.ticks' : 'Show ticks', 'TimeSeriesPanel.ticks' : 'Show ticks',
'TimeSeriesPanel.grid' : 'Show grid', 'TimeSeriesPanel.grid' : 'Show grid',
'TimeSeriesPanel.smooth' : 'Smooth data',
'TimeSeriesPanel.autoScale' : 'Auto-scale', 'TimeSeriesPanel.autoScale' : 'Auto-scale',
'TimeSeriesPanel.xLogScale' : 'Log scale (x axis)', 'TimeSeriesPanel.xLogScale' : 'Log scale (x axis)',
'TimeSeriesPanel.yLogScale' : 'Log scale (y axis)', 'TimeSeriesPanel.yLogScale' : 'Log scale (y axis)',
...@@ -355,7 +357,7 @@ choices = TypeDict({ ...@@ -355,7 +357,7 @@ choices = TypeDict({
'ColourBarCanvas.orientation.horizontal' : 'Horizontal', 'ColourBarCanvas.orientation.horizontal' : 'Horizontal',
'ColourBarCanvas.orientation.vertical' : 'Vertical', 'ColourBarCanvas.orientation.vertical' : 'Vertical',
'ColourBarCanvas.labelSide.top-left' : 'Top / Left', 'ColourBarCanvas.labelSide.top-left' : 'Top / Left',
'ColourBarCanvas.labelSide.bottom-right' : 'Bottom / Right', 'ColourBarCanvas.labelSide.bottom-right' : 'Bottom / Right',
'VolumeOpts.displayRange.min' : 'Min.', 'VolumeOpts.displayRange.min' : 'Min.',
......
...@@ -25,6 +25,7 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel): ...@@ -25,6 +25,7 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel):
self.__usePixdim = props.makeWidget(self, tsPanel, 'usePixdim') self.__usePixdim = props.makeWidget(self, tsPanel, 'usePixdim')
self.__logx = props.makeWidget(self, tsPanel, 'xLogScale') self.__logx = props.makeWidget(self, tsPanel, 'xLogScale')
self.__logy = props.makeWidget(self, tsPanel, 'yLogScale') self.__logy = props.makeWidget(self, tsPanel, 'yLogScale')
self.__smooth = props.makeWidget(self, tsPanel, 'smooth')
self.__legend = props.makeWidget(self, tsPanel, 'legend') self.__legend = props.makeWidget(self, tsPanel, 'legend')
self.__ticks = props.makeWidget(self, tsPanel, 'ticks') self.__ticks = props.makeWidget(self, tsPanel, 'ticks')
self.__grid = props.makeWidget(self, tsPanel, 'grid') self.__grid = props.makeWidget(self, tsPanel, 'grid')
...@@ -38,6 +39,7 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel): ...@@ -38,6 +39,7 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel):
self.__ymin = props.makeWidget(self, tsPanel, 'ymin') self.__ymin = props.makeWidget(self, tsPanel, 'ymin')
self.__ymax = props.makeWidget(self, tsPanel, 'ymax') self.__ymax = props.makeWidget(self, tsPanel, 'ymax')
self.__lblLabel = wx.StaticText(self)
self.__xlblLabel = wx.StaticText(self) self.__xlblLabel = wx.StaticText(self)
self.__ylblLabel = wx.StaticText(self) self.__ylblLabel = wx.StaticText(self)
self.__xlimLabel = wx.StaticText(self) self.__xlimLabel = wx.StaticText(self)
...@@ -47,42 +49,56 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel): ...@@ -47,42 +49,56 @@ class TimeSeriesControlPanel(fslpanel.FSLViewPanel):
self.__usePixdim.SetLabel(strings.properties[tsPanel, 'usePixdim']) self.__usePixdim.SetLabel(strings.properties[tsPanel, 'usePixdim'])
self.__logx .SetLabel(strings.properties[tsPanel, 'xLogScale']) self.__logx .SetLabel(strings.properties[tsPanel, 'xLogScale'])
self.__logy .SetLabel(strings.properties[tsPanel, 'yLogScale']) self.__logy .SetLabel(strings.properties[tsPanel, 'yLogScale'])
self.__smooth .SetLabel(strings.properties[tsPanel, 'smooth'])
self.__legend .SetLabel(strings.properties[tsPanel, 'legend']) self.__legend .SetLabel(strings.properties[tsPanel, 'legend'])
self.__ticks .SetLabel(strings.properties[tsPanel, 'ticks']) self.__ticks .SetLabel(strings.properties[tsPanel, 'ticks'])
self.__grid .SetLabel(strings.properties[tsPanel, 'grid']) self.__grid .SetLabel(strings.properties[tsPanel, 'grid'])
self.__autoScale.SetLabel(strings.properties[tsPanel, 'autoScale']) self.__autoScale.SetLabel(strings.properties[tsPanel, 'autoScale'])
self.__xlimLabel.SetLabel(strings.labels[ self, 'xlim']) self.__xlimLabel.SetLabel(strings.labels[ self, 'xlim'])
self.__ylimLabel.SetLabel(strings.labels[ self, 'ylim']) self.__ylimLabel.SetLabel(strings.labels[ self, 'ylim'])
self.__lblLabel .SetLabel(strings.labels[ self, 'labels'])
self.__xlblLabel.SetLabel(strings.labels[ self, 'xlabel']) self.__xlblLabel.SetLabel(strings.labels[ self, 'xlabel'])
self.__ylblLabel.SetLabel(strings.labels[ self, 'ylabel']) self.__ylblLabel.SetLabel(strings.labels[ self, 'ylabel'])
self.__sizer = wx.GridSizer(10, 2) self.__sizer = wx.GridSizer(6, 3)
self.SetSizer(self.__sizer) self.SetSizer(self.__sizer)
self.__xlblSizer = wx.BoxSizer(wx.HORIZONTAL)
self.__xlblSizer.Add(self.__xlblLabel)
self.__xlblSizer.Add(self.__xlabel, flag=wx.EXPAND, proportion=1)
self.__ylblSizer = wx.BoxSizer(wx.HORIZONTAL)
self.__ylblSizer.Add(self.__ylblLabel)
self.__ylblSizer.Add(self.__ylabel, flag=wx.EXPAND, proportion=1)
self.__sizer.Add(self.__demean, flag=wx.EXPAND) self.__sizer.Add(self.__demean, flag=wx.EXPAND)
self.__sizer.Add(self.__usePixdim, flag=wx.EXPAND) self.__sizer.Add(self.__usePixdim, flag=wx.EXPAND)
self.__sizer.Add(self.__smooth, flag=wx.EXPAND)
self.__sizer.Add(self.__logx, flag=wx.EXPAND) self.__sizer.Add(self.__logx, flag=wx.EXPAND)
self.__sizer.Add(self.__logy, flag=wx.EXPAND) self.__sizer.Add(self.__logy, flag=wx.EXPAND)
self.__sizer.Add(self.__legend, flag=wx.EXPAND) self.__sizer.Add(self.__legend, flag=wx.EXPAND)
self.__sizer.Add(self.__ticks, flag=wx.EXPAND) self.__sizer.Add(self.__ticks, flag=wx.EXPAND)
self.__sizer.Add(self.__grid, flag=wx.EXPAND) self.__sizer.Add(self.__grid, flag=wx.EXPAND)
self.__sizer.Add(self.__autoScale, flag=wx.EXPAND) self.__sizer.Add(self.__autoScale, flag=wx.EXPAND)
self.__sizer.Add(self.__xlblLabel, flag=wx.EXPAND)
self.__sizer.Add(self.__ylblLabel, flag=wx.EXPAND) self.__sizer.Add(self.__lblLabel, flag=wx.EXPAND)
self.__sizer.Add(self.__xlabel, flag=wx.EXPAND) self.__sizer.Add(self.__xlblSizer, flag=wx.EXPAND)
self.__sizer.Add(self.__ylabel, flag=wx.EXPAND) self.__sizer.Add(self.__ylblSizer, flag=wx.EXPAND)
self.__sizer.Add(self.__xlimLabel, flag=wx.EXPAND) self.__sizer.Add(self.__xlimLabel, flag=wx.EXPAND)
self.__sizer.Add((-1, -1), flag=wx.EXPAND)
self.__sizer.Add(self.__xmin, flag=wx.EXPAND) self.__sizer.Add(self.__xmin, flag=wx.EXPAND)
self.__sizer.Add(self.__xmax, flag=wx.EXPAND) self.__sizer.Add(self.__xmax, flag=wx.EXPAND)
self.__sizer.Add(self.__ylimLabel, flag=wx.EXPAND) self.__sizer.Add(self.__ylimLabel, flag=wx.EXPAND)
self.__sizer.Add((-1, -1), flag=wx.EXPAND)
self.__sizer.Add(self.__ymin, flag=wx.EXPAND) self.__sizer.Add(self.__ymin, flag=wx.EXPAND)
self.__sizer.Add(self.__ymax, flag=wx.EXPAND) self.__sizer.Add(self.__ymax, flag=wx.EXPAND)
self.Layout() self.Layout()
self.SetMinSize(self.__sizer.GetMinSize()) self.SetMinSize(self.__sizer.GetMinSize())
self.SetMaxSize(self.__sizer.GetMinSize())
tsPanel.addListener('autoScale', self._name, self.__autoScaleChanged) tsPanel.addListener('autoScale', self._name, self.__autoScaleChanged)
......
...@@ -133,7 +133,7 @@ class TimeSeriesListPanel(fslpanel.FSLViewPanel): ...@@ -133,7 +133,7 @@ class TimeSeriesListPanel(fslpanel.FSLViewPanel):
return return
ts.alpha = 1 ts.alpha = 1
ts.lineWidth = 1 ts.lineWidth = 2
ts.lineStyle = '-' ts.lineStyle = '-'
ts.colour = fslcm.randomColour() ts.colour = fslcm.randomColour()
ts.label = self.__makeLabel(ts) ts.label = self.__makeLabel(ts)
......
...@@ -15,6 +15,7 @@ of overlay objects stored in an :class:`.OverlayList`. ...@@ -15,6 +15,7 @@ of overlay objects stored in an :class:`.OverlayList`.
import logging import logging
import wx import wx
import scipy.interpolate as interp
import numpy as np import numpy as np
import props import props
...@@ -66,6 +67,7 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -66,6 +67,7 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
yLogScale = props.Boolean(default=False) yLogScale = props.Boolean(default=False)
ticks = props.Boolean(default=True) ticks = props.Boolean(default=True)
grid = props.Boolean(default=True) grid = props.Boolean(default=True)
smooth = props.Boolean(default=False)
xlabel = props.String() xlabel = props.String()
ylabel = props.String() ylabel = props.String()
xmin = props.Real() xmin = props.Real()
...@@ -239,21 +241,9 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -239,21 +241,9 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
xlims.append(xlim) xlims.append(xlim)
ylims.append(ylim) ylims.append(ylim)
if self.xLogScale: axis.set_xscale('log') (xmin, xmax), (ymin, ymax) = self.__calcLimits(xlims, ylims)
else: axis.set_xscale('linear')
if self.yLogScale: axis.set_yscale('log')
else: axis.set_yscale('linear')
xlim, ylim = self.__calcLimits(xlims, ylims)
bPad = (ylim[1] - ylim[0]) * (50.0 / height)
tPad = (ylim[1] - ylim[0]) * (20.0 / height)
lPad = (xlim[1] - xlim[0]) * (50.0 / width)
rPad = (xlim[1] - xlim[0]) * (20.0 / width)
axis.set_xlim((xlim[0] - lPad, xlim[1] + rPad))
axis.set_ylim((ylim[0] - bPad, ylim[1] + tPad))
# x/y axis labels
xlabel = self.xlabel xlabel = self.xlabel
ylabel = self.ylabel ylabel = self.ylabel
...@@ -271,9 +261,10 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -271,9 +261,10 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
axis.set_ylabel(self.ylabel, va='top') axis.set_ylabel(self.ylabel, va='top')
axis.yaxis.set_label_coords(10.0 / width, 0.5) axis.yaxis.set_label_coords(10.0 / width, 0.5)
# Ticks
if self.ticks: if self.ticks:
xticks = np.linspace(xlim[0], xlim[1], 4) xticks = np.linspace(xmin, xmax, 4)
yticks = np.linspace(ylim[0], ylim[1], 4) yticks = np.linspace(ymin, ymax, 4)
axis.tick_params(direction='in', pad=-5) axis.tick_params(direction='in', pad=-5)
...@@ -289,6 +280,15 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -289,6 +280,15 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
axis.set_xticks([]) axis.set_xticks([])
axis.set_yticks([]) axis.set_yticks([])
# Limits
bPad = (ymax - ymin) * (50.0 / height)
tPad = (ymax - ymin) * (20.0 / height)
lPad = (xmax - xmin) * (50.0 / width)
rPad = (xmax - xmin) * (20.0 / width)
axis.set_xlim((xmin - lPad, xmax + rPad))
axis.set_ylim((ymin - bPad, ymax + tPad))
# legend - don't show if we're only # legend - don't show if we're only
# plotting the current location # plotting the current location
if len(self.timeSeries) > 0 and self.legend: if len(self.timeSeries) > 0 and self.legend:
...@@ -300,7 +300,6 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -300,7 +300,6 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
fancybox=True) fancybox=True)
legend.get_frame().set_alpha(0.3) legend.get_frame().set_alpha(0.3)
if self.grid: if self.grid:
axis.grid() axis.grid()
...@@ -312,14 +311,29 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -312,14 +311,29 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
if ts.alpha == 0: if ts.alpha == 0:
return (0, 0), (0, 0) return (0, 0), (0, 0)
ydata = ts.data
ydata = np.array(ts.data, dtype=np.float32)
npoints = len(ydata)
if self.demean: if self.demean:
ydata = ydata - ydata.mean() ydata = ydata - ydata.mean()
if self.usePixdim: xdata = np.arange(len(ydata)) * ts.overlay.pixdim[3] if self.smooth:
else: xdata = np.arange(len(ydata)) tck = interp.splrep(np.arange(npoints), ydata)
ydata = interp.splev(np.linspace(0, npoints - 1, 5 * npoints), tck)
xdata = np.linspace(0, npoints - 1, len(ydata), dtype=np.float32)
if self.usePixdim:
xdata *= ts.overlay.pixdim[3]
if self.xLogScale: xdata = np.log10(xdata)
if self.yLogScale: ydata = np.log10(ydata)
nans = ~(np.isfinite(xdata) & np.isfinite(ydata))
xdata[nans] = np.nan
ydata[nans] = np.nan
kwargs = {} kwargs = {}
kwargs['lw'] = ts.lineWidth kwargs['lw'] = ts.lineWidth
...@@ -330,5 +344,5 @@ class TimeSeriesPanel(plotpanel.PlotPanel): ...@@ -330,5 +344,5 @@ class TimeSeriesPanel(plotpanel.PlotPanel):
self.getAxis().plot(xdata, ydata, **kwargs) self.getAxis().plot(xdata, ydata, **kwargs)
return ((xdata.min(), xdata.max()), return ((np.nanmin(xdata), np.nanmax(xdata)),
(ydata.min(), ydata.max())) (np.nanmin(ydata), np.nanmax(ydata)))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment