Changeset 9290b1a in sasview for src/sas/qtgui/PlotterBase.py
- Timestamp:
- Dec 16, 2016 12:43:18 PM (7 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:
- d3ca363
- Parents:
- 0ba0774
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/PlotterBase.py
r27313b7 r9290b1a 1 1 import pylab 2 import numpy 2 3 3 4 from PyQt4 import QtGui … … 13 14 14 15 DEFAULT_CMAP = pylab.cm.jet 16 from sas.sasgui.plottools.binder import BindArtist 17 15 18 from sas.qtgui.ScaleProperties import ScaleProperties 16 19 from sas.qtgui.WindowTitle import WindowTitle 17 20 import sas.qtgui.PlotHelper as PlotHelper 21 import sas.qtgui.PlotUtilities as PlotUtilities 18 22 19 23 class PlotterBase(QtGui.QWidget): … … 53 57 self.y_label = "log10(y)" 54 58 59 # Mouse click related 60 self.x_click = None 61 self.y_click = None 62 self.event_pos = None 63 self.leftdown = False 64 self.gotLegend = 0 65 66 # Annotations 67 self.selectedText = None 68 self.textList = [] 69 55 70 # Pre-define the Scale properties dialog 56 71 self.properties = ScaleProperties(self, … … 66 81 self.ax = self.figure.add_subplot(self.current_plot) 67 82 83 # Remove this, DAMMIT 84 self.axes = [self.ax] 85 68 86 # Set the background color to white 69 87 self.canvas.figure.set_facecolor('#FFFFFF') 88 89 # Canvas event handlers 90 self.canvas.mpl_connect('button_release_event', self.onMplMouseUp) 91 self.canvas.mpl_connect('button_press_event', self.onMplMouseDown) 92 self.canvas.mpl_connect('motion_notify_event', self.onMplMouseMotion) 93 self.canvas.mpl_connect('pick_event', self.onMplPick) 94 self.canvas.mpl_connect('scroll_event', self.onMplWheel) 70 95 71 96 if not quickplot: … … 166 191 """ 167 192 Define common context menu and associated actions for the MPL widget 168 TODO: move to plotter1d/plotter2d169 193 """ 170 194 raise NotImplementedError("Context menu method must be implemented in derived class.") … … 180 204 Display the context menu 181 205 """ 182 self.contextMenu.exec_(self.canvas.mapToGlobal(event.pos())) 206 event_pos = event.pos() 207 self.contextMenu.exec_(self.canvas.mapToGlobal(event_pos)) 208 209 def onMplMouseDown(self, event): 210 """ 211 Left button down and ready to drag 212 """ 213 # Check that the LEFT button was pressed 214 if event.button == 1: 215 self.leftdown = True 216 ax = event.inaxes 217 for text in self.textList: 218 if text.contains(event)[0]: # If user has clicked on text 219 self.selectedText = text 220 return 221 222 if ax != None: 223 self.xInit, self.yInit = event.xdata, event.ydata 224 try: 225 self.x_click = float(event.xdata) # / size_x 226 self.y_click = float(event.ydata) # / size_y 227 except: 228 self.position = None 229 230 def onMplMouseUp(self, event): 231 """ 232 Set the data coordinates of the click 233 """ 234 self.x_click = event.xdata 235 self.y_click = event.ydata 236 237 # Check that the LEFT button was released 238 if event.button == 1: 239 self.leftdown = False 240 #self.leftup = True 241 self.selectedText = None 242 243 #release the legend 244 if self.gotLegend == 1: 245 self.gotLegend = 0 246 247 def onMplMouseMotion(self, event): 248 """ 249 Check if the left button is press and the mouse in moving. 250 Compute delta for x and y coordinates and then perform the drag 251 """ 252 if self.gotLegend == 1 and self.leftdown: 253 self.onLegendMotion(event) 254 return 255 256 if self.leftdown and self.selectedText is not None: 257 # User has clicked on text and is dragging 258 ax = event.inaxes 259 if ax != None: 260 # Only move text if mouse is within axes 261 self.selectedText.set_position((event.xdata, event.ydata)) 262 self.canvas.draw_idle() 263 else: 264 # User has dragged outside of axes 265 self.selectedText = None 266 return 267 268 def onMplPick(self, event): 269 """ 270 On pick legend 271 """ 272 legend = self.legend 273 if event.artist == legend: 274 # Get the box of the legend. 275 bbox = self.legend.get_window_extent() 276 # Get mouse coordinates at time of pick. 277 self.mouse_x = event.mouseevent.x 278 self.mouse_y = event.mouseevent.y 279 # Get legend coordinates at time of pick. 280 self.legend_x = bbox.xmin 281 self.legend_y = bbox.ymin 282 # Indicate we picked up the legend. 283 self.gotLegend = 1 284 285 #self.legend.legendPatch.set_alpha(0.5) 286 287 def onLegendMotion(self, event): 288 """ 289 On legend in motion 290 """ 291 ax = event.inaxes 292 if ax == None: 293 return 294 # Event occurred inside a plotting area 295 lo_x, hi_x = ax.get_xlim() 296 lo_y, hi_y = ax.get_ylim() 297 # How much the mouse moved. 298 x = mouse_diff_x = self.mouse_x - event.x 299 y = mouse_diff_y = self.mouse_y - event.y 300 # Put back inside 301 if x < lo_x: 302 x = lo_x 303 if x > hi_x: 304 x = hi_x 305 if y < lo_y: 306 y = lo_y 307 if y > hi_y: 308 y = hi_y 309 # Move the legend from its previous location by that same amount 310 loc_in_canvas = self.legend_x - mouse_diff_x, \ 311 self.legend_y - mouse_diff_y 312 # Transform into legend coordinate system 313 trans_axes = self.legend.parent.transAxes.inverted() 314 loc_in_norm_axes = trans_axes.transform_point(loc_in_canvas) 315 self.legend_pos_loc = tuple(loc_in_norm_axes) 316 self.legend._loc = self.legend_pos_loc 317 # self.canvas.draw() 318 self.canvas.draw_idle() 319 320 def onMplWheel(self, event): 321 """ 322 Process mouse wheel as zoom events 323 """ 324 ax = event.inaxes 325 step = event.step 326 327 if ax != None: 328 # Event occurred inside a plotting area 329 lo, hi = ax.get_xlim() 330 lo, hi = PlotUtilities.rescale(lo, hi, step, 331 pt=event.xdata, scale=ax.get_xscale()) 332 if not self.xscale == 'log' or lo > 0: 333 self._scale_xlo = lo 334 self._scale_xhi = hi 335 ax.set_xlim((lo, hi)) 336 337 lo, hi = ax.get_ylim() 338 lo, hi = PlotUtilities.rescale(lo, hi, step, pt=event.ydata, 339 scale=ax.get_yscale()) 340 if not self.yscale == 'log' or lo > 0: 341 self._scale_ylo = lo 342 self._scale_yhi = hi 343 ax.set_ylim((lo, hi)) 344 else: 345 # Check if zoom happens in the axes 346 xdata, ydata = None, None 347 x, y = event.x, event.y 348 349 for ax in self.axes: 350 insidex, _ = ax.xaxis.contains(event) 351 if insidex: 352 xdata, _ = ax.transAxes.inverted().transform_point((x, y)) 353 insidey, _ = ax.yaxis.contains(event) 354 if insidey: 355 _, ydata = ax.transAxes.inverted().transform_point((x, y)) 356 if xdata is not None: 357 lo, hi = ax.get_xlim() 358 lo, hi = PlotUtilities.rescale(lo, hi, step, 359 bal=xdata, scale=ax.get_xscale()) 360 if not self.xscale == 'log' or lo > 0: 361 self._scale_xlo = lo 362 self._scale_xhi = hi 363 ax.set_xlim((lo, hi)) 364 if ydata is not None: 365 lo, hi = ax.get_ylim() 366 lo, hi = PlotUtilities.rescale(lo, hi, step, bal=ydata, 367 scale=ax.get_yscale()) 368 if not self.yscale == 'log' or lo > 0: 369 self._scale_ylo = lo 370 self._scale_yhi = hi 371 ax.set_ylim((lo, hi)) 372 self.canvas.draw_idle() 183 373 184 374 def clean(self):
Note: See TracChangeset
for help on using the changeset viewer.