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

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 b4b8589 was b4b8589, checked in by Piotr Rozyczko <rozyczko@…>, 8 years ago

Code review from WP. Also, added 1D plots with error bars as default.

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