On Mar 3, 2019, at 1:48 PM, Doug Wood <[email protected]> wrote:
Hi Bryan,
Thank you for your reply (and for all the work you are doing on Bokeh)!
The problem is that I am separating the data into separate data sources so I can use the interactive legends feature as per
Interactive legends — Bokeh 3.3.2 Documentation
Here is the an example from that page which I modified to add a lasso tool to try it out:
import pandas as pd
from bokeh.palettes import Spectral4
from bokeh.plotting import figure, output_file, show
from bokeh.sampledata.stocks import AAPL, IBM, MSFT, GOOG
p = figure(plot_width=800, plot_height=250,
tools=('pan, lasso_select, reset'),
active_drag='lasso_select',
x_axis_type="datetime")
p.title.text = 'Click on legend entries to mute the corresponding lines'
for data, name, color in zip([AAPL, IBM, MSFT, GOOG], ["AAPL", "IBM", "MSFT", "GOOG"], Spectral4):
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
p.circle(df['date'], df['close'], line_width=2, color=color, alpha=0.8,
nonselection_color='gray',
muted_color='gray', muted_alpha=0.2, legend=name)
p.legend.location = "top_left"
p.legend.click_policy="mute"
output_file("interactive_legend.html", title="interactive_legend.py example")
show(p)
Yes, I understand why it is happening, but it would be great if interactive legends and selections worked together. I am actually using a list of data sources (like the 4 data sets the example) across multiple graphs. When I select points in one plot (even in multiple glyphs), they are selected in all the other graphs because I am sharing the same list of data sources. But all I need now is for the lasso tool to deselect any points in the glyphs that have no intersection at all with the selection region when the user makes a section in one of the graphs.
I will look into the CustomJS to run after a lasso selection and if any all of the elements of a glyph are selected then I'll deselect them all. The problem is I will have to deal with the special case of a selection happening to include all the points of a glyph. Looking quickly at the CustomJS example, I think I could just keep a flag for each glyph/data source to keep track of whether any of its points were hit during the select, and at the end, deselect all the glyphs that never got touched.
Thanks again!
Doug
On Sunday, March 3, 2019 at 4:06:21 PM UTC-5, Bryan Van de ven wrote:
Hi Doug,
I am not sure there is any simple way to avoid this behavior. The reason for it is this: Bokeh only draws points as "unselected" if *some* selection has been made at all on a glyph's data source. Since you are not sharing a data source between glyphs, and the lasso you make does not intersect the MSFT or GOOG glyphs, there is no selection for those glyph's data source, therefore their appearance is unchanged.
Offhand I can openly think of two possible options:
* share a CDS between all the glyphs. This is only really practical if all the time series have the same length, and even then be aware that the selection indices are *unioned* across every glyph that shares a source, which may not be what you want
* use a CustomJS callback on the glyph's data source selections to brute force whatever muting/visual change you want to perform on other glyphs:
https://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-selections
Thanks,
Bryan
> On Mar 3, 2019, at 12:44 PM, Doug Wood <[email protected]> wrote:
>
> import pandas as pd
>
> from bokeh.palettes import Spectral4
> from bokeh.plotting import figure, output_file, show
> from bokeh.sampledata.stocks import AAPL, IBM, MSFT, GOOG
>
> p = figure(plot_width=800, plot_height=250,
> tools=('pan, lasso_select, reset'),
> active_drag='lasso_select',
> x_axis_type="datetime")
> p.title.text = 'Click on legend entries to mute the corresponding lines'
>
> for data, name, color in zip([AAPL, IBM, MSFT, GOOG], ["AAPL", "IBM", "MSFT", "GOOG"], Spectral4):
> df = pd.DataFrame(data)
> df['date'] = pd.to_datetime(df['date'])
> p.circle(df['date'], df['close'], line_width=2, color=color, alpha=0.8,
> #selection_color='black',
> nonselection_color='gray',
> muted_color='gray', muted_alpha=0.2, legend=name)
>
> p.legend.location = "top_left"
> p.legend.click_policy="mute"
>
> output_file("interactive_legend.html", title="interactive_legend.py example")
>
> show(p)
--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/dab558d9-c205-47dc-9e86-069344b23de9%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.