def plot_spectral_analysis_raster(self, time_series, freq=None, spectral_options={}, special_idx=[], labels=[], title='Spectral Analysis', figure_name=None, figsize=None, **kwargs): if isinstance(time_series, TimeSeries): return self.plot_ts_spectral_analysis_raster( numpy.swapaxes(time_series.data, 1, 2).squeeze(), time_series.time, time_series.time_unit, freq, spectral_options, special_idx, labels, title, figure_name, figsize) elif isinstance(time_series, (numpy.ndarray, dict, list, tuple)): time = kwargs.get("time", None) return self.plot_ts_spectral_analysis_raster( time_series, time=time, freq=freq, spectral_options=spectral_options, special_idx=special_idx, labels=labels, title=title, figure_name=figure_name, figsize=figsize) else: raise_value_error( "Input time_series: %s \n" "is not on of one of the following types: [TimeSeries (tvb-contrib), " "TimeSeries (tvb-library), numpy.ndarray, dict]" % str(time_series), LOGGER)
def normalize_signals(signals, normalization=None, axis=None, percent=None): # Following pylab demean: def matrix_subtract_along_axis(x, y, axis=0): "Return x minus y, where y corresponds to some statistic of x along the specified axis" if axis == 0 or axis is None or x.ndim <= 1: return x - y ind = [slice(None)] * x.ndim ind[axis] = np.newaxis return x - y[ind] def matrix_divide_along_axis(x, y, axis=0): "Return x divided by y, where y corresponds to some statistic of x along the specified axis" if axis == 0 or axis is None or x.ndim <= 1: return x / y ind = [slice(None)] * x.ndim ind[axis] = np.newaxis return x / y[ind] for norm, ax, prcnd in zip(ensure_list(normalization), cycle(ensure_list(axis)), cycle(ensure_list(percent))): if isinstance(norm, string_types): if isequal_string(norm, "zscore"): signals = zscore(signals, axis=ax) # / 3.0 elif isequal_string(norm, "baseline-std"): signals = normalize_signals(["baseline", "std"], axis=axis) elif norm.find("baseline") == 0 and norm.find("amplitude") >= 0: signals = normalize_signals(signals, ["baseline", norm.split("-")[1]], axis=axis, percent=percent) elif isequal_string(norm, "minmax"): signals = normalize_signals(signals, ["min", "max"], axis=axis) elif isequal_string(norm, "mean"): signals = demean(signals, axis=ax) elif isequal_string(norm, "baseline"): if prcnd is None: prcnd = 1 signals = matrix_subtract_along_axis(signals, np.percentile(signals, prcnd, axis=ax), axis=ax) elif isequal_string(norm, "min"): signals = matrix_subtract_along_axis(signals, np.min(signals, axis=ax), axis=ax) elif isequal_string(norm, "max"): signals = matrix_divide_along_axis(signals, np.max(signals, axis=ax), axis=ax) elif isequal_string(norm, "std"): signals = matrix_divide_along_axis(signals, signals.std(axis=ax), axis=ax) elif norm.find("amplitude") >= 0: if prcnd is None: prcnd = [1, 99] amplitude = np.percentile(signals, prcnd[1], axis=ax) - np.percentile(signals, prcnd[0], axis=ax) this_ax = ax if isequal_string(norm.split("amplitude")[0], "max"): amplitude = amplitude.max() this_ax = None elif isequal_string(norm.split("amplitude")[0], "mean"): amplitude = amplitude.mean() this_ax = None signals = matrix_divide_along_axis(signals, amplitude, axis=this_ax) else: raise_value_error("Ignoring signals' normalization " + normalization + ",\nwhich is not one of the currently available " + str(NORMALIZATION_METHODS) + "!", logger) return signals
def plot_time_series(self, time_series, mode="ts", subplots=None, special_idx=[], subtitles=[], offset=0.5, title=None, figure_name=None, figsize=None, **kwargs): if isinstance(time_series, TimeSeries): self.plot_tvb_time_series(time_series, mode, subplots, special_idx, subtitles, offset, title, figure_name, figsize) elif isinstance(time_series, (numpy.ndarray, dict, list, tuple)): time = kwargs.get("time", None) time_unit = kwargs.get("time_unit", "ms") labels = kwargs.get("labels", []) var_labels = kwargs.get("var_labels", []) if title is None: title = "Time Series" return self.plot_ts(time_series, time=time, mode=mode, time_unit=time_unit, labels=labels, var_labels=var_labels, subplots=subplots, special_idx=special_idx, subtitles=subtitles, offset=offset, title=title, figure_name=figure_name, figsize=figsize) else: raise_value_error( "Input time_series: %s \n" "is not on of one of the following types: [TimeSeries " "(tvb-contrib), TimeSeries (tvb-library), numpy.ndarray, dict]" % str(time_series), LOGGER)
def plot_time_series_interactive(self, time_series, first_n=-1, **kwargs): if isinstance(time_series, TimeSeries): self.plot_tvb_time_series_interactive(time_series, first_n, **kwargs) elif isinstance(time_series, numpy.ndarray): self.plot_tvb_time_series_interactive(TimeSeries(data=time_series), first_n, **kwargs) elif isinstance(time_series, (list, tuple)): self.plot_tvb_time_series_interactive( TimeSeries(data=TimeSeries( data=numpy.stack(time_series, axis=1))), first_n, **kwargs) elif isinstance(time_series, dict): ts = numpy.stack(time_series.values(), axis=1) time_series = TimeSeries( data=ts, labels_dimensions={"State Variable": time_series.keys()}) self.plot_tvb_time_series_interactive(time_series, first_n, **kwargs) else: raise_value_error( "Input time_series: %s \n" "is not on of one of the following types: [TimeSeries " "(tvb-contrib), TimeSeriesTVB (tvb-library), numpy.ndarray, dict, list, tuple]" % str(time_series), LOGGER)
def from_folder(cls, path=None, head=None, **kwargs): # TODO confirm the filetypes and add (h5 and other) readers to all TVB classes .from_file methods # Default patterns: # *conn* for zip/h5 files # (*cort/subcort*)surf*(*cort/subcort*) / (*cort/subcort*)srf*(*cort/subcort*) for zip/h5 files # (*cort/subcort*)reg*map(*cort/subcort*) for txt files # *map*vol* / *vol*map* for txt files # *t1/t2/flair/b0 for ??? files # *eeg/seeg/meg*sensors/locations* / *sensors/locations*eeg/seeg/meg for txt files # # *eeg/seeg/meg*proj/gain* / *proj/gain*eeg/seeg/meg for npy/mat used_filepaths = [] if head is None: head = Head() head.path = path title = os.path.basename(path) if len(title) > 0: head.title = title # We need to read local_connectivity first to avoid confusing it with connectivity: head.local_connectivity, kwargs = \ head._load_reference(LocalConnectivity, 'local_connectivity', ["loc*conn", "conn*loc"], used_filepaths, **kwargs) # Connectivity is required # conn_instances connectivity, kwargs = \ head._load_reference(Connectivity, "connectivity", ["conn"], used_filepaths, **kwargs) if connectivity is None: raise_value_error("A Connectivity instance is minimally required for a Head instance!", cls.log) head.connectivity = connectivity # TVB only volume datatypes: do before region_mappings to avoid confusing them with volume_mapping structural = None for datatype, arg_name, patterns in zip([B0, Flair, T2, T1], ["b0", "flair", "t2", "t1", ], [["b0"], ["flair"], ["t2"], ["t1"]]): try: datatype.from_file instance, kwargs = head._load_reference(datatype, arg_name, patterns, used_filepaths, **kwargs) except: cls.log.warning("No 'from_file' method yet for %s!" % datatype.__class__.__name__) instance = None if instance is not None: setattr(head, arg_name, instance) volume_instance = instance if structural is not None: head.region_volume_mapping, kwargs = \ head._load_reference(RegionVolumeMapping, "region_volume_mapping", ["vol*map", "map*vol"], used_filepaths, **kwargs) # Surfaces and mappings # (read subcortical ones first to avoid confusion): head.subcortical_surface, kwargs = \ head._load_reference(SubcorticalSurface, "subcortical_surface", ["subcort*surf", "surf*subcort", "subcort*srf", "srf*subcort"], used_filepaths, **kwargs) if head.subcortical_surface is not None: # Region Mapping requires Connectivity and Surface head.subcortical_region_mapping, kwargs = \ head._load_reference(SubcorticalRegionMapping, "subcortical_region_mapping", ["subcort*reg*map", "reg*map*subcort"], used_filepaths, **kwargs) head.cortical_surface, kwargs = \ head._load_reference(CorticalSurface, "cortical_surface", ["cort*surf", "surf*cort", "cort*srf", "srf*cort", "surf", "srf"], used_filepaths, **kwargs) if head.cortical_surface is not None: # Region Mapping requires Connectivity and Surface head.cortical_region_mapping, kwargs = \ head._load_reference(CorticalRegionMapping, "cortical_region_mapping", ["cort*reg*map", "reg*map*cort", "reg*map"], used_filepaths, **kwargs) # Sensors and projections # (read seeg before eeg to avoid confusion!) for s_datatype, p_datatype, s_type in zip([SensorsSEEG, SensorsEEG, SensorsMEG], [ProjectionSurfaceSEEG, ProjectionSurfaceEEG, ProjectionSurfaceMEG], ["seeg", "eeg", "meg"]): arg_name = "%s_sensors" % s_type patterns = ["%s*sensors" % s_type, "sensors*%s" % s_type, "%s*locations" % s_type, "locations*%s" % s_type] sensors, kwargs = head._load_reference(s_datatype, arg_name, patterns, used_filepaths, **kwargs) if sensors is not None: setattr(head, arg_name, sensors) arg_name = "%s_projection" % s_type patterns = ["%s*proj" % s_type, "proj*%s" % s_type, "%s*gain" % s_type, "gain*%s" % s_type] projection, kwargs = head._load_reference(p_datatype, arg_name, patterns, used_filepaths, **kwargs) setattr(head, arg_name, projection) return head
def plot_ts(self, data, time=None, var_labels=[], mode="ts", subplots=None, special_idx=[], subtitles=[], labels=[], offset=0.5, time_unit="ms", title='Time series', figure_name=None, figsize=None): if not isinstance(figsize, (list, tuple)): figsize = self.config.LARGE_SIZE if isinstance(data, dict): var_labels = data.keys() data = data.values() elif isinstance(data, numpy.ndarray): if len(data.shape) < 3: if len(data.shape) < 2: data = numpy.expand_dims(data, 1) data = numpy.expand_dims(data, 2) data = [data] else: # Assuming a structure of Time X Space X Variables X Samples data = [ data[:, :, iv].squeeze() for iv in range(data.shape[2]) ] elif isinstance(data, (list, tuple)): data = ensure_list(data) else: raise_value_error( "Input timeseries: %s \n" "is not on of one of the following types: " "[numpy.ndarray, dict, list, tuple]" % str(data), LOGGER) n_vars = len(data) data_lims = [] for id, d in enumerate(data): if isequal_string(mode, "raster"): data[id] = (d - d.mean(axis=0)) drange = numpy.max(data[id].max(axis=0) - data[id].min(axis=0)) data[id] = data[id] / drange # zscore(d, axis=None) data_lims.append([d.min(), d.max()]) data_shape = data[0].shape if len(data_shape) == 1: n_times = data_shape[0] nTS = 1 for iV in range(n_vars): data[iV] = data[iV][:, numpy.newaxis] else: n_times, nTS = data_shape[:2] if len(data_shape) > 2: nSamples = data_shape[2] else: nSamples = 1 if special_idx is None: special_idx = [] n_special_idx = len(special_idx) if len(subtitles) == 0: subtitles = var_labels if isinstance(labels, list) and len(labels) == n_vars: labels = [ generate_region_labels(nTS, label, ". ", self.print_ts_indices) for label in labels ] else: labels = [ generate_region_labels(nTS, labels, ". ", self.print_ts_indices) for _ in range(n_vars) ] if isequal_string(mode, "traj"): data_fun, plot_lines, projection, n_rows, n_cols, def_alpha, loopfun, \ subtitle, subtitle_col, axlabels, axlimits = \ self._trajectories_plot(n_vars, nTS, nSamples, subplots) else: if isequal_string(mode, "raster"): data_fun, time, plot_lines, projection, n_rows, n_cols, def_alpha, loopfun, \ subtitle, subtitle_col, axlabels, axlimits, axYticks = \ self._ts_plot(time, n_vars, nTS, n_times, time_unit, 0, offset, data_lims) else: data_fun, time, plot_lines, projection, n_rows, n_cols, def_alpha, loopfun, \ subtitle, subtitle_col, axlabels, axlimits, axYticks = \ self._ts_plot(time, n_vars, nTS, n_times, time_unit, ensure_list(subplots)[0]) alpha_ratio = 1.0 / nSamples alphas = numpy.maximum( numpy.array([def_alpha] * nTS) * alpha_ratio, 0.1) alphas[special_idx] = numpy.maximum(alpha_ratio, 0.1) if isequal_string(mode, "traj") and (n_cols * n_rows > 1): colors = numpy.zeros((nTS, 4)) colors[special_idx] = \ numpy.array([numpy.array([1.0, 0, 0, 1.0]) for _ in range(n_special_idx)]).reshape((n_special_idx, 4)) else: cmap = matplotlib.cm.get_cmap('jet') colors = numpy.array([cmap(0.5 * iTS / nTS) for iTS in range(nTS)]) colors[special_idx] = \ numpy.array([cmap(1.0 - 0.25 * iTS / nTS) for iTS in range(n_special_idx)]).reshape((n_special_idx, 4)) colors[:, 3] = alphas lines = [] pyplot.figure(title, figsize=figsize) axes = [] for icol in range(n_cols): if n_rows == 1: # If there are no more rows, create axis, and set its limits, labels and possible subtitle axes += ensure_list( pyplot.subplot(n_rows, n_cols, icol + 1, projection=projection)) axlimits(data_lims, time, n_vars, icol) axlabels(labels[icol % n_vars], var_labels, n_vars, n_rows, 1, 0) pyplot.gca().set_title(subtitles[icol]) for iTS in loopfun(nTS, n_rows, icol): if n_rows > 1: # If there are more rows, create axes, and set their limits, labels and possible subtitles axes += ensure_list( pyplot.subplot(n_rows, n_cols, iTS + 1, projection=projection)) axlimits(data_lims, time, n_vars, icol) subtitle(labels[icol % n_vars], iTS) axlabels(labels[icol % n_vars], var_labels, n_vars, n_rows, (iTS % n_rows) + 1, iTS) lines += ensure_list( plot_lines(data_fun(data, time, icol), iTS, colors, labels[icol % n_vars])) if isequal_string( mode, "raster"): # set yticks as labels if this is a raster plot axYticks(labels[icol % n_vars], nTS) yticklabels = pyplot.gca().yaxis.get_ticklabels() self.tick_font_size = numpy.minimum( self.tick_font_size, int(numpy.round(self.tick_font_size * 100.0 / nTS))) for iTS in range(nTS): yticklabels[iTS].set_fontsize(self.tick_font_size) if iTS in special_idx: yticklabels[iTS].set_color(colors[iTS, :3].tolist() + [1]) pyplot.gca().yaxis.set_ticklabels(yticklabels) pyplot.gca().invert_yaxis() if self.config.MOUSE_HOOVER: for line in lines: self.HighlightingDataCursor(line, formatter='{label}'.format, bbox=dict(fc='white'), arrowprops=dict( arrowstyle='simple', fc='white', alpha=0.5)) self._save_figure(pyplot.gcf(), figure_name) self._check_show() return pyplot.gcf(), axes, lines
def _trajectories_plot(self, n_dims, nTS, nSamples, subplots): data_fun = lambda data, time, icol: data def plot_traj_2D(x, iTS, colors, labels): x, y = x try: return pyplot.plot(x[:, iTS], y[:, iTS], color=colors[iTS], label=labels[iTS], **self.line_format) except: self.logger.warning( "Cannot convert labels' strings for line labels!") return pyplot.plot(x[:, iTS], y[:, iTS], color=colors[iTS], label=str(iTS), **self.line_format) def plot_traj_3D(x, iTS, colors, labels): x, y, z = x try: return pyplot.plot(x[:, iTS], y[:, iTS], z[:, iTS], color=colors[iTS], label=labels[iTS], **self.line_format) except: self.logger.warning( "Cannot convert labels' strings for line labels!") return pyplot.plot(x[:, iTS], y[:, iTS], z[:, iTS], color=colors[iTS], label=str(iTS), **self.line_format) def subtitle_traj(labels, iTS): try: if self.print_ts_indices: pyplot.gca().set_title(str(iTS) + "." + labels[iTS]) else: pyplot.gca().set_title(labels[iTS]) except: self.logger.warning( "Cannot convert labels' strings for subplot titles!") pyplot.gca().set_title(str(iTS)) def axlabels_traj(vars, n_vars): pyplot.gca().set_xlabel(vars[0]) pyplot.gca().set_ylabel(vars[1]) if n_vars > 2: pyplot.gca().set_zlabel(vars[2]) def axlimits_traj(data_lims, n_vars): pyplot.gca().set_xlim([data_lims[0][0], data_lims[0][1]]) pyplot.gca().set_ylim([data_lims[1][0], data_lims[1][1]]) if n_vars > 2: pyplot.gca().set_zlim([data_lims[2][0], data_lims[2][1]]) if n_dims == 2: plot_lines = lambda x, iTS, colors, labels: \ plot_traj_2D(x, iTS, colors, labels) projection = None elif n_dims == 3: plot_lines = lambda x, iTS, colors, labels: \ plot_traj_3D(x, iTS, colors, labels) projection = '3d' else: raise_value_error( "Data dimensions are neigher 2D nor 3D!, but " + str(n_dims) + "D!", LOGGER) n_rows = 1 n_cols = 1 if subplots is None: # if nSamples > 1: n_rows = int(numpy.floor(numpy.sqrt(nTS))) n_cols = int(numpy.ceil((1.0 * nTS) / n_rows)) elif isinstance(subplots, (list, tuple)): n_rows = subplots[0] n_cols = subplots[1] if n_rows * n_cols < nTS: raise_value_error( "Not enough subplots for all time series:" "\nn_rows * n_cols = product(subplots) = product(" + str(subplots) + " = " + str(n_rows * n_cols) + "!", LOGGER) if n_rows * n_cols > 1: def_alpha = 0.5 subtitle = lambda labels, iTS: subtitle_traj(labels, iTS) subtitle_col = lambda subtitles, icol: None else: def_alpha = 1.0 subtitle = lambda labels, iTS: None subtitle_col = lambda subtitles, icol: pyplot.gca().set_title( pyplot.gcf().title) axlabels = lambda labels, vars, n_vars, n_rows, irow, iTS: axlabels_traj( vars, n_vars) axlimits = lambda data_lims, time, n_vars, icol: axlimits_traj( data_lims, n_vars) loopfun = lambda nTS, n_rows, icol: list(range(icol, nTS, n_rows)) return data_fun, plot_lines, projection, n_rows, n_cols, def_alpha, loopfun, \ subtitle, subtitle_col, axlabels, axlimits