|
8 | 8 | import numpy as np |
9 | 9 |
|
10 | 10 | import wx |
11 | | -import matplotlib |
12 | | -matplotlib.interactive(False) |
13 | | -matplotlib.use('WXAgg') |
14 | 11 | from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg |
15 | 12 | from matplotlib.figure import Figure |
16 | 13 |
|
@@ -108,55 +105,48 @@ def setKnob(self, value): |
108 | 105 | class FourierDemoFrame(wx.Frame): |
109 | 106 | def __init__(self, *args, **kwargs): |
110 | 107 | wx.Frame.__init__(self, *args, **kwargs) |
| 108 | + panel = wx.Panel(self) |
111 | 109 |
|
112 | | - self.fourierDemoWindow = FourierDemoWindow(self) |
113 | | - self.frequencySliderGroup = SliderGroup( |
114 | | - self, |
115 | | - label='Frequency f0:', |
116 | | - param=self.fourierDemoWindow.f0) |
117 | | - self.amplitudeSliderGroup = SliderGroup(self, label=' Amplitude a:', |
118 | | - param=self.fourierDemoWindow.A) |
| 110 | + # create the GUI elements |
| 111 | + self.createCanvas(panel) |
| 112 | + self.createSliders(panel) |
119 | 113 |
|
| 114 | + # place them in a sizer for the Layout |
120 | 115 | sizer = wx.BoxSizer(wx.VERTICAL) |
121 | | - sizer.Add(self.fourierDemoWindow, 1, wx.EXPAND) |
| 116 | + sizer.Add(self.canvas, 1, wx.EXPAND) |
122 | 117 | sizer.Add(self.frequencySliderGroup.sizer, 0, |
123 | 118 | wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) |
124 | 119 | sizer.Add(self.amplitudeSliderGroup.sizer, 0, |
125 | 120 | wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) |
126 | | - self.SetSizer(sizer) |
127 | | - |
| 121 | + panel.SetSizer(sizer) |
128 | 122 |
|
129 | | -class FourierDemoWindow(wx.Window, Knob): |
130 | | - def __init__(self, *args, **kwargs): |
131 | | - wx.Window.__init__(self, *args, **kwargs) |
| 123 | + def createCanvas(self, parent): |
132 | 124 | self.lines = [] |
133 | 125 | self.figure = Figure() |
134 | | - self.canvas = FigureCanvasWxAgg(self, -1, self.figure) |
| 126 | + self.canvas = FigureCanvasWxAgg(parent, -1, self.figure) |
135 | 127 | self.canvas.callbacks.connect('button_press_event', self.mouseDown) |
136 | 128 | self.canvas.callbacks.connect('motion_notify_event', self.mouseMotion) |
137 | 129 | self.canvas.callbacks.connect('button_release_event', self.mouseUp) |
138 | 130 | self.state = '' |
139 | 131 | self.mouseInfo = (None, None, None, None) |
140 | 132 | self.f0 = Param(2., minimum=0., maximum=6.) |
141 | 133 | self.A = Param(1., minimum=0.01, maximum=2.) |
142 | | - self.draw() |
| 134 | + self.createPlots() |
143 | 135 |
|
144 | 136 | # Not sure I like having two params attached to the same Knob, |
145 | 137 | # but that is what we have here... it works but feels kludgy - |
146 | 138 | # although maybe it's not too bad since the knob changes both params |
147 | 139 | # at the same time (both f0 and A are affected during a drag) |
148 | 140 | self.f0.attach(self) |
149 | 141 | self.A.attach(self) |
150 | | - self.Bind(wx.EVT_SIZE, self.sizeHandler) |
151 | | - |
152 | | - self.Bind(wx.EVT_PAINT, self.OnPaint) |
153 | | - |
154 | | - def OnPaint(self, event): |
155 | | - self.canvas.draw() |
156 | | - event.Skip() |
157 | 142 |
|
158 | | - def sizeHandler(self, *args, **kwargs): |
159 | | - self.canvas.SetSize(self.GetSize()) |
| 143 | + def createSliders(self, panel): |
| 144 | + self.frequencySliderGroup = SliderGroup( |
| 145 | + panel, |
| 146 | + label='Frequency f0:', |
| 147 | + param=self.f0) |
| 148 | + self.amplitudeSliderGroup = SliderGroup(panel, label=' Amplitude a:', |
| 149 | + param=self.A) |
160 | 150 |
|
161 | 151 | def mouseDown(self, evt): |
162 | 152 | if self.lines[0].contains(evt)[0]: |
@@ -186,7 +176,10 @@ def mouseMotion(self, evt): |
186 | 176 | def mouseUp(self, evt): |
187 | 177 | self.state = '' |
188 | 178 |
|
189 | | - def draw(self): |
| 179 | + def createPlots(self): |
| 180 | + # This method creates the subplots, waveforms and labels. |
| 181 | + # Later, when the waveforms or sliders are dragged, only the |
| 182 | + # waveform data will be updated (not here, but below in setKnob). |
190 | 183 | if not hasattr(self, 'subplot1'): |
191 | 184 | self.subplot1, self.subplot2 = self.figure.subplots(2) |
192 | 185 | x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value) |
@@ -222,15 +215,14 @@ def compute(self, f0, A): |
222 | 215 | (np.exp(-np.pi * (f - f0) ** 2) + np.exp(-np.pi * (f + f0) ** 2)) |
223 | 216 | return f, X, t, x |
224 | 217 |
|
225 | | - def repaint(self): |
226 | | - self.canvas.draw() |
227 | | - |
228 | 218 | def setKnob(self, value): |
229 | 219 | # Note, we ignore value arg here and just go by state of the params |
230 | 220 | x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value) |
| 221 | + # update the data of the two waveforms |
231 | 222 | self.lines[0].set(xdata=x1, ydata=y1) |
232 | 223 | self.lines[1].set(xdata=x2, ydata=y2) |
233 | | - self.repaint() |
| 224 | + # make the canvas draw its contents again with the new data |
| 225 | + self.canvas.draw() |
234 | 226 |
|
235 | 227 |
|
236 | 228 | class App(wx.App): |
|
0 commit comments