Changeset 14d9c7b in sasview


Ignore:
Timestamp:
Nov 23, 2016 4:21:03 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
31c5b58
Parents:
49e124c
Message:

2D plotter cleanup

Location:
src/sas/qtgui
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/DataExplorer.py

    r49e124c r14d9c7b  
    388388        """ 
    389389        Create a new matplotlib chart from selected data 
    390  
    391         TODO: Add 2D-functionality 
    392390        """ 
    393391        plots = GuiUtils.plotsFromCheckedItems(self.model) 
     
    437435        old_plot = PlotHelper.plotById(plot_id) 
    438436 
    439         # Add new data to the old plot 
     437        # Add new data to the old plot, if data type is the same. 
    440438        for plot_set in new_plots: 
    441             old_plot.data(plot_set) 
    442             old_plot.plot() 
     439            if type(plot_set) is type(old_plot._data): 
     440                old_plot.data(plot_set) 
     441                old_plot.plot() 
    443442 
    444443    def chooseFiles(self): 
  • src/sas/qtgui/Plotter2D.py

    r49e124c r14d9c7b  
    1616DEFAULT_CMAP = pylab.cm.jet 
    1717 
     18import PlotUtilities 
    1819import PlotHelper 
    1920 
     
    6061    def data(self, data=None): 
    6162        """ data setter """ 
    62         self._data = data.data 
     63        self._data = data 
    6364        self._qx_data=data.qx_data 
    6465        self._qy_data=data.qy_data 
     
    116117        # self.figure.subplots_adjust(left=0.2, right=.8, bottom=.2) 
    117118 
    118         output = self._build_matrix() 
     119        output = PlotUtilities.build_matrix(self._data.data, self._qx_data, self._qy_data) 
    119120 
    120121        im = ax.imshow(output, 
     
    144145        event.accept() 
    145146 
    146     def _build_matrix(self): 
    147         """ 
    148         Build a matrix for 2d plot from a vector 
    149         Returns a matrix (image) with ~ square binning 
    150         Requirement: need 1d array formats of 
    151         self.data, self._qx_data, and self._qy_data 
    152         where each one corresponds to z, x, or y axis values 
    153  
    154         """ 
    155         # No qx or qy given in a vector format 
    156         if self._qx_data == None or self._qy_data == None \ 
    157                 or self._qx_data.ndim != 1 or self._qy_data.ndim != 1: 
    158             # do we need deepcopy here? 
    159             return self._data 
    160  
    161         # maximum # of loops to fillup_pixels 
    162         # otherwise, loop could never stop depending on data 
    163         max_loop = 1 
    164         # get the x and y_bin arrays. 
    165         self._get_bins() 
    166         # set zero to None 
    167  
    168         #Note: Can not use scipy.interpolate.Rbf: 
    169         # 'cause too many data points (>10000)<=JHC. 
    170         # 1d array to use for weighting the data point averaging 
    171         #when they fall into a same bin. 
    172         weights_data = numpy.ones([self._data.size]) 
    173         # get histogram of ones w/len(data); this will provide 
    174         #the weights of data on each bins 
    175         weights, xedges, yedges = numpy.histogram2d(x=self._qy_data, 
    176                                                     y=self._qx_data, 
    177                                                     bins=[self.y_bins, self.x_bins], 
    178                                                     weights=weights_data) 
    179         # get histogram of data, all points into a bin in a way of summing 
    180         image, xedges, yedges = numpy.histogram2d(x=self._qy_data, 
    181                                                   y=self._qx_data, 
    182                                                   bins=[self.y_bins, self.x_bins], 
    183                                                   weights=self._data) 
    184         # Now, normalize the image by weights only for weights>1: 
    185         # If weight == 1, there is only one data point in the bin so 
    186         # that no normalization is required. 
    187         image[weights > 1] = image[weights > 1] / weights[weights > 1] 
    188         # Set image bins w/o a data point (weight==0) as None (was set to zero 
    189         # by histogram2d.) 
    190         image[weights == 0] = None 
    191  
    192         # Fill empty bins with 8 nearest neighbors only when at least 
    193         #one None point exists 
    194         loop = 0 
    195  
    196         # do while loop until all vacant bins are filled up up 
    197         #to loop = max_loop 
    198         while not(numpy.isfinite(image[weights == 0])).all(): 
    199             if loop >= max_loop:  # this protects never-ending loop 
    200                 break 
    201             image = self._fillup_pixels(image=image, weights=weights) 
    202             loop += 1 
    203  
    204         return image 
    205  
    206     def _get_bins(self): 
    207         """ 
    208         get bins 
    209         set x_bins and y_bins into self, 1d arrays of the index with 
    210         ~ square binning 
    211         Requirement: need 1d array formats of 
    212         self._qx_data, and self._qy_data 
    213         where each one corresponds to  x, or y axis values 
    214         """ 
    215         # No qx or qy given in a vector format 
    216         if self._qx_data == None or self._qy_data == None \ 
    217                 or self._qx_data.ndim != 1 or self._qy_data.ndim != 1: 
    218             return self._data 
    219  
    220         # find max and min values of qx and qy 
    221         xmax = self._qx_data.max() 
    222         xmin = self._qx_data.min() 
    223         ymax = self._qy_data.max() 
    224         ymin = self._qy_data.min() 
    225  
    226         # calculate the range of qx and qy: this way, it is a little 
    227         # more independent 
    228         x_size = xmax - xmin 
    229         y_size = ymax - ymin 
    230  
    231         # estimate the # of pixels on each axes 
    232         npix_y = int(numpy.floor(numpy.sqrt(len(self._qy_data)))) 
    233         npix_x = int(numpy.floor(len(self._qy_data) / npix_y)) 
    234  
    235         # bin size: x- & y-directions 
    236         xstep = x_size / (npix_x - 1) 
    237         ystep = y_size / (npix_y - 1) 
    238  
    239         # max and min taking account of the bin sizes 
    240         xmax = xmax + xstep / 2.0 
    241         xmin = xmin - xstep / 2.0 
    242         ymax = ymax + ystep / 2.0 
    243         ymin = ymin - ystep / 2.0 
    244  
    245         # store x and y bin centers in q space 
    246         x_bins = numpy.linspace(xmin, xmax, npix_x) 
    247         y_bins = numpy.linspace(ymin, ymax, npix_y) 
    248  
    249         #set x_bins and y_bins 
    250         self.x_bins = x_bins 
    251         self.y_bins = y_bins 
    252  
    253     def _fillup_pixels(self, image=None, weights=None): 
    254         """ 
    255         Fill z values of the empty cells of 2d image matrix 
    256         with the average over up-to next nearest neighbor points 
    257  
    258         :param image: (2d matrix with some zi = None) 
    259  
    260         :return: image (2d array ) 
    261  
    262         :TODO: Find better way to do for-loop below 
    263  
    264         """ 
    265         # No image matrix given 
    266         if image == None or numpy.ndim(image) != 2 \ 
    267                 or numpy.isfinite(image).all() \ 
    268                 or weights == None: 
    269             return image 
    270         # Get bin size in y and x directions 
    271         len_y = len(image) 
    272         len_x = len(image[1]) 
    273         temp_image = numpy.zeros([len_y, len_x]) 
    274         weit = numpy.zeros([len_y, len_x]) 
    275         # do for-loop for all pixels 
    276         for n_y in range(len(image)): 
    277             for n_x in range(len(image[1])): 
    278                 # find only null pixels 
    279                 if weights[n_y][n_x] > 0 or numpy.isfinite(image[n_y][n_x]): 
    280                     continue 
    281                 else: 
    282                     # find 4 nearest neighbors 
    283                     # check where or not it is at the corner 
    284                     if n_y != 0 and numpy.isfinite(image[n_y - 1][n_x]): 
    285                         temp_image[n_y][n_x] += image[n_y - 1][n_x] 
    286                         weit[n_y][n_x] += 1 
    287                     if n_x != 0 and numpy.isfinite(image[n_y][n_x - 1]): 
    288                         temp_image[n_y][n_x] += image[n_y][n_x - 1] 
    289                         weit[n_y][n_x] += 1 
    290                     if n_y != len_y - 1 and numpy.isfinite(image[n_y + 1][n_x]): 
    291                         temp_image[n_y][n_x] += image[n_y + 1][n_x] 
    292                         weit[n_y][n_x] += 1 
    293                     if n_x != len_x - 1 and numpy.isfinite(image[n_y][n_x + 1]): 
    294                         temp_image[n_y][n_x] += image[n_y][n_x + 1] 
    295                         weit[n_y][n_x] += 1 
    296                     # go 4 next nearest neighbors when no non-zero 
    297                     # neighbor exists 
    298                     if n_y != 0 and n_x != 0 and\ 
    299                          numpy.isfinite(image[n_y - 1][n_x - 1]): 
    300                         temp_image[n_y][n_x] += image[n_y - 1][n_x - 1] 
    301                         weit[n_y][n_x] += 1 
    302                     if n_y != len_y - 1 and n_x != 0 and \ 
    303                         numpy.isfinite(image[n_y + 1][n_x - 1]): 
    304                         temp_image[n_y][n_x] += image[n_y + 1][n_x - 1] 
    305                         weit[n_y][n_x] += 1 
    306                     if n_y != len_y and n_x != len_x - 1 and \ 
    307                         numpy.isfinite(image[n_y - 1][n_x + 1]): 
    308                         temp_image[n_y][n_x] += image[n_y - 1][n_x + 1] 
    309                         weit[n_y][n_x] += 1 
    310                     if n_y != len_y - 1 and n_x != len_x - 1 and \ 
    311                         numpy.isfinite(image[n_y + 1][n_x + 1]): 
    312                         temp_image[n_y][n_x] += image[n_y + 1][n_x + 1] 
    313                         weit[n_y][n_x] += 1 
    314  
    315         # get it normalized 
    316         ind = (weit > 0) 
    317         image[ind] = temp_image[ind] / weit[ind] 
    318  
    319         return image 
Note: See TracChangeset for help on using the changeset viewer.