Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactively hide or show lines after plot finished by clicking (without re-ploting like plot browser feature in MATLAB) #3715

Closed
bluehope opened this issue Jan 22, 2016 · 13 comments

Comments

@bluehope
Copy link

It would be great to have a feature to interactively hide or show certain lines after the plot is being finished.

When many lines of data exist (5 or more),
plot once and just by clicking to show or hide, similarly in plot browser of MATLAB, feature will be very useful.

Example of interactively hide or show cetain lines in MATLAB.

interactive_plot

This is one of killing feature in MATLAB. http://mathworks.com/help/matlab/ref/plotbrowser.html ### Example of interactively hide or show certain lines in Plotly

plotly_example

This feature would remove painful manual repeating job like below example.

Plot all

p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot(x, y[1,:])
plot(x, y[2,:])
plot(x, y[3,:])
plot(x, y[4,:])
plot(x, y[5,:])
plot(x, y[6,:])
...

remove data 2,3,5,6 & re-plot to compare between data 1,4

p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot(x, y[1,:])
#plot(x, y[2,:])
#plot(x, y[3,:])
plot(x, y[4,:])
#plot(x, y[5,:])
#plot(x, y[6,:])
...

remove data 3,4,5 & re-plot to compare between data 1,2,6. Keep repeating for bunch of datas

p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')
plot(x, y[1,:])
plot(x, y[2,:])
#plot(x, y[3,:])
#plot(x, y[4,:])
#plot(x, y[5,:])
plot(x, y[6,:])
...

keep repeating...

@birdsarah
Copy link
Member

Thanks for this request

It's a feature we've had requested a lot before and I believe there are a number of open issues that describe the pieces of the puzzle that would make this work.

You have described two things that would be implemented separately.

The first (checkboxes) is possible now - just not in one line. See: http://cecp.mit.edu/pages/air-pollution.html to see an example and check out the checkboxes widget. http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#checkbox-group

The second means interacting with a legend. I also agree this is a nice feature - similar to C3JS - but is probably further off being done.

Hope this helps.

@e-pet
Copy link
Contributor

e-pet commented Jan 29, 2016

@birdsarah Is the code for the checkboxes example available somewhere on the web? Or alternatively, a similar example? I already had the impression that it should be possible to do that, but it isn't obvious to me how - due to missing JS skills. Also see my SO question on the topic.

@damianavila damianavila added this to the long-term milestone Jan 29, 2016
@bluehope
Copy link
Author

@birdsarah @damianavila Thankyou for responding!
I didn't notice that it was two separate feature.
This comment also might be the third feature...

Adding plot selector as a tool would be nice.

fig = figure(tools="pan,wheel_zoom,box_zoom,reset,resize,selector")
fig.add_tools(BoxSelectTool(dimensions=["width"]))

Then it might look like blue boxed below image.
selection_example

Thank you for the greate library!

@birdsarah
Copy link
Member

@birdsarah Is the code for the checkboxes example available somewhere on the web?

Yes @bluehope - the code for that whole website is here: https://github.com/mit-jp/cge-tools/tree/master/crem_presentation/site (note the data is not available, so you'll just have to look at the code - the dirty secret is that I use a hidden bokeh text input to pass the data back and forth between my external checkboxes and the bokeh plot - you would not have to do this anymore by using User Defined Models)

(I haven't implemented User Defined Models yet so don't have more details on that)

@e-pet
Copy link
Contributor

e-pet commented Mar 8, 2016

Thanks for the reply - really looking forward to that feature addition!

@cp-boettcher
Copy link

That would be a nice feature.
I hope it will be implemented soon.

@mattpap mattpap self-assigned this Mar 14, 2016
@mattpap mattpap modified the milestones: short-term, long-term Mar 14, 2016
@birdsarah
Copy link
Member

See #4868 - this adds a visible property to renderers and some checkbox examples showing how to easily turn lines on and off.

This isn't the same as interactive legends, and it's still some work to set up, but it gets us closer.

@mattpap mattpap modified the milestones: 0.12.5, short-term Oct 31, 2016
@birdsarah birdsarah modified the milestones: 0.12.4, 0.12.5 Dec 9, 2016
@bryevdv bryevdv modified the milestones: 0.12.5, 0.12.4 Dec 14, 2016
@PBrockmann
Copy link

PBrockmann commented Feb 15, 2017

Would be very interested to use this feature to toggle visibility of lines or patches as below
bokeh_plot
Lots of similar plots in climate science without any interactivity (zoom, pan and toggle on visibility of plots). So this tool feature would be very welcome.
Will try with callback waiting it.

@PBrockmann
Copy link

PBrockmann commented Feb 15, 2017

Here is a snippet (no bokeh server) that does the toggle of lines. Is there a simpler way ?

bokeh_toggle

import numpy as np

from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import CheckboxGroup
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.layouts import column, row

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(3*np.pi*t)
c = np.cos(3*np.pi*t)

source = ColumnDataSource(data=dict(t=t, s=s, c=c))

plot = figure(plot_width=400, plot_height=400)
a = plot.line('t', 's', source=source, line_width=3, line_alpha=0.6, line_color='blue')
b = plot.line('t', 'c', source=source, line_width=3, line_alpha=0.6, line_color='red')

checkbox = CheckboxGroup(labels=["Cosinus", "Sinus"], active=[0,1])

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code="""
    //console.log(cb_obj.active);
    line0.visible = false;
    line1.visible = false;
    for (i in cb_obj.active) {
        //console.log(cb_obj.active[i]);
        if (cb_obj.active[i] == 0) {
            line0.visible = true;
        } else if (cb_obj.active[i] == 1) {
            line1.visible = true;
        }
    }
""")

layout = row(plot, widgetbox(checkbox))

show(layout)

@bryevdv
Copy link
Member

bryevdv commented Feb 15, 2017

There is an open PR for this issue to add interactive legends as a built-in feature to Bokeh. It is not yet merged or in a release.

@nealmcb
Copy link

nealmcb commented May 3, 2017

Reference to the PR that closed this, for more details: #5349

@HarryJJ
Copy link

HarryJJ commented Nov 10, 2017

Hi. Thanks for this - it's been really helpful.

I'm just curious but how would one do this for an arbitrary number of lines?

@bokeh bokeh deleted a comment from XavierTolza Apr 30, 2018
@MarynaLongnickel
Copy link

Here is a snippet (no bokeh server) that does the toggle of lines. Is there a simpler way ?

bokeh_toggle

import numpy as np

from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import CheckboxGroup
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.layouts import column, row

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(3*np.pi*t)
c = np.cos(3*np.pi*t)

source = ColumnDataSource(data=dict(t=t, s=s, c=c))

plot = figure(plot_width=400, plot_height=400)
a = plot.line('t', 's', source=source, line_width=3, line_alpha=0.6, line_color='blue')
b = plot.line('t', 'c', source=source, line_width=3, line_alpha=0.6, line_color='red')

checkbox = CheckboxGroup(labels=["Cosinus", "Sinus"], active=[0,1])

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code="""
    //console.log(cb_obj.active);
    line0.visible = false;
    line1.visible = false;
    for (i in cb_obj.active) {
        //console.log(cb_obj.active[i]);
        if (cb_obj.active[i] == 0) {
            line0.visible = true;
        } else if (cb_obj.active[i] == 1) {
            line1.visible = true;
        }
    }
""")

layout = row(plot, widgetbox(checkbox))

show(layout)

I was trying to run your code (in VSCode), but keep getting 'SyntaxError: EOF while scanning triple-quoted string literal' error :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests