source: sasview/src/sas/qtgui/ColorMap.py @ 03c372d

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

Added unit tests to SASVIEW-391

  • Property mode set to 100755
File size: 6.8 KB
Line 
1"""
2Allows users to change the range of the current graph
3"""
4from PyQt4 import QtGui
5from PyQt4 import QtCore
6import path_prepare
7
8import matplotlib as mpl
9from matplotlib import pylab
10import numpy
11
12from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
13from sas.sasgui.guiframe.dataFitting import Data2D
14from sas.qtgui.GuiUtils import formatNumber
15
16DEFAULT_MAP = 'jet'
17
18# Local UI
19from sas.qtgui.UI.ColorMapUI import Ui_ColorMapUI
20
21class ColorMap(QtGui.QDialog, Ui_ColorMapUI):
22    def __init__(self, parent=None, cmap=None, vmin=0.0, vmax=100.0, data=None):
23        super(ColorMap, self).__init__()
24
25        self.setupUi(self)
26        assert(isinstance(data, Data2D))
27
28        self.data = data
29        self._cmap_orig = self._cmap = cmap if cmap is not None else DEFAULT_MAP
30        self.all_maps = [m for m in pylab.cm.datad]
31        self.maps = sorted(m for m in self.all_maps if not m.endswith("_r"))
32        self.rmaps = sorted(set(self.all_maps) - set(self.maps))
33
34        self.vmin = vmin
35        self.vmax = vmax
36
37        # Initialize detector labels
38        self.initDetectorData()
39
40        # Initialize the combo box
41        self.initMapCombobox()
42
43        # Add the color map component
44        self.initColorMap()
45
46        # Initialize validators on amplitude textboxes
47        validator_min = QtGui.QDoubleValidator(self.txtMinAmplitude)
48        validator_min.setNotation(0)
49        self.txtMinAmplitude.setValidator(validator_min)
50        validator_max = QtGui.QDoubleValidator(self.txtMaxAmplitude)
51        validator_max.setNotation(0)
52        self.txtMaxAmplitude.setValidator(validator_max)
53
54        # Enforce constant size on the widget
55        self.setFixedSize(self.minimumSizeHint())
56
57        # Handle combobox changes
58        self.cbColorMap.currentIndexChanged.connect(self.onMapIndexChange)
59
60        # Handle checkbox changes
61        self.chkReverse.stateChanged.connect(self.onColorMapReversed)
62
63        # Handle the reset button click
64        self.buttonBox.button(QtGui.QDialogButtonBox.Reset).clicked.connect(self.onReset)
65
66        # Handle the amplitude setup
67        self.txtMinAmplitude.editingFinished.connect(self.onAmplitudeChange)
68        self.txtMaxAmplitude.editingFinished.connect(self.onAmplitudeChange)
69
70    def cmap(self):
71        """
72        Getter for the color map
73        """
74        return self._cmap
75
76    def norm(self):
77        """
78        Getter for the color map norm
79        """
80        return (self._norm.vmin, self._norm.vmax)
81
82    def onReset(self):
83        """
84        Respond to the Reset button click
85        """
86        # Go back to original settings
87        self._cmap = self._cmap_orig
88        self._norm = mpl.colors.Normalize(vmin=self.vmin, vmax=self.vmax)
89        self.txtMaxAmplitude.clear()
90        self.txtMinAmplitude.clear()
91        self.initMapCombobox()
92        # Redraw the widget
93        self.redrawColorBar()
94        self.canvas.draw()
95
96    def initDetectorData(self):
97        """
98        Fill out the Detector labels
99        """
100        xnpts = len(self.data.x_bins)
101        ynpts = len(self.data.y_bins)
102        self.lblWidth.setText(formatNumber(xnpts))
103        self.lblHeight.setText(formatNumber(ynpts))
104        xmax = max(self.data.xmin, self.data.xmax)
105        ymax = max(self.data.ymin, self.data.ymax)
106        qmax = numpy.sqrt(numpy.power(xmax, 2) + numpy.power(ymax, 2))
107        self.lblQmax.setText(formatNumber(qmax))
108        self.lblStopRadius.setText(formatNumber(self.data.xmin))
109
110    def initMapCombobox(self):
111        """
112        Fill out the combo box with all available color maps
113        """
114        if self._cmap in self.rmaps:
115            maps = self.rmaps
116            # Assure correct state of the checkbox
117            self.chkReverse.setChecked(True)
118        else:
119            maps = self.maps
120            # Assure correct state of the checkbox
121            self.chkReverse.setChecked(False)
122
123        self.cbColorMap.addItems(maps)
124        # Set the default/passed map
125        self.cbColorMap.setCurrentIndex(self.cbColorMap.findText(self._cmap))
126
127    def initColorMap(self):
128        """
129        Prepare and display the color map
130        """
131        self.fig = mpl.figure.Figure(figsize=(4, 1))
132        self.ax1 = self.fig.add_axes([0.05, 0.65, 0.9, 0.15])
133        self._norm = mpl.colors.Normalize(vmin=self.vmin, vmax=self.vmax)
134        self.redrawColorBar()
135        self.canvas = FigureCanvas(self.fig)
136        layout = QtGui.QVBoxLayout()
137        layout.addWidget(self.canvas)
138        self.widget.setLayout(layout)
139
140    def onMapIndexChange(self, index):
141        """
142        Respond to the color map change event
143        """
144        new_map = str(self.cbColorMap.itemText(index))
145        self._cmap = new_map
146        self.redrawColorBar()
147        self.canvas.draw()
148
149    def redrawColorBar(self):
150        """
151        Call ColorbarBase with current values, effectively redrawing the widget
152        """
153        self.cb = mpl.colorbar.ColorbarBase(self.ax1, cmap=self._cmap,
154                                            norm=self._norm,
155                                            orientation='horizontal')
156        self.cb.set_label('Detector Colors')
157
158    def onColorMapReversed(self, isChecked):
159        """
160        Respond to ticking/unticking the color map reverse checkbox
161        """
162        current_map = str(self.cbColorMap.currentText())
163        if isChecked:
164            # Add "_r" to map name for the reversed version
165            new_map = current_map + "_r"
166            maps = self.rmaps
167            # Assure the reversed map exists.
168            if new_map not in maps:
169                new_map = maps[0]
170        else:
171            new_map = current_map[:-2] # "_r" = last two chars
172            maps = self.maps
173            # Base map for the reversed map should ALWAYS exist,
174            # but let's be paranoid here
175            if new_map not in maps:
176                new_map = maps[0]
177
178        self._cmap = new_map
179        # Clearning the content of the combobox.
180        # Needs signal blocking, or else onMapIndexChange() spoils it all
181        self.cbColorMap.blockSignals(True)
182        self.cbColorMap.clear()
183        # Add the new set of maps
184        self.cbColorMap.addItems(maps)
185        # Remove the signal block before the proper index set
186        self.cbColorMap.blockSignals(False)
187        self.cbColorMap.setCurrentIndex(self.cbColorMap.findText(new_map))
188
189    def onAmplitudeChange(self):
190        """
191        Respond to editing the amplitude fields
192        """
193        min_amp = self.vmin
194        max_amp = self.vmax
195
196        try:
197            min_amp = float(self.txtMinAmplitude.text())
198        except ValueError:
199            pass
200        try:
201            max_amp = float(self.txtMaxAmplitude.text())
202        except ValueError:
203            pass
204
205        self._norm = mpl.colors.Normalize(vmin=min_amp, vmax=max_amp)
206        self.redrawColorBar()
207        self.canvas.draw()
Note: See TracBrowser for help on using the repository browser.