Changeset aadf0af1 in sasview for src/sas/qtgui
- Timestamp:
- Jan 4, 2017 4:35:08 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:
- 570a58f9
- Parents:
- 257bd57
- Location:
- src/sas/qtgui
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/DataExplorer.py
r9290b1a raadf0af1 44 44 self.manager = manager if manager is not None else DataManager() 45 45 self.txt_widget = QtGui.QTextEdit(None) 46 # self.txt_widget = GuiUtils.DisplayWindow()47 48 46 49 47 # Be careful with twisted threads. -
src/sas/qtgui/GuiUtils.py
r27313b7 raadf0af1 28 28 from periodictable import formula as Formula 29 29 30 from sas.sasgui.plottools import transform 31 from sas.sasgui.plottools.convert_units import convert_unit 30 32 from sas.sasgui.guiframe.dataFitting import Data1D 31 33 from sas.sasgui.guiframe.dataFitting import Data2D … … 584 586 pass 585 587 588 def xyTransform(data, xLabel="", yLabel=""): 589 """ 590 Transforms x and y in View and set the scale 591 """ 592 # Changing the scale might be incompatible with 593 # currently displayed data (for instance, going 594 # from ln to log when all plotted values have 595 # negative natural logs). 596 # Go linear and only change the scale at the end. 597 xscale = 'linear' 598 yscale = 'linear' 599 # Local data is either 1D or 2D 600 if data.id == 'fit': 601 return 602 603 # control axis labels from the panel itself 604 yname, yunits = data.get_yaxis() 605 xname, xunits = data.get_xaxis() 606 607 # Goes through all possible scales 608 # self.x_label is already wrapped with Latex "$", so using the argument 609 610 # X 611 if xLabel == "x": 612 data.transformX(transform.toX, transform.errToX) 613 xLabel = "%s(%s)" % (xname, xunits) 614 if xLabel == "x^(2)": 615 data.transformX(transform.toX2, transform.errToX2) 616 xunits = convert_unit(2, xunits) 617 xLabel = "%s^{2}(%s)" % (xname, xunits) 618 if xLabel == "x^(4)": 619 data.transformX(transform.toX4, transform.errToX4) 620 xunits = convert_unit(4, xunits) 621 xLabel = "%s^{4}(%s)" % (xname, xunits) 622 if xLabel == "ln(x)": 623 data.transformX(transform.toLogX, transform.errToLogX) 624 xLabel = "\ln{(%s)}(%s)" % (xname, xunits) 625 if xLabel == "log10(x)": 626 data.transformX(transform.toX_pos, transform.errToX_pos) 627 xscale = 'log' 628 xLabel = "%s(%s)" % (xname, xunits) 629 if xLabel == "log10(x^(4))": 630 data.transformX(transform.toX4, transform.errToX4) 631 xunits = convert_unit(4, xunits) 632 xLabel = "%s^{4}(%s)" % (xname, xunits) 633 xscale = 'log' 634 635 # Y 636 if yLabel == "ln(y)": 637 data.transformY(transform.toLogX, transform.errToLogX) 638 yLabel = "\ln{(%s)}(%s)" % (yname, yunits) 639 if yLabel == "y": 640 data.transformY(transform.toX, transform.errToX) 641 yLabel = "%s(%s)" % (yname, yunits) 642 if yLabel == "log10(y)": 643 data.transformY(transform.toX_pos, transform.errToX_pos) 644 yscale = 'log' 645 yLabel = "%s(%s)" % (yname, yunits) 646 if yLabel == "y^(2)": 647 data.transformY(transform.toX2, transform.errToX2) 648 yunits = convert_unit(2, yunits) 649 yLabel = "%s^{2}(%s)" % (yname, yunits) 650 if yLabel == "1/y": 651 data.transformY(transform.toOneOverX, transform.errOneOverX) 652 yunits = convert_unit(-1, yunits) 653 yLabel = "1/%s(%s)" % (yname, yunits) 654 if yLabel == "y*x^(2)": 655 data.transformY(transform.toYX2, transform.errToYX2) 656 xunits = convert_unit(2, xunits) 657 yLabel = "%s \ \ %s^{2}(%s%s)" % (yname, xname, yunits, xunits) 658 if yLabel == "y*x^(4)": 659 data.transformY(transform.toYX4, transform.errToYX4) 660 xunits = convert_unit(4, xunits) 661 yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits) 662 if yLabel == "1/sqrt(y)": 663 data.transformY(transform.toOneOverSqrtX, 664 transform.errOneOverSqrtX) 665 yunits = convert_unit(-0.5, yunits) 666 yLabel = "1/\sqrt{%s}(%s)" % (yname, yunits) 667 if yLabel == "ln(y*x)": 668 data.transformY(transform.toLogXY, transform.errToLogXY) 669 yLabel = "\ln{(%s \ \ %s)}(%s%s)" % (yname, xname, yunits, xunits) 670 if yLabel == "ln(y*x^(2))": 671 data.transformY(transform.toLogYX2, transform.errToLogYX2) 672 xunits = convert_unit(2, xunits) 673 yLabel = "\ln (%s \ \ %s^{2})(%s%s)" % (yname, xname, yunits, xunits) 674 if yLabel == "ln(y*x^(4))": 675 data.transformY(transform.toLogYX4, transform.errToLogYX4) 676 xunits = convert_unit(4, xunits) 677 yLabel = "\ln (%s \ \ %s^{4})(%s%s)" % (yname, xname, yunits, xunits) 678 if yLabel == "log10(y*x^(4))": 679 data.transformY(transform.toYX4, transform.errToYX4) 680 xunits = convert_unit(4, xunits) 681 yscale = 'log' 682 yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits) 683 684 # Perform the transformation of data in data1d->View 685 data.transformView() 686 687 return (xLabel, yLabel, xscale, yscale) 688 586 689 def dataFromItem(item): 587 690 """ -
src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py
r8548d739 raadf0af1 269 269 # Convert the data into plottable 270 270 extrapolated_data = self._manager.createGuiData(extrapolated_data) 271 extrapolated_data.name = title 271 272 272 273 # Add the plot to the model item … … 289 290 # Convert the data into plottable 290 291 high_out_data = self._manager.createGuiData(high_out_data) 292 high_out_data.name = title 291 293 292 294 # find how to add this plot to the existing plot for low_extrapolate -
src/sas/qtgui/Plotter.py
r257bd57 raadf0af1 1 1 from PyQt4 import QtGui 2 from PyQt4 import QtCore 3 import functools 4 import copy 2 5 3 6 import matplotlib.pyplot as plt … … 5 8 6 9 from sas.sasgui.guiframe.dataFitting import Data1D 7 from sas.sasgui.plottools import transform8 from sas.sasgui.plottools.convert_units import convert_unit9 10 from sas.qtgui.PlotterBase import PlotterBase 11 import sas.qtgui.GuiUtils as GuiUtils 10 12 from sas.qtgui.AddText import AddText 11 13 from sas.qtgui.SetGraphRange import SetGraphRange … … 20 22 self.addText = AddText(self) 21 23 24 # Dictionary of {plot_id:Data1d} 25 self.plot_dict = {} 26 27 # Simple window for data display 28 self.txt_widget = QtGui.QTextEdit(None) 29 22 30 @property 23 31 def data(self): … … 30 38 self.xLabel = "%s(%s)"%(value._xaxis, value._xunit) 31 39 self.yLabel = "%s(%s)"%(value._yaxis, value._yunit) 32 self.title(title=value. title)40 self.title(title=value.name) 33 41 34 42 def plot(self, data=None, marker=None, linestyle=None, hide_error=False): 35 43 """ 36 Plot self._data44 Add a new plot of self._data to the chart. 37 45 """ 38 46 # Data1D … … 50 58 linestyle = '' 51 59 60 if not self._title: 61 self.title(title=self.data.name) 62 52 63 # plot data with/without errorbars 53 64 if hide_error: 54 ax.plot(self._data.view.x, self._data.view.y,65 line = ax.plot(self._data.view.x, self._data.view.y, 55 66 marker=marker, 56 67 linestyle=linestyle, … … 58 69 picker=True) 59 70 else: 60 ax.errorbar(self._data.view.x, self._data.view.y,61 yerr=self._data.view.d x, xerr=None,71 line = ax.errorbar(self._data.view.x, self._data.view.y, 72 yerr=self._data.view.dy, xerr=None, 62 73 capsize=2, linestyle='', 63 74 barsabove=False, … … 68 79 picker=True) 69 80 81 # Update the list of data sets (plots) in chart 82 self.plot_dict[self._data.id] = self.data 83 70 84 # Now add the legend with some customizations. 71 85 self.legend = ax.legend(loc='upper right', shadow=True) 72 #self.legend.get_frame().set_alpha(0.4)73 86 self.legend.set_picker(True) 74 87 … … 92 105 self.canvas.draw() 93 106 94 def c ontextMenu(self):107 def createContextMenu(self): 95 108 """ 96 109 Define common context menu and associated actions for the MPL widget 97 110 """ 98 111 self.defaultContextMenu() 112 113 # Separate plots 114 self.addPlotsToContextMenu() 99 115 100 116 # Additional menu items … … 112 128 self.contextMenu.addAction("Reset Graph Range") 113 129 # Add the title change for dialogs 114 if self.parent:115 116 130 #if self.parent: 131 self.contextMenu.addSeparator() 132 self.actionWindowTitle = self.contextMenu.addAction("Window Title") 117 133 118 134 # Define the callbacks … … 125 141 self.actionWindowTitle.triggered.connect(self.onWindowsTitle) 126 142 127 def contextMenuQuickPlot(self): 143 def addPlotsToContextMenu(self): 144 """ 145 Adds operations on all plotted sets of data to the context menu 146 """ 147 for id in self.plot_dict.keys(): 148 plot = self.plot_dict[id] 149 name = plot.name 150 plot_menu = self.contextMenu.addMenu('&%s' % name) 151 152 self.actionDataInfo = plot_menu.addAction("&DataInfo") 153 self.actionDataInfo.triggered.connect( 154 functools.partial(self.onDataInfo, plot)) 155 156 self.actionSavePointsAsFile = plot_menu.addAction("&Save Points as a File") 157 self.actionSavePointsAsFile.triggered.connect( 158 functools.partial(self.onSavePoints, plot)) 159 plot_menu.addSeparator() 160 161 if plot.id != 'fit': 162 self.actionLinearFit = plot_menu.addAction('&Linear Fit') 163 self.actionLinearFit.triggered.connect(self.onLinearFit) 164 plot_menu.addSeparator() 165 166 self.actionRemovePlot = plot_menu.addAction("Remove") 167 self.actionRemovePlot.triggered.connect( 168 functools.partial(self.onRemovePlot, id)) 169 170 if not plot.is_data: 171 self.actionFreeze = plot_menu.addAction('&Freeze') 172 self.actionFreeze.triggered.connect( 173 functools.partial(self.onFreeze, id)) 174 plot_menu.addSeparator() 175 176 if plot.is_data: 177 self.actionHideError = plot_menu.addAction("Hide Error Bar") 178 if plot.dy is not None and plot.dy != []: 179 if plot.hide_error: 180 self.actionHideError.setText('Show Error Bar') 181 else: 182 self.actionHideError.setEnabled(False) 183 self.actionHideError.triggered.connect( 184 functools.partial(self.onToggleHideError, id)) 185 plot_menu.addSeparator() 186 187 self.actionModifyPlot = plot_menu.addAction('&Modify Plot Property') 188 self.actionModifyPlot.triggered.connect(self.onModifyPlot) 189 190 def createContextMenuQuick(self): 128 191 """ 129 192 Define context menu and associated actions for the quickplot MPL widget … … 231 294 self.canvas.draw_idle() 232 295 296 def onDataInfo(self, plot_data): 297 """ 298 Displays data info text window for the selected plot 299 """ 300 text_to_show = GuiUtils.retrieveData1d(plot_data) 301 # Hardcoded sizes to enable full width rendering with default font 302 self.txt_widget.resize(420,600) 303 304 self.txt_widget.setReadOnly(True) 305 self.txt_widget.setWindowFlags(QtCore.Qt.Window) 306 self.txt_widget.setWindowIcon(QtGui.QIcon(":/res/ball.ico")) 307 self.txt_widget.setWindowTitle("Data Info: %s" % plot_data.filename) 308 self.txt_widget.insertPlainText(text_to_show) 309 310 self.txt_widget.show() 311 # Move the slider all the way up, if present 312 vertical_scroll_bar = self.txt_widget.verticalScrollBar() 313 vertical_scroll_bar.triggerAction(QtGui.QScrollBar.SliderToMinimum) 314 315 def onSavePoints(self, plot_data): 316 """ 317 Saves plot data to a file 318 """ 319 GuiUtils.saveData1D(plot_data) 320 321 def onLinearFit(self): 322 """ 323 Creates and displays a simple linear fit for the selected plot 324 """ 325 pass 326 327 def onRemovePlot(self, id): 328 """ 329 Deletes the selected plot from the chart 330 """ 331 selected_plot = self.plot_dict[id] 332 333 plot_dict = copy.deepcopy(self.plot_dict) 334 335 self.plot_dict = {} 336 337 plt.cla() 338 self.ax.cla() 339 340 for ids in plot_dict: 341 if ids != id: 342 self.plot(data=plot_dict[ids], hide_error=plot_dict[ids].hide_error) 343 344 if len(self.plot_dict) == 0: 345 # last plot: graph is empty must be the panel must be destroyed 346 self.parent.close() 347 348 def onFreeze(self, id): 349 """ 350 Freezes the selected plot to a separate chart 351 """ 352 plot = self.plot_dict[id] 353 self.manager.add_data(data_list=[plot]) 354 355 def onModifyPlot(self): 356 """ 357 Allows for MPL modifications to the selected plot 358 """ 359 pass 360 361 def onToggleHideError(self, id): 362 """ 363 Toggles hide error/show error menu item 364 """ 365 selected_plot = self.plot_dict[id] 366 current = selected_plot.hide_error 367 368 # Flip the flag 369 selected_plot.hide_error = not current 370 371 plot_dict = copy.deepcopy(self.plot_dict) 372 self.plot_dict = {} 373 374 # Clean the canvas 375 plt.cla() 376 self.ax.cla() 377 378 # Recreate the plots but reverse the error flag for the current 379 for ids in plot_dict: 380 if ids == id: 381 self.plot(data=plot_dict[ids], hide_error=(not current)) 382 else: 383 self.plot(data=plot_dict[ids], hide_error=plot_dict[ids].hide_error) 384 233 385 def xyTransform(self, xLabel="", yLabel=""): 234 386 """ … … 239 391 self.ax.cla() 240 392 241 # Changing the scale might be incompatible with 242 # currently displayed data (for instance, going 243 # from ln to log when all plotted values have 244 # negative natural logs). 245 # Go linear and only change the scale at the end. 246 self._xscale = "linear" 247 self._yscale = "linear" 248 _xscale = 'linear' 249 _yscale = 'linear' 250 # Local data is either 1D or 2D 251 if self.data.id == 'fit': 252 return 253 254 # control axis labels from the panel itself 255 yname, yunits = self.data.get_yaxis() 256 xname, xunits = self.data.get_xaxis() 257 258 # Goes through all possible scales 259 # self.x_label is already wrapped with Latex "$", so using the argument 260 261 # X 262 if xLabel == "x": 263 self.data.transformX(transform.toX, transform.errToX) 264 self.xLabel = "%s(%s)" % (xname, xunits) 265 if xLabel == "x^(2)": 266 self.data.transformX(transform.toX2, transform.errToX2) 267 xunits = convert_unit(2, xunits) 268 self.xLabel = "%s^{2}(%s)" % (xname, xunits) 269 if xLabel == "x^(4)": 270 self.data.transformX(transform.toX4, transform.errToX4) 271 xunits = convert_unit(4, xunits) 272 self.xLabel = "%s^{4}(%s)" % (xname, xunits) 273 if xLabel == "ln(x)": 274 self.data.transformX(transform.toLogX, transform.errToLogX) 275 self.xLabel = "\ln{(%s)}(%s)" % (xname, xunits) 276 if xLabel == "log10(x)": 277 self.data.transformX(transform.toX_pos, transform.errToX_pos) 278 _xscale = 'log' 279 self.xLabel = "%s(%s)" % (xname, xunits) 280 if xLabel == "log10(x^(4))": 281 self.data.transformX(transform.toX4, transform.errToX4) 282 xunits = convert_unit(4, xunits) 283 self.xLabel = "%s^{4}(%s)" % (xname, xunits) 284 _xscale = 'log' 285 286 # Y 287 if yLabel == "ln(y)": 288 self.data.transformY(transform.toLogX, transform.errToLogX) 289 self.yLabel = "\ln{(%s)}(%s)" % (yname, yunits) 290 if yLabel == "y": 291 self.data.transformY(transform.toX, transform.errToX) 292 self.yLabel = "%s(%s)" % (yname, yunits) 293 if yLabel == "log10(y)": 294 self.data.transformY(transform.toX_pos, transform.errToX_pos) 295 _yscale = 'log' 296 self.yLabel = "%s(%s)" % (yname, yunits) 297 if yLabel == "y^(2)": 298 self.data.transformY(transform.toX2, transform.errToX2) 299 yunits = convert_unit(2, yunits) 300 self.yLabel = "%s^{2}(%s)" % (yname, yunits) 301 if yLabel == "1/y": 302 self.data.transformY(transform.toOneOverX, transform.errOneOverX) 303 yunits = convert_unit(-1, yunits) 304 self.yLabel = "1/%s(%s)" % (yname, yunits) 305 if yLabel == "y*x^(2)": 306 self.data.transformY(transform.toYX2, transform.errToYX2) 307 xunits = convert_unit(2, xunits) 308 self.yLabel = "%s \ \ %s^{2}(%s%s)" % (yname, xname, yunits, xunits) 309 if yLabel == "y*x^(4)": 310 self.data.transformY(transform.toYX4, transform.errToYX4) 311 xunits = convert_unit(4, xunits) 312 self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits) 313 if yLabel == "1/sqrt(y)": 314 self.data.transformY(transform.toOneOverSqrtX, 315 transform.errOneOverSqrtX) 316 yunits = convert_unit(-0.5, yunits) 317 self.yLabel = "1/\sqrt{%s}(%s)" % (yname, yunits) 318 if yLabel == "ln(y*x)": 319 self.data.transformY(transform.toLogXY, transform.errToLogXY) 320 self.yLabel = "\ln{(%s \ \ %s)}(%s%s)" % (yname, xname, yunits, xunits) 321 if yLabel == "ln(y*x^(2))": 322 self.data.transformY(transform.toLogYX2, transform.errToLogYX2) 323 xunits = convert_unit(2, xunits) 324 self.yLabel = "\ln (%s \ \ %s^{2})(%s%s)" % (yname, xname, yunits, xunits) 325 if yLabel == "ln(y*x^(4))": 326 self.data.transformY(transform.toLogYX4, transform.errToLogYX4) 327 xunits = convert_unit(4, xunits) 328 self.yLabel = "\ln (%s \ \ %s^{4})(%s%s)" % (yname, xname, yunits, xunits) 329 if yLabel == "log10(y*x^(4))": 330 self.data.transformY(transform.toYX4, transform.errToYX4) 331 xunits = convert_unit(4, xunits) 332 _yscale = 'log' 333 self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits) 334 335 # Perform the transformation of data in data1d->View 336 self.data.transformView() 337 338 self.xscale = _xscale 339 self.yscale = _yscale 393 new_xlabel, new_ylabel, xscale, yscale = GuiUtils.xyTransform(self.data, xLabel, yLabel) 394 self.xscale = xscale 395 self.yscale = yscale 396 self.xLabel = new_xlabel 397 self.yLabel = new_ylabel 340 398 341 399 # Plot the updated chart … … 347 405 348 406 QtGui.QDialog.__init__(self) 349 PlotterWidget.__init__(self, manager=parent, quickplot=quickplot)407 PlotterWidget.__init__(self, parent=self, manager=parent, quickplot=quickplot) 350 408 icon = QtGui.QIcon() 351 409 icon.addPixmap(QtGui.QPixmap(":/res/ball.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) -
src/sas/qtgui/PlotterBase.py
rd3ca363 raadf0af1 94 94 self.canvas.mpl_connect('scroll_event', self.onMplWheel) 95 95 96 self.contextMenu = QtGui.QMenu(self) 97 96 98 if not quickplot: 97 # set the layout99 # Add the toolbar 98 100 layout.addWidget(self.toolbar) 99 # Add the context menu100 self.contextMenu()101 101 # Notify PlotHelper about the new plot 102 102 self.upatePlotHelper() 103 else:104 self.contextMenuQuickPlot()105 103 106 104 self.setLayout(layout) … … 177 175 """ 178 176 # Actions 179 self.contextMenu = QtGui.QMenu(self)177 self.contextMenu.clear() 180 178 self.actionSaveImage = self.contextMenu.addAction("Save Image") 181 179 self.actionPrintImage = self.contextMenu.addAction("Print Image") … … 188 186 self.actionCopyToClipboard.triggered.connect(self.onClipboardCopy) 189 187 190 def c ontextMenu(self):188 def createContextMenu(self): 191 189 """ 192 190 Define common context menu and associated actions for the MPL widget … … 194 192 raise NotImplementedError("Context menu method must be implemented in derived class.") 195 193 196 def c ontextMenuQuickPlot(self):194 def createContextMenuQuick(self): 197 195 """ 198 196 Define context menu and associated actions for the quickplot MPL widget … … 204 202 Display the context menu 205 203 """ 204 if not self.quickplot: 205 self.createContextMenu() 206 else: 207 self.createContextMenuQuick() 208 206 209 event_pos = event.pos() 207 210 self.contextMenu.exec_(self.canvas.mapToGlobal(event_pos)) -
src/sas/qtgui/UnitTesting/PlotterBaseTest.py
r9290b1a raadf0af1 33 33 return MyPerspective() 34 34 35 PlotterBase.PlotterBase.contextMenuQuickPlot = MagicMock()35 #PlotterBase.PlotterBase.contextMenuQuickPlot = MagicMock() 36 36 self.plotter = PlotterBase.PlotterBase(None, manager=dummy_manager(), quickplot=True) 37 37 … … 64 64 ''' Test the default context menu ''' 65 65 with self.assertRaises(NotImplementedError): 66 self.plotter.c ontextMenu()66 self.plotter.createContextMenu() 67 67 68 68 def testClean(self): -
src/sas/qtgui/UnitTesting/PlotterTest.py
r257bd57 raadf0af1 31 31 dy=[0.1, 0.2, 0.3]) 32 32 self.data.title="Test data" 33 self.data.name="Test name" 33 34 self.data.id = 1 34 35 … … 42 43 43 44 self.assertEqual(self.plotter.data, self.data) 44 self.assertEqual(self.plotter._title, self.data. title)45 self.assertEqual(self.plotter._title, self.data.name) 45 46 self.assertEqual(self.plotter.xLabel, "$()$") 46 47 self.assertEqual(self.plotter.yLabel, "$()$") … … 70 71 def testContextMenuQuickPlot(self): 71 72 """ Test the right click menu """ 73 self.plotter.createContextMenuQuick() 72 74 actions = self.plotter.contextMenu.actions() 73 75 self.assertEqual(len(actions), 7)
Note: See TracChangeset
for help on using the changeset viewer.