source: sasview/src/sas/qtgui/Plotter.py @ 27313b7

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

Added window title GUI for charts

  • Property mode set to 100644
File size: 10.4 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        self.parent = parent
16
17    @property
18    def data(self):
19        return self._data
20
21    @data.setter
22    def data(self, value):
23        """ data setter """
24        self._data = value
25        self.xLabel = "%s(%s)"%(value._xaxis, value._xunit)
26        self.yLabel = "%s(%s)"%(value._yaxis, value._yunit)
27        self.title(title=value.title)
28
29    def plot(self, marker=None, linestyle=None, hide_error=False):
30        """
31        Plot self._data
32        """
33        # Shortcut for an axis
34        ax = self.ax
35
36        if marker == None:
37            marker = 'o'
38
39        if linestyle == None:
40            linestyle = ''
41
42        # plot data with/without errorbars
43        if hide_error:
44            ax.plot(self._data.view.x, self._data.view.y,
45                    marker=marker,
46                    linestyle=linestyle,
47                    label=self._title)
48        else:
49            ax.errorbar(self._data.view.x, self._data.view.y,
50                        yerr=self._data.view.dx, xerr=None,
51                        capsize=2, linestyle='',
52                        barsabove=False,
53                        marker=marker,
54                        lolims=False, uplims=False,
55                        xlolims=False, xuplims=False,
56                        label=self._title)
57
58        # Now add the legend with some customizations.
59        legend = ax.legend(loc='upper right', shadow=True)
60
61        # Current labels for axes
62        ax.set_ylabel(self.y_label)
63        ax.set_xlabel(self.x_label)
64
65        # Title only for regular charts
66        if not self.quickplot:
67            ax.set_title(label=self._title)
68
69        # Include scaling (log vs. linear)
70        ax.set_xscale(self.xscale)
71        ax.set_yscale(self.yscale)
72
73        # refresh canvas
74        self.canvas.draw()
75
76    def contextMenu(self):
77        """
78        Define common context menu and associated actions for the MPL widget
79        """
80        self.defaultContextMenu()
81
82        # Additional menu items
83        self.contextMenu.addSeparator()
84        self.actionModifyGraphAppearance =\
85            self.contextMenu.addAction("Modify Graph Appearance")
86        self.contextMenu.addSeparator()
87        self.actionAddText = self.contextMenu.addAction("Add Text")
88        self.actionRemoveText = self.contextMenu.addAction("Remove Text")
89        self.contextMenu.addSeparator()
90        self.actionChangeScale = self.contextMenu.addAction("Change Scale")
91        self.contextMenu.addSeparator()
92        self.actionSetGraphRange = self.contextMenu.addAction("Set Graph Range")
93        self.actionResetGraphRange =\
94            self.contextMenu.addAction("Reset Graph Range")
95        # Add the title change for dialogs
96        if self.parent:
97            self.contextMenu.addSeparator()
98            self.actionWindowTitle = self.contextMenu.addAction("Window Title")
99
100        # Define the callbacks
101        self.actionModifyGraphAppearance.triggered.connect(self.onModifyGraph)
102        self.actionAddText.triggered.connect(self.onAddText)
103        self.actionRemoveText.triggered.connect(self.onRemoveText)
104        self.actionChangeScale.triggered.connect(self.onScaleChange)
105        self.actionSetGraphRange.triggered.connect(self.onSetGraphRange)
106        self.actionResetGraphRange.triggered.connect(self.onResetGraphRange)
107        self.actionWindowTitle.triggered.connect(self.onWindowsTitle)
108
109    def contextMenuQuickPlot(self):
110        """
111        Define context menu and associated actions for the quickplot MPL widget
112        """
113        # Default actions
114        self.defaultContextMenu()
115
116        # Additional actions
117        self.actionToggleGrid = self.contextMenu.addAction("Toggle Grid On/Off")
118        self.contextMenu.addSeparator()
119        self.actionChangeScale = self.contextMenu.addAction("Change Scale")
120
121        # Define the callbacks
122        self.actionToggleGrid.triggered.connect(self.onGridToggle)
123        self.actionChangeScale.triggered.connect(self.onScaleChange)
124
125    def onScaleChange(self):
126        """
127        Show a dialog allowing axes rescaling
128        """
129        if self.properties.exec_() == QtGui.QDialog.Accepted:
130            xLabel, yLabel = self.properties.getValues()
131            self.xyTransform(xLabel, yLabel)
132
133    def onModifyGraph(self):
134        """
135        Show a dialog allowing chart manipulations
136        """
137        print ("onModifyGraph")
138        pass
139
140    def onAddText(self):
141        """
142        Show a dialog allowing adding custom text to the chart
143        """
144        print("onAddText")
145        pass
146
147    def onRemoveText(self):
148        """
149        Remove the most recent added text
150        """
151        print("onRemoveText")
152        pass
153
154    def onSetGraphRange(self):
155        """
156        Show a dialog allowing setting the chart ranges
157        """
158        print("onSetGraphRange")
159        pass
160
161    def onResetGraphRange(self):
162        """
163        Resets the chart X and Y ranges to the original values
164        """
165        print("onResetGraphRange")
166        pass
167
168    def xyTransform(self, xLabel="", yLabel=""):
169        """
170        Transforms x and y in View and set the scale
171        """
172        # Clear the plot first
173        plt.cla()
174
175        # Changing the scale might be incompatible with
176        # currently displayed data (for instance, going
177        # from ln to log when all plotted values have
178        # negative natural logs).
179        # Go linear and only change the scale at the end.
180        self._xscale = "linear"
181        self._yscale = "linear"
182        _xscale = 'linear'
183        _yscale = 'linear'
184        # Local data is either 1D or 2D
185        if self.data.id == 'fit':
186            return
187
188        # control axis labels from the panel itself
189        yname, yunits = self.data.get_yaxis()
190        xname, xunits = self.data.get_xaxis()
191
192        # Goes through all possible scales
193        # self.x_label is already wrapped with Latex "$", so using the argument
194
195        # X
196        if xLabel == "x":
197            self.data.transformX(transform.toX, transform.errToX)
198            self.xLabel = "%s(%s)" % (xname, xunits)
199        if xLabel == "x^(2)":
200            self.data.transformX(transform.toX2, transform.errToX2)
201            xunits = convert_unit(2, xunits)
202            self.xLabel = "%s^{2}(%s)" % (xname, xunits)
203        if xLabel == "x^(4)":
204            self.data.transformX(transform.toX4, transform.errToX4)
205            xunits = convert_unit(4, xunits)
206            self.xLabel = "%s^{4}(%s)" % (xname, xunits)
207        if xLabel == "ln(x)":
208            self.data.transformX(transform.toLogX, transform.errToLogX)
209            self.xLabel = "\ln{(%s)}(%s)" % (xname, xunits)
210        if xLabel == "log10(x)":
211            self.data.transformX(transform.toX_pos, transform.errToX_pos)
212            _xscale = 'log'
213            self.xLabel = "%s(%s)" % (xname, xunits)
214        if xLabel == "log10(x^(4))":
215            self.data.transformX(transform.toX4, transform.errToX4)
216            xunits = convert_unit(4, xunits)
217            self.xLabel = "%s^{4}(%s)" % (xname, xunits)
218            _xscale = 'log'
219
220        # Y
221        if yLabel == "ln(y)":
222            self.data.transformY(transform.toLogX, transform.errToLogX)
223            self.yLabel = "\ln{(%s)}(%s)" % (yname, yunits)
224        if yLabel == "y":
225            self.data.transformY(transform.toX, transform.errToX)
226            self.yLabel = "%s(%s)" % (yname, yunits)
227        if yLabel == "log10(y)":
228            self.data.transformY(transform.toX_pos, transform.errToX_pos)
229            _yscale = 'log'
230            self.yLabel = "%s(%s)" % (yname, yunits)
231        if yLabel == "y^(2)":
232            self.data.transformY(transform.toX2, transform.errToX2)
233            yunits = convert_unit(2, yunits)
234            self.yLabel = "%s^{2}(%s)" % (yname, yunits)
235        if yLabel == "1/y":
236            self.data.transformY(transform.toOneOverX, transform.errOneOverX)
237            yunits = convert_unit(-1, yunits)
238            self.yLabel = "1/%s(%s)" % (yname, yunits)
239        if yLabel == "y*x^(2)":
240            self.data.transformY(transform.toYX2, transform.errToYX2)
241            xunits = convert_unit(2, xunits)
242            self.yLabel = "%s \ \ %s^{2}(%s%s)" % (yname, xname, yunits, xunits)
243        if yLabel == "y*x^(4)":
244            self.data.transformY(transform.toYX4, transform.errToYX4)
245            xunits = convert_unit(4, xunits)
246            self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
247        if yLabel == "1/sqrt(y)":
248            self.data.transformY(transform.toOneOverSqrtX,
249                                 transform.errOneOverSqrtX)
250            yunits = convert_unit(-0.5, yunits)
251            self.yLabel = "1/\sqrt{%s}(%s)" % (yname, yunits)
252        if yLabel == "ln(y*x)":
253            self.data.transformY(transform.toLogXY, transform.errToLogXY)
254            self.yLabel = "\ln{(%s \ \ %s)}(%s%s)" % (yname, xname, yunits, xunits)
255        if yLabel == "ln(y*x^(2))":
256            self.data.transformY(transform.toLogYX2, transform.errToLogYX2)
257            xunits = convert_unit(2, xunits)
258            self.yLabel = "\ln (%s \ \ %s^{2})(%s%s)" % (yname, xname, yunits, xunits)
259        if yLabel == "ln(y*x^(4))":
260            self.data.transformY(transform.toLogYX4, transform.errToLogYX4)
261            xunits = convert_unit(4, xunits)
262            self.yLabel = "\ln (%s \ \ %s^{4})(%s%s)" % (yname, xname, yunits, xunits)
263        if yLabel == "log10(y*x^(4))":
264            self.data.transformY(transform.toYX4, transform.errToYX4)
265            xunits = convert_unit(4, xunits)
266            _yscale = 'log'
267            self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
268
269        # Perform the transformation of data in data1d->View
270        self.data.transformView()
271
272        self.xscale = _xscale
273        self.yscale = _yscale
274
275        # Plot the updated chart
276        self.plot(marker='o', linestyle='')
277
278
279class Plotter(QtGui.QDialog, PlotterWidget):
280    def __init__(self, parent=None, quickplot=False):
281
282        QtGui.QDialog.__init__(self)
283        PlotterWidget.__init__(self, manager=parent, quickplot=quickplot)
284        icon = QtGui.QIcon()
285        icon.addPixmap(QtGui.QPixmap(":/res/ball.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
286        self.setWindowIcon(icon)
287
288
Note: See TracBrowser for help on using the repository browser.