Hi,
I am making a heatmap and the user selects what data to look at via a multiselect tool. They can also change the heatmap start and end. But when the user changes the heatmap high and end, the labels disappear. What am I doing wrong?
from math import pi
import pandas as pd
from bokeh.io import show
from bokeh.models import BasicTicker, ColorBar, LinearColorMapper, PrintfTickFormatter, BooleanFilter, MultiSelect, CDSView, TextInput, ColumnDataSource, CustomJS
from bokeh.plotting import figure
from bokeh.layouts import row, column
from bokeh.sampledata.unemployment1948 import data
data['Year'] = data['Year'].astype(str)
data = data.set_index('Year')
#data.drop('Annual', axis=1, inplace=True)
data.columns.name = 'Month'
years = list(data.index)
months = list(data.columns)
# reshape to 1D array or rates with a month and year for each row.
df = pd.DataFrame(data.stack(), columns=['rate']).reset_index()
source = ColumnDataSource(df)
year_filter= BooleanFilter([True if x == '2000' else False for x in source.data['Year']])
hmLow = TextInput(title = 'Heatmap low:', value = str(df.rate.min()))
hmMax = TextInput(title = 'Heatmap high:', value = str(df.rate.max()))
view = CDSView(source=source, filters=[year_filter])
year_select = MultiSelect(title= 'Year: ', value =['2000'], width = 200, height = 200,
options=years)
colors = ["#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"]
mapper = LinearColorMapper(palette=colors, low=df.rate.min(), high=df.rate.max())
TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
p = figure(title="US Unemployment ({0} - {1})".format(years[0], years[-1]),
x_range=years, y_range=list(reversed(months)),
x_axis_location="above", plot_width=900, plot_height=400,
tools=TOOLS, toolbar_location='below',
tooltips=[('date', '@Month @Year'), ('rate', '@rate%')])
p.grid.grid_line_color = None
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "14px"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = pi / 3
p.rect(x="Year", y="Month", width=1, height=1,
source=source,
view = view,
fill_color={'field': 'rate', 'transform': mapper},
line_color=None)
color_bar = ColorBar(color_mapper=mapper, major_label_text_font_size="7px",
ticker=BasicTicker(desired_num_ticks=len(colors)),
formatter=PrintfTickFormatter(format="%d%%"),
label_standoff=6, border_line_color=None, location=(0, 0))
p.add_layout(color_bar, 'right')
year_select.js_on_change('value', CustomJS(args = dict(f = year_filter,
source = source),
code="""\
const val = cb_obj.value;
f.booleans = Array.from(source.data['Year']).map(d => val.includes(d != null && d.toString()));
//source.selected.indices = [...new Set(source.data.index.filter((_, idx) => f.booleans[idx]))];
source.change.emit();
"""))
heatmapchange = CustomJS(args = dict(mapper = mapper,
hmLow = hmLow,
hmMax = hmMax),
code="""\
console.log(mapper)
mapper.attributes.low = hmLow.value
mapper.attributes.high = hmMax.value
console.log(mapper)
mapper.change.emit()
""")
hmLow.js_on_change('value', heatmapchange)
hmMax.js_on_change('value', heatmapchange)
show(row(p, year_select, column(hmLow, hmMax)))