Geo map: create a new div + plot upon click on a country

I created an interactive map using GeoJSONDataSource (using the patches glyph). The map represents sales of a company in every country of the world, the country is identified by both a ‘country name’ column and an ‘iso code’ column. The goal is the following: the user clicks on a given country, and a div is populated with information about the sales in the given country, as well as a pie chart. The div would be next to the map somehwere, on the same page. I have already created the function to do this (in Python, not JavaScript), but I am having trouble understanding how to extract the column value of the country name/iso code when the tap has happened, so I can use it later in the above mentioned function. E.g. when clicked on the United Kingdom, the iso code ‘GB’ has to be extracted.

I have been reading the (excellent) Bokeh documentation like crazy but I can’t find a way to construct this. I can use a tap event (p.js_on_event('tap', callback) to print the clicked x, y coordinates into the console (console.log(cb_obj.x)),but this is not what I want. It seems I have to create a blank figure ( for the pie chart), and write a CustomJS code which will filter out the suitable data and populate this pie chart, using the iso code (which I don’t know how to extract from the tap event). But I also want to have some simple text in the div, which I was hoping can show up when the click has happened.

This might be a horrible ‘architecture’ idea in the first place, I started using Bokeh a week ago and I’m not an experienced programmer either, so any ideas will be greatly appreciated!

Hi @ISquared the “tap” event just unconditionally reports the x and y position of every tap. If you want to know when a specific glyph instance is “hit” then it’s more likely you’d want to add a TapTool to the plot and then install a callback on the selection indices:

source.selected("indices", ...)

Then the new value of indices will contain indexes into the data source for the glyph that was hit. E.g if the value is [11] that means you’d look at source.data["colname"][11] to get the corresponding value from that column.

Regarding adding the pie chart on the tap. My very strong advice is to create an empty plot with an empty wedge glyph all up front from the Python code. Then in the JS code all you have to do is update the data source for the wedge glyph. JS callbacks are much better suited for updating existing things, rather than creating new whole plots, etc. [1] If you want you could also toggle the plot’s visible property that that it only shows up when there is data to show.


  1. cc @Timo I am not sure I have ever elucidated this distinction this way but seems like a very succinct way of describing when JS callbacks are best used. ↩︎

2 Likes