2

I'm trying to add a button to my bokeh plot that will allow me to change the colour used on a patch glyph that I've added to a GMapPlot using a callback.

Currently what I have is:

from bokeh.io import output_file, show
from bokeh.models import GMapPlot, GMapOptions, ColumnDataSource, DataRange1d, Patch

map_options = GMapOptions(lat=-41.281909, lng=174.775993, zoom=13)
p = GMapPlot(x_range=DataRange1d(), y_range=DataRange1d(), map_options=map_options, api_key=API_KEY)
lats = [-41.281909, -41.281044, -41.294968]
longs = [174.775993, 174.761222, 174.764916]
source = ColumnDataSource(data=dict(lats=lats, longs=longs))
patch = Patch(x='longs', y='lats', fill_color='red', fill_alpha=0.2)
p.add_glyph(source, patch)
output_file('gmapplot.html')
show(p)

I'd like to be able to edit that fill_color through a callback using a button. I tried appropriating this response but haven't been able to get it to work.

Any help would be greatly appreciated.

PS. If you're trying to run this code you will need to use your own google maps API key. You can get one here.

Community
  • 1
  • 1
user1425706
  • 195
  • 1
  • 1
  • 7

1 Answers1

0

The other response changes the fill_color of a bunch of circles to refer to a different column of colors in a column data source (so that all the circles can have their own color) by changing the field attribute. Since you are trying to set just a single color value for the once Patch, you probably want to set value instead of field

cb = CustomJS(args=dict(patch=patch), code ="""
    patch.glyph.fill_color.value = 'blue';
""")

I guess it's possible you might need a trigger there but I don't think so.

The patch and line glyphs are the two glyphs that are a little quirky in the API, because they don't really support vectorized properties like all the other glyphs do.


UPDATE: Perhaps a complete example is clearer. Also FYI the trigger is needed, at least as of current versions (0.12.4).

from bokeh.io import output_file, show
from bokeh.layouts import column
from bokeh.models import CustomJS, Select
from bokeh.plotting import figure

plot = figure()

r = plot.patch(x=[1, 2, 3, 4], y=[1, 2, 2, 1],
               fill_color="firebrick", fill_alpha=0.6, line_color="black")


select = Select(title="Select colors", value="firebrick",
                options = ["firebrick","navy", "olive"])

callback = CustomJS(args=dict(renderer=r, select=select), code ="""
    renderer.glyph.fill_color.value = select.value;
    renderer.trigger('change')
""")
select.callback = callback

output_file("foo.html")

show(column(select, plot))

The patch starts out red. Changing the Select widget in the UI causes the color of the patch to update:

enter image description here

If that's not what you are asking then I have to gently suggest that the question is not clear.

bigreddot
  • 33,642
  • 5
  • 69
  • 122
  • Thanks for your response. I think I probably oversimplified my question a bit before asking it since I do in fact want to be able to control the colour change programatically. Do I need to add list of colours to ColumnDataSource?Also, if I have multiple patches, how would I change them all with the callback? – user1425706 Jan 04 '17 at 21:41
  • I'm not sure I understand. I showed how you can change it programmatically, in a `CustomJS` callback that you could attach, e.g. to a Bokeh `Button`. My only comment was that `patch` only draws a single patch, which is why you want to set `value` instead of `field`, in contrast to things like `circle`, which can draw lots of circles at once. – bigreddot Jan 04 '17 at 23:16