def aliases_figure(f0, fs): t = np.linspace(0, 1, 50*fs) y = np.sin(f0 * 2*np.pi * t) sig = Signal(t, y) alias_sig = Signal(t, y) fig = sig.get_fig(size=(1080,300),title="Aliases of {} Hz signal".format(f0)) alias_sig.update_line_opts({'line_color' : 'orange', 'line_alpha': 1}) alias_sig.create_line_renderer(fig) alias_x = np.linspace(0, 1, fs, endpoint=False) alias_y = np.sin(f0 * 2*np.pi * alias_x) alias_points = ColumnDataSource({ 'x' : alias_x, 'y' : alias_y, 'y0': np.zeros(alias_x.size) }) fig.circle(x='x', y='y', source=alias_points, fill_color='red', line_width=3, line_color='red') fig.segment(x0='x', x1='x', y0='y0', y1='y', source=alias_points,line_width=3, line_color='red') handle = show(fig, notebook_handle=True) def frame_gen(fv): return {'y': np.sin(fv*2*np.pi*t)} anim_sets = [] for k in range(1, 6): f_previous = f0 + (k-1)*fs f_alias = f0 + k*fs frame_values = np.linspace(f_previous, f_alias, 60) anim = FrameAnimation(alias_sig.data_source(), frame_gen, frame_values) anim_sets.append(AnimationSet([anim])) anim_sets.append(AnimationSet([Pause(1)])) AnimateSets(anim_sets, handle).run()
def add_functions(t, ft, gt, xt, animated=False): sig_ft = Signal(t, ft) sig_gt = Signal(t, gt) sig_xt = Signal(t, xt) y_max = max(sig_ft.max(), sig_gt.max(), sig_xt.max()) y_min = min(sig_ft.min(), sig_gt.min(), sig_xt.min()) def update_axis_range(fig): fig.x_range.start = t[0] fig.x_range.end = t[-1] fig.y_range.start = y_min fig.y_range.end = y_max fig_ft = sig_ft.create_fig(size=(900,300), title='f(t)', scale='time') update_axis_range(fig_ft) fig_ft.xaxis.axis_label = 't' fig_ft.yaxis.axis_label = 'f(t)' sig_ft.update_line_opts({'line_color':'red'}) sig_ft.create_renderers(fig_ft, ['line', 'stems']) fig_gt = sig_gt.create_fig(size=(900,300), title='g(t)', scale='time') update_axis_range(fig_gt) fig_gt.xaxis.axis_label = 't' fig_gt.yaxis.axis_label = 'g(t)' sig_gt.update_line_opts({'line_color':'green'}) sig_gt.update_stem_opts({'line_color':'green'}) sig_gt.create_renderers(fig_gt, ['line', 'stems']) fig_xt = sig_xt.create_fig(size=(1800,300), title='x(t)', scale='time') update_axis_range(fig_xt) fig_xt.xaxis.axis_label = 't' fig_xt.yaxis.axis_label = 'x(t)' sig_xt.update_line_opts({'line_color':'purple', 'line_width': 5, 'line_alpha':1}) sig_xt.create_renderers(fig_xt, ['line']) # sig_gt.update_line_opts({'line_width':1, 'line_alpha':0.6}) sig_ft.create_renderers(fig_xt, ['stems']) # sig_ft.update_line_opts({'line_width':1, 'line_alpha':0.6}) # sig_ft.create_renderers(fig_xt, ['line']) extra_ds = ColumnDataSource({'x':t, 'y0': np.zeros(t.size), 'y1': gt}) opts = stem_defaults.copy() opts.update({'line_color':'green'}) fig_xt.segment(x0='x', x1='x', y0='y0', y1='y1', source=extra_ds, **opts) handle = show(column(row(fig_ft, fig_gt), fig_xt), notebook_handle=True) if animated: ft_anim = sig_ft.create_stem_animation(frames=t.size) gt_anim = sig_gt.create_stem_animation(frames=t.size) xs = np.array_split(extra_ds.data['x'], t.size) y1 = np.array_split(extra_ds.data['y1'], t.size) y0 = np.array_split(extra_ds.data['y0'], t.size) data = [{ 'x': xs[frame], 'y1': y1[frame], 'y0': y0[frame]} for frame in range(0, t.size)] gt_on_figxt = StreamAnimation(extra_ds, data) slide_to_data = [{ 'y0': [ (frame, ft[frame]) ], 'y1': [ (frame, xt[frame]) ] } for frame in range(0, t.size)] slide_to = UpdateAnimation(extra_ds, slide_to_data) a1set = AnimationSet([ft_anim]) a2set = AnimationSet([gt_anim, gt_on_figxt]) a3set = AnimationSet([slide_to]) AnimateSets([a1set, a2set, a3set], handle, fps=45).run()