Changeset 6c0568b in sasview for guiframe/local_perspectives/plotting
- Timestamp:
- Mar 5, 2009 10:17:33 AM (15 years ago)
- Branches:
- master, 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, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 12aa9b5
- Parents:
- fe2ade9
- Location:
- guiframe/local_perspectives/plotting
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
guiframe/local_perspectives/plotting/Plotter1D.py
r6285a79 r6c0568b 58 58 ## save errors dy for each data plotted 59 59 self.err_dy={} 60 ## flag to determine if the hide or show context menu item should 61 ## be displayed 60 62 self.errors_hide=0 61 62 63 ## Unique ID (from gui_manager) 63 64 self.uid = None 64 65 65 ## Action IDs for internal call-backs 66 66 self.action_ids = {} 67 68 67 ## Graph 69 68 self.graph = Graph() … … 72 71 self.graph.render(self) 73 72 73 74 74 def _reset(self): 75 75 """ … … 80 80 self.action_ids = {} 81 81 82 82 83 def _onEVT_1DREPLOT(self, event): 83 84 """ … … 87 88 88 89 #TODO: Check for existence of plot attribute 89 90 90 # Check whether this is a replot. If we ask for a replot 91 91 # and the plottable no longer exists, ignore the event. … … 107 107 is_new = False 108 108 109 110 111 109 if is_new: 112 110 # a new plottable overwrites a plotted one using the same id … … 126 124 self.plots[event.plot.name].dx = event.plot.dx 127 125 128 129 # Check axis labels130 126 #TODO: Should re-factor this 131 #if event.plot._xunit != self.graph.prop["xunit"]: 132 self.errors_hide=0 127 ## for all added plot the option to hide error show be displayed first 128 self.errors_hide = 0 129 ## Set axis labels 133 130 self.graph.xaxis(event.plot._xaxis, event.plot._xunit) 134 135 #if event.plot._yunit != self.graph.prop["yunit"]:136 131 self.graph.yaxis(event.plot._yaxis, event.plot._yunit) 137 138 # Set the view scale for all plots 139 132 ## Set the view scale for all plots 140 133 self._onEVT_FUNC_PROPERTY() 141 134 ## render the graph 142 135 self.graph.render(self) 143 144 136 self.subplot.figure.canvas.draw_idle() 145 137 138 146 139 def onLeftDown(self,event): 147 """ left button down and ready to drag""" 148 140 """ 141 left button down and ready to drag 142 Display the position of the mouse on the statusbar 143 """ 149 144 PlotPanel.onLeftDown(self, event) 150 145 ax = event.inaxes … … 153 148 wx.PostEvent(self.parent, StatusEvent(status=position)) 154 149 150 155 151 def _onRemove(self, event): 156 152 """ 157 """ 153 Remove a plottable from the graph and render the graph 154 @param event: Menu event 155 """ 156 ## Check if there is a selected graph to remove 158 157 if not self.graph.selected_plottable == None: 159 #print self.graph.selected_plottable160 158 self.graph.delete(self.plots[self.graph.selected_plottable]) 161 159 del self.plots[self.graph.selected_plottable] … … 169 167 @param event: wx context event 170 168 """ 171 #slicerpop = wx.Menu()172 169 slicerpop = PanelMenu() 173 170 slicerpop.set_plots(self.plots) 174 171 slicerpop.set_graph(self.graph) 175 176 # Option to save the data displayed177 178 179 172 180 173 # Various plot options … … 193 186 slicerpop.AppendSeparator() 194 187 item_list = self.parent.get_context_menu(self.graph) 195 #print "item_list",item_list188 196 189 if (not item_list==None) and (not len(item_list)==0): 197 190 for item in item_list: … … 201 194 wx.EVT_MENU(self, id, item[2]) 202 195 except: 196 wx.PostEvent(self.parent, StatusEvent(status=\ 197 "ModelPanel1D.onContextMenu: bad menu item %s"%sys.exc_value)) 203 198 pass 204 #print sys.exc_value205 #print RuntimeError, "View1DPanel.onContextMenu: bad menu item"206 199 slicerpop.AppendSeparator() 207 #for plot in self.graph.plottables:200 208 201 if self.graph.selected_plottable in self.plots: 209 202 plot = self.plots[self.graph.selected_plottable] 210 203 id = wx.NewId() 211 204 name = plot.name 205 212 206 slicerpop.Append(id, "&Save %s points" % name) 213 207 self.action_ids[str(id)] = plot 214 208 wx.EVT_MENU(self, id, self._onSave) 215 #save as cansas209 216 210 id = wx.NewId() 217 211 slicerpop.Append(id, "&Save %s canSAS XML" % name) 218 212 self.action_ids[str(id)] = plot 219 213 wx.EVT_MENU(self, id, self._onSaveXML) 220 221 # Option to delete plottable 214 222 215 id = wx.NewId() 223 216 slicerpop.Append(id, "Remove %s curve" % name) … … 227 220 # Option to hide 228 221 #TODO: implement functionality to hide a plottable (legend click) 229 230 222 231 223 if self.graph.selected_plottable in self.plots: 232 224 if self.plots[self.graph.selected_plottable].name in self.err_dy.iterkeys()\ 233 225 and self.errors_hide==1: 234 235 #if self.plots[self.graph.selected_plottable].__class__.__name__=="Theory1D": 226 236 227 id = wx.NewId() 237 228 slicerpop.Append(id, '&Show errors to data') 238 #print "panel scale before ",self.xLabel, self.yLabel239 #print "cyllinder before adding error", self.plots[self.graph.selected_plottable].x240 229 wx.EVT_MENU(self, id, self._on_add_errors) 241 230 242 243 231 elif self.plots[self.graph.selected_plottable].__class__.__name__=="Data1D"\ 244 232 and self.errors_hide==0: 233 245 234 id = wx.NewId() 246 235 slicerpop.Append(id, '&Hide Error bars') 247 #print "panel scale before ",self.xLabel, self.yLabel248 #print "cyllinder before adding error", self.plots[self.graph.selected_plottable].x249 236 wx.EVT_MENU(self, id, self._on_remove_errors) 250 251 252 237 else: 253 238 id = wx.NewId() … … 256 241 257 242 slicerpop.AppendSeparator() 243 258 244 id = wx.NewId() 259 245 slicerpop.Append(id, '&Change scale') 260 246 wx.EVT_MENU(self, id, self._onProperties) 261 247 262 248 id = wx.NewId() 263 249 slicerpop.Append(id, '&Reset Graph') 264 250 wx.EVT_MENU(self, id, self.onResetGraph) 265 251 266 267 268 252 pos = event.GetPosition() 269 253 pos = self.ScreenToClient(pos) … … 272 256 273 257 def _on_remove_errors(self, evt): 258 """ 259 Save name and dy of data in dictionary self.err_dy 260 Create a new data1D with the same x, y 261 vector and dy with zeros. 262 post self.err_dy as event (ErrorDataEvent) for any object 263 which wants to reconstruct the initial data. 264 @param evt: Menu event 265 """ 274 266 if not self.graph.selected_plottable == None: 267 ## store existing dy 275 268 name =self.plots[self.graph.selected_plottable].name 276 269 dy = self.plots[self.graph.selected_plottable].dy 277 270 self.err_dy[name]= dy 271 ## Create a new dy for a new plottable 278 272 import numpy 279 273 dy= numpy.zeros(len(self.plots[self.graph.selected_plottable].y)) … … 282 276 dy=dy) 283 277 new_plot.interactive = True 284 self.errors_hide =1278 self.errors_hide = 1 285 279 new_plot.name = self.plots[self.graph.selected_plottable].name 286 280 if hasattr(self.plots[self.graph.selected_plottable], "group_id"): … … 294 288 label, unit = self.plots[self.graph.selected_plottable].get_yaxis() 295 289 new_plot.yaxis(label, unit) 296 #print "panel scale ",self.xLabel, self.yLabel 297 #print "color",self.graph.plottables[self.plots[self.graph.selected_plottable]] 290 ## save the color of the selected plottable before it is deleted 298 291 color=self.graph.plottables[self.plots[self.graph.selected_plottable]] 299 292 self.graph.delete(self.plots[self.graph.selected_plottable]) 300 293 ## add newly created plottable to the graph with the save color 301 294 self.graph.add(new_plot,color) 302 # transforming the view of the new data into the same of the previous data295 ## transforming the view of the new data into the same of the previous data 303 296 self._onEVT_FUNC_PROPERTY() 304 # print "cyllinder", self.plots[self.graph.selected_plottable].x,self.plots[self.graph.selected_plottable].view.x, new_plot.x, new_plot.view.x297 ## save the plot 305 298 self.plots[self.graph.selected_plottable]=new_plot 306 299 ## Render the graph 307 300 self.graph.render(self) 308 301 self.subplot.figure.canvas.draw_idle() … … 311 304 wx.PostEvent(self.parent, event) 312 305 306 313 307 def _on_add_errors(self, evt): 314 308 """ 309 create a new data1D witht the errors saved in self.err_dy 310 to show errors of the plot. 315 311 Compute reasonable errors for a data set without 316 312 errors and transorm the plottable to a Data1D 313 @param evt: Menu event 317 314 """ 318 315 import math … … 321 318 322 319 if not self.graph.selected_plottable == None: 320 ##Reset the flag to display the hide option on the context menu 321 self.errors_hide = 0 322 ## restore dy 323 323 length = len(self.plots[self.graph.selected_plottable].x) 324 324 dy = numpy.zeros(length) … … 329 329 for i in range(length): 330 330 dy[i] = math.sqrt(self.plots[self.graph.selected_plottable].y[i]) 331 #for i in range(length): 332 # dy[i] = math.sqrt(self.plots[self.graph.selected_plottable].y[i]) 333 331 ## Create a new plottable data1D 334 332 new_plot = Data1D(self.plots[self.graph.selected_plottable].x, 335 333 self.plots[self.graph.selected_plottable].y, 336 334 dy=dy) 337 335 new_plot.interactive = True 338 self.errors_hide=0336 339 337 new_plot.name = self.plots[self.graph.selected_plottable].name 340 338 if hasattr(self.plots[self.graph.selected_plottable], "group_id"): … … 349 347 label, unit = self.plots[self.graph.selected_plottable].get_yaxis() 350 348 new_plot.yaxis(label, unit) 351 # print "panel scale ",self.xLabel, self.yLabel349 ## save the color of the selected plottable before it is deleted 352 350 color=self.graph.plottables[self.plots[self.graph.selected_plottable]] 353 351 self.graph.delete(self.plots[self.graph.selected_plottable]) 352 ## add newly created plottable to the graph with the save color 354 353 self.graph.add(new_plot, color) 355 356 # transforming the view of the new data into the same of the previous data 354 ## transforming the view of the new data into the same of the previous data 357 355 self._onEVT_FUNC_PROPERTY() 358 # print "cyllinder", self.plots[self.graph.selected_plottable].x,self.plots[self.graph.selected_plottable].view.x, new_plot.x, new_plot.view.x356 ## save the plot 359 357 self.plots[self.graph.selected_plottable]=new_plot 360 358 ## render the graph with its new content 361 359 self.graph.render(self) 362 360 self.subplot.figure.canvas.draw_idle() 363 361 362 364 363 def _onSaveXML(self, evt): 364 """ 365 Save 1D Data to XML file 366 @param evt: Menu event 367 """ 365 368 import os 366 369 id = str(evt.GetId()) … … 371 374 path = dlg.GetPath() 372 375 mypath = os.path.basename(path) 373 #print path374 376 dlg.Destroy() 375 377 … … 381 383 reader.write( path, datainfo) 382 384 return 383 384 385 385 386 386 387 … … 399 400 path = dlg.GetPath() 400 401 mypath = os.path.basename(path) 401 #print path402 402 403 dlg.Destroy() 403 404 … … 412 413 try: 413 414 if len(self.action_ids[id].y) != len(self.action_ids[id].dy): 414 #print "Y and dY have different lengths"415 415 416 has_errors = False 416 417 except: … … 433 434 out.close() 434 435 435 436 437 def _onToggleScale(self, event): 438 if self.get_yscale() == 'log': 439 self.set_yscale('linear') 440 else: 441 self.set_yscale('log') 442 self.subplot.figure.canvas.draw_idle() 443 436 437 -
guiframe/local_perspectives/plotting/Plotter2D.py
reba08f1a r6c0568b 60 60 ## Reference to the parent window 61 61 self.parent = parent 62 ## Plottables62 ## Dictionary containing Plottables 63 63 self.plots = {} 64 self.data2D= data2d65 self.data =data2d.data64 ## Save reference of the current plotted 65 self.data2D = data2d 66 66 ## Unique ID (from gui_manager) 67 67 self.uid = None 68 69 68 ## Action IDs for internal call-backs 70 69 self.action_ids = {} 70 ## Create Artist and bind it 71 71 self.connect = BindArtist(self.subplot.figure) 72 73 # Beam stop 72 ## Beam stop 74 73 self.beamstop_radius = DEFAULT_BEAM 75 74 ## to set the order of lines drawn first. 76 75 self.slicer_z = 5 76 ## Reference to the current slicer 77 77 self.slicer = None 78 # self.parent.Bind(EVT_INTERNAL, self._onEVT_INTERNAL)78 ## event to send slicer info 79 79 self.Bind(EVT_INTERNAL, self._onEVT_INTERNAL) 80 80 81 self.axes_frozen = False 81 82 ## panel that contains result from slicer motion (ex: Boxsum info) 82 83 self.panel_slicer=None 83 #self.parent.Bind(EVT_SLICER_PARS, self.onParamChange)84 84 ## Graph 85 85 self.graph = Graph() … … 87 87 self.graph.yaxis("\\rm{Intensity} ","cm^{-1}") 88 88 self.graph.render(self) 89 #self.Bind(boxSum.EVT_SLICER_PARS_UPDATE, self._onEVT_SLICER_PARS) 90 #self.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 91 92 93 94 def _onEVT_SLICER_PARS(self, event): 95 #print "paramaters entered on slicer panel", event.type, event.params 96 self.slicer.set_params(event.params) 97 #from sans.guicomm.events import SlicerPanelEvent 98 #wx.PostEvent(self.parent, SlicerPanelEvent (panel= self.panel_slicer)) 89 99 90 100 91 def _onEVT_1DREPLOT(self, event): … … 108 99 @param event: data event 109 100 """ 110 111 self.data2D= event.plot 112 self.data =event.plot.data 101 ## Update self.data2d with the current plot 102 self.data2D = event.plot 113 103 #TODO: Check for existence of plot attribute 114 104 115 105 # Check whether this is a replot. If we ask for a replot 116 106 # and the plottable no longer exists, ignore the event. … … 157 147 158 148 self.slicer= None 159 160 149 # Check axis labels 161 150 #TODO: Should re-factor this 162 # if event.plot._xunit != self.graph.prop["xunit"]:151 ## render the graph with its new content 163 152 self.graph.xaxis(event.plot._xaxis, event.plot._xunit) 164 165 #if event.plot._yunit != self.graph.prop["yunit"]:166 153 self.graph.yaxis(event.plot._yaxis, event.plot._yunit) 167 154 self.graph.title(self.data2D.name) … … 175 162 @param event: wx context event 176 163 """ 177 178 #slicerpop = wx.Menu()179 164 slicerpop = PanelMenu() 180 165 slicerpop.set_plots(self.plots) … … 204 189 wx.EVT_MENU(self, id, item[2]) 205 190 except: 191 wx.PostEvent(self.parent, StatusEvent(status=\ 192 "ModelPanel1D.onContextMenu: bad menu item %s"%sys.exc_value)) 206 193 pass 207 #print sys.exc_value208 #print RuntimeError, "View1DPanel2D.onContextMenu: bad menu item"209 210 194 slicerpop.AppendSeparator() 211 195 … … 237 221 slicerpop.Append(id, '&Box averaging in Qy') 238 222 wx.EVT_MENU(self, id, self.onBoxavgY) 223 239 224 if self.slicer !=None : 240 225 id = wx.NewId() 241 226 slicerpop.Append(id, '&Clear slicer') 242 227 wx.EVT_MENU(self, id, self.onClearSlicer) 228 243 229 if self.slicer.__class__.__name__ !="BoxSum": 244 230 id = wx.NewId() 245 231 slicerpop.Append(id, '&Edit Slicer Parameters') 246 232 wx.EVT_MENU(self, id, self._onEditSlicer) 233 247 234 slicerpop.AppendSeparator() 248 235 … … 255 242 self.PopupMenu(slicerpop, pos) 256 243 244 257 245 def _onEditDetector(self, event): 258 246 """ 259 """ 260 #print "edit detortor param",self.zmin_2D, self.zmax_2D 247 Allow to view and edits detector parameters 248 @param event: wx.menu event 249 """ 250 261 251 import detector_dialog 262 252 dialog = detector_dialog.DetectorDialog(self, -1,base=self.parent) 253 ## info of current detector and data2D 263 254 xnpts = len(self.data2D.x_bins) 264 255 ynpts = len(self.data2D.y_bins) … … 269 260 zmin = self.zmin_2D 270 261 zmax = self.zmax_2D 262 ## set dialog window content 271 263 dialog.setContent(xnpts=xnpts,ynpts=ynpts,qmax=qmax, 272 264 beam=self.data2D.xmin, … … 279 271 280 272 dialog.Destroy() 281 # print "zmn ,zmax", self.zmin_2D, self.zmax_2D273 ## Redraw the current image 282 274 self.image(data= self.data2D.data, 283 275 xmin= self.data2D.xmin, … … 288 280 zmax= self.zmax_2D, 289 281 color=0,symbol=0,label='data2D') 290 #self.graph.render(self)291 282 self.subplot.figure.canvas.draw_idle() 292 283 293 def get_corrected_data(self): 294 # Protect against empty data set 295 if self.data == None: 296 return None 297 import copy 298 output = copy.deepcopy(self.data) 299 return output 284 285 300 286 def freeze_axes(self): 301 287 self.axes_frozen = True … … 307 293 pass 308 294 def onWheel(self, event): 309 pass 295 pass 296 310 297 def update(self, draw=True): 311 298 """ … … 313 300 profiles and resetting the widgets. 314 301 """ 315 #self.slicer.update()316 302 self.draw() 317 303 318 304 319 305 def _getEmptySlicerEvent(self): 306 """ 307 create an empty slicervent 308 """ 320 309 return SlicerEvent(type=None, 321 310 params=None, … … 323 312 def _onEVT_INTERNAL(self, event): 324 313 """ 325 I don't understand why Unbind followed by a Bind 326 using a modified self.slicer doesn't work. 327 For now, I post a clear event followed by 328 a new slicer event... 314 Draw the slicer 315 @param event: wx.lib.newevent (SlicerEvent) containing slicer 316 parameter 329 317 """ 330 318 self._setSlicer(event.slicer) 331 319 332 320 def _setSlicer(self, slicer): 333 # Clear current slicer 334 #printEVT("Plotter2D._setSlicer %s" % slicer) 335 321 """ 322 Clear the previous slicer and create a new one.Post an internal 323 event. 324 @param slicer: slicer class to create 325 """ 326 327 ## Clear current slicer 336 328 if not self.slicer == None: 337 329 self.slicer.clear() 338 330 ## Create a new slicer 339 331 self.slicer_z += 1 340 332 self.slicer = slicer(self, self.subplot, zorder=self.slicer_z) 341 #print "come here"342 333 self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax) 343 334 self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax) 344 335 ## Draw slicer 345 336 self.update() 346 337 self.slicer.update() 347 338 wx.PostEvent(self.parent, StatusEvent(status=\ 339 "Plotter2D._setSlicer %s"%self.slicer.__class__.__name__)) 348 340 # Post slicer event 349 341 event = self._getEmptySlicerEvent() … … 352 344 event.obj_class = self.slicer.__class__ 353 345 event.params = self.slicer.get_params() 354 #print "Plotter2D: event.type",event.type,event.params, self.parent355 356 #wx.PostEvent(self.parent, event)357 346 wx.PostEvent(self, event) 358 347 348 359 349 def onCircular(self, event): 360 350 """ 361 351 perform circular averaging on Data2D 352 @param event: wx.menu event 362 353 """ 363 354 364 355 from DataLoader.manipulations import CircularAverage 365 import math356 ## compute the maximum radius of data2D 366 357 self.qmax= max(math.fabs(self.data2D.xmax),math.fabs(self.data2D.xmin)) 367 358 self.ymax=max(math.fabs(self.data2D.ymax),math.fabs(self.data2D.ymin)) 368 359 self.radius= math.sqrt( math.pow(self.qmax,2)+math.pow(self.ymax,2)) 369 #print "radius?",self.radius 370 # bin_width = self.qmax -self.qmin/nbins 371 #nbins= 30 360 ##Compute beam width 372 361 bin_width = (self.qmax +self.qmax)/100 373 362 ## Create data1D circular average of data2D 374 363 Circle = CircularAverage( r_min=0, r_max=self.radius, bin_width=bin_width) 375 376 364 circ = Circle(self.data2D) 365 377 366 from sans.guiframe.dataFitting import Data1D 378 367 if hasattr(circ,"dxl"): … … 390 379 #new_plot.info=self.data2D.info 391 380 new_plot.interactive = True 392 #print "loader output.detector",output.source393 381 new_plot.detector =self.data2D.detector 394 395 # If the data file does not tell us what the axes are, just assume... 382 ## If the data file does not tell us what the axes are, just assume... 396 383 new_plot.xaxis("\\rm{Q}","A^{-1}") 397 384 new_plot.yaxis("\\rm{Intensity} ","cm^{-1}") 398 385 new_plot.group_id = "Circ avg "+ self.data2D.name 399 386 new_plot.id = "Circ avg "+ self.data2D.name 400 self.scale = 'log' 401 387 402 388 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=new_plot.name)) 403 389 390 404 391 def _onEditSlicer(self, event): 392 """ 393 Is available only when a slicer is drawn.Create a dialog 394 window where the user can enter value to reset slicer 395 parameters. 396 @param event: wx.menu event 397 """ 405 398 if self.slicer !=None: 406 399 from SlicerParameters import SlicerParameterPanel 407 400 dialog = SlicerParameterPanel(self, -1, "Slicer Parameters") 408 #dialog = SlicerParameterPanel(self.parent, -1, "Slicer Parameters")409 401 dialog.set_slicer(self.slicer.__class__.__name__, 410 402 self.slicer.get_params()) … … 412 404 dialog.Destroy() 413 405 406 414 407 def onSectorQ(self, event): 415 408 """ 416 Perform sector averaging on Q 417 """ 418 #print "onsector self.data2Dxmax",self.data2D.xmax, self.parent 409 Perform sector averaging on Q and draw sector slicer 410 """ 419 411 from SectorSlicer import SectorInteractor 420 412 self.onClearSlicer(event) 421 #wx.PostEvent(self.parent, InternalEvent(slicer= SectorInteractor))422 413 wx.PostEvent(self, InternalEvent(slicer= SectorInteractor)) 423 414 424 415 def onSectorPhi(self, event): 425 416 """ 426 Perform sector averaging on Phi 417 Perform sector averaging on Phi and draw annulus slicer 427 418 """ 428 419 from AnnulusSlicer import AnnulusInteractor 429 420 self.onClearSlicer(event) 430 #wx.PostEvent(self.parent, InternalEvent(slicer= AnnulusInteractor))431 421 wx.PostEvent(self, InternalEvent(slicer= AnnulusInteractor)) 432 422 … … 434 424 from boxSum import BoxSum 435 425 self.onClearSlicer(event) 436 #wx.PostEvent(self.parent, InternalEvent(slicer= BoxSum)) 437 if not self.slicer == None: 438 self.slicer.clear() 426 439 427 self.slicer_z += 1 440 428 self.slicer = BoxSum(self, self.subplot, zorder=self.slicer_z) 441 #print "come here"429 442 430 self.subplot.set_ylim(self.data2D.ymin, self.data2D.ymax) 443 431 self.subplot.set_xlim(self.data2D.xmin, self.data2D.xmax) … … 445 433 self.update() 446 434 self.slicer.update() 447 448 # Post slicer event 449 event = self._getEmptySlicerEvent() 450 event.type = self.slicer.__class__.__name__ 451 452 453 event.obj_class = self.slicer.__class__ 454 event.params = self.slicer.get_params() 455 #print "Plotter2D: event.type",event.type,event.params, self.parent 456 435 ## Value used to initially set the slicer panel 436 type = self.slicer.__class__.__name__ 437 params = self.slicer.get_params() 438 ## Create a new panel to display results of summation of Data2D 457 439 from slicerpanel import SlicerPanel 458 new_panel = SlicerPanel(parent= self.parent,id= -1,base= self,type=event.type, 459 params=event.params, style=wx.RAISED_BORDER) 460 #new_panel.set_slicer(self.slicer.__class__.__name__, 461 new_panel.window_caption=str(self.slicer_z)+self.slicer.__class__.__name__+" "+ str(self.data2D.name) 462 new_panel.window_name = str(self.slicer_z)+self.slicer.__class__.__name__+" "+ str(self.data2D.name) 440 new_panel = SlicerPanel(parent= self.parent, id= -1, 441 base= self, type= type, 442 params= params, style= wx.RAISED_BORDER) 443 444 new_panel.window_caption=self.slicer.__class__.__name__+" "+ str(self.data2D.name) 445 new_panel.window_name = self.slicer.__class__.__name__+" "+ str(self.data2D.name) 446 ## Store a reference of the new created panel 463 447 self.panel_slicer= new_panel 448 ## save the window_caption of the new panel in the current slicer 464 449 self.slicer.set_panel_name( name= new_panel.window_caption) 465 # wx.PostEvent(self.panel_slicer, event)450 ## post slicer panel to guiframe to display it 466 451 from sans.guicomm.events import SlicerPanelEvent 467 452 wx.PostEvent(self.parent, SlicerPanelEvent (panel= self.panel_slicer)) 468 #print "finish box sum" 453 469 454 470 455 def onBoxavgX(self,event): 456 """ 457 Perform 2D data averaging on Qx 458 Create a new slicer . 459 @param event: wx.menu event 460 """ 471 461 from boxSlicer import BoxInteractorX 472 462 self.onClearSlicer(event) 473 #wx.PostEvent(self.parent, InternalEvent(slicer= BoxInteractorX))474 463 wx.PostEvent(self, InternalEvent(slicer= BoxInteractorX)) 475 464 476 465 477 466 def onBoxavgY(self,event): 467 """ 468 Perform 2D data averaging on Qy 469 Create a new slicer . 470 @param event: wx.menu event 471 """ 478 472 from boxSlicer import BoxInteractorY 479 473 self.onClearSlicer(event) 480 474 wx.PostEvent(self, InternalEvent(slicer= BoxInteractorY)) 481 #wx.PostEvent(self.parent, InternalEvent(slicer= BoxInteractorY))475 482 476 483 477 def onClearSlicer(self, event): … … 492 486 # Post slicer None event 493 487 event = self._getEmptySlicerEvent() 494 #wx.PostEvent(self.parent, event)495 488 wx.PostEvent(self, event) 496 489 497 498 490 499 491 def _onToggleScale(self, event): 500 492 """ … … 505 497 else: 506 498 self.scale = 'log' 507 self.image(self.data ,self.xmin_2D,self.xmax_2D,self.ymin_2D,499 self.image(self.data2D.data,self.xmin_2D,self.xmax_2D,self.ymin_2D, 508 500 self.ymax_2D,self.zmin_2D ,self.zmax_2D ) 509 501 wx.PostEvent(self.parent, StatusEvent(status="Image is in %s scale"%self.scale)) -
guiframe/local_perspectives/plotting/SectorSlicer.py
r1a6ec25 r6c0568b 13 13 14 14 from BaseInteractor import _BaseInteractor 15 from sans.guicomm.events import NewPlotEvent, StatusEvent,SlicerParameterEvent,EVT_SLICER_PARS 16 17 18 19 15 from sans.guicomm.events import NewPlotEvent, StatusEvent 16 from sans.guicomm.events import SlicerParameterEvent,EVT_SLICER_PARS 20 17 21 18 22 19 class SectorInteractor(_BaseInteractor): 23 20 """ 24 Select an annulus through a 2D plot21 Draw a sector slicer.Allow to performQ averaging on data 2D 25 22 """ 26 23 def __init__(self,base,axes,color='black', zorder=3): 27 24 28 25 _BaseInteractor.__init__(self, base, axes, color=color) 26 ## Class initialization 29 27 self.markers = [] 30 self.axes = axes 31 self.qmax = math.sqrt(math.pow(max(self.base.data2D.xmax,math.fabs(self.base.data2D.xmin)),2)+math.pow(max(self.base.data2D.xmax,math.fabs(self.base.data2D.xmin)),2)) 32 #print "sector qmax", self.qmax 28 self.axes = axes 29 ## connect the plot to event 33 30 self.connect = self.base.connect 34 31 32 ## compute qmax limit to reset the graph 33 x = math.pow(max(self.base.data2D.xmax,math.fabs(self.base.data2D.xmin)),2) 34 y = math.pow(max(self.base.data2D.ymax,math.fabs(self.base.data2D.ymin)),2) 35 self.qmax= math.sqrt(x + y) 35 36 ## Number of points on the plot 36 37 self.nbins = 20 37 self.theta1= math.pi/438 ## Angle of the middle line 38 39 self.theta2= math.pi/3 40 ## Absolute value of the Angle between the middle line and any side line 39 41 self.phi=math.pi/12 40 #self.theta3= 2*self.theta2 -self.theta141 # Inner circle42 self.main_line = LineInteractor(self, self.base.subplot,color=' green', zorder=zorder, r=self.qmax,42 43 ## Middle line 44 self.main_line = LineInteractor(self, self.base.subplot,color='blue', zorder=zorder, r=self.qmax, 43 45 theta= self.theta2) 44 46 self.main_line.qmax = self.qmax 45 #self.left_line = SectionInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax, 46 # theta1= self.theta1, theta2= self.theta2) 47 #self.left_line.qmax = self.base.qmax 47 ## Right Side line 48 48 self.right_line= SideInteractor(self, self.base.subplot,color='black', zorder=zorder, 49 49 r=self.qmax, … … 51 51 theta2=self.theta2) 52 52 self.right_line.qmax = self.qmax 53 self.left_line= SideInteractor(self, self.base.subplot,color='blue', zorder=zorder, 53 ## Left Side line 54 self.left_line= SideInteractor(self, self.base.subplot,color='black', zorder=zorder, 54 55 r=self.qmax, 55 56 phi= self.phi, 56 57 theta2=self.theta2) 57 58 self.left_line.qmax = self.qmax 58 #self.outer_circle.set_cursor(self.base.qmax/1.8, 0) 59 60 59 ## draw the sector 61 60 self.update() 62 61 self._post_data() 63 64 # Bind to slice parameter events62 63 ## Bind to slice parameter events 65 64 self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 66 65 66 67 67 def _onEVT_SLICER_PARS(self, event): 68 68 """ 69 receive an event containing parameters values to reset the slicer 70 @param event: event of type SlicerParameterEvent with params as 71 attribute 72 """ 69 73 wx.PostEvent(self.base.parent, StatusEvent(status="SectorSlicer._onEVT_SLICER_PARS")) 70 74 event.Skip() … … 73 77 self.base.update() 74 78 75 def update_and_post(self):76 self.update()77 #self._post_data()78 79 def save_data(self, path, image, x, y):80 output = open(path, 'w')81 82 data_x, data_y = self.get_data(image, x, y)83 84 output.write("<phi> <average>\n")85 for i in range(len(data_x)):86 output.write("%g %g\n" % (data_x[i], data_y[i]))87 output.close()88 79 89 80 def set_layer(self, n): 81 """ 82 Allow adding plot to the same panel 83 @param n: the number of layer 84 """ 90 85 self.layernum = n 91 86 self.update() 92 87 88 93 89 def clear(self): 90 """ 91 Clear the slicer and all connected events related to this slicer 92 """ 94 93 self.clear_markers() 95 94 self.main_line.clear() … … 97 96 self.right_line.clear() 98 97 self.base.connect.clearall() 99 100 98 self.base.Unbind(EVT_SLICER_PARS) 101 99 100 102 101 def update(self): 103 102 """ 104 Respond to changes in the model by recalculating the profiles and 105 resetting the widgets. 106 """ 107 # Update locations 108 109 #if self.main_line.has_move: 110 #self.main_line.update() 111 #self.right_line.update() 112 #self.left_line.update() 103 Respond to changes in the model by recalculating the profiles and 104 resetting the widgets. 105 """ 106 # Update locations 107 ## Check if the middle line was dragged and update the picture accordingly 113 108 if self.main_line.has_move: 114 109 self.main_line.update() 115 #print "main_theta--->",self.main_line.get_radius()*180/3.14 116 self.right_line.update( delta = -self.left_line.phi/2+math.pi,mline= self.main_line.theta) 117 #print "main_theta--->",self.main_line.get_radius()*180/3.14 118 self.left_line.update( delta = self.left_line.phi/2+math.pi ,mline= self.main_line.theta) 119 #print "main_theta--->",self.main_line.get_radius()*180/3.14 120 #print "Main line has moved ---> phi right",math.degrees(self.main_line.theta),math.degrees(self.main_line.get_radius()),math.degrees(self.main_line.get_radius()+self.right_line.theta) 121 #print "Main line has moved ---> phi left",math.degrees(self.left_line.theta+self.main_line.get_radius()) 110 self.right_line.update( delta= -self.left_line.phi/2+math.pi , 111 mline= self.main_line.theta ) 112 self.left_line.update( delta = self.left_line.phi/2+math.pi , 113 mline= self.main_line.theta ) 114 ## Check if the left side has moved and update the slicer accordingly 122 115 if self.left_line.has_move: 123 #print "left line has moved --->"124 116 self.main_line.update() 125 self.left_line.update(phi=None,delta=None, mline=self.main_line,side=True, left=True) 126 #self.right_line.update(-1*delta,linem=self.main_line,linel=self.left_line) 127 self.right_line.update(phi=self.left_line.phi,delta=None, mline=self.main_line,side=True,left=False, right=True) 128 117 self.left_line.update( phi=None, delta=None, mline=self.main_line , 118 side=True, left=True ) 119 self.right_line.update( phi= self.left_line.phi, delta= None, 120 mline= self.main_line, side= True, 121 left=False, right= True ) 122 ## Check if the right side line has moved and update the slicer accordingly 129 123 if self.right_line.has_move: 130 131 124 self.main_line.update() 132 self.right_line.update(phi=None,delta=None, mline=self.main_line,side=True, left=False,right=True) 133 #print "right line has moved --->",self.right_line.phi 134 self.left_line.update(phi=self.right_line.phi,delta=None, mline=self.main_line,side=True, left=False) 135 136 137 125 self.right_line.update( phi=None, delta=None, mline=self.main_line, 126 side=True, left=False, right=True ) 127 self.left_line.update( phi=self.right_line.phi, delta=None, 128 mline=self.main_line, side=True, left=False ) 129 138 130 139 131 def save(self, ev): … … 143 135 """ 144 136 self.base.freeze_axes() 145 self.inner_circle.save(ev) 146 self.outer_circle.save(ev) 137 self.main_line.save(ev) 138 self.right_line.save(ev) 139 self.left_line.save(ev) 147 140 148 141 def _post_data(self, nbins=None): 149 # Compute data 142 """ 143 compute sector averaging of data2D into data1D 144 @param nbins: the number of point to plot for the average 1D data 145 """ 146 ## get the data2D to average 150 147 data = self.base.data2D 151 148 # If we have no data, just return 152 149 if data == None: 153 150 return 154 155 name = "Sector " 151 ## Averaging 156 152 from DataLoader.manipulations import SectorQ 157 radius = self.qmax #radius=math.sqrt(math.pow(self.qmax,2)+math.pow(self.qmax,2)) 158 phimin = -self.left_line.phi+self.main_line.theta 159 phimax = self.left_line.phi+self.main_line.theta 160 #phimin = min(self.right_line.theta+math.pi,self.left_line.theta+math.pi) 161 #phimax = max(self.right_line.theta+math.pi,self.left_line.theta+math.pi) 162 #print "sector Q angles=",phimin*180/math.pi,phimax*180/math.pi,self.main_line.theta*180/math.pi 163 #phi must be 0 to 2pi with cut-off line sts on the left. 153 radius = self.qmax 154 phimin = -self.left_line.phi + self.main_line.theta 155 phimax = self.left_line.phi + self.main_line.theta 156 164 157 if nbins==None: 165 158 nbins = 20 166 sect = SectorQ(r_min= 0.0, r_max= radius , phi_min=phimin+math.pi, phi_max=phimax+math.pi, nbins=nbins)167 #sect = SectorQ(r_min=-1*radius , r_max= radius , phi_min=phimin, phi_max=phimax)168 169 159 sect = SectorQ(r_min= 0.0, r_max= radius , 160 phi_min= phimin + math.pi, 161 phi_max= phimax + math.pi, nbins=nbins) 162 170 163 sector = sect(self.base.data2D) 171 164 ##Create 1D data resulting from average 172 165 from sans.guiframe.dataFitting import Data1D 173 166 if hasattr(sector,"dxl"): … … 183 176 new_plot.name = "SectorQ" +"("+ self.base.data2D.name+")" 184 177 185 186 187 178 new_plot.source=self.base.data2D.source 188 179 #new_plot.info=self.base.data2D.info 189 180 new_plot.interactive = True 190 #print "loader output.detector",self.base.data2D.info,output.source,191 181 new_plot.detector =self.base.data2D.detector 192 #print "loader output.detector",new_plot.detector193 182 # If the data file does not tell us what the axes are, just assume... 194 183 new_plot.xaxis("\\rm{Q}", 'A^{-1}') … … 202 191 203 192 def moveend(self, ev): 193 """ 194 Called a dragging motion ends.Get slicer event 195 """ 204 196 self.base.thaw_axes() 205 206 # Post paramters 197 ## Post parameters 207 198 event = SlicerParameterEvent() 208 199 event.type = self.__class__.__name__ 209 200 event.params = self.get_params() 210 # wx.PostEvent(self.base.parent, event)201 ## Send slicer paramers to plotter2D 211 202 wx.PostEvent(self.base, event) 212 203 self._post_data() 204 213 205 214 206 def restore(self): … … 226 218 pass 227 219 220 228 221 def set_cursor(self, x, y): 229 222 pass 230 223 224 231 225 def get_params(self): 226 """ 227 Store a copy of values of parameters of the slicer into a dictionary. 228 @return params: the dictionary created 229 """ 232 230 params = {} 233 params["Phi"] = self.main_line.theta 231 ## Always make sure that the left and the right line are at phi 232 ## angle of the middle line 234 233 if math.fabs(self.left_line.phi) != math.fabs(self.right_line.phi): 235 234 raise ValueError,"Phi left and phi right are different %f, %f"%(self.left_line.phi, self.right_line.phi) 235 236 params["Phi"] = self.main_line.theta 236 237 params["Delta_Phi"] = math.fabs(self.left_line.phi) 237 238 params["nbins"] = self.nbins 238 239 return params 239 240 241 240 242 def set_params(self, params): 241 243 """ 244 Receive a dictionary and reset the slicer with values contained 245 in the values of the dictionary. 246 @param params: a dictionary containing name of slicer parameters and 247 values the user assigned to the slicer. 248 """ 242 249 main = params["Phi"] 243 250 phi = math.fabs(params["Delta_Phi"] ) 244 251 self.nbins = int(params["nbins"]) 245 252 self.main_line.theta= main 246 253 ## Reset the slicer parameters 247 254 self.main_line.update() 248 self.right_line.update(phi=phi,delta=None, mline=self.main_line,side=True,right=True) 249 self.left_line.update(phi=phi,delta=None, mline=self.main_line,side=True) 250 255 self.right_line.update( phi=phi,delta=None, mline=self.main_line, 256 side=True, right=True ) 257 self.left_line.update( phi=phi, delta=None, mline=self.main_line, side=True ) 258 ## post the new corresponding data 251 259 self._post_data(nbins=self.nbins) 260 252 261 253 262 def freeze_axes(self): 254 263 self.base.freeze_axes() 255 264 265 256 266 def thaw_axes(self): 257 267 self.base.thaw_axes() 258 268 269 259 270 def draw(self): 260 271 self.base.draw() … … 263 274 class SideInteractor(_BaseInteractor): 264 275 """ 265 Select an annulus through a 2D plot 276 Draw an oblique line 277 @param phi: the phase between the middle line and one side line 278 @param theta2: the angle between the middle line and x- axis 266 279 """ 267 280 def __init__(self,base,axes,color='black', zorder=5, r=1.0,phi=math.pi/4, theta2= math.pi/3): 268 281 269 282 _BaseInteractor.__init__(self, base, axes, color=color) 283 ## Initialize the class 270 284 self.markers = [] 271 285 self.axes = axes 272 273 286 ## compute the value of the angle between the current line and 287 ## the x-axis 274 288 self.save_theta = theta2 + phi 275 289 self.theta= theta2 + phi 290 ## the value of the middle line angle with respect to the x-axis 276 291 self.theta2 = theta2 292 ## Radius to find polar coordinates this line's endpoints 277 293 self.radius = r 294 ## phi is the phase between the current line and the middle line 278 295 self.phi = phi 279 self.scale = 10.0280 # Inner circle296 297 ## End points polar coordinates 281 298 x1= self.radius*math.cos(self.theta) 282 299 y1= self.radius*math.sin(self.theta) 283 300 x2= -1*self.radius*math.cos(self.theta) 284 301 y2= -1*self.radius*math.sin(self.theta) 285 302 ## defining a new marker 286 303 try: 287 # Inner circle marker288 304 self.inner_marker = self.axes.plot([x1/2.5],[y1/2.5], linestyle='', 289 305 marker='s', markersize=10, … … 300 316 message = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION OF MATPLOTLIB\n" 301 317 message += "Get the SVN version that is at least as recent as June 1, 2007" 302 303 304 305 318 owner=self.base.base.parent 319 wx.PostEvent(owner, StatusEvent(status="sectorSlicer: %s"%message)) 320 321 ## Defining the current line 306 322 self.line = self.axes.plot([x1,x2],[y1,y2], 307 323 linestyle='-', marker='', 308 324 color=self.color, 309 325 visible=True)[0] 326 ## Flag to differentiate the left line from the right line motion 310 327 self.left_moving=False 311 312 self.npts = 20 328 ## Flag to define a motion 313 329 self.has_move=False 330 ## connecting markers and draw the picture 314 331 self.connect_markers([self.inner_marker, self.line]) 315 #self.update()332 316 333 317 334 def set_layer(self, n): 335 """ 336 Allow adding plot to the same panel 337 @param n: the number of layer 338 """ 318 339 self.layernum = n 319 340 self.update() 320 341 321 342 def clear(self): 343 """ 344 Clear the slicer and all connected events related to this slicer 345 """ 322 346 self.clear_markers() 323 347 try: … … 330 354 331 355 332 333 def get_radius(self): 334 335 return self.theta - self.save_theta 336 337 def update(self,phi=None,delta=None, mline=None,side=False, left= False, right=False): 338 """ 339 Draw the new roughness on the graph. 356 def update(self, phi=None, delta=None, mline=None, 357 side=False, left= False, right=False): 358 """ 359 Draw oblique line 360 @param phi: the phase between the middle line and the current line 361 @param delta: 340 362 """ 341 363 #print "update left or right ", self.has_move … … 365 387 theta3=self.theta2+delta 366 388 367 #self.phi= math.fabs(self.theta2 - (self.theta+delta)) 368 #print "U:for line side theta2, phi, theta",math.degrees(self.theta2),math.degrees(self.phi),math.degrees(self.theta) 369 #if self.theta2 >= self.theta and self.theta>=0: 370 # print "between 0-pi",math.degrees(self.theta) 371 389 372 390 x1= self.radius*math.cos(theta3) 373 391 y1= self.radius*math.sin(theta3) … … 538 556 for item in range(len(self.axes.lines)): 539 557 del self.axes.lines[0] 540 541 542 543 def get_radius(self): 544 545 return self.theta - self.save_theta 546 558 559 547 560 def update(self, theta=None): 548 561 """ 549 562 Draw the new roughness on the graph. 550 563 """ 551 #print "update main line", self.theta564 552 565 if theta !=None: 553 566 self.theta= theta -
guiframe/local_perspectives/plotting/boxSlicer.py
reba08f1a r6c0568b 25 25 def __init__(self,base,axes,color='black', zorder=3): 26 26 _BaseInteractor.__init__(self, base, axes, color=color) 27 27 ## Class initialization 28 28 self.markers = [] 29 29 self.axes = axes 30 30 ##connecting artist 31 31 self.connect = self.base.connect 32 32 ## determine x y values 33 33 self.x= 0.5*min(math.fabs(self.base.data2D.xmax),math.fabs( self.base.data2D.xmin)) 34 34 self.y= 0.5*min(math.fabs(self.base.data2D.xmax),math.fabs( self.base.data2D.xmin)) 35 35 ## when reach qmax reset the graph 36 36 self.qmax = max(self.base.data2D.xmax,self.base.data2D.xmin, 37 37 self.base.data2D.ymax,self.base.data2D.ymin ) 38 39 38 ## Number of points on the plot 40 39 self.nbins = 30 41 40 ## reference of the current Slab averaging 42 41 self.averager=None 43 42 ## Create vertical and horizaontal lines for the rectangle 44 43 self.vertical_lines = VerticalLines(self, self.base.subplot,color='blue', 45 44 zorder=zorder, … … 53 52 y= self.y) 54 53 self.horizontal_lines.qmax= self.qmax 55 54 ## draw the rectangle and plost the data 1D resulting 55 ## of averaging data2D 56 56 self.update() 57 57 self._post_data() 58 59 # Bind to slice parameter events 58 ## Bind to slice parameter events 60 59 self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 61 60 62 61 63 62 def _onEVT_SLICER_PARS(self, event): 63 """ 64 receive an event containing parameters values to reset the slicer 65 @param event: event of type SlicerParameterEvent with params as 66 attribute 67 """ 64 68 wx.PostEvent(self.base.parent, StatusEvent(status="BoxSlicer._onEVT_SLICER_PARS")) 65 69 event.Skip() … … 68 72 self.base.update() 69 73 74 70 75 def update_and_post(self): 76 """ 77 Update the slicer and plot the resulting data 78 """ 71 79 self.update() 72 80 self._post_data() 73 81 74 def save_data(self, path, image, x, y):75 output = open(path, 'w')76 77 data_x, data_y = self.get_data(image, x, y)78 79 output.write("<phi> <average>\n")80 for i in range(len(data_x)):81 output.write("%g %g\n" % (data_x[i], data_y[i]))82 output.close()83 82 84 83 def set_layer(self, n): 84 """ 85 Allow adding plot to the same panel 86 @param n: the number of layer 87 """ 85 88 self.layernum = n 86 89 self.update() 87 90 91 88 92 def clear(self): 93 """ 94 Clear the slicer and all connected events related to this slicer 95 """ 89 96 self.averager=None 90 97 self.clear_markers() … … 92 99 self.vertical_lines.clear() 93 100 self.base.connect.clearall() 94 95 101 self.base.Unbind(EVT_SLICER_PARS) 102 96 103 97 104 def update(self): … … 100 107 resetting the widgets. 101 108 """ 109 ##Update the slicer if an horizontal line is dragged 102 110 if self.horizontal_lines.has_move: 103 #print "top has moved"104 111 self.horizontal_lines.update() 105 112 self.vertical_lines.update(y=self.horizontal_lines.y) 113 114 ##Update the slicer if a vertical line is dragged 106 115 if self.vertical_lines.has_move: 107 #print "right has moved"108 116 self.vertical_lines.update() 109 117 self.horizontal_lines.update(x=self.vertical_lines.x) 110 111 118 112 119 … … 125 132 126 133 def post_data(self,new_slab=None , nbins=None): 127 """ post data averaging in Q""" 134 """ 135 post data averaging in Qx or Qy given new_slab type 136 @param new_slab: slicer that determine with direction to average 137 @param nbins: the number of points plotted when averaging 138 """ 128 139 x_min= -1*math.fabs(self.vertical_lines.x) 129 140 x_max= math.fabs(self.vertical_lines.x) … … 139 150 self.averager= new_slab 140 151 bin_width= (x_max + math.fabs(x_min))/self.nbins 141 152 ## Average data2D given Qx or Qy 142 153 box = self.averager( x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max, 143 154 bin_width=bin_width) 144 155 145 156 boxavg = box(self.base.data2D) 146 157 #3 Create Data1D to plot 147 158 from sans.guiframe.dataFitting import Data1D 148 159 if hasattr(boxavg,"dxl"): … … 158 169 new_plot.name = str(self.averager.__name__) +"("+ self.base.data2D.name+")" 159 170 160 161 162 171 new_plot.source=self.base.data2D.source 163 172 new_plot.interactive = True 164 #print "loader output.detector",output.source165 173 new_plot.detector =self.base.data2D.detector 166 174 # If the data file does not tell us what the axes are, just assume... … … 175 183 176 184 def moveend(self, ev): 185 """ 186 Called after a dragging event. 187 Post the slicer new parameters and creates a new Data1D 188 corresponding to the new average 189 """ 177 190 self.base.thaw_axes() 178 179 191 # Post paramters 180 192 event = SlicerParameterEvent() … … 182 194 event.params = self.get_params() 183 195 wx.PostEvent(self.base.parent, event) 184 196 # create the new data1D 185 197 self._post_data() 198 186 199 187 200 def restore(self): … … 199 212 pass 200 213 214 201 215 def set_cursor(self, x, y): 202 216 pass 203 217 218 204 219 def get_params(self): 220 """ 221 Store a copy of values of parameters of the slicer into a dictionary. 222 @return params: the dictionary created 223 """ 205 224 params = {} 206 225 params["x_max"]= math.fabs(self.vertical_lines.x) 207 226 params["y_max"]= math.fabs(self.horizontal_lines.y) 208 227 params["nbins"]= self.nbins 209 210 228 return params 211 229 212 230 def set_params(self, params): 213 231 """ 232 Receive a dictionary and reset the slicer with values contained 233 in the values of the dictionary. 234 @param params: a dictionary containing name of slicer parameters and 235 values the user assigned to the slicer. 236 """ 214 237 self.x = float(math.fabs(params["x_max"])) 215 238 self.y = float(math.fabs(params["y_max"] )) … … 224 247 self.base.freeze_axes() 225 248 249 226 250 def thaw_axes(self): 227 251 self.base.thaw_axes() 228 252 253 229 254 def draw(self): 230 255 self.base.draw() 231 256 257 232 258 class HorizontalLines(_BaseInteractor): 233 259 """ 234 Select an annulus through a 2D plot 260 Draw 2 Horizontal lines centered on (0,0) that can move 261 on the x- direction and in opposite direction 235 262 """ 236 263 def __init__(self,base,axes,color='black', zorder=5,x=0.5, y=0.5): 237 264 238 265 _BaseInteractor.__init__(self, base, axes, color=color) 266 ##Class initialization 239 267 self.markers = [] 240 268 self.axes = axes 269 ## Saving the end points of two lines 241 270 self.x= x 242 271 self.save_x= x … … 244 273 self.y= y 245 274 self.save_y= y 246 275 ## Creating a marker 247 276 try: 248 277 # Inner circle marker … … 261 290 message = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION OF MATPLOTLIB\n" 262 291 message += "Get the SVN version that is at least as recent as June 1, 2007" 263 292 owner=self.base.base.parent 293 wx.PostEvent(owner, StatusEvent(status="AnnulusSlicer: %s"%message)) 294 295 ## Define 2 horizontal lines 264 296 self.top_line = self.axes.plot([self.x,-self.x], 265 297 [self.y,self.y], … … 272 304 color=self.color, 273 305 visible=True)[0] 274 306 ## Flag to check the motion of the lines 275 307 self.has_move=False 308 ## Connecting markers to mouse events and draw 276 309 self.connect_markers([self.top_line, self.inner_marker]) 277 310 self.update() 278 311 312 279 313 def set_layer(self, n): 314 """ 315 Allow adding plot to the same panel 316 @param n: the number of layer 317 """ 280 318 self.layernum = n 281 319 self.update() 282 320 321 283 322 def clear(self): 323 """ 324 Clear this slicer and its markers 325 """ 284 326 self.clear_markers() 285 327 try: … … 295 337 def update(self,x=None,y=None): 296 338 """ 297 Draw the new roughness on the graph. 298 """ 339 Draw the new roughness on the graph. 340 @param x: x-coordinates to reset current class x 341 @param y: y-coordinates to reset current class y 342 """ 343 ## Reset x, y- coordinates if send as parameters 299 344 if x!=None: 300 345 self.x = numpy.sign(self.x)*math.fabs(x) 301 346 if y !=None: 302 347 self.y = numpy.sign(self.y)*math.fabs(y) 348 ## Draw lines and markers 303 349 self.inner_marker.set(xdata=[0],ydata=[self.y]) 304 305 350 self.top_line.set(xdata=[self.x,-self.x], 306 351 ydata=[self.y,self.y]) … … 316 361 self.save_x= self.x 317 362 self.save_y= self.y 318 319 363 self.base.freeze_axes() 320 364 365 321 366 def moveend(self, ev): 322 367 """ 368 Called after a dragging this edge and set self.has_move to False 369 to specify the end of dragging motion 370 """ 323 371 self.has_move=False 324 372 self.base.moveend(ev) 373 325 374 326 375 def restore(self): … … 336 385 Process move to a new position, making sure that the move is allowed. 337 386 """ 338 #print "horizontal move x y "339 387 self.y= y 340 388 self.has_move=True … … 342 390 343 391 344 345 346 347 392 class VerticalLines(_BaseInteractor): 348 393 """ … … 390 435 self.update() 391 436 437 392 438 def set_layer(self, n): 439 """ 440 Allow adding plot to the same panel 441 @param n: the number of layer 442 """ 393 443 self.layernum = n 394 444 self.update() 395 445 446 396 447 def clear(self): 448 """ 449 Clear this slicer and its markers 450 """ 397 451 self.clear_markers() 398 452 try: … … 405 459 del self.axes.lines[0] 406 460 461 407 462 def update(self,x=None,y=None): 408 463 """ 409 Draw the new roughness on the graph. 410 """ 411 464 Draw the new roughness on the graph. 465 @param x: x-coordinates to reset current class x 466 @param y: y-coordinates to reset current class y 467 """ 468 ## reset x, y -coordinates if given as parameters 412 469 if x!=None: 413 470 self.x = numpy.sign(self.x)*math.fabs(x) 414 471 if y !=None: 415 472 self.y = numpy.sign(self.y)*math.fabs(y) 416 473 ## draw lines and markers 417 474 self.inner_marker.set(xdata=[self.x],ydata=[0]) 418 475 self.left_line.set(xdata=[-self.x,-self.x], … … 432 489 self.base.freeze_axes() 433 490 491 434 492 def moveend(self, ev): 435 493 """ 494 Called after a dragging this edge and set self.has_move to False 495 to specify the end of dragging motion 496 """ 436 497 self.has_move=False 437 498 self.base.moveend(ev) 499 438 500 439 501 def restore(self): … … 464 526 self.base=base 465 527 self._post_data() 528 529 466 530 def _post_data(self): 531 """ 532 Post data creating by averaging in Qx direction 533 """ 467 534 from DataLoader.manipulations import SlabX 468 535 self.post_data(SlabX ) … … 477 544 self.base=base 478 545 self._post_data() 546 547 479 548 def _post_data(self): 549 """ 550 Post data creating by averaging in Qy direction 551 """ 480 552 from DataLoader.manipulations import SlabY 481 553 self.post_data(SlabY ) -
guiframe/local_perspectives/plotting/boxSum.py
reba08f1a r6c0568b 497 497 def clear(self): 498 498 """ 499 Clear this figureand its markers499 Clear this slicer and its markers 500 500 """ 501 501 self.clear_markers() -
guiframe/local_perspectives/plotting/plotting.py
r6d920cd r6c0568b 12 12 import wx 13 13 import sys 14 #import danse.common.plottools15 #from danse.common.plottools.PlotPanel import PlotPanel16 #from danse.common.plottools.plottables import Graph,Data1D17 14 from sans.guicomm.events import EVT_NEW_PLOT 18 15 from sans.guicomm.events import StatusEvent … … 86 83 pass 87 84 85 88 86 def _on_show_panel(self, event): 89 print "_on_show_panel" 90 87 """show plug-in panel""" 88 pass 89 90 91 91 def _on_plot_event(self, event): 92 92 """ … … 104 104 and event.plot._yunit == panel.graph.prop["yunit_base"]: 105 105 if hasattr(event.plot, "group_id"): 106 ## if same group_id used the same panel to plot 106 107 if not event.plot.group_id==None \ 107 108 and event.plot.group_id==panel.group_id: … … 109 110 110 111 panel._onEVT_1DREPLOT(event) 111 self.parent.show_panel(panel.uid) 112 #print "went here for replottiing", event.plot.name 113 112 self.parent.show_panel(panel.uid) 114 113 else: 115 114 # Check that the plot panel has no group ID 115 ## Use a panel with group_id ==None to plot 116 116 if panel.group_id==None: 117 117 is_available = True … … 123 123 if not hasattr(event.plot,'data'): 124 124 from Plotter1D import ModelPanel1D 125 ## get the data representation label of the data to plot 126 ## when even the user select "change scale" 125 127 if hasattr(event.plot,"xtransform"): 126 #print "went here"127 128 xtransform = event.plot.xtransform 128 129 else: 129 130 130 xtransform =None 131 131 132 if hasattr(event.plot,"ytransform"): 132 133 ytransform= event.plot.ytransform 133 134 else: 134 135 ytransform=None 136 ## create a plotpanel for 1D Data 135 137 new_panel = ModelPanel1D(self.parent, -1,xtransform=xtransform, 136 138 ytransform=ytransform, style=wx.RAISED_BORDER) 137 139 else: 140 ##Create a new plotpanel for 2D data 138 141 from Plotter2D import ModelPanel2D 139 142 new_panel = ModelPanel2D(self.parent, -1, data2d=event.plot,style=wx.RAISED_BORDER) 140 # Set group ID if available 143 144 ## Set group ID if available 145 ## Assign data properties to the new create panel 141 146 group_id_str = '' 142 147 if hasattr(event.plot, "group_id"): … … 148 153 new_panel.window_caption = event.title 149 154 new_panel.window_name = event.title 150 #new_panel.window_caption = event.title+group_id_str 151 #new_panel.window_name = event.title+group_id_str 152 155 153 156 event_id = self.parent.popup_panel(new_panel) 154 157 self.menu.Append(event_id, new_panel.window_caption,
Note: See TracChangeset
for help on using the changeset viewer.