def _plotTimeSeriesInEC(self, values, vmin=None, vmax=None, bb=(0.0, 1.0, 0.0, 1.0), file_name=None): # Plot time series in electrode coordinate system, i.e. the values of # each channel at the position of the channel import pylab ec = self.getMetadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # Define x and y coordinates of electrodes in the order of the channels # of data x = numpy.array([ec_2d[key][0] for key in self.channel_names]) y = numpy.array([ec_2d[key][1] for key in self.channel_names]) # Determine min and max values if vmin == None: vmin = values.min() if vmax == None: vmax = values.max() width = (bb[1] - bb[0]) height = (bb[3] - bb[2]) for channel_index, channel_name in enumerate(self.channel_names): ax = pylab.axes([x[channel_index]/(1.2*(x.max() - x.min()))*width + bb[0] + width/2 - 0.025, y[channel_index]/(1.2*(y.max() - y.min()))*height + bb[2] + height/2 - 0.0375, 0.05, 0.075]) ax.plot(values[channel_index, :], color='k', lw=1) ax.set_xticks([]) ax.set_yticks([]) ax.set_ylim((vmin, vmax)) ax.text(values.shape[1]/2, vmax*.8, channel_name, horizontalalignment='center', verticalalignment='center')
def _plot_spatial_values(ax, spatial_values, channel_names, title=""): # TODO: Move to common spatial filter superclass import pylab ec_2d = StreamDataset.project2d(StreamDataset.ec) # Define x and y coordinates of electrodes in the order of the channels # of data x = numpy.array([ec_2d[key][0] for key in channel_names]) y = numpy.array([ec_2d[key][1] for key in channel_names]) # define grid. xi = numpy.linspace(-150, 150, 100) yi = numpy.linspace(-125, 125, 100) # grid the data. try: zi = pylab.griddata(x, y, spatial_values, xi, yi) except RuntimeError: warnings.warn( "Natbib packackage is not available for interpolating a" " grid. Using linear interpolation instead.") zi = pylab.griddata(x, y, spatial_values, xi, yi, interpl='linear') # contour the gridded data, plotting dots at the nonuniform data points. ax.contour(xi, yi, zi, 15, linewidths=0.5, colors='k') CS = ax.contourf(xi, yi, zi, 15, cmap=pylab.cm.jet) cb = pylab.colorbar(CS, ax=ax) # plot data points. pylab.scatter(x, y, marker='o', c='b', s=5) # Add channel labels for label, position in ec_2d.iteritems(): if label in channel_names: ax.text(position[0], position[1], label, fontsize='x-small') ax.set_xlim(-125, 125) ax.set_ylim(-100, 100) ax.text(0, 80, title, fontweight='bold', horizontalalignment='center', verticalalignment='center')
def _plotTimeSeriesInEC(self, values, vmin=None, vmax=None, bb=(0.0, 1.0, 0.0, 1.0), file_name=None): # Plot time series in electrode coordinate system, i.e. the values of # each channel at the position of the channel import pylab ec = self.get_metadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # Define x and y coordinates of electrodes in the order of the channels # of data x = numpy.array([ec_2d[key][0] for key in self.channel_names]) y = numpy.array([ec_2d[key][1] for key in self.channel_names]) # Determine min and max values if vmin is None: vmin = values.min() if vmax is None: vmax = values.max() width = (bb[1] - bb[0]) height = (bb[3] - bb[2]) for channel_index, channel_name in enumerate(self.channel_names): ax = pylab.axes([ x[channel_index] / (1.2 * (x.max() - x.min())) * width + bb[0] + width / 2 - 0.025, y[channel_index] / (1.2 * (y.max() - y.min())) * height + bb[2] + height / 2 - 0.0375, 0.05, 0.075 ]) ax.plot(values[channel_index, :], color='k', lw=1) ax.set_xticks([]) ax.set_yticks([]) ax.set_ylim((vmin, vmax)) ax.text(values.shape[1] / 2, vmax * .8, channel_name, horizontalalignment='center', verticalalignment='center')
def _plotValues(self, values, #dict TimeSeries values plot_label, #str Plot-Label fig_num, #int Figure-number for classify plots # 1: average, # 2: single trial, # 3: average accumulating store_dir = None, #str Directory to store the plots counter=0): #int Plotcounter for all trials #compute sampling_frequency and classes to plot sampling_frequency = values[values.keys()[0]].sampling_frequency list_of_classes = values.keys() num_of_classes = len(list_of_classes) #autoscale color bar or use user scaling if self.limits: levels = self._compute_levels() else: levels = None #compute maximum and minimum for colorbar scaling if not existing vmax = float(max(numpy.array(v).max() for v in values.itervalues())) vmin = float(min(numpy.array(v).min() for v in values.itervalues())) levels = self._compute_levels(limits=[vmin, vmax]) #normalizer=matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) #computing time points to show num_tpoints = values.values()[0].shape[0] all_tpoints = numpy.arange(0, num_tpoints * (1000/sampling_frequency), 1000 / sampling_frequency ) + self.timeshift if self.time_stamps == [-1]: tpoints = all_tpoints else: #check if desired time points are existing and confirm if not self.time_checked: for t in self.time_stamps: if not t in all_tpoints: warnings.warn("Electrode_Coordination_Plot:: At least" \ " one desired time stamp not available!" \ " Legal time stamps are " \ + str(all_tpoints) + ". Switching to " \ "next legal time point. Please check " \ "for consistency!") if t < 0: new_t = self.timeshift else: new_t = range(0, t+1, int(1000/sampling_frequency))[-1] #if we obtain an empty list reset to timeshift if new_t == []: new_t = self.timeshift else: new_t = new_t+self.timeshift #finally check for too high or low values if new_t < self.timeshift: new_t = self.timeshift elif new_t > all_tpoints[-1]: new_t = all_tpoints[-1] self.time_stamps[self.time_stamps.index(t)] = new_t self.time_checked = True #has to be performed only once tpoints = numpy.array(self.time_stamps) num_of_tpoints = len(tpoints) # selecting formatting and clearing figure default_size = [8., 6.] if self.single_plot: num_of_rows = num_of_tpoints if num_of_rows > 4: default_size[0] = default_size[0]/(int((num_of_rows+3)/4)) default_size[1] = default_size[1]/(int((num_of_rows+3)/4)) else: num_of_rows = 1 f=pylab.figure(fig_num, figsize=[default_size[0]*num_of_classes, default_size[1]*num_of_rows]) if pylab.get_backend() in pylab.matplotlib.backends.interactive_bk: f.show() if counter%20 == 19: #clear every 20th trial pylab.figure(fig_num).clear() # Iterate over the time window for time_index in range(num_of_tpoints): pylab.subplots_adjust(left=0.025, right=0.8) #shift a bit to the left if self.single_plot: pl_offset=time_index else: pl_offset=0 for index, class_label in enumerate(list_of_classes): current_plot_num=(num_of_classes*pl_offset)+index+1 pylab.subplot(num_of_rows, num_of_classes, current_plot_num) pylab.gca().clear() # Get the values for the respective class data = values[class_label].view(numpy.ndarray) ec = self.getMetadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec # observe channels channel_names = [channel for channel in values[class_label].channel_names if channel in ec.keys()] fcn = [channel for channel in values[class_label].channel_names if not channel in ec.keys()] if not fcn == []: self._log("Unsupported channels ignored:%s ."%str(fcn), level=logging.CRITICAL) if channel_names == []: self._log("No channel for plotting left.", level=logging.CRITICAL) return ec_2d = StreamDataset.project2d(ec) # Define x and y coordinates of electrodes in the order of the channels # of data x = numpy.array([ec_2d[key][0] for key in channel_names]) y = numpy.array([ec_2d[key][1] for key in channel_names]) # x = numpy.array([self.electrode_coordinates[key][0] * numpy.cos(self.electrode_coordinates[key][1]/180*numpy.pi) # for key in channel_names]) # y = numpy.array([self.electrode_coordinates[key][0] * numpy.sin(self.electrode_coordinates[key][1]/180*numpy.pi) # for key in channel_names]) # The values of the electrodes at this point of time pos=list(all_tpoints).index(tpoints[time_index]) z = data[pos, :] if self.smooth_corners: x,y,z = self._smooth_corners(x,y,z, data, pos) #griddata returns a masked array #you can get the data via zi[~zi.mask] zi = griddata(x, y, z, self.xi, self.yi) #clip values if self.clip and self.limits: zi=numpy.clip(zi, self.limits[0], self.limits[1]) #minimum and maximum # contour the gridded data, # plotting dots at the nonuniform data points. cs=pylab.contourf(self.xi, self.yi, zi, 15, cmap=pylab.cm.jet, levels=levels) if self.contourlines: pylab.contour(self.xi, self.yi, zi, 15, linewidths=0.5, colors='k', levels=levels) if self.figlabels: # plot data points. if not self.smooth_corners: pylab.scatter(x, y, c='b', s=5, marker='o') else: # dont plot invented electrode positions pylab.scatter(x[:-4], y[:-4], c='b', s=5, marker='o') # Add channel labels for label, position in ec_2d.iteritems(): if label in channel_names: pylab.text(position[0], position[1], label) if self.add_info: if counter: if len(list_of_classes) > 1: if index == 0: pylab.text(-120, -98, 'Trial No. ' + str(counter), fontsize=12) else: pylab.text(-120, -98, 'Trial No. ' + str(counter), fontsize=12) if self.nose_ears: #nose ytips=[87.00,87.00, 97] xtips=[-10.00,10.00, 0] pylab.fill(xtips,ytips, facecolor='k', edgecolor='none') #left xtips=[-108.0,-113.0,-113.0,-108.0] ytips=[-10.0,-10.0,10.0,10.0] pylab.fill(xtips,ytips, facecolor='k', edgecolor='none') #right xtips=[108.0,114.0,113.0,108.0] ytips=[-10.0,-10.0,10.0,10.0] pylab.fill(xtips,ytips, facecolor='k', edgecolor='none') pylab.xlim(-125, 125) pylab.ylim(-100, 100) if not self.single_plot or time_index==0: #if single_plot=True do only for the first row pylab.title(class_label, fontsize=20) pylab.setp(pylab.gca(), xticks=[], yticks=[]) pylab.draw() caxis = pylab.axes([.85, .1, .04, .75]) cb = pylab.colorbar(mappable=cs, cax=caxis) # TODO: The label read 'Amplitude ($\mu$V)' # Removed the unit. Or can we really still assume # a (correct) \muV scale after all preprocessing? cb.ax.set_ylabel(r'Amplitude', fontsize=16) # Position of the time axes ax = pylab.axes([.79, .94, .18, .04]) pylab.gca().clear() pylab.bar(tpoints[time_index], 1.0, width=1000.0/sampling_frequency) pylab.xlim(tpoints[0], tpoints[-1]) pylab.xlabel("time (ms)", fontsize=12) pylab.setp(ax, yticks=[],xticks=[all_tpoints[0], tpoints[time_index], all_tpoints[-1]]) # Draw or store the figure if store_dir is None: pylab.draw() #pylab.show() elif self.single_plot and not current_plot_num==(num_of_rows*num_of_classes): #save only if everything is plotted pylab.draw() #pylab.show() else: current_split=self.current_split if current_split != 0 and not\ plot_label.endswith('_split_' + str(current_split)): #more than one split and first call plot_label = plot_label + '_split_' + str(current_split) f_name=str(store_dir) + str(os.sep) + str(plot_label) + "_" + str(int(tpoints[time_index])) pylab.savefig(f_name + ".png") if self.store_data: import pickle f_name=str(store_dir) + str(os.sep) + str(plot_label) pickle.dump(values, open(f_name + ".pickle",'w'))
def _plotValues(self, values, #dict TimeSeries values plot_label, #str Plot-Label fig_num, #int Figure-number for classify plots # 1: average, # 2: single trial, # 3: average accumulating store_dir = None, #str Directory to store the plots counter=0): #int Plotcounter for all trialsdef plot_values sampling_frequency = values[values.keys()[0]].sampling_frequency list_of_classes = values.keys() num_of_classes = len(list_of_classes) #computing time points to show #num_tpoints = values.values()[0].shape[0] pylab.subplots_adjust(left = 0.05, # the left side of the subplots of the figure right = 0.95, # the right side of the subplots of the figure bottom = 0.05, # the bottom of the subplots of the figure top = 0.95, # the top of the subplots of the figure wspace = 0.15, # the amount of width reserved for blank space between subplots hspace = 0.1, # the amount of height reserved for white space between subplots ) #plot all channels separately in one figure #plot just 1 channel if self.channel_names != None and len(self.channel_names)==1: f=pylab.figure(fig_num, figsize = (18,13)) #assure that figure is displayed with an interactive backend if pylab.get_backend() in pylab.matplotlib.backends.interactive_bk: f.show() for index, class_label in enumerate(list_of_classes): assert (self.channel_names[0] in values[class_label].channel_names),\ "SpectrumPlot::Channel requested for plotting is not available in data" channel_index = values[class_label].channel_names.index(self.channel_names[0]) #operations like splicing only on view of object data = values[class_label].view(numpy.ndarray) pylab.subplot(1, num_of_classes, index + 1) title = pylab.title(str(self.channel_names) + ' ' + class_label) self._plot_spectrum(data[:,channel_index], sampling_frequency) # Draw or store the figure if store_dir is None: pylab.draw() else: current_split=self.current_split if current_split != 0 and not\ plot_label.endswith('_split_' + str(current_split)): #more than one split and first call plot_label = plot_label + '_split_' + str(current_split) f_name=str(store_dir) + str(os.sep) + str(plot_label) pylab.savefig(f_name + ".png") #plot more than one channel in one figure for each label else: for index, class_label in enumerate(list_of_classes): title = pylab.title(class_label) if self.channel_names==None: #this means all channels are plotted self.channel_names=values[class_label].channel_names f=pylab.figure(fig_num, figsize = (18,13)) #assure that figure is displayed with an interactive backend if pylab.get_backend() in pylab.matplotlib.backends.interactive_bk: f.show() number_of_channels=len(self.channel_names) # Compute number of rows and cols for subplot-arrangement: # use 8 as upper limit for cols and compute rows accordingly if number_of_channels <= 8: nr_of_cols = number_of_channels else: nr_of_cols = 8 nr_of_rows = (number_of_channels - 1) / 8 + 1 data = values[class_label].view(numpy.ndarray) ec = self.getMetadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # plot everything channel-wise for channel_index in range(number_of_channels): channel_name = self.channel_names[channel_index] f.add_subplot(nr_of_rows, nr_of_cols, channel_index + 1) pylab.title(channel_name) # actual plotting of the data self._plot_spectrum(data[:,channel_index], sampling_frequency) if self.physiological_arrangement: x, y = ec_2d[channel_name] w = .05 h = .045 pylab.gca().set_position([(x + 110) / 220, (y + 110) / 220, w, h]) pylab.draw() # Draw or store the figure if store_dir is None: pylab.draw() else: current_split=self.current_split if current_split != 0 and not\ plot_label.endswith('_split_' + str(current_split)): #more than one split and first call plot_label = plot_label + '_split_' + str(current_split) f_name=str(store_dir) + str(os.sep) + str(plot_label) + '_' + class_label pylab.savefig(f_name + ".png")
def _plot_all_channels_separated(self, tpoints, values): """ This function generates time series plot separated for each channel """ #def _generate_time_series_plot(self, label, data): f=pylab.gcf() # in case of [phys_arrangement], write the figure title only once # and large in the upper left corner of the plot. this fails whenever # there are no more channels in that area, as the plot gets cropped # if self.physiological_arrangement: # h, l = pylab.gca().get_legend_handles_labels() # prop = pylab.matplotlib.font_manager.FontProperties(size='xx-large') # f.legend(h, l, prop=prop, loc=1) # text_x = .4 # text_y = .4 # # #if self.shrink_plots: text_y = 1.2 # f.text(text_x, text_y, 'Channel-wise time series\n' + # samples_per_condition_string, # ha='center', color='black', size=32) for index, class_label in enumerate(values.keys()): data = values[class_label].view(numpy.ndarray) channel_names=values[class_label].channel_names line_color = 'bgrcmyk'[index] number_of_channels=len(channel_names) # Compute number of rows and cols for subplot-arrangement: # use 8 as upper limit for cols and compute rows accordingly if number_of_channels <= 8: nr_of_cols = number_of_channels else: nr_of_cols = 8 nr_of_rows = (number_of_channels - 1) / 8 + 1 # Set canvas size in inches. These values turned out fine, depending # on [physiological_arrangement] #if not self.physiological_arrangement: # f.set_size_inches((5 * nr_of_cols, 3 * nr_of_rows)) #else: #if not self.shrink_plots: # figure.set_size_inches((3*11.7, 3*8.3)) # f.set_size_inches((4*11.7, 4*8.3)) ec = self.getMetadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # plot everything channel-wise for channel_index in range(number_of_channels): channel_name = channel_names[channel_index] skip_plot=False #skip_plot? if self.channel_names and (channel_name not in self.channel_names): skip_plot=True if not skip_plot: f.add_subplot(nr_of_rows, nr_of_cols, channel_index + 1) # actual plotting of the data. This can always be done pylab.plot(tpoints, data[:, channel_index], color=line_color) channel_name = channel_names[channel_index] pylab.title(channel_name) if self.physiological_arrangement: x, y = ec_2d[channel_name] w = .05 h = .045 pylab.gca().set_position([(x + 110) / 220, (y + 110) / 220, w, h]) pylab.draw()
def _plotValues( self, values, #dict TimeSeries values plot_label, #str Plot-Label fig_num, #int Figure-number for classify plots # 1: average, # 2: single trial, # 3: average accumulating store_dir=None, #str Directory to store the plots counter=0): #int Plotcounter for all trials #compute sampling_frequency and classes to plot sampling_frequency = values[values.keys()[0]].sampling_frequency list_of_classes = values.keys() num_of_classes = len(list_of_classes) #autoscale color bar or use user scaling if self.limits: levels = self._compute_levels() else: levels = None #compute maximum and minimum for colorbar scaling if not existing vmax = float(max( numpy.array(v).max() for v in values.itervalues())) vmin = float(min( numpy.array(v).min() for v in values.itervalues())) levels = self._compute_levels(limits=[vmin, vmax]) #normalizer=matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) #computing time points to show num_tpoints = values.values()[0].shape[0] all_tpoints = numpy.arange(0, num_tpoints * (1000 / sampling_frequency), 1000 / sampling_frequency) + self.timeshift if self.time_stamps == [-1]: tpoints = all_tpoints else: #check if desired time points are existing and confirm if not self.time_checked: for t in self.time_stamps: if not t in all_tpoints: warnings.warn("Electrode_Coordination_Plot:: At least" \ " one desired time stamp not available!" \ " Legal time stamps are " \ + str(all_tpoints) + ". Switching to " \ "next legal time point. Please check " \ "for consistency!") if t < 0: new_t = self.timeshift else: new_t = range(0, t + 1, int(1000 / sampling_frequency))[-1] #if we obtain an empty list reset to timeshift if new_t == []: new_t = self.timeshift else: new_t = new_t + self.timeshift #finally check for too high or low values if new_t < self.timeshift: new_t = self.timeshift elif new_t > all_tpoints[-1]: new_t = all_tpoints[-1] self.time_stamps[self.time_stamps.index(t)] = new_t self.time_checked = True #has to be performed only once tpoints = numpy.array(self.time_stamps) num_of_tpoints = len(tpoints) # selecting formatting and clearing figure default_size = [8., 6.] if self.single_plot: num_of_rows = num_of_tpoints if num_of_rows > 4: default_size[0] = default_size[0] / (int( (num_of_rows + 3) / 4)) default_size[1] = default_size[1] / (int( (num_of_rows + 3) / 4)) else: num_of_rows = 1 f = pylab.figure(fig_num, figsize=[ default_size[0] * num_of_classes, default_size[1] * num_of_rows ]) if pylab.get_backend() in pylab.matplotlib.backends.interactive_bk: f.show() if counter % 20 == 19: #clear every 20th trial pylab.figure(fig_num).clear() # Iterate over the time window for time_index in range(num_of_tpoints): pylab.subplots_adjust(left=0.025, right=0.8) #shift a bit to the left if self.single_plot: pl_offset = time_index else: pl_offset = 0 for index, class_label in enumerate(list_of_classes): current_plot_num = (num_of_classes * pl_offset) + index + 1 pylab.subplot(num_of_rows, num_of_classes, current_plot_num) pylab.gca().clear() # Get the values for the respective class data = values[class_label].view(numpy.ndarray) ec = self.get_metadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec # observe channels channel_names = [ channel for channel in values[class_label].channel_names if channel in ec.keys() ] fcn = [ channel for channel in values[class_label].channel_names if not channel in ec.keys() ] if not fcn == []: self._log("Unsupported channels ignored:%s ." % str(fcn), level=logging.CRITICAL) if channel_names == []: self._log("No channel for plotting left.", level=logging.CRITICAL) return ec_2d = StreamDataset.project2d(ec) # Define x and y coordinates of electrodes in the order of the channels # of data x = numpy.array([ec_2d[key][0] for key in channel_names]) y = numpy.array([ec_2d[key][1] for key in channel_names]) # x = numpy.array([self.electrode_coordinates[key][0] * numpy.cos(self.electrode_coordinates[key][1]/180*numpy.pi) # for key in channel_names]) # y = numpy.array([self.electrode_coordinates[key][0] * numpy.sin(self.electrode_coordinates[key][1]/180*numpy.pi) # for key in channel_names]) # The values of the electrodes at this point of time pos = list(all_tpoints).index(tpoints[time_index]) z = data[pos, :] if self.smooth_corners: x, y, z = self._smooth_corners(x, y, z, data, channel_names, pos) #griddata returns a masked array #you can get the data via zi[~zi.mask] zi = griddata(x, y, z, self.xi, self.yi) #clip values if self.clip and self.limits: zi = numpy.clip(zi, self.limits[0], self.limits[1]) #minimum and maximum # contour the gridded data, # plotting dots at the nonuniform data points. cs = pylab.contourf(self.xi, self.yi, zi, 15, cmap=pylab.cm.jet, levels=levels) if self.contourlines: pylab.contour(self.xi, self.yi, zi, 15, linewidths=0.5, colors='k', levels=levels) if self.figlabels: # plot data points. if not self.smooth_corners: pylab.scatter(x, y, c='b', s=5, marker='o') else: # dont plot invented electrode positions pylab.scatter(x[:-4], y[:-4], c='b', s=5, marker='o') # Add channel labels for label, position in ec_2d.iteritems(): if label in channel_names: pylab.text(position[0], position[1], label) if self.add_info: if counter: if len(list_of_classes) > 1: if index == 0: pylab.text(-120, -98, 'Trial No. ' + str(counter), fontsize=12) else: pylab.text(-120, -98, 'Trial No. ' + str(counter), fontsize=12) if self.nose_ears: #nose ytips = [87.00, 87.00, 97] xtips = [-10.00, 10.00, 0] pylab.fill(xtips, ytips, facecolor='k', edgecolor='none') #left xtips = [-108.0, -113.0, -113.0, -108.0] ytips = [-10.0, -10.0, 10.0, 10.0] pylab.fill(xtips, ytips, facecolor='k', edgecolor='none') #right xtips = [108.0, 114.0, 113.0, 108.0] ytips = [-10.0, -10.0, 10.0, 10.0] pylab.fill(xtips, ytips, facecolor='k', edgecolor='none') pylab.xlim(-125, 125) pylab.ylim(-100, 100) if not self.single_plot or time_index == 0: #if single_plot=True do only for the first row if self.figtitle: pylab.title(self.figtitle, fontsize=20) else: pylab.title(class_label, fontsize=20) pylab.setp(pylab.gca(), xticks=[], yticks=[]) pylab.draw() caxis = pylab.axes([.85, .1, .04, .75]) cb = pylab.colorbar(mappable=cs, cax=caxis) # TODO: The label read 'Amplitude ($\mu$V)' # Removed the unit. Or can we really still assume # a (correct) \muV scale after all preprocessing? cb.ax.set_ylabel(r'Amplitude', fontsize=16) # Position of the time axes ax = pylab.axes([.79, .94, .18, .04]) pylab.gca().clear() pylab.bar(tpoints[time_index], 1.0, width=1000.0 / sampling_frequency) pylab.xlim(tpoints[0], tpoints[-1]) pylab.xlabel("time (ms)", fontsize=12) pylab.setp( ax, yticks=[], xticks=[all_tpoints[0], tpoints[time_index], all_tpoints[-1]]) # Draw or store the figure if store_dir is None: pylab.draw() #pylab.show() elif self.single_plot and not current_plot_num == ( num_of_rows * num_of_classes): #save only if everything is plotted pylab.draw() #pylab.show() else: current_split = self.current_split if current_split != 0 and not\ plot_label.endswith('_split_' + str(current_split)): #more than one split and first call plot_label = plot_label + '_split_' + str(current_split) f_name = str(store_dir) + str( os.sep) + str(plot_label) + "_" + str( int(tpoints[time_index])) pylab.savefig(f_name + ".png") if self.store_data: import pickle f_name = str(store_dir) + str(os.sep) + str(plot_label) pickle.dump(values, open(f_name + ".pickle", 'w'))
def _plotValues( self, values, #dict TimeSeries values plot_label, #str Plot-Label fig_num, #int Figure-number for classify plots # 1: average, # 2: single trial, # 3: average accumulating store_dir=None, #str Directory to store the plots counter=0): #int Plotcounter for all trialsdef plot_values sampling_frequency = values[values.keys()[0]].sampling_frequency list_of_classes = values.keys() num_of_classes = len(list_of_classes) #computing time points to show #num_tpoints = values.values()[0].shape[0] pylab.subplots_adjust( left=0.05, # the left side of the subplots of the figure right=0.95, # the right side of the subplots of the figure bottom=0.05, # the bottom of the subplots of the figure top=0.95, # the top of the subplots of the figure wspace= 0.15, # the amount of width reserved for blank space between subplots hspace= 0.1, # the amount of height reserved for white space between subplots ) #plot all channels separately in one figure #plot just 1 channel if self.channel_names != None and len(self.channel_names) == 1: f = pylab.figure(fig_num, figsize=(18, 13)) #assure that figure is displayed with an interactive backend if pylab.get_backend() in pylab.matplotlib.backends.interactive_bk: f.show() for index, class_label in enumerate(list_of_classes): assert (self.channel_names[0] in values[class_label].channel_names),\ "SpectrumPlot::Channel requested for plotting is not available in data" channel_index = values[class_label].channel_names.index( self.channel_names[0]) #operations like splicing only on view of object data = values[class_label].view(numpy.ndarray) pylab.subplot(1, num_of_classes, index + 1) title = pylab.title( str(self.channel_names) + ' ' + class_label) self._plot_spectrum(data[:, channel_index], sampling_frequency) # Draw or store the figure if store_dir is None: pylab.draw() else: current_split = self.current_split if current_split != 0 and not\ plot_label.endswith('_split_' + str(current_split)): #more than one split and first call plot_label = plot_label + '_split_' + str(current_split) f_name = str(store_dir) + str(os.sep) + str(plot_label) pylab.savefig(f_name + ".png") #plot more than one channel in one figure for each label else: for index, class_label in enumerate(list_of_classes): title = pylab.title(class_label) if self.channel_names == None: #this means all channels are plotted self.channel_names = values[class_label].channel_names f = pylab.figure(fig_num, figsize=(18, 13)) #assure that figure is displayed with an interactive backend if pylab.get_backend( ) in pylab.matplotlib.backends.interactive_bk: f.show() number_of_channels = len(self.channel_names) # Compute number of rows and cols for subplot-arrangement: # use 8 as upper limit for cols and compute rows accordingly if number_of_channels <= 8: nr_of_cols = number_of_channels else: nr_of_cols = 8 nr_of_rows = (number_of_channels - 1) / 8 + 1 data = values[class_label].view(numpy.ndarray) ec = self.getMetadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # plot everything channel-wise for channel_index in range(number_of_channels): channel_name = self.channel_names[channel_index] f.add_subplot(nr_of_rows, nr_of_cols, channel_index + 1) pylab.title(channel_name) # actual plotting of the data self._plot_spectrum(data[:, channel_index], sampling_frequency) if self.physiological_arrangement: x, y = ec_2d[channel_name] w = .05 h = .045 pylab.gca().set_position([(x + 110) / 220, (y + 110) / 220, w, h]) pylab.draw() # Draw or store the figure if store_dir is None: pylab.draw() else: current_split = self.current_split if current_split != 0 and not\ plot_label.endswith('_split_' + str(current_split)): #more than one split and first call plot_label = plot_label + '_split_' + str( current_split) f_name = str(store_dir) + str( os.sep) + str(plot_label) + '_' + class_label pylab.savefig(f_name + ".png")
def _plot_all_channels_separated(self, tpoints, values): """ This function generates time series plot separated for each channel """ #def _generate_time_series_plot(self, label, data): f = pylab.gcf() # in case of [phys_arrangement], write the figure title only once # and large in the upper left corner of the plot. this fails whenever # there are no more channels in that area, as the plot gets cropped # if self.physiological_arrangement: # h, l = pylab.gca().get_legend_handles_labels() # prop = pylab.matplotlib.font_manager.FontProperties(size='xx-large') # f.legend(h, l, prop=prop, loc=1) # text_x = .4 # text_y = .4 # # #if self.shrink_plots: text_y = 1.2 # f.text(text_x, text_y, 'Channel-wise time series\n' + # samples_per_condition_string, # ha='center', color='black', size=32) for index, class_label in enumerate(values.keys()): data = values[class_label].view(numpy.ndarray) channel_names = values[class_label].channel_names line_color = 'bgrcmyk'[index] number_of_channels = len(channel_names) # Compute number of rows and cols for subplot-arrangement: # use 8 as upper limit for cols and compute rows accordingly if number_of_channels <= 8: nr_of_cols = number_of_channels else: nr_of_cols = 8 nr_of_rows = (number_of_channels - 1) / 8 + 1 # Set canvas size in inches. These values turned out fine, depending # on [physiological_arrangement] #if not self.physiological_arrangement: # f.set_size_inches((5 * nr_of_cols, 3 * nr_of_rows)) #else: #if not self.shrink_plots: # figure.set_size_inches((3*11.7, 3*8.3)) # f.set_size_inches((4*11.7, 4*8.3)) ec = self.getMetadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # plot everything channel-wise for channel_index in range(number_of_channels): channel_name = channel_names[channel_index] skip_plot = False #skip_plot? if self.channel_names and (channel_name not in self.channel_names): skip_plot = True if not skip_plot: f.add_subplot(nr_of_rows, nr_of_cols, channel_index + 1) # actual plotting of the data. This can always be done pylab.plot(tpoints, data[:, channel_index], color=line_color) channel_name = channel_names[channel_index] pylab.title(channel_name) if self.physiological_arrangement: x, y = ec_2d[channel_name] w = .05 h = .045 pylab.gca().set_position([(x + 110) / 220, (y + 110) / 220, w, h]) pylab.draw()
def _generate_time_series_plot(self): """ This function generates the actual time series plot""" # This string will show up as text in the plot and looks something # like "Target: 123; Standard:634" samples_per_condition_string = \ "; ".join([("%s: " + str(self.samples_per_condition[label])) % label for label in self.mean_time_series.keys()]) figTS = pylab.figure() # Compute number of rows and cols for subplot-arrangement: # use 8 as upper limit for cols and compute rows accordingly if self.number_of_channels <= 8: nr_of_cols = self.number_of_channels else: nr_of_cols = 8 nr_of_rows = (self.number_of_channels - 1) / 8 + 1 # Set canvas size in inches. These values turned out fine, depending # on [physiological_arrengement] and [shrink_plots] if not self.physiological_arrangement: figTS.set_size_inches((5 * nr_of_cols, 3 * nr_of_rows)) ec_2d = None else: if not self.shrink_plots: figTS.set_size_inches((3*11.7, 3*8.3)) else: figTS.set_size_inches((4*11.7, 4*8.3)) ec = self.get_metadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # plot everything channel-wise for i_chan in range(self.number_of_channels): figTS.add_subplot(nr_of_rows, nr_of_cols, i_chan + 1) # actual plotting of the data. This can always be done for tslabel in self.mean_time_series.keys(): tmp_plot=pylab.plot(self.mean_time_series[tslabel][:, i_chan], label=tslabel) cur_color = tmp_plot[0].get_color() if self.error_type != None: for sample in range(self.samples_per_window): current_error = self.error[label][sample, i_chan] pylab.bar(sample-.35, 2*current_error, width=.7, bottom=self.mean_time_series[tslabel][sample, i_chan] -current_error, color=cur_color, ec=None, alpha=.3) # plotting of features; only if features present if (self.feature_time_series != None): # plot those nice grey circles pylab.plot(self.feature_time_series[:, i_chan], 'o', color='0.5', label='Feature', alpha=0.5) for sample in range(self.samples_per_window): if [sample, i_chan] in self.indexlist: # write down value... pylab.text(sample, self.feature_time_series[sample, i_chan], '%.2f' % self.feature_time_series[sample, i_chan], ha='center', color='black', size='xx-small') # ...compute the corresponding color-representation... marker_color = \ self.own_colormap(self.normalizer(\ self.feature_time_series[sample, i_chan])) # ...and draw vertical boxes at the feature's position pylab.axvspan(sample - .25, sample + .25, color=marker_color, ec=None, alpha=.8) # more format. and rearrangement in case of [phys_arrengement] self._format_subplots('mean time series', i_chan, samples_per_condition_string, ec_2d) # in case of [phys_arrengement], write the figure title only once # and large in the upper left corner of the plot. this fails whenever # there are no more channels in that area, as the plot gets cropped if self.physiological_arrangement: h, l = pylab.gca().get_legend_handles_labels() prop = matplotlib.font_manager.FontProperties(size='xx-large') figTS.legend(h, l, prop=prop, loc=1) if not self.emotiv: text_x = .1 text_y = .92 else: text_x = .4 text_y = .4 if self.shrink_plots: text_y = 1.2 figTS.text(text_x, text_y, 'Channel-wise mean time series\n' + samples_per_condition_string, ha='center', color='black', size=32) return figTS
def _generate_time_series_plot(self): """ This function generates the actual time series plot""" # This string will show up as text in the plot and looks something # like "Target: 123; Standard:634" samples_per_condition_string = \ "; ".join([("%s: " + str(self.samples_per_condition[label])) % label for label in self.mean_time_series.keys()]) figTS = pylab.figure() # Compute number of rows and cols for subplot-arrangement: # use 8 as upper limit for cols and compute rows accordingly if self.number_of_channels <= 8: nr_of_cols = self.number_of_channels else: nr_of_cols = 8 nr_of_rows = (self.number_of_channels - 1) / 8 + 1 # Set canvas size in inches. These values turned out fine, depending # on [physiological_arrengement] and [shrink_plots] if not self.physiological_arrangement: figTS.set_size_inches((5 * nr_of_cols, 3 * nr_of_rows)) ec_2d = None else: if not self.shrink_plots: figTS.set_size_inches((3 * 11.7, 3 * 8.3)) else: figTS.set_size_inches((4 * 11.7, 4 * 8.3)) ec = self.get_metadata("electrode_coordinates") if ec is None: ec = StreamDataset.ec ec_2d = StreamDataset.project2d(ec) # plot everything channel-wise for i_chan in range(self.number_of_channels): figTS.add_subplot(nr_of_rows, nr_of_cols, i_chan + 1) # actual plotting of the data. This can always be done for tslabel in self.mean_time_series.keys(): tmp_plot = pylab.plot(self.mean_time_series[tslabel][:, i_chan], label=tslabel) cur_color = tmp_plot[0].get_color() if self.error_type != None: for sample in range(self.samples_per_window): current_error = self.error[label][sample, i_chan] pylab.bar( sample - .35, 2 * current_error, width=.7, bottom=self.mean_time_series[tslabel][sample, i_chan] - current_error, color=cur_color, ec=None, alpha=.3) # plotting of features; only if features present if (self.feature_time_series != None): # plot those nice grey circles pylab.plot(self.feature_time_series[:, i_chan], 'o', color='0.5', label='Feature', alpha=0.5) for sample in range(self.samples_per_window): if [sample, i_chan] in self.indexlist: # write down value... pylab.text(sample, self.feature_time_series[sample, i_chan], '%.2f' % self.feature_time_series[sample, i_chan], ha='center', color='black', size='xx-small') # ...compute the corresponding color-representation... marker_color = \ self.own_colormap(self.normalizer(\ self.feature_time_series[sample, i_chan])) # ...and draw vertical boxes at the feature's position pylab.axvspan(sample - .25, sample + .25, color=marker_color, ec=None, alpha=.8) # more format. and rearrangement in case of [phys_arrengement] self._format_subplots('mean time series', i_chan, samples_per_condition_string, ec_2d) # in case of [phys_arrengement], write the figure title only once # and large in the upper left corner of the plot. this fails whenever # there are no more channels in that area, as the plot gets cropped if self.physiological_arrangement: h, l = pylab.gca().get_legend_handles_labels() prop = matplotlib.font_manager.FontProperties(size='xx-large') figTS.legend(h, l, prop=prop, loc=1) if not self.emotiv: text_x = .1 text_y = .92 else: text_x = .4 text_y = .4 if self.shrink_plots: text_y = 1.2 figTS.text(text_x, text_y, 'Channel-wise mean time series\n' + samples_per_condition_string, ha='center', color='black', size=32) return figTS