source: sasview/src/sas/qtgui/Plotter.py @ fecfe28

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since fecfe28 was fecfe28, checked in by Piotr Rozyczko <rozyczko@…>, 8 years ago

Code review for 3D plots.

  • Property mode set to 100644
File size: 8.6 KB
Line 
1from PyQt4 import QtGui
2
3import matplotlib.pyplot as plt
4
5from sas.sasgui.plottools import transform
6from sas.sasgui.plottools.convert_units import convert_unit
7from sas.qtgui.PlotterBase import PlotterBase
8
9class PlotterWidget(PlotterBase):
10    """
11    1D Plot widget for use with a QDialog
12    """
13    def __init__(self, parent=None, manager=None, quickplot=False):
14        super(PlotterWidget, self).__init__(parent, manager=manager, quickplot=quickplot)
15
16    @property
17    def data(self):
18        return self._data
19
20    @data.setter
21    def data(self, value):
22        """ data setter """
23        self._data = value
24        self.xLabel = "%s(%s)"%(value._xaxis, value._xunit)
25        self.yLabel = "%s(%s)"%(value._yaxis, value._yunit)
26        self.title(title=value.title)
27
28    def plot(self, marker=None, linestyle=None, hide_error=False):
29        """
30        Plot self._data
31        """
32        # Shortcut for an axis
33        ax = self.ax
34
35        if marker == None:
36            marker = 'o'
37
38        if linestyle == None:
39            linestyle = ''
40
41        # plot data with/without errorbars
42        if hide_error:
43            ax.plot(self._data.view.x, self._data.view.y,
44                    marker=marker,
45                    linestyle=linestyle,
46                    label=self._title)
47        else:
48            ax.errorbar(self._data.view.x, self._data.view.y,
49                        yerr=self._data.view.dx, xerr=None,
50                        capsize=2, linestyle='',
51                        barsabove=False,
52                        marker=marker,
53                        lolims=False, uplims=False,
54                        xlolims=False, xuplims=False,
55                        label=self._title)
56
57        # Now add the legend with some customizations.
58        legend = ax.legend(loc='upper right', shadow=True)
59
60        # Current labels for axes
61        ax.set_ylabel(self.y_label)
62        ax.set_xlabel(self.x_label)
63
64        # Title only for regular charts
65        if not self.quickplot:
66            ax.set_title(label=self._title)
67
68        # Include scaling (log vs. linear)
69        ax.set_yscale(self.xscale)
70        ax.set_xscale(self.xscale)
71
72        # refresh canvas
73        self.canvas.draw()
74
75    def contextMenuQuickPlot(self):
76        """
77        Define context menu and associated actions for the quickplot MPL widget
78        """
79        # Actions
80        self.contextMenu = QtGui.QMenu(self)
81        self.actionSaveImage = self.contextMenu.addAction("Save Image")
82        self.actionPrintImage = self.contextMenu.addAction("Print Image")
83        self.actionCopyToClipboard = self.contextMenu.addAction("Copy to Clipboard")
84        self.contextMenu.addSeparator()
85        self.actionToggleGrid = self.contextMenu.addAction("Toggle Grid On/Off")
86        self.contextMenu.addSeparator()
87        self.actionChangeScale = self.contextMenu.addAction("Change Scale")
88
89        # Define the callbacks
90        self.actionSaveImage.triggered.connect(self.onImageSave)
91        self.actionPrintImage.triggered.connect(self.onImagePrint)
92        self.actionCopyToClipboard.triggered.connect(self.onClipboardCopy)
93        self.actionToggleGrid.triggered.connect(self.onGridToggle)
94        self.actionChangeScale.triggered.connect(self.onScaleChange)
95
96    def onScaleChange(self):
97        """
98        Show a dialog allowing axes rescaling
99        """
100        if self.properties.exec_() == QtGui.QDialog.Accepted:
101            xLabel, yLabel = self.properties.getValues()
102            self.xyTransform(xLabel, yLabel)
103
104    def xyTransform(self, xLabel="", yLabel=""):
105        """
106        Transforms x and y in View and set the scale
107        """
108        # Clear the plot first
109        plt.cla()
110
111        # Changing the scale might be incompatible with
112        # currently displayed data (for instance, going
113        # from ln to log when all plotted values have
114        # negative natural logs).
115        # Go linear and only change the scale at the end.
116        self._xscale = "linear"
117        self._yscale = "linear"
118        _xscale = 'linear'
119        _yscale = 'linear'
120        # Local data is either 1D or 2D
121        if self.data.id == 'fit':
122            return
123
124        # control axis labels from the panel itself
125        yname, yunits = self.data.get_yaxis()
126        xname, xunits = self.data.get_xaxis()
127
128        # Goes through all possible scales
129        # self.x_label is already wrapped with Latex "$", so using the argument
130
131        # X
132        if xLabel == "x":
133            self.data.transformX(transform.toX, transform.errToX)
134            self.xLabel = "%s(%s)" % (xname, xunits)
135        if xLabel == "x^(2)":
136            self.data.transformX(transform.toX2, transform.errToX2)
137            xunits = convert_unit(2, xunits)
138            self.xLabel = "%s^{2}(%s)" % (xname, xunits)
139        if xLabel == "x^(4)":
140            self.data.transformX(transform.toX4, transform.errToX4)
141            xunits = convert_unit(4, xunits)
142            self.xLabel = "%s^{4}(%s)" % (xname, xunits)
143        if xLabel == "ln(x)":
144            self.data.transformX(transform.toLogX, transform.errToLogX)
145            self.xLabel = "\ln{(%s)}(%s)" % (xname, xunits)
146        if xLabel == "log10(x)":
147            self.data.transformX(transform.toX_pos, transform.errToX_pos)
148            _xscale = 'log'
149            self.xLabel = "%s(%s)" % (xname, xunits)
150        if xLabel == "log10(x^(4))":
151            self.data.transformX(transform.toX4, transform.errToX4)
152            xunits = convert_unit(4, xunits)
153            self.xLabel = "%s^{4}(%s)" % (xname, xunits)
154            _xscale = 'log'
155
156        # Y
157        if yLabel == "ln(y)":
158            self.data.transformY(transform.toLogX, transform.errToLogX)
159            self.yLabel = "\ln{(%s)}(%s)" % (yname, yunits)
160        if yLabel == "y":
161            self.data.transformY(transform.toX, transform.errToX)
162            self.yLabel = "%s(%s)" % (yname, yunits)
163        if yLabel == "log10(y)":
164            self.data.transformY(transform.toX_pos, transform.errToX_pos)
165            _yscale = 'log'
166            self.yLabel = "%s(%s)" % (yname, yunits)
167        if yLabel == "y^(2)":
168            self.data.transformY(transform.toX2, transform.errToX2)
169            yunits = convert_unit(2, yunits)
170            self.yLabel = "%s^{2}(%s)" % (yname, yunits)
171        if yLabel == "1/y":
172            self.data.transformY(transform.toOneOverX, transform.errOneOverX)
173            yunits = convert_unit(-1, yunits)
174            self.yLabel = "1/%s(%s)" % (yname, yunits)
175        if yLabel == "y*x^(2)":
176            self.data.transformY(transform.toYX2, transform.errToYX2)
177            xunits = convert_unit(2, xunits)
178            self.yLabel = "%s \ \ %s^{2}(%s%s)" % (yname, xname, yunits, xunits)
179        if yLabel == "y*x^(4)":
180            self.data.transformY(transform.toYX4, transform.errToYX4)
181            xunits = convert_unit(4, xunits)
182            self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
183        if yLabel == "1/sqrt(y)":
184            self.data.transformY(transform.toOneOverSqrtX,
185                                 transform.errOneOverSqrtX)
186            yunits = convert_unit(-0.5, yunits)
187            self.yLabel = "1/\sqrt{%s}(%s)" % (yname, yunits)
188        if yLabel == "ln(y*x)":
189            self.data.transformY(transform.toLogXY, transform.errToLogXY)
190            self.yLabel = "\ln{(%s \ \ %s)}(%s%s)" % (yname, xname, yunits, xunits)
191        if yLabel == "ln(y*x^(2))":
192            self.data.transformY(transform.toLogYX2, transform.errToLogYX2)
193            xunits = convert_unit(2, xunits)
194            self.yLabel = "\ln (%s \ \ %s^{2})(%s%s)" % (yname, xname, yunits, xunits)
195        if yLabel == "ln(y*x^(4))":
196            self.data.transformY(transform.toLogYX4, transform.errToLogYX4)
197            xunits = convert_unit(4, xunits)
198            self.yLabel = "\ln (%s \ \ %s^{4})(%s%s)" % (yname, xname, yunits, xunits)
199        if yLabel == "log10(y*x^(4))":
200            self.data.transformY(transform.toYX4, transform.errToYX4)
201            xunits = convert_unit(4, xunits)
202            _yscale = 'log'
203            self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
204
205        # Perform the transformation of data in data1d->View
206        self.data.transformView()
207
208        self.xscale = _xscale
209        self.yscale = _yscale
210
211        # Plot the updated chart
212        self.plot(marker='o', linestyle='')
213
214
215class Plotter(QtGui.QDialog, PlotterWidget):
216    def __init__(self, parent=None, quickplot=False):
217
218        QtGui.QDialog.__init__(self)
219        PlotterWidget.__init__(self, manager=parent, quickplot=quickplot)
220        icon = QtGui.QIcon()
221        icon.addPixmap(QtGui.QPixmap(":/res/ball.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
222        self.setWindowIcon(icon)
223
224
Note: See TracBrowser for help on using the repository browser.