Changing selection to nothing within button callback

I’m trying to create a web app that simply allows me to select some points and then remove them from the plot by pushing a button. The code I have below does this except that after the selected points are removed other points then show as though they are now selected. I thought perhaps manually changing the list of selected indices to an empty list would accomplish this but that doesn’t work. Any ideas?

remove.py

import numpy as np

from bokeh.io import curdoc

from bokeh.models import Button

from bokeh.plotting import figure, curdoc, vplot

xs = np.random.normal(loc=1.0, size=100)

ys = np.random.normal(loc=1.0, size=100)

TOOLS=“pan,wheel_zoom,box_select,lasso_select”

p = figure(tools=TOOLS, plot_width=600, plot_height=600, title=None, min_border=10, min_border_left=50)

r = p.scatter(xs, ys, size=3, color="#3A5785", alpha=0.6)

def callback():

for index in sorted(r.data_source.selected[‘1d’][‘indices’], reverse=True):

r.data_source.data[‘x’].pop(index)

r.data_source.data[‘y’].pop(index)

r.data_source.selected[‘1d’][‘indices’] = list() # this seemingly has no effect

r.data_source.trigger(‘data’, r.data_source.data, r.data_source.data)

button = Button(label=“Remove Points”)

button.on_click(callback)

put the button and plot in a layout and add to the document

curdoc().add_root(vplot(button, p))

``

Thanks!

My guess is that you have a misperception about what the default
appearance of selected and unselected is. In the scenario you’re
working on, I understand why it’s a little intuitive. I’m guessing
you’re expecting “unselected all” to be all greyed out, but it
defaults back to all colored when nothing is selected.

Have a play with:

Try explicitly styling your selection and unselection glyphs.

Best,

Bird

···

http://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs
On 5/26/16 2:05 PM, Nicholas Stahl
wrote:

    I'm trying to create a web app that simply allows

me to select some points and then remove them from the plot by
pushing a button. The code I have below does this except that
after the selected points are removed other points then show as
though they are now selected. I thought perhaps manually
changing the list of selected indices to an empty list would
accomplish this but that doesn’t work. Any ideas?

remove.py

import numpy as np

                from bokeh.io import

curdoc

                from bokeh.models import

Button

                from bokeh.plotting import

figure, curdoc, vplot

                xs =

np.random.normal(loc=1.0, size=100)

                ys =

np.random.normal(loc=1.0, size=100)

TOOLS=“pan,wheel_zoom,box_select,lasso_select”

                p = figure(tools=TOOLS,

plot_width=600, plot_height=600, title=None,
min_border=10, min_border_left=50)

                r = p.scatter(xs, ys,

size=3, color=“#3A5785”, alpha=0.6)

def callback():

                for index in

sorted(r.data_source.selected[‘1d’][‘indices’],
reverse=True):

r.data_source.data[‘x’].pop(index)

r.data_source.data[‘y’].pop(index)

                r.data_source.selected['1d']['indices'] = list()  #

this seemingly has no effect

                r.data_source.trigger('data', r.data_source.data,

r.data_source.data)

                button =

Button(label=“Remove Points”)

button.on_click(callback)

                # put the button and plot

in a layout and add to the document

                curdoc().add_root(vplot(button,

p))

``

Thanks!

  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/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io?utm_medium=email&utm_source=footer)      .

For more options, visit .


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

https://groups.google.com/a/continuum.io/d/msgid/bokeh/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io
https://groups.google.com/a/continuum.io/d/optout

I understand that when nothing is selected it defaults back to all colored. I don’t think that’s the source of the issue. If I select 5 points, for example, and then click “Remove Points” those 5 points disappear but then another 5 points take on the selected color with all the other points still grayed out. Presumably the now-selected 5 points are at the indices that the original points I deleted were at. If I hit escape on my keyboard I can get back the no-selection appearance I want.

Is there a way to programmatically force the escape key behavior?

Nick

···

On Thursday, May 26, 2016 at 5:34:38 PM UTC-7, Sarah Bird wrote:

  My guess is that you have a misperception about what the default

appearance of selected and unselected is. In the scenario you’re
working on, I understand why it’s a little intuitive. I’m guessing
you’re expecting “unselected all” to be all greyed out, but it
defaults back to all colored when nothing is selected.

Have a play with:
http://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs

Try explicitly styling your selection and unselection glyphs.

Best,

Bird

  On 5/26/16 2:05 PM, Nicholas Stahl > wrote:
    I'm trying to create a web app that simply allows

me to select some points and then remove them from the plot by
pushing a button. The code I have below does this except that
after the selected points are removed other points then show as
though they are now selected. I thought perhaps manually
changing the list of selected indices to an empty list would
accomplish this but that doesn’t work. Any ideas?

remove.py

import numpy as np

from bokeh.io import
curdoc

                from bokeh.models import

Button

                from bokeh.plotting import

figure, curdoc, vplot

                xs =

np.random.normal(loc=1.0, size=100)

                ys =

np.random.normal(loc=1.0, size=100)

TOOLS=“pan,wheel_zoom,box_select,lasso_select”

                p = figure(tools=TOOLS,

plot_width=600, plot_height=600, title=None,
min_border=10, min_border_left=50)

                r = p.scatter(xs, ys,

size=3, color=“#3A5785”, alpha=0.6)

def callback():

                for index in

sorted(r.data_source.selected[ ‘1d’][‘indices’],
reverse=True):

r.data_source.data[‘x’].pop(index)

r.data_source.data[‘y’].pop(index)

r.data_source.selected[‘1d’][’ indices’] = list() #
this seemingly has no effect

                r.data_source.trigger('data', r.data_source.data,

r.data_source.data)

                button =

Button(label=“Remove Points”)

button.on_click(callback)

                # put the button and plot

in a layout and add to the document

curdoc().add_root(vplot( button,
p))

``

Thanks!

  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/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io?utm_medium=email&utm_source=footer)[https://groups.google.com/a/continuum.io/d/msgid/bokeh/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io).

  For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).


Sarah Bird
Developer, Bokeh

    [
      <img alt="Continuum Analytics" src="https://lh6.googleusercontent.com/proxy/VYgVjggTk1hCXSN9wFkffE3I6kxTvJ51tT4KvDXOuKbs1WyFG66k7kt2-vkDimbyxfWtP-d1paJmstMYhPPnDYSUF4rLPoYM2GM2QFM=w5000-h5000" height="30px" width="150px">
    ](http://continuum.io)

Nicholas,

AFAIK no way to simulate <ESC> clear from Python. There are two ideas I have:

* Use a CustomJS callback to do this instead of a server one. There's nothing in here that looks like it couldn't be done in a JS update. The data changes would get propagated back to the server and the selection could be cleared from JS for sure.

* you might try copying and replacing the entire .selected attribute. The selection structure is a bit of a wonky on currently, and my guess is that our automagic update detection will not work on it. But if you replace all of .selected, that should get picked up. You could also try triggering 'selected' instead of 'data' on the source (you should not need to trigger 'data' anyway)

One warning, in any case. Columns of data sources are assumed and supposed to be the same length at all times. Popping one value off one column, then another value off another column, may violate this assumption momentarily and lead to undesirable results. I'd recommend updating all of the .data dictionary at once as well. In this case that probably means data copying, we may need to explore API to enable doing things like you are doing now more safely.

Thanks,

Bryan

···

On May 27, 2016, at 12:31 PM, Nicholas Stahl <[email protected]> wrote:

I understand that when nothing is selected it defaults back to all colored. I don't think that's the source of the issue. If I select 5 points, for example, and then click "Remove Points" those 5 points disappear but then another 5 points take on the selected color with all the other points still grayed out. Presumably the now-selected 5 points are at the indices that the original points I deleted were at. If I hit escape on my keyboard I can get back the no-selection appearance I want.

Is there a way to programmatically force the escape key behavior?

Nick

On Thursday, May 26, 2016 at 5:34:38 PM UTC-7, Sarah Bird wrote:
My guess is that you have a misperception about what the default appearance of selected and unselected is. In the scenario you're working on, I understand why it's a little intuitive. I'm guessing you're expecting "unselected all" to be all greyed out, but it defaults back to all colored when nothing is selected.
Have a play with: Appearance — Bokeh 3.3.2 Documentation

Try explicitly styling your selection and unselection glyphs.

Best,

Bird

On 5/26/16 2:05 PM, Nicholas Stahl wrote:

I'm trying to create a web app that simply allows me to select some points and then remove them from the plot by pushing a button. The code I have below does this except that after the selected points are removed other points then show as though they are now selected. I thought perhaps manually changing the list of selected indices to an empty list would accomplish this but that doesn't work. Any ideas?

# remove.py

import numpy as np

from bokeh.io import curdoc
from bokeh.models import Button
from bokeh.plotting import figure, curdoc, vplot

xs = np.random.normal(loc=1.0, size=100)
ys = np.random.normal(loc=1.0, size=100)

TOOLS="pan,wheel_zoom,box_select,lasso_select"

p = figure(tools=TOOLS, plot_width=600, plot_height=600, title=None, min_border=10, min_border_left=50)
r = p.scatter(xs, ys, size=3, color="#3A5785", alpha=0.6)

def callback():
    for index in sorted(r.data_source.selected['1d']['indices'], reverse=True):
        r.data_source.data['x'].pop(index)
        r.data_source.data['y'].pop(index)
    r.data_source.selected['1d']['indices'] = list() # this seemingly has no effect
    r.data_source.trigger('data', r.data_source.data, r.data_source.data)

button = Button(label="Remove Points")
button.on_click(callback)

# put the button and plot in a layout and add to the document
curdoc().add_root(vplot(button, p))

Thanks!

--
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 bokeh+un...@continuum.io.
To post to this group, send email to bo...@continuum.io.
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
Sarah Bird
Developer, Bokeh

--
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/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Sorry for over-explaining. I didn’t run your code - sorry!

When I first ran your code I get the message:

            Unhandled ERROR reply to

CF1265DC851F4F628BF5164A4CBA8A02:
AttributeError(“‘numpy.ndarray’ object has no attribute
‘pop’”,)

              But I fixed it up and

came up with a much simpler solution:

` r = p.scatter(xs.tolist(), ys.tolist(),
size=3, color=“#3A5785”, alpha=0.6)``

    ``empty_selection = r.data_source.selected``

    ``

    ``def callback():``

    ``    source.selected = empty_selection`

I was able to rep roduce
your original problem and this seems to fix it.

I’m guessing Bryan’s answer explains why your o riginal solution
di dn’t
work.

···

On 5/27/16 10:31 AM, Nicholas Stahl
wrote:

    I understand that when nothing is selected it

defaults back to all colored. I don’t think that’s the source of
the issue. If I select 5 points, for example, and then click
“Remove Points” those 5 points disappear but then another 5
points take on the selected color with all the other points
still grayed out. Presumably the now-selected 5 points are at
the indices that the original points I deleted were at. If I hit
escape on my keyboard I can get back the no-selection appearance
I want.

      Is there a way to programmatically force the escape key

behavior?

Nick

      On Thursday, May 26, 2016 at 5:34:38 PM UTC-7, Sarah Bird

wrote:

            My guess is that you have a misperception about what

the default appearance of selected and unselected is. In
the scenario you’re working on, I understand why it’s a
little intuitive. I’m guessing you’re expecting
“unselected all” to be all greyed out, but it defaults
back to all colored when nothing is selected.

            Have a play with:

http://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs

            Try explicitly styling your selection and unselection

glyphs.

Best,

Bird

On 5/26/16 2:05 PM, Nicholas Stahl wrote:

              I'm trying to create a web app that

simply allows me to select some points and then remove
them from the plot by pushing a button. The code I
have below does this except that after the selected
points are removed other points then show as though
they are now selected. I thought perhaps manually
changing the list of selected indices to an empty list
would accomplish this but that doesn’t work. Any
ideas?

remove.py

import numpy as np

from bokeh.io import curdoc

from bokeh.models import Button

                          from bokeh.plotting import figure,

curdoc, vplot

                          xs = np.random.normal(loc=1.0,

size=100)

                          ys = np.random.normal(loc=1.0,

size=100)

TOOLS=“pan,wheel_zoom,box_select,lasso_select”

                          p = figure(tools=TOOLS, plot_width=600,

plot_height=600, title=None,
min_border=10, min_border_left=50)

                          r = p.scatter(xs, ys, size=3,

color=“#3A5785”, alpha=0.6)

def callback():

                          for index in

sorted(r.data_source.selected[ ‘1d’][‘indices’],
reverse=True):

r.data_source.data[‘x’].pop(index)

r.data_source.data[‘y’].pop(index)

r.data_source.selected[‘1d’][’ indices’]
= list() # this seemingly has no effect

                          r.data_source.trigger('data',

r.data_source.data, r.data_source.data)

button = Button(label=“Remove Points”)

button.on_click(callback)

                          # put the button and plot in a layout

and add to the document

curdoc().add_root(vplot( button,
p))

``

Thanks!

            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                 .

To view this discussion on the web visit


Sarah Bird
Developer, Bokeh

              [ ![Continuum
                  Analytics](https://lh6.googleusercontent.com/proxy/VYgVjggTk1hCXSN9wFkffE3I6kxTvJ51tT4KvDXOuKbs1WyFG66k7kt2-vkDimbyxfWtP-d1paJmstMYhPPnDYSUF4rLPoYM2GM2QFM=w5000-h5000) ](http://continuum.io)

  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/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io?utm_medium=email&utm_source=footer)      .

For more options, visit .


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

[email protected]
https://groups.google.com/a/continuum.io/d/msgid/bokeh/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io.

            For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).

          [https://groups.google.com/a/continuum.io/d/msgid/bokeh/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io)

https://groups.google.com/a/continuum.io/d/optout

Sorry, I
missed a line in the copy-paste:

`import numpy as np

      from bokeh.io import curdoc

      from bokeh.models import Button

      from bokeh.plotting import figure, curdoc, vplot

      xs = np.random.normal(loc=1.0, size=100).tolist()

      ys = np.random.normal(loc=1.0, size=100).tolist()

      TOOLS="pan,wheel_zoom,box_select,lasso_select"

    `

` p = figure(tools=TOOLS, plot_width=600,
plot_height=600, title=None, min_border=10,
min_border_left=50)``

    ``          r = p.scatter(xs, ys, size=3, color="#3A5785",

alpha=0.6)``

    ``

    ``source = r.data_source``

    ``empty_selection = r.data_source.selected``

    ``

    ``def callback():``

    ``    source.selected = empty_selection``

    ``

    ``button = Button(label="Remove Points", width=20)``

    ``button.on_click(callback)``

    ``

    ``          # put the button and plot in a layout and add to the

document``

    ``curdoc().add_root(vplot(button, p))`
···

On 5/27/16 12:32 PM, Sarah Bird -
Continuum wrote:

Sorry for over-explaining. I didn’t run your code - sorry!

              When I first ran your code I get

the message:

              Unhandled ERROR reply to

CF1265DC851F4F628BF5164A4CBA8A02:
AttributeError(“‘numpy.ndarray’ object has no
attribute ‘pop’”,)

                But

I fixed it up and came up with a much simpler solution:

` r = p.scatter(xs.tolist(), ys.tolist(),
size=3, color=“#3A5785”, alpha=0.6)``

      ``empty_selection = r.data_source.selected``

      ``

      ``def callback():``

      ``    source.selected = empty_selection`
                I

was able to rep roduce your original
problem and this seems to fix it.

I’m guessing Bryan’s answer explains why your o riginal
solution didn’t work.


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

    On 5/27/16 10:31 AM, Nicholas Stahl

wrote:

      I understand that when nothing is selected it

defaults back to all colored. I don’t think that’s the source
of the issue. If I select 5 points, for example, and then
click “Remove Points” those 5 points disappear but then
another 5 points take on the selected color with all the other
points still grayed out. Presumably the now-selected 5 points
are at the indices that the original points I deleted were at.
If I hit escape on my keyboard I can get back the no-selection
appearance I want.

        Is there a way to programmatically force the escape key

behavior?

Nick

        On Thursday, May 26, 2016 at 5:34:38 PM UTC-7, Sarah Bird

wrote:

              My guess is that you have a misperception about what

the default appearance of selected and unselected is.
In the scenario you’re working on, I understand why
it’s a little intuitive. I’m guessing you’re expecting
“unselected all” to be all greyed out, but it defaults
back to all colored when nothing is selected.

Have a play with: http://bokeh.pydata.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs

              Try explicitly styling your selection and unselection

glyphs.

Best,

Bird

On 5/26/16 2:05 PM, Nicholas Stahl wrote:

                I'm trying to create a web app that

simply allows me to select some points and then
remove them from the plot by pushing a button. The
code I have below does this except that after the
selected points are removed other points then show
as though they are now selected. I thought perhaps
manually changing the list of selected indices to an
empty list would accomplish this but that doesn’t
work. Any ideas?

remove.py

import numpy as np

from bokeh.io import curdoc

from bokeh.models import Button

                            from bokeh.plotting import figure,

curdoc, vplot

                            xs = np.random.normal(loc=1.0,

size=100)

                            ys = np.random.normal(loc=1.0,

size=100)

TOOLS=“pan,wheel_zoom,box_select,lasso_select”

                            p = figure(tools=TOOLS,

plot_width=600, plot_height=600,
title=None, min_border=10,
min_border_left=50)

                            r = p.scatter(xs, ys, size=3,

color=“#3A5785”, alpha=0.6)

def callback():

                            for index in

sorted(r.data_source.selected[ ‘1d’][‘indices’],
reverse=True):

r.data_source.data[‘x’].pop(index)

r.data_source.data[‘y’].pop(index)

r.data_source.selected[‘1d’][’ indices’]
= list() # this seemingly has no effect

                            r.data_source.trigger('data',

r.data_source.data, r.data_source.data)

                            button = Button(label="Remove

Points")

button.on_click(callback)

                            # put the button and plot in a layout

and add to the document

curdoc().add_root(vplot( button,
p))

``

Thanks!

              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


Sarah Bird
Developer, Bokeh

                [ ![Continuum Analytics](https://lh6.googleusercontent.com/proxy/VYgVjggTk1hCXSN9wFkffE3I6kxTvJ51tT4KvDXOuKbs1WyFG66k7kt2-vkDimbyxfWtP-d1paJmstMYhPPnDYSUF4rLPoYM2GM2QFM=w5000-h5000) ](http://continuum.io)

    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 .

For more options, visit .
[email protected].

              To post to this group, send email to .

To view this discussion on the web visit [email protected]
https://groups.google.com/a/continuum.io/d/msgid/bokeh/d19d892f-77d2-4fb8-b914-1526a5cfc09e%40continuum.io.

              For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).

            [](https://groups.google.com/a/continuum.io/d/msgid/bokeh/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io)[https://groups.google.com/a/continuum.io/d/msgid/bokeh/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/5260974a-53a8-4784-97f9-0bb232fb8635%40continuum.io)

https://groups.google.com/a/continuum.io/d/optout


Sarah Bird
Developer, Bokeh

      [ ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png) ](http://continuum.io)