Changeset 3bdbfcc in sasview for src/sas/qtgui/Plotter2D.py
- Timestamp:
- Feb 2, 2017 8:29:07 AM (8 years ago)
- 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:
- 965fbd8
- Parents:
- 5d89f43
- git-author:
- Piotr Rozyczko <rozyczko@…> (01/23/17 09:21:03)
- git-committer:
- Piotr Rozyczko <rozyczko@…> (02/02/17 08:29:07)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Plotter2D.py
r5d89f43 r3bdbfcc 11 11 12 12 import sas.qtgui.PlotUtilities as PlotUtilities 13 import sas.qtgui.GuiUtils as GuiUtils 13 14 from sas.qtgui.PlotterBase import PlotterBase 14 15 from sas.qtgui.ColorMap import ColorMap 16 from sas.sasgui.guiframe.dataFitting import Data1D 15 17 from sas.sasgui.guiframe.dataFitting import Data2D 18 from sas.sascalc.dataloader.manipulations import CircularAverage 19 from sas.sasgui.guiframe.local_perspectives.plotting.binder import BindArtist 20 from sas.qtgui.BoxSum import BoxSum 21 from sas.qtgui.GuiUtils import formatNumber 22 from sas.qtgui.SlicerParameters import SlicerParameters 23 from sas.sasgui.guiframe.local_perspectives.plotting.boxSlicer import BoxInteractorX 24 from sas.sasgui.guiframe.local_perspectives.plotting.AnnulusSlicer import AnnulusInteractor 25 from sas.sasgui.guiframe.local_perspectives.plotting.SectorSlicer import SectorInteractor 26 from sas.sasgui.guiframe.local_perspectives.plotting.boxSum import BoxSumCalculator 27 from sas.sasgui.guiframe.local_perspectives.plotting.boxSlicer import BoxInteractorY 16 28 17 29 # Minimum value of Z for which we will present data. 18 MIN_Z =-3230 MIN_Z = -32 19 31 20 32 class Plotter2DWidget(PlotterBase): … … 29 41 # Default scale 30 42 self.scale = 'log_{10}' 43 # to set the order of lines drawn first. 44 self.slicer_z = 5 45 # Reference to the current slicer 46 self.slicer = None 47 # Create Artist and bind it 48 self.connect = BindArtist(self.figure) 31 49 self.vmin = None 32 50 self.vmax = None … … 53 71 self.title(title=data.title) 54 72 55 def plot(self, data=None, marker=None, linestyle=None): 73 @property 74 def item(self): 75 ''' getter for this plot's QStandardItem ''' 76 return self._item 77 78 @item.setter 79 def item(self, item=None): 80 ''' setter for this plot's QStandardItem ''' 81 self._item = item 82 83 def plot(self, data=None): 56 84 """ 57 85 Plot 2D self._data … … 61 89 self.data = data 62 90 63 assert (self._data)91 assert self._data 64 92 65 93 # Toggle the scale … … 128 156 self.actionBoxAveragingY = self.contextMenu.addAction("&Box Averaging in Qy") 129 157 self.actionBoxAveragingY.triggered.connect(self.onBoxAveragingY) 130 self.contextMenu.addSeparator() 131 self.actionEditGraphLabel = self.contextMenu.addAction("&Edit Graph Label") 132 self.actionEditGraphLabel.triggered.connect(self.onEditgraphLabel) 158 # Additional items for slicer interaction 159 if self.slicer: 160 self.actionClearSlicer = self.contextMenu.addAction("&Clear Slicer") 161 self.actionClearSlicer.triggered.connect(self.onClearSlicer) 162 self.actionEditSlicer = self.contextMenu.addAction("&Edit Slicer Parameters") 163 self.actionEditSlicer.triggered.connect(self.onEditSlicer) 133 164 self.contextMenu.addSeparator() 134 165 self.actionColorMap = self.contextMenu.addAction("&2D Color Map") … … 166 197 self.plot() 167 198 199 def onClearSlicer(self): 200 """ 201 Remove all sclicers from the chart 202 """ 203 if self.slicer: 204 self.slicer.clear() 205 self.canvas.draw() 206 self.slicer = None 207 208 def onEditSlicer(self): 209 """ 210 Present a small dialog for manipulating the current slicer 211 """ 212 assert self.slicer 213 214 self.param_model = self.slicer.model() 215 # Pass the model to the Slicer Parameters widget 216 self.slicer_widget = SlicerParameters(self, model=self.param_model) 217 self.slicer_widget.show() 218 168 219 def onCircularAverage(self): 169 220 """ 170 """ 171 pass 221 Perform circular averaging on Data2D 222 """ 223 # Find the best number of bins 224 npt = numpy.sqrt(len(self.data.data[numpy.isfinite(self.data.data)])) 225 npt = numpy.floor(npt) 226 # compute the maximum radius of data2D 227 self.qmax = max(numpy.fabs(self.data.xmax), 228 numpy.fabs(self.data.xmin)) 229 self.ymax = max(numpy.fabs(self.data.ymax), 230 numpy.fabs(self.data.ymin)) 231 self.radius = numpy.sqrt(numpy.power(self.qmax, 2) + numpy.power(self.ymax, 2)) 232 #Compute beam width 233 bin_width = (self.qmax + self.qmax) / npt 234 # Create data1D circular average of data2D 235 circle = CircularAverage(r_min=0, r_max=self.radius, bin_width=bin_width) 236 circ = circle(self.data) 237 dxl = circ.dxl if hasattr(circ, "dxl") else None 238 dxw = circ.dxw if hasattr(circ, "dxw") else None 239 240 new_plot = Data1D(x=circ.x, y=circ.y, dy=circ.dy, dx=circ.dx) 241 new_plot.dxl = dxl 242 new_plot.dxw = dxw 243 new_plot.name = new_plot.title = "Circ avg " + self.data.name 244 new_plot.source = self.data.source 245 new_plot.interactive = True 246 new_plot.detector = self.data.detector 247 248 # Define axes if not done yet. 249 new_plot.xaxis("\\rm{Q}", "A^{-1}") 250 if hasattr(self.data, "scale") and \ 251 self.data.scale == 'linear': 252 new_plot.ytransform = 'y' 253 new_plot.yaxis("\\rm{Residuals} ", "normalized") 254 else: 255 new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}") 256 257 new_plot.group_id = "2daverage" + self.data.name 258 new_plot.id = "Circ avg " + self.data.name 259 new_plot.is_data = True 260 variant_plot = QtCore.QVariant(new_plot) 261 GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 262 # TODO: force immediate display (?) 263 264 def setSlicer(self, slicer): 265 """ 266 Clear the previous slicer and create a new one. 267 slicer: slicer class to create 268 """ 269 # Clear current slicer 270 if self.slicer is not None: 271 self.slicer.clear() 272 # Create a new slicer 273 self.slicer_z += 1 274 self.slicer = slicer(self, self.ax, item=self._item, zorder=self.slicer_z) 275 self.ax.set_ylim(self.data.ymin, self.data.ymax) 276 self.ax.set_xlim(self.data.xmin, self.data.xmax) 277 # Draw slicer 278 self.figure.canvas.draw() 279 self.slicer.update() 172 280 173 281 def onSectorView(self): 174 282 """ 175 """ 176 pass 283 Perform sector averaging on Q and draw sector slicer 284 """ 285 self.setSlicer(slicer=SectorInteractor) 177 286 178 287 def onAnnulusView(self): 179 288 """ 180 """ 181 pass 289 Perform sector averaging on Phi and draw annulus slicer 290 """ 291 self.setSlicer(slicer=AnnulusInteractor) 182 292 183 293 def onBoxSum(self): 184 294 """ 185 """ 186 pass 295 Perform 2D Data averaging Qx and Qy. 296 Display box slicer details. 297 """ 298 self.onClearSlicer() 299 self.slicer_z += 1 300 self.slicer = BoxSumCalculator(self, self.ax, zorder=self.slicer_z) 301 302 self.ax.set_ylim(self.data.ymin, self.data.ymax) 303 self.ax.set_xlim(self.data.xmin, self.data.xmax) 304 self.figure.canvas.draw() 305 self.slicer.update() 306 307 # Get the BoxSumCalculator model. 308 self.box_sum_model = self.slicer.model() 309 # Pass the BoxSumCalculator model to the BoxSum widget 310 self.boxwidget = BoxSum(self, model=self.box_sum_model) 311 # Add the plot to the workspace 312 self.manager.parent.workspace().addWindow(self.boxwidget) 313 self.boxwidget.show() 187 314 188 315 def onBoxAveragingX(self): 189 316 """ 190 """ 191 pass 317 Perform 2D data averaging on Qx 318 Create a new slicer. 319 """ 320 self.setSlicer(slicer=BoxInteractorX) 192 321 193 322 def onBoxAveragingY(self): 194 323 """ 195 """ 196 pass 197 198 def onEditgraphLabel(self): 199 """ 200 """ 201 pass 324 Perform 2D data averaging on Qy 325 Create a new slicer . 326 """ 327 self.setSlicer(slicer=BoxInteractorY) 202 328 203 329 def onColorMap(self): … … 225 351 226 352 def showPlot(self, data, qx_data, qy_data, xmin, xmax, ymin, ymax, 227 zmin, zmax, color=0, symbol=0, markersize=0, 228 label='data2D', cmap=DEFAULT_CMAP): 353 zmin, zmax, label='data2D', cmap=DEFAULT_CMAP): 229 354 """ 230 355 Render and show the current data … … 310 435 self.figure.subplots_adjust(left=0.1, right=.8, bottom=.1) 311 436 312 X = self._data.x_bins[0:-1] 313 Y = self._data.y_bins[0:-1] 314 X, Y = numpy.meshgrid(X, Y) 437 data_x, data_y = numpy.meshgrid(self._data.x_bins[0:-1], 438 self._data.y_bins[0:-1]) 315 439 316 440 ax = Axes3D(self.figure) … … 319 443 # TODO: Define "large" for a dataset 320 444 SET_TOO_LARGE = 500 321 if len( X) > SET_TOO_LARGE:445 if len(data_x) > SET_TOO_LARGE: 322 446 ax.disable_mouse_rotation() 323 447 324 448 self.figure.canvas.resizing = False 325 im = ax.plot_surface(X, Y, output, rstride=1, cstride=1, cmap=cmap, 449 im = ax.plot_surface(data_x, data_y, output, rstride=1, 450 cstride=1, cmap=cmap, 326 451 linewidth=0, antialiased=False) 327 452 self.ax.set_axis_off() … … 332 457 self.figure.canvas.draw() 333 458 459 def update(self): 460 self.figure.canvas.draw() 461 462 def draw(self): 463 self.figure.canvas.draw() 464 465 334 466 class Plotter2D(QtGui.QDialog, Plotter2DWidget): 467 """ 468 Plotter widget implementation 469 """ 335 470 def __init__(self, parent=None, quickplot=False, dimension=2): 336 337 471 QtGui.QDialog.__init__(self) 338 472 Plotter2DWidget.__init__(self, manager=parent, quickplot=quickplot, dimension=dimension)
Note: See TracChangeset
for help on using the changeset viewer.