Beispiel #1
0
 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')
Beispiel #2
0
    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')
Beispiel #3
0
    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')
Beispiel #4
0
 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 _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'))
Beispiel #6
0
    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") 
Beispiel #7
0
    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'))
Beispiel #9
0
    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")
Beispiel #10
0
    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