[49e124c] | 1 | import logging |
---|
| 2 | import copy |
---|
| 3 | import numpy |
---|
| 4 | import pylab |
---|
| 5 | |
---|
| 6 | from PyQt4 import QtGui |
---|
| 7 | |
---|
| 8 | # TODO: Replace the qt4agg calls below with qt5 equivalent. |
---|
| 9 | # Requires some code modifications. |
---|
| 10 | # https://www.boxcontrol.net/embedding-matplotlib-plot-on-pyqt5-gui.html |
---|
| 11 | # |
---|
| 12 | from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas |
---|
| 13 | from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar |
---|
| 14 | import matplotlib.pyplot as plt |
---|
| 15 | |
---|
[31c5b58] | 16 | DEFAULT_CMAP = pylab.cm.jet |
---|
| 17 | |
---|
| 18 | import sas.qtgui.PlotUtilities as PlotUtilities |
---|
| 19 | import sas.qtgui.PlotHelper as PlotHelper |
---|
[49e124c] | 20 | |
---|
| 21 | class Plotter2D(QtGui.QDialog): |
---|
| 22 | def __init__(self, parent=None): |
---|
| 23 | super(Plotter2D, self).__init__(parent) |
---|
| 24 | |
---|
| 25 | # Required for the communicator |
---|
| 26 | self.parent = parent |
---|
| 27 | |
---|
| 28 | # a figure instance to plot on |
---|
| 29 | self.figure = plt.figure() |
---|
| 30 | |
---|
| 31 | # this is the Canvas Widget that displays the `figure` |
---|
| 32 | # it takes the `figure` instance as a parameter to __init__ |
---|
| 33 | self.canvas = FigureCanvas(self.figure) |
---|
| 34 | |
---|
| 35 | # this is the Navigation widget |
---|
| 36 | # it takes the Canvas widget and a parent |
---|
| 37 | self.toolbar = NavigationToolbar(self.canvas, self) |
---|
| 38 | |
---|
| 39 | # set the layout |
---|
| 40 | layout = QtGui.QVBoxLayout() |
---|
| 41 | layout.addWidget(self.canvas) |
---|
| 42 | layout.addWidget(self.toolbar) |
---|
| 43 | self.setLayout(layout) |
---|
| 44 | |
---|
| 45 | # defaults |
---|
| 46 | self._current_plot = 111 |
---|
| 47 | self._data = [] |
---|
| 48 | self._qx_data = [] |
---|
| 49 | self._qy_data = [] |
---|
[31c5b58] | 50 | self._color=0 |
---|
| 51 | self._symbol=0 |
---|
| 52 | self._scale = 'linear' |
---|
| 53 | |
---|
| 54 | # default color map |
---|
| 55 | self._cmap = DEFAULT_CMAP |
---|
[49e124c] | 56 | |
---|
| 57 | self._ax = self.figure.add_subplot(self._current_plot) |
---|
| 58 | |
---|
| 59 | # Notify the helper |
---|
| 60 | PlotHelper.addPlot(self) |
---|
| 61 | # Notify the listeners |
---|
| 62 | self.parent.communicator.activeGraphsSignal.emit(PlotHelper.currentPlots()) |
---|
| 63 | |
---|
[31c5b58] | 64 | @property |
---|
| 65 | def data(self): |
---|
| 66 | return self._data |
---|
| 67 | |
---|
| 68 | @data.setter |
---|
[49e124c] | 69 | def data(self, data=None): |
---|
| 70 | """ data setter """ |
---|
[14d9c7b] | 71 | self._data = data |
---|
[31c5b58] | 72 | self._qx_data=data.qx_data |
---|
| 73 | self._qy_data=data.qy_data |
---|
| 74 | self._xmin=data.xmin |
---|
| 75 | self._xmax=data.xmax |
---|
| 76 | self._ymin=data.ymin |
---|
| 77 | self._ymax=data.ymax |
---|
| 78 | self._zmin=data.zmin |
---|
| 79 | self._zmax=data.zmax |
---|
| 80 | self._label=data.name |
---|
| 81 | self.x_label(xlabel=data._xaxis + data._xunit) |
---|
| 82 | self.y_label(ylabel=data._yaxis + data._yunit) |
---|
[49e124c] | 83 | self.title(title=data.title) |
---|
| 84 | |
---|
| 85 | def title(self, title=""): |
---|
| 86 | """ title setter """ |
---|
| 87 | self._title = title |
---|
| 88 | |
---|
| 89 | def id(self, id=""): |
---|
| 90 | """ id setter """ |
---|
| 91 | self._id = id |
---|
| 92 | |
---|
| 93 | def x_label(self, xlabel=""): |
---|
| 94 | """ x-label setter """ |
---|
| 95 | self._xlabel = r'$%s$'% xlabel |
---|
| 96 | |
---|
| 97 | def y_label(self, ylabel=""): |
---|
| 98 | """ y-label setter """ |
---|
| 99 | self._ylabel = r'$%s$'% ylabel |
---|
| 100 | |
---|
| 101 | def clean(self): |
---|
| 102 | """ |
---|
| 103 | Redraw the graph |
---|
| 104 | """ |
---|
| 105 | self.figure.delaxes(self._ax) |
---|
| 106 | self._ax = self.figure.add_subplot(self._current_plot) |
---|
| 107 | |
---|
| 108 | def plot(self, marker=None, linestyle=None): |
---|
| 109 | """ |
---|
| 110 | Plot 2D self._data |
---|
| 111 | """ |
---|
| 112 | # create an axis |
---|
| 113 | ax = self._ax |
---|
| 114 | |
---|
[31c5b58] | 115 | # graph properties |
---|
| 116 | ax.set_xlabel(self._xlabel) |
---|
| 117 | ax.set_ylabel(self._ylabel) |
---|
| 118 | ax.set_title(label=self._title) |
---|
| 119 | |
---|
| 120 | # Re-adjust colorbar |
---|
| 121 | # self.figure.subplots_adjust(left=0.2, right=.8, bottom=.2) |
---|
| 122 | |
---|
| 123 | output = PlotUtilities.build_matrix(self._data.data, self._qx_data, self._qy_data) |
---|
| 124 | |
---|
| 125 | im = ax.imshow(output, |
---|
| 126 | interpolation='nearest', |
---|
| 127 | origin='lower', |
---|
| 128 | vmin=self._zmin, vmax=self._zmax, |
---|
| 129 | cmap=self._cmap, |
---|
| 130 | extent=(self._xmin, self._xmax, |
---|
| 131 | self._ymin, self._ymax)) |
---|
| 132 | |
---|
| 133 | cbax = self.figure.add_axes([0.84, 0.2, 0.02, 0.7]) |
---|
| 134 | cb = self.figure.colorbar(im, cax=cbax) |
---|
| 135 | cb.update_bruteforce(im) |
---|
| 136 | cb.set_label('$' + self._scale + '$') |
---|
| 137 | |
---|
| 138 | # Schedule the draw for the next time the event loop is idle. |
---|
| 139 | self.canvas.draw_idle() |
---|
[49e124c] | 140 | |
---|
| 141 | def closeEvent(self, event): |
---|
| 142 | """ |
---|
| 143 | Overwrite the close event adding helper notification |
---|
| 144 | """ |
---|
| 145 | # Please remove me from your database. |
---|
| 146 | PlotHelper.deletePlot(PlotHelper.idOfPlot(self)) |
---|
| 147 | # Notify the listeners |
---|
| 148 | self.parent.communicator.activeGraphsSignal.emit(PlotHelper.currentPlots()) |
---|
| 149 | event.accept() |
---|
| 150 | |
---|