Note
Go to the end to download the full example code.
Creating widgets with SpectAcoular.
This example creates an interactive plot of a microphone array geometry with additional control widgets using the SpectAcoular package.
Note
This example can be rendered as a standalone Bokeh document, but full interactivity with Python callbacks requires running it as a Bokeh server application.
Set up the microphone geometry plot#
Similar to the basic_mic_geom_plot, we will first import the necessary modules and set up the microphone geometry plot.
from pathlib import Path
import acoular as ac
import spectacoular as sp
from bokeh.io import curdoc, show
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, NumberEditor, PointDrawTool, TableColumn
from bokeh.models.widgets import DataTable, NumericInput
from bokeh.plotting import figure
# set up the figure
figure = figure(
title='Microphone Geometry',
tools='hover,zoom_in,zoom_out,reset,lasso_select',
match_aspect=True,
)
# set up the microphone geometry
default_xml_file = Path(ac.__file__).parent / 'xml' / 'tub_vogel64.xml'
mics = sp.MicGeom(file=default_xml_file)
# add circles to the figure to represent the microphones
cds = ColumnDataSource(data={'x': mics.pos_total[0], 'y': mics.pos_total[1]})
glyph = figure.circle(
x='x',
y='y',
radius=0.02,
line_color='black',
fill_color='#1F77B4',
fill_alpha=0.4,
source=cds,
)
Create widgets for MicGeom#
The MicGeom class provides several
attributes, known as traits, that can either provide additional
information about the microphone array or modify the geometry. In this
example, we focus on the most relevant ones for widget creation:
num_mics,
aperture, and
pos_total.
If we want to inspect the number of microphones
(num_mics) and the aperture of the
microphone array (aperture), we can
use SpectAcoular’s get_widgets() function to
translate each attribute into a Bokeh widget.
Defining each trait to widget mapping individually can become cumbersome, and not all widgets are suitable for all traits. Therefore, SpectAcoular provides default widget mapping for most of Acoular’s classes.
numeric_widgets = mics.get_widgets(
{'aperture': NumericInput, 'num_mics': NumericInput},
{
'aperture': {'title': 'Aperture/m', 'disabled': True},
'num_mics': {'title': 'Number of Mics', 'disabled': True},
},
)
It would also be beneficial to have a widget that allows the user to edit the microphone positions
and to display the coodinates in a table format. Both can be achieved by using Bokeh’s
DataTable widget. In addition, we will use the
NumberEditor to allow the user to edit the values in the table.
editor = NumberEditor()
pos_table = [
TableColumn(field='x', title='x/m', editor=editor),
TableColumn(field='y', title='y/m', editor=editor),
TableColumn(field='z', title='z/m', editor=editor),
]
# get the widgets for the MicGeom instance
data_table_widget = mics.get_widgets(
{'pos_total': DataTable},
{
'pos_total': {
'height': 450,
'transposed': True,
'columns': pos_table,
'source': cds,
'editable': True,
}
},
)
Finally, we want to allow the user to add or remove microphones from the microphone array.
Therefore, we will use the PointDrawTool.
draw_tool = PointDrawTool(renderers=[glyph], empty_value=0.0)
figure.add_tools(draw_tool)
figure.toolbar.active_tap = draw_tool
Let’s create a layout that contains the figure and the widgets.
widget_column = column(*numeric_widgets.values(), *data_table_widget.values(), width=400)
layout = row(figure, widget_column)
show(layout) # Show the plot in a new browser window
The following code is for Bokeh server apps only.
curdoc().add_root(layout) # Add the layout to the current document for Bokeh server apps