title: Get the attributes of the selected item in a GeoJSONDataSource
body: <p>I want to link a plot containing patches (from a <code>GeoJSONDataSource</code>) with a line chart but i'm having trouble getting the attributes of the selected patch.</p>
  <p>Its basically a plot showing polygons, and when a polygon is selected, i want to update the line chart with a timeseries of data for that polygon. The line chart is driven by a normal <code>ColumnDataSource</code>.</p>
  <p>I can get the indices of the selected patch by adding a callback combined with <code>geo_source.selected['1d']['indices']</code>. But how do i get the data/attributes which correspond to that index? I need to get a 'key' in the attributes which i can then use to update the line chart.</p>
  <p>The <code>GeoJSONDataSource</code> has no <code>data</code> attribute in which i can lookup the data itself. Bokeh can use the attributes for things like coloring/tooltips etc, so i assume there must be a way to get these out of the <code>GeoJSONDataSource</code>, i cant find it unfortunately.</p>
  <h3>edit:</h3>
  <p>Here is working toy example showing what i've got so far.</p>
  <pre><code>import pandas as pd
  import numpy as np
  
  from bokeh import events
  from bokeh.models import (Select, Column, Row, ColumnDataSource, HoverTool, 
                            Range1d, LinearAxis, GeoJSONDataSource)
  from bokeh.plotting import figure
  from bokeh.io import curdoc
  
  import os
  import datetime
  from collections import OrderedDict
  
  def make_plot(src):
      # function to create the line chart
  
      p = figure(width=500, height=200, x_axis_type='datetime', title='Some parameter',
                 tools=['xwheel_zoom', 'xpan'], logo=None, toolbar_location='below', toolbar_sticky=False)
      
      p.circle('index', 'var1', color='black', fill_alpha=0.2, size=10, source=src)
  
      return p
  
  def make_geo_plot(src):
      # function to create the spatial plot with polygons
      
      p = figure(width=300, height=300, title=&quot;Select area&quot;, tools=['tap', 'pan', 'box_zoom', 'wheel_zoom','reset'], logo=None)
  
      p.patches('xs', 'ys', fill_alpha=0.2, fill_color='black',
                line_color='black', line_width=0.5, source=src)
                
      p.on_event(events.SelectionGeometry, update_plot_from_geo)
  
      return p
  
  def update_plot_from_geo(event):
      # update the line chart based on the selected polygon
  
      selected = geo_source.selected['1d']['indices']
      
      if (len(selected) &gt; 0):
          first = selected[0]
          print(geo_source.selected['1d']['indices'])
  
  
  def update_plot(attrname, old, new):
      # Callback for the dropdown menu which updates the line chart
      new_src = get_source(df, area_select.value)    
      src.data.update(new_src.data)
    
  def get_source(df, fieldid):
      # function to get a subset of the multi-hierarchical DataFrame
      
      # slice 'out' the selected area
      dfsub = df.xs(fieldid, axis=1, level=0)
      src = ColumnDataSource(dfsub)
      
      return src
  
  # example timeseries
  n_points = 100
  df = pd.DataFrame({('area_a','var1'): np.sin(np.linspace(0,5,n_points)) + np.random.rand(100)*0.1,
                     ('area_b','var1'): np.sin(np.linspace(0,2,n_points)) + np.random.rand(100)*0.1,
                     ('area_c','var1'): np.sin(np.linspace(0,3,n_points)) + np.random.rand(100)*0.1,
                     ('area_d','var1'): np.sin(np.linspace(0,4,n_points)) + np.random.rand(100)*0.1},
                    index=pd.DatetimeIndex(start='2017-01-01', freq='D', periods=100))
  
  # example polygons
  geojson = &quot;&quot;&quot;{
  &quot;type&quot;:&quot;FeatureCollection&quot;,
  &quot;crs&quot;:{&quot;type&quot;:&quot;name&quot;,&quot;properties&quot;:{&quot;name&quot;:&quot;urn:ogc:def:crs:OGC:1.3:CRS84&quot;}},
  &quot;features&quot;:[
  {&quot;type&quot;:&quot;Feature&quot;,&quot;properties&quot;:{&quot;key&quot;:&quot;area_a&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;MultiPolygon&quot;,&quot;coordinates&quot;:[[[[-108.8,42.7],[-104.5,42.0],[-108.3,39.3],[-108.8,42.7]]]]}},
  {&quot;type&quot;:&quot;Feature&quot;,&quot;properties&quot;:{&quot;key&quot;:&quot;area_b&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;MultiPolygon&quot;,&quot;coordinates&quot;:[[[[-106.3,44.0],[-106.2,42.6],[-103.3,42.6],[-103.4,44.0],[-106.3,44.0]]]]}},
  {&quot;type&quot;:&quot;Feature&quot;,&quot;properties&quot;:{&quot;key&quot;:&quot;area_d&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;MultiPolygon&quot;,&quot;coordinates&quot;:[[[[-104.3,41.0],[-101.5,41.0],[-102.9,37.8],[-104.3,41.0]]]]}},
  {&quot;type&quot;:&quot;Feature&quot;,&quot;properties&quot;:{&quot;key&quot;:&quot;area_c&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;MultiPolygon&quot;,&quot;coordinates&quot;:[[[[-105.8,40.3],[-108.3,37.7],[-104.0,37.4],[-105.8,40.3]]]]}}
  ]
  }&quot;&quot;&quot;
  
  geo_source = GeoJSONDataSource(geojson=geojson)
  
  # populate a drop down menu with the area's 
  area_ids = sorted(df.columns.get_level_values(0).unique().values.tolist())
  area_ids = [str(x) for x in area_ids]
  area_select = Select(value=area_ids[0], title='Select area', options=area_ids)
  area_select.on_change('value', update_plot)
  
  src = get_source(df, area_select.value)
  
  p = make_plot(src)
  pgeo = make_geo_plot(geo_source)
  
  # add to document
  curdoc().add_root(Row(Column(area_select, p), pgeo))
  </code></pre>
  <p>Save the code in a <code>.py</code> file and load with <code>bokeh serve example.py --show</code></p>
  <p><a href="https://i.stack.imgur.com/vXAYP.png" rel="noreferrer"><img src="https://i.stack.imgur.com/vXAYP.png" alt="enter image description here" /></a></p>