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 | |
---|
16 | DEFAULT_CMAP = pylab.cm.jet |
---|
17 | |
---|
18 | import sas.qtgui.PlotUtilities as PlotUtilities |
---|
19 | import sas.qtgui.PlotHelper as PlotHelper |
---|
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 = [] |
---|
50 | self._color=0 |
---|
51 | self._symbol=0 |
---|
52 | self._scale = 'linear' |
---|
53 | |
---|
54 | # default color map |
---|
55 | self._cmap = DEFAULT_CMAP |
---|
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 | |
---|
64 | @property |
---|
65 | def data(self): |
---|
66 | return self._data |
---|
67 | |
---|
68 | @data.setter |
---|
69 | def data(self, data=None): |
---|
70 | """ data setter """ |
---|
71 | self._data = data |
---|
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) |
---|
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 | |
---|
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() |
---|
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 | |
---|