Skip to content

Commit 71fe342

Browse files
committed
add option to plot probabilities with stacked bars
1 parent e9f872b commit 71fe342

File tree

3 files changed

+50
-12
lines changed

3 files changed

+50
-12
lines changed

configuration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
gui_spectrogram_low_hz=0
6969
gui_spectrogram_high_hz=1250
7070
gui_spectrogram_clip=[1,99]
71+
gui_probability_style="lines" # either "lines" or "bars"
7172

7273
# neural network architecture to use
7374
architecture_plugin="convolutional"

src/gui/model.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ def init(_bokeh_document, _configuration_file, _use_aitch):
248248
global time_scale, freq_scale, context_time_scale, context_freq_scale
249249
global context_waveform_low, context_waveform_high, label_colors
250250
global spectrogram_colormap, spectrogram_clip, spectrogram_window, spectrogram_length_sec, spectrogram_overlap, spectrogram_low_hz, spectrogram_high_hz
251+
global probability_style
251252
global overlapped_prefix
252253
global deterministic
253254
global context_width_sec0, context_offset_sec0
@@ -376,6 +377,8 @@ def is_local_server_or_cluster(varname, varvalue):
376377
context_freq_units = gui_context_freq_units
377378
context_freq_scale = gui_context_freq_scale
378379

380+
probability_style=gui_probability_style
381+
379382
spectrogram_clip=gui_spectrogram_clip
380383
spectrogram_colormap=gui_spectrogram_colormap
381384
spectrogram_window=gui_spectrogram_window

src/gui/view.py

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import sys
33
from bokeh.models.widgets import RadioButtonGroup, TextInput, Button, Div, DateFormatter, TextAreaInput, Select, NumberFormatter, Slider, Toggle, ColorPicker, MultiSelect, Paragraph
44
from bokeh.models.formatters import FuncTickFormatter
5-
from bokeh.models import ColumnDataSource, TableColumn, DataTable, LayoutDOM, Span
5+
from bokeh.models import ColumnDataSource, TableColumn, DataTable, LayoutDOM, Span, HoverTool
66
from bokeh.plotting import figure
7-
from bokeh.transform import linear_cmap
7+
from bokeh.transform import linear_cmap, stack
88
from bokeh.events import Tap, DoubleTap, PanStart, Pan, PanEnd, ButtonClick, MouseWheel
99
from bokeh.models.callbacks import CustomJS
1010
from bokeh.models.markers import Circle
@@ -1130,9 +1130,19 @@ def context_update():
11301130
if xwav and not np.isnan(xwav[0][-1]):
11311131
spectrogram_range_source.data.update(x=[xwav[0][-1]])
11321132

1133-
probability_source.data.update(xs=xprob, ys=yprob,
1134-
colors=[M.label_colors[x] for x in M.used_labels],
1135-
labels=list(M.used_labels))
1133+
if M.probability_style=="lines":
1134+
probability_source.data.update(xs=xprob, ys=yprob,
1135+
colors=[M.label_colors[x] for x in M.used_labels],
1136+
labels=list(M.used_labels))
1137+
else:
1138+
if len(xprob)>1:
1139+
probability_source.data.update(**{'x'+str(i):(xprob[i] if i<len(xprob) else xprob[0])
1140+
for i in range(M.nlabels)},
1141+
**{'y'+str(i):(yprob[i] if i<len(yprob) else [0]*len(yprob[0]))
1142+
for i in range(M.nlabels)})
1143+
if len(xprob[0])>1:
1144+
for g in probability_glyphs:
1145+
g.glyph.width = xprob[0][1] - xprob[0][0]
11361146

11371147
if M.context_waveform:
11381148
waveform_quad_grey_used.data.update(left=left_used,
@@ -1248,6 +1258,9 @@ def recordings_update():
12481258
recordings.options = []
12491259

12501260
M.used_labels = set([x['label'] for x in M.used_sounds]) if M.used_sounds else []
1261+
if M.probability_style=="bars":
1262+
for ilabel,label in enumerate(M.used_labels):
1263+
probability_glyphs[ilabel].name = label
12511264
M.label_colors = { l:c for l,c in zip(M.used_labels, cycle(label_palette)) }
12521265
M.isnippet = -1
12531266
M.context_sound = None
@@ -1519,7 +1532,7 @@ def init(_bokeh_document):
15191532
global p_snippets, snippet_palette, snippets_dy, snippets_both, snippets_label_sources_clustered, snippets_label_sources_annotated, snippets_wave_sources, snippets_wave_glyphs, snippets_gram_sources, snippets_gram_glyphs, snippets_quad_grey, snippets_quad_fuchsia
15201533
global p_waveform, waveform_span_red, waveform_quad_grey_used, waveform_quad_grey_annotated, waveform_quad_grey_pan, waveform_quad_fuchsia, waveform_source, waveform_glyph, waveform_label_source_used, waveform_label_source_annotated
15211534
global p_spectrogram, spectrogram_span_red, spectrogram_quad_grey_used, spectrogram_quad_grey_annotated, spectrogram_quad_grey_pan, spectrogram_quad_fuchsia, spectrogram_source, spectrogram_glyph, spectrogram_label_source_used, spectrogram_label_source_annotated, spectrogram_range_source, spectrogram_length
1522-
global p_probability, probability_span_red, probability_source, probability_glyph
1535+
global p_probability, probability_span_red, probability_source
15231536
global which_layer, which_species, which_word, which_nohyphen, which_kind
15241537
global color_picker
15251538
global zoom_width, zoom_offset, zoomin, zoomout, reset, panleft, panright, allleft, allout, allright, firstlabel, nextlabel, prevlabel, lastlabel
@@ -1750,9 +1763,12 @@ def init(_bokeh_document):
17501763
text_font_size='6pt', text_align='center', text_baseline='bottom',
17511764
text_line_height=0.8, level='underlay', text_color='white')
17521765

1753-
TOOLTIPS = """
1754-
<div><div><span style="color:@colors;">@labels</span></div></div>
1755-
"""
1766+
if M.probability_style=="lines":
1767+
TOOLTIPS = """
1768+
<div><div><span style="color:@colors;">@labels,$y</span></div></div>
1769+
"""
1770+
else:
1771+
TOOLTIPS = ""
17561772

17571773
p_probability = figure(plot_width=M.gui_width_pix, tooltips=TOOLTIPS,
17581774
plot_height=M.context_probability_height_pix,
@@ -1765,9 +1781,27 @@ def init(_bokeh_document):
17651781
p_probability.y_range.end = 1
17661782
p_probability.xaxis.visible = False
17671783

1768-
probability_source = ColumnDataSource(data=dict(xs=[], ys=[], colors=[], labels=[]))
1769-
probability_glyph = p_probability.multi_line(xs='xs', ys='ys',
1770-
source=probability_source, color='colors')
1784+
if M.probability_style=="lines":
1785+
probability_source = ColumnDataSource(data=dict(xs=[], ys=[], colors=[], labels=[]))
1786+
global probability_glyph
1787+
probability_glyph = p_probability.multi_line(xs='xs', ys='ys',
1788+
source=probability_source, color='colors')
1789+
else:
1790+
xs = {'x'+str(i):[] for i in range(M.nlabels)}
1791+
ys = {'y'+str(i):[] for i in range(M.nlabels)}
1792+
probability_source = ColumnDataSource(data=xs|ys)
1793+
global probability_glyphs
1794+
probability_glyphs = []
1795+
for i in range(M.nlabels):
1796+
probability_glyphs.append(p_probability.vbar(
1797+
x='x'+str(i),
1798+
bottom=stack(*['y'+str(j) for j in range(i)]),
1799+
top=stack(*['y'+str(j) for j in range(i+1)]),
1800+
line_width = 0,
1801+
fill_color=label_palette[i],
1802+
source=probability_source))
1803+
p_probability.add_tools(HoverTool(renderers=[probability_glyphs[i]],
1804+
tooltips=[("", "$name, @y"+str(i))]))
17711805

17721806
probability_span_red = Span(location=0, dimension='height', line_color='red')
17731807
p_probability.add_layout(probability_span_red)

0 commit comments

Comments
 (0)