For the Lasso, Box Select and Tap tools, I’ve run across a situation where selected Scatter points aren’t being highlighted when selected, and some outside the range are.
I’m grouping my data by Glyph and by Color. The selection is working fine when Color is ignored, but once a color grouping field is selected, the selection tools don’t work properly.
Here’s the relevant part of the code (the whole of it is pretty coupled to my environment, so I left it out):
…
self.tools = ‘pan,wheel_zoom,tap,lasso_select,reset’
self.markers = ['circle', 'square', 'triangle', 'diamond', 'square', 'cross', 'x', 'asterisk', 'inverted_triangle', 'circle_cross', 'square_cross', 'circle_x', 'square_x']
self.size = 10
self.highlight_fill = 1
self.default_fill = .1
def create_figure(self):
try:
x_lookup_val = my_pandas.get_parallel_col_val(self.fields_df, self.x.value, 'LabelName', 'FieldName')
y_lookup_val = my_pandas.get_parallel_col_val(self.fields_df, self.y.value, 'LabelName', 'FieldName')
xs = self.df[x_lookup_val].values
ys = self.df[y_lookup_val].values
except (KeyError, AssertionError):
blank_set = [0 for i in range(len(self.df.index))]
self.p = figure(plot_height=self.fig_height, plot_width=self.fig_width)
if self.df.empty:
if self.x.value == 'None' or self.y.value == 'None':
blank_legend = 'data not loaded + missing x/y'
else:
blank_legend = 'data not loaded'
else:
blank_legend = 'missing x/y'
o = self.p.scatter(x=blank_set, y=blank_set)
self.p.add_layout(Legend(items=[(blank_legend, [o])], location=(35,-20), label_width=200), 'right')
return self.p
# prep plot
kw = dict()
x_title = self.x.value.title()
y_title = self.y.value.title()
kw['title'] = "%s vs %s" % (x_title, y_title)
if x_lookup_val in self.discrete:
kw['x_range'] = sorted(set(xs))
if y_lookup_val in self.discrete:
kw['y_range'] = sorted(set(ys))
hover = HoverTool(tooltips='''<div>@des</div>''')
kw['tools'] = [hover, self.tools]
kw['toolbar_location'] = 'above'
self.p = figure(plot_height=self.fig_height, plot_width=self.fig_width, **kw)
self.p.xaxis.axis_label = x_title
self.p.yaxis.axis_label = y_title
if x_lookup_val in self.discrete:
self.p.xaxis.major_label_orientation = pd.np.pi / 4
# set markers to differentiate sims
num_markers = min(len(self.df['SimName'].unique()), len(self.markers))
if num_markers > 1:
m_discrete_idxs = self.df['SimName'].astype('category').cat.codes
m = [self.markers[idx] for idx in m_discrete_idxs]
self.df['plot_marker'] = m
else:
self.df['plot_marker'] = self.markers[0]
# set for gradient
if self.gradient.value != 'None':
gradient_lookup_val = my_pandas.get_parallel_col_val(self.fields_df, self.gradient.value, 'LabelName', 'FieldName')
self.df = self.df.sort([gradient_lookup_val])
num_colors = len(self.df[gradient_lookup_val].unique())
colors = gen_heatmap(num_colors)
if num_colors > 1:
if gradient_lookup_val in self.discrete:
g_discrete_idxs = self.df[gradient_lookup_val].astype('category').cat.codes
g = [colors[idx] for idx in g_discrete_idxs]
else:
g_groups = pd.cut(self.df[gradient_lookup_val].values, num_colors)
g = [colors[idx] for idx in g_groups.codes]
else:
g = colors[0]
self.df['plot_color'] = g
else:
self.df['plot_color'] = gen_heatmap(1)
# set for transparency
self.df['plot_highlight'] = 0
for label_idx in self.sims.active:
cur_sim = self.sims.labels[label_idx]
selected_labels = [self.assets.labels[l_idx] for l_idx in self.assets.active]
selected_assets = [my_pandas.get_parallel_col_val(self.assets_df, sl, 'LabelName', 'AssetName') for sl in selected_labels]
min_constituent_pct = float(self.asset_pct.value)/100
allocation_df = pd.read_csv(os.path.join(self.sim_dir, cur_sim, 'Allocation.csv'), index_col=0)
highlighted_ports = allocation_df.loc[(allocation_df[selected_assets]>=min_constituent_pct).any(axis=1)].index.values
if len(highlighted_ports):
self.df.loc[(self.df['SimName'] == cur_sim) & (self.df['PortName'].isin(highlighted_ports)), 'plot_highlight'] = 1
# gen legend, gen data points by group, apply to plot
legend_items = []
for marker_group, mg in self.df.groupby(['plot_marker']):
legend_str = mg['SimName'].values[0]
group_point_sets = []
for marker_color_highlight_group, mchg in mg.groupby(['plot_color', 'plot_highlight']):
if mchg['plot_highlight'].values[0] == 1:
self.source = ColumnDataSource(data=dict(x=mchg[x_lookup_val].values, y=mchg[y_lookup_val].values, des=mchg['Des'].values))
o = self.p.scatter(x='x', y='y', source=self.source, marker=mchg['plot_marker'].values[0], color=mchg['plot_color'].values[0], size=self.size, fill_alpha=self.highlight_fill)
else:
self.source = ColumnDataSource(data=dict(x=mchg[x_lookup_val].values, y=mchg[y_lookup_val].values, des=mchg['Des'].values))
o = self.p.scatter(x='x', y='y', source=self.source, marker=mchg['plot_marker'].values[0], color=mchg['plot_color'].values[0], size=self.size, fill_alpha=self.default_fill)
group_point_sets.append(o)
legend_items.append((legend_str, group_point_sets))
legend = Legend(items=legend_items, location=(10,-30), label_width=150)
self.p.add_layout(legend, 'right')
return self.p