- Timestamp:
- Dec 1, 2008 5:09:36 PM (16 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:
- a92d51b
- Parents:
- 7a7bf55
- Location:
- guiframe/local_perspectives/plotting
- Files:
-
- 6 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
guiframe/local_perspectives/plotting/DataPanel.py
rce64735 rb06ef8c 17 17 from sans.guicomm.events import EVT_NEW_PLOT 18 18 from sans.guicomm.events import StatusEvent ,NewPlotEvent 19 20 from binder import BindArtist 21 #from SlicerParameters import SlicerEvent 22 #(InternalEvent, EVT_INTERNAL) = wx.lib.newevent.NewEvent() 23 DEFAULT_QMAX = 0.05 24 25 DEFAULT_QSTEP = 0.001 26 DEFAULT_BEAM = 0.005 27 28 import pylab 19 29 20 30 class PanelMenu(wx.Menu): … … 344 354 ## Plottables 345 355 self.plots = {} 346 self.data = data2d 356 self.data2D= data2d 357 self.data = data2d.data 347 358 ## Unique ID (from gui_manager) 348 359 self.uid = None … … 350 361 ## Action IDs for internal call-backs 351 362 self.action_ids = {} 352 363 self.connect = BindArtist(self.subplot.figure) 364 365 # Beam stop 366 self.beamstop_radius = DEFAULT_BEAM 367 # Slicer 368 369 self.qmax = data2d.xmax 370 self.imax= data2d.ymax 371 self.qstep = DEFAULT_QSTEP 372 self.x = pylab.arange(-self.qmax, self.qmax+self.qstep*0.01, self.qstep) 373 self.y = pylab.arange(-self.imax, self.imax+self.qstep*0.01, self.qstep) 374 375 self.slicer_z = 5 376 self.slicer = None 377 #self.parent.Bind(EVT_INTERNAL, self._onEVT_INTERNAL) 378 self.axes_frozen = False 353 379 ## Graph 354 380 self.graph = Graph() … … 427 453 428 454 id = wx.NewId() 455 slicerpop.Append(id, '&Sector') 456 wx.EVT_MENU(self, id, self.onSector) 457 458 459 460 id = wx.NewId() 461 slicerpop.Append(id, '&Clear slicer') 462 wx.EVT_MENU(self, id, self.onClearSlicer) 463 464 id = wx.NewId() 465 slicerpop.Append(id, '&Edit Parameters') 466 wx.EVT_MENU(self, id, self._onEditDetector) 467 468 slicerpop.AppendSeparator() 469 470 id = wx.NewId() 471 slicerpop.Append(id, '&Save image') 472 wx.EVT_MENU(self, id, self.onSaveImage) 473 474 id = wx.NewId() 429 475 slicerpop.Append(id, '&Toggle Linear/Log scale') 430 476 wx.EVT_MENU(self, id, self._onToggleScale) 431 477 432 478 pos = event.GetPosition() 433 479 pos = self.ScreenToClient(pos) 434 480 self.PopupMenu(slicerpop, pos) 435 481 482 def _setSlicer(self, slicer): 483 # Clear current slicer 484 #printEVT("Plotter2D._setSlicer %s" % slicer) 485 486 if not self.slicer == None: 487 self.slicer.clear() 488 489 self.slicer_z += 1 490 self.slicer = slicer(self, self.subplot, zorder=self.slicer_z) 491 self.subplot.set_ylim(-self.qmax, self.qmax) 492 self.subplot.set_xlim(-self.qmax, self.qmax) 493 self.update() 494 self.slicer.update() 495 496 497 def get_corrected_data(self): 498 # Protect against empty data set 499 if self.data == None: 500 return None 501 import copy 502 output = copy.deepcopy(self.data) 503 return output 504 def freeze_axes(self): 505 self.axes_frozen = True 506 507 def thaw_axes(self): 508 self.axes_frozen = False 509 510 def onMouseMotion(self,event): 511 pass 512 def onWheel(self, event): 513 pass 514 def update(self, draw=True): 515 """ 516 Respond to changes in the model by recalculating the 517 profiles and resetting the widgets. 518 """ 519 #self.slicer.update() 520 self.draw() 521 522 523 def onSector(self, event): 524 525 from SectorSlicer import SectorInteractor 526 527 self.slicer_z += 1 528 self.slicer = SectorInteractor(self, self.subplot, zorder=self.slicer_z) 529 self.subplot.set_ylim(-self.qmax, self.qmax) 530 self.subplot.set_xlim(-self.qmax, self.qmax) 531 self.update() 532 self.slicer.update() 533 534 535 def onClearSlicer(self, event): 536 print "on clear" 537 538 539 def _onEditDetector(self, event): 540 print "on parameter" 541 542 436 543 def _onToggleScale(self, event): 437 544 """ … … 524 631 525 632 526 def onSectorSlicer(self, event): 527 print "onLineSlicer" 528 import math 529 from DataLoader.manipulations import SectorPhi 530 for item in self.graph.plottables: 531 r= SectorPhi(005,.01, 0.0, math.pi/2.0) 532 print r(item) 533 data=r(item) 534 new_plot= Data1D(x=data.x,y=data.y,dy=data.dy ) 535 new_plot.name = "sector" 536 new_plot.group_id= "sector" 537 #wx.PostEvent(self.parent, NewPlotEvent(plot=r(item), title="Analytical model")) 538 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="Analytical model")) 539 540 541 633 634 -
guiframe/local_perspectives/plotting/plotting.py
rc4172272 rb06ef8c 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,Data1D14 #import danse.common.plottools 15 #from danse.common.plottools.PlotPanel import PlotPanel 16 #from danse.common.plottools.plottables import Graph,Data1D 17 17 from sans.guicomm.events import EVT_NEW_PLOT 18 18 from sans.guicomm.events import StatusEvent 19 class PanelMenu(wx.Menu):20 plots = None21 graph = None22 23 def set_plots(self, plots):24 self.plots = plots25 26 def set_graph(self, graph):27 self.graph = graph28 29 class View1DPanel1D(PlotPanel):30 """31 Plot panel for use with the GUI manager32 """33 34 ## Internal name for the AUI manager35 window_name = "plotpanel"36 ## Title to appear on top of the window37 window_caption = "Plot Panel"38 ## Flag to tell the GUI manager that this panel is not39 # tied to any perspective40 ALWAYS_ON = True41 ## Group ID42 group_id = None43 44 def __init__(self, parent, id = -1, color = None,\45 dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):46 """47 Initialize the panel48 """49 PlotPanel.__init__(self, parent, id = id, style = style, **kwargs)50 51 ## Reference to the parent window52 self.parent = parent53 ## Plottables54 self.plots = {}55 56 ## Unique ID (from gui_manager)57 self.uid = None58 59 ## Action IDs for internal call-backs60 self.action_ids = {}61 62 ## Graph63 self.graph = Graph()64 self.graph.xaxis("\\rm{Q}", 'A^{-1}')65 self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")66 self.graph.render(self)67 68 def _reset(self):69 """70 Resets internal data and graph71 """72 self.graph.reset()73 self.plots = {}74 self.action_ids = {}75 76 def _onEVT_1DREPLOT(self, event):77 """78 Data is ready to be displayed79 @param event: data event80 """81 #TODO: Check for existence of plot attribute82 19 83 # Check whether this is a replot. If we ask for a replot84 # and the plottable no longer exists, ignore the event.85 if hasattr(event, "update") and event.update==True \86 and event.plot.name not in self.plots.keys():87 return88 89 if hasattr(event, "reset"):90 self._reset()91 92 is_new = True93 if event.plot.name in self.plots.keys():94 # Check whether the class of plottable changed95 #print "panel1D ",event.plot.__class_96 #print "event panel 1d",self.plots[event.plot.name].__class__97 if not event.plot.__class__==self.plots[event.plot.name].__class__:98 self.graph.delete(self.plots[event.plot.name])99 else:100 is_new = False101 102 if is_new:103 self.plots[event.plot.name] = event.plot104 self.graph.add(self.plots[event.plot.name])105 else:106 self.plots[event.plot.name].x = event.plot.x107 self.plots[event.plot.name].y = event.plot.y108 self.plots[event.plot.name].dy = event.plot.dy109 if hasattr(event.plot, 'dx') and hasattr(self.plots[event.plot.name], 'dx'):110 self.plots[event.plot.name].dx = event.plot.dx111 112 113 # Check axis labels114 #TODO: Should re-factor this115 #if event.plot._xunit != self.graph.prop["xunit"]:116 self.graph.xaxis(event.plot._xaxis, event.plot._xunit)117 118 #if event.plot._yunit != self.graph.prop["yunit"]:119 self.graph.yaxis(event.plot._yaxis, event.plot._yunit)120 121 # Set the view scale for all plots122 self._onEVT_FUNC_PROPERTY()123 124 self.graph.render(self)125 self.subplot.figure.canvas.draw_idle()126 127 def onLeftDown(self,event):128 """ left button down and ready to drag"""129 130 PlotPanel.onLeftDown(self, event)131 ax = event.inaxes132 if ax != None:133 position = "x: %8.3g y: %8.3g" % (event.xdata, event.ydata)134 wx.PostEvent(self.parent, StatusEvent(status=position))135 136 def _onRemove(self, event):137 """138 """139 if not self.graph.selected_plottable == None:140 print self.graph.selected_plottable141 142 143 self.graph.delete(self.plots[self.graph.selected_plottable])144 del self.plots[self.graph.selected_plottable]145 self.graph.render(self)146 self.subplot.figure.canvas.draw_idle()147 148 149 def onContextMenu(self, event):150 """151 1D plot context menu152 @param event: wx context event153 """154 #slicerpop = wx.Menu()155 slicerpop = PanelMenu()156 slicerpop.set_plots(self.plots)157 slicerpop.set_graph(self.graph)158 159 # Option to save the data displayed160 161 #for plot in self.graph.plottables:162 if self.graph.selected_plottable in self.plots:163 plot = self.plots[self.graph.selected_plottable]164 id = wx.NewId()165 name = plot.name166 slicerpop.Append(id, "&Save %s points" % name)167 self.action_ids[str(id)] = plot168 wx.EVT_MENU(self, id, self._onSave)169 170 # Option to delete plottable171 id = wx.NewId()172 slicerpop.Append(id, "Remove %s curve" % name)173 self.action_ids[str(id)] = plot174 wx.EVT_MENU(self, id, self._onRemove)175 176 # Option to hide177 #TODO: implement functionality to hide a plottable (legend click)178 slicerpop.AppendSeparator()179 180 # Various plot options181 id = wx.NewId()182 slicerpop.Append(id,'&Save image', 'Save image as PNG')183 wx.EVT_MENU(self, id, self.onSaveImage)184 185 186 item_list = self.parent.get_context_menu(self.graph)187 if (not item_list==None) and (not len(item_list)==0):188 slicerpop.AppendSeparator()189 for item in item_list:190 try:191 id = wx.NewId()192 slicerpop.Append(id, item[0], item[1])193 wx.EVT_MENU(self, id, item[2])194 except:195 print sys.exc_value196 print RuntimeError, "View1DPanel.onContextMenu: bad menu item"197 198 slicerpop.AppendSeparator()199 200 if self.graph.selected_plottable in self.plots:201 if self.plots[self.graph.selected_plottable].__class__.__name__=="Theory1D":202 id = wx.NewId()203 slicerpop.Append(id, '&Add errors to data')204 wx.EVT_MENU(self, id, self._on_add_errors)205 else:206 id = wx.NewId()207 slicerpop.Append(id, '&Linear fit')208 wx.EVT_MENU(self, id, self.onFitting)209 210 211 212 id = wx.NewId()213 slicerpop.Append(id, '&Change scale')214 wx.EVT_MENU(self, id, self._onProperties)215 216 id = wx.NewId()217 #slicerpop.AppendSeparator()218 slicerpop.Append(id, '&Reset Graph')219 wx.EVT_MENU(self, id, self.onResetGraph)220 221 pos = event.GetPosition()222 pos = self.ScreenToClient(pos)223 self.PopupMenu(slicerpop, pos)224 225 226 def _on_add_errors(self, evt):227 """228 Compute reasonable errors for a data set without229 errors and transorm the plottable to a Data1D230 """231 import math232 import numpy233 import time234 235 if not self.graph.selected_plottable == None:236 length = len(self.plots[self.graph.selected_plottable].x)237 dy = numpy.zeros(length)238 for i in range(length):239 dy[i] = math.sqrt(self.plots[self.graph.selected_plottable].y[i])240 241 new_plot = Data1D(self.plots[self.graph.selected_plottable].x,242 self.plots[self.graph.selected_plottable].y,243 dy=dy)244 new_plot.interactive = True245 new_plot.name = self.plots[self.graph.selected_plottable].name246 if hasattr(self.plots[self.graph.selected_plottable], "group_id"):247 new_plot.group_id = self.plots[self.graph.selected_plottable].group_id248 else:249 new_plot.group_id = str(time.time())250 251 label, unit = self.plots[self.graph.selected_plottable].get_xaxis()252 new_plot.xaxis(label, unit)253 label, unit = self.plots[self.graph.selected_plottable].get_yaxis()254 new_plot.yaxis(label, unit)255 256 self.graph.delete(self.plots[self.graph.selected_plottable])257 258 self.graph.add(new_plot)259 self.plots[self.graph.selected_plottable]=new_plot260 261 self.graph.render(self)262 self.subplot.figure.canvas.draw_idle()263 264 def _onSave(self, evt):265 """266 Save a data set to a text file267 @param evt: Menu event268 """269 import os270 id = str(evt.GetId())271 if id in self.action_ids:272 273 path = None274 dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.txt", wx.SAVE)275 if dlg.ShowModal() == wx.ID_OK:276 path = dlg.GetPath()277 mypath = os.path.basename(path)278 print path279 dlg.Destroy()280 281 if not path == None:282 out = open(path, 'w')283 has_errors = True284 if self.action_ids[id].dy==None or self.action_ids[id].dy==[]:285 has_errors = False286 287 # Sanity check288 if has_errors:289 try:290 if len(self.action_ids[id].y) != len(self.action_ids[id].dy):291 print "Y and dY have different lengths"292 has_errors = False293 except:294 has_errors = False295 296 if has_errors:297 out.write("<X> <Y> <dY>\n")298 else:299 out.write("<X> <Y>\n")300 301 for i in range(len(self.action_ids[id].x)):302 if has_errors:303 out.write("%g %g %g\n" % (self.action_ids[id].x[i],304 self.action_ids[id].y[i],305 self.action_ids[id].dy[i]))306 else:307 out.write("%g %g\n" % (self.action_ids[id].x[i],308 self.action_ids[id].y[i]))309 310 out.close()311 312 313 def _onToggleScale(self, event):314 if self.get_yscale() == 'log':315 self.set_yscale('linear')316 else:317 self.set_yscale('log')318 self.subplot.figure.canvas.draw_idle()319 320 class View1DPanel2D( View1DPanel1D):321 """322 Plot panel for use with the GUI manager323 """324 325 ## Internal name for the AUI manager326 window_name = "plotpanel"327 ## Title to appear on top of the window328 window_caption = "Plot Panel"329 ## Flag to tell the GUI manager that this panel is not330 # tied to any perspective331 ALWAYS_ON = True332 ## Group ID333 group_id = None334 335 def __init__(self, parent, id = -1, color = None,\336 dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):337 """338 Initialize the panel339 """340 View1DPanel1D.__init__(self, parent, id = id, style = style, **kwargs)341 342 ## Reference to the parent window343 self.parent = parent344 ## Plottables345 self.plots = {}346 347 ## Unique ID (from gui_manager)348 self.uid = None349 350 ## Action IDs for internal call-backs351 self.action_ids = {}352 353 ## Graph354 self.graph = Graph()355 self.graph.xaxis("\\rm{Q}", 'A^{-1}')356 self.graph.yaxis("\\rm{Intensity} ","cm^{-1}")357 self.graph.render(self)358 359 def _onEVT_1DREPLOT(self, event):360 """361 Data is ready to be displayed362 @param event: data event363 """364 #TODO: Check for existence of plot attribute365 # Check whether this is a replot. If we ask for a replot366 # and the plottable no longer exists, ignore the event.367 if hasattr(event, "update") and event.update==True \368 and event.plot.name not in self.plots.keys():369 return370 if hasattr(event, "reset"):371 self._reset()372 is_new = True373 if event.plot.name in self.plots.keys():374 # Check whether the class of plottable changed375 if not event.plot.__class__==self.plots[event.plot.name].__class__:376 self.graph.delete(self.plots[event.plot.name])377 else:378 is_new = False379 self.plots[event.plot.name] = event.plot380 #if is_new:381 self.graph.add(self.plots[event.plot.name])382 383 384 # Check axis labels385 #TODO: Should re-factor this386 #if event.plot._xunit != self.graph.prop["xunit"]:387 388 self.graph.xaxis(event.plot._xaxis, event.plot._xunit)389 #if event.plot._yunit != self.graph.prop["yunit"]:390 self.graph.yaxis(event.plot._yaxis, event.plot._yunit)391 self.graph.render(self)392 self.subplot.figure.canvas.draw_idle()393 394 395 def onContextMenu(self, event):396 """397 2D plot context menu398 @param event: wx context event399 """400 401 #slicerpop = wx.Menu()402 slicerpop = PanelMenu()403 slicerpop.set_plots(self.plots)404 slicerpop.set_graph(self.graph)405 406 # Option to save the data displayed407 408 # Various plot options409 id = wx.NewId()410 slicerpop.Append(id,'&Save image', 'Save image as PNG')411 wx.EVT_MENU(self, id, self.onSaveImage)412 413 414 item_list = self.parent.get_context_menu(self.graph)415 if (not item_list==None) and (not len(item_list)==0):416 slicerpop.AppendSeparator()417 for item in item_list:418 try:419 id = wx.NewId()420 slicerpop.Append(id, item[0], item[1])421 wx.EVT_MENU(self, id, item[2])422 except:423 print sys.exc_value424 print RuntimeError, "View1DPanel2D.onContextMenu: bad menu item"425 426 slicerpop.AppendSeparator()427 428 id = wx.NewId()429 slicerpop.Append(id, '&Toggle Linear/Log scale')430 wx.EVT_MENU(self, id, self._onToggleScale)431 432 pos = event.GetPosition()433 pos = self.ScreenToClient(pos)434 self.PopupMenu(slicerpop, pos)435 436 def _onToggleScale(self, event):437 """438 toggle axis and replot image439 """440 if self.scale == 'log':441 self.scale = 'linear'442 else:443 self.scale = 'log'444 self.image(self.data,self.xmin_2D,self.xmax_2D,self.ymin_2D,445 self.ymax_2D,self.zmin_2D ,self.zmax_2D )446 wx.PostEvent(self.parent, StatusEvent(status="Image is in %s scale"%self.scale))447 448 20 class Plugin: 449 21 """ … … 545 117 if not is_available: 546 118 if not hasattr(event.plot,'data'): 119 from DataPanel import View1DPanel1D 547 120 new_panel = View1DPanel1D(self.parent, -1, style=wx.RAISED_BORDER) 548 121 else: 549 new_panel = View1DPanel2D(self.parent, -1, style=wx.RAISED_BORDER) 122 from DataPanel import View1DPanel2D 123 new_panel = View1DPanel2D(self.parent, -1, data2d=event.plot,style=wx.RAISED_BORDER) 550 124 # Set group ID if available 551 125 group_id_str = ''
Note: See TracChangeset
for help on using the changeset viewer.