|
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