Hi, The problem I am having is labels still showing, overlapping with other labels and the BoxAnnotations, looking untidy, when series are hidden (legend.click_policy=“hide”).
I found a partial fix using
circ.js_on_change('visible', CustomJS(args=dict(ls=labels),
code="ls.visible = cb_obj.visible;"))
but it seems that all the series have to be visible when the plot loads and it is inconvenient to click through the legend items to hide all but the one of interest. I tired combining with
circ.visible=False
line.visible=False
but with no success. Ideally I’d like the plot to display with no series showing to start with and no labels visible or overlapping.
Minimal code to replicate issue:
'''Data'''
import random
x_labels = ['A' ,'B' , 'C', 'D', 'E', 'F', 'G']
scores_dict = {
'x' : x_labels
}
names = ['S'+str(x) for x in range(35)]
for n in names:
scores_dict[n] = [random.randint(1,9) for i in range(7)]
from bokeh.io import show, output_notebook
from bokeh.models import ColumnDataSource, LabelSet, Label, Band, BoxAnnotation, Span, CustomJS
from bokeh.transform import factor_cmap, linear_cmap
from bokeh.plotting import figure
source = ColumnDataSource(scores_dict)
palette = ['#C40936', '#000000', '#198BCA']
series = list (scores_dict.keys())
series.pop(0) #removes 'x'
p = figure(x_range=x_labels, title=' Scores ', plot_width=800, plot_height=900, tools='save')
for s in range (len (series)):
mapper = linear_cmap(field_name=series[s], palette=palette ,low=0.5 ,high=9.5)
line = p.line(x='x', y=series[s], line_color='grey', source=source, line_width=2, alpha=0.8, legend_label=series[s])
circ = p.circle(x='x', y=series[s], line_color=mapper, color=mapper, source=source, size=26, alpha=0.8, legend_label=series[s])
labels = LabelSet(x='x', y=series[s], text=series[s], level='overlay', text_font_size='10pt', text_font_style='bold',
text_align='center', text_color='white', x_offset=0, y_offset=-7, source=source, render_mode='canvas')
p.add_layout(labels)
# with .visible active as below the labels are visible even when the glyphs are hidden,
# you can see the values agains the BoxAnnotations.
# circ.visible=False
# line.visible=False
# with these .js_on_change active instead (they don't seem to work with .visible=False
# all series are unhidden and have to be hidden by clicking the legend entries, inconvenient
circ.js_on_change('visible', CustomJS(args=dict(ls=labels),
code="ls.visible = cb_obj.visible;"))
line.js_on_change('visible', CustomJS(args=dict(ls=labels),
code="ls.visible = cb_obj.visible;"))
high_box = BoxAnnotation(bottom=3.5, fill_alpha=0.1, fill_color='red')
mid_box = BoxAnnotation(bottom=6.5, top=3.5, fill_alpha=0.1, fill_color='lightgrey')
low_box = BoxAnnotation(top=6.5, fill_alpha=0.1, fill_color='blue')
p.add_layout(low_box)
p.add_layout(mid_box)
p.add_layout(high_box)
divide1 = Span(location=3, dimension='height', line_color='black', line_dash='solid', line_width=1)
divide2 = Span(location=5, dimension='height', line_color='firebrick', line_dash='dashed', line_width=2)
p.add_layout(divide1)
p.add_layout(divide2)
'''x-axis settings'''
#p.xgrid.ticker = [1, 2, 3, 4, 5, 6,7]
'''y-axis settings'''
p.y_range.start = 9.5
p.y_range.end = 0.5
p.y_range.range_padding = 0
p.yaxis.visible = False
p.ygrid.grid_line_color = None
'''both axis settings'''
p.axis.major_tick_line_color = None
'''Legend setup'''
p.right.append(p.legend[0])
p.legend.click_policy="hide"
show(p)