0

First time posting in stackoverflow. Hope you guys are doing well. Recently, I am trying to create a filterable Bokeh graph to graph a US map base on the filter an user select. However, when I try to fit a geometry to ColumnDataSource. It is giving me an error: TypeError: Object of type Polygon is not JSON serializable when I run show(figure)

The code below shows how I want to update geometry to ColumnDataSource and I get an error

# <------- This is where the graph starts------->

# reset the graph
reset_output()

# import data
data = gpd.read_file("/Users/xxxx/Desktop/cb_2015_us_state_500k/cb_2015_us_state_500k.shp", encoding="utf-8")
data1 = data[~data.STUSPS.isin(['AK','AS', 'GU', 'HI', 'PR','MP', 'VI'])]
data2 = data[data.STUSPS.isin(['TX', 'UT'])]

# get a list of unique value
unique_state = sorted(list(data2.NAME.unique()))
select = Select(title="State", options=unique_state)

# get data into ColumnDataSource
source=ColumnDataSource(ColumnDataSource.from_df(data2.loc[:]))

# crate filtered dataframe
filteredSource = ColumnDataSource(data=dict(STUSPS=[],NAME=[],ALAND=[]))

columns = [TableColumn(field="NAME",title="NAME",sortable=True),
           TableColumn(field="STUSPS",title="STUSPS",sortable=True),
           TableColumn(field="ALAND",title="ALAND",sortable=True),
           TableColumn(field="geometry",title="geometry",sortable=True)]

data_table=DataTable(source=filteredSource,columns=columns, width=800 )

# <---- Call back starts ---->
callback = CustomJS(args=dict(source=source,
                              filteredSource=filteredSource,
                              data_table=data_table), code="""
var data = source.data;
var f = cb_obj.value;
var d2 = filteredSource.data;
d2['STUSPS']=[]
d2['NAME']=[]
d2['ALAND']=[]
d2['geometry']=[]


for(i = 0; i < data['NAME'].length;i++){

if(data['NAME'][i]==f){

    d2['STUSPS'].push(data['STUSPS'][i])
    d2['NAME'].push(data['NAME'][i])
    d2['ALAND'].push(data['ALAND'][i])
    d2['geometry'].push(data['geometry'][i])
}

}

filteredSource.change.emit()
// trigger change on datatable
data_table.change.emit()

""")

select.js_on_change('value',callback)

layout = column(widgetbox(select, data_table))

# output_file("filter.html", title="filter example")

show(layout)

Afterwards, I saw an example directly fitting shape file to dictionary or dataframe which may solve the problem. Here is the link: Bokeh Mapping Counties However, when I using the code to graph it. it is giving me

ValueError: Out of range float values are not JSON compliant

This is the code I run:

import shapefile
import itertools

shp = open("/Users/xxxx/Desktop/cb_2015_us_state_500k/cb_2015_us_state_500k.shp", "rb")
dbf = open("/Users/xxxx/Desktop/cb_2015_us_state_500k/cb_2015_us_state_500k.dbf", "rb")
sf = shapefile.Reader(shp=shp, dbf=dbf)

lats = []
lons = []
ct_name = []
st_id = []
ct_state_name = []
for shprec in sf.shapeRecords():
    st_id.append(int(shprec.record[0]))
    ct_name.append(shprec.record[5])
    ct_state_name.append(shprec.record[4])
    lat, lon = map(list, zip(*shprec.shape.points))
    indices = shprec.shape.parts.tolist()
    lat = [lat[i:j] + [float('NaN')] for i, j in zip(indices, indices[1:]+[None])]
    lon = [lon[i:j] + [float('NaN')] for i, j in zip(indices, indices[1:]+[None])]
    lat = list(itertools.chain.from_iterable(lat))
    lon = list(itertools.chain.from_iterable(lon))
    lats.append(lat)
    lons.append(lon)

map_data = pd.DataFrame({'x': lats, 'y': lons, 'state': st_id, 'county_name': ct_name, 'ct_state_name': ct_state_name})
map_data_m = map_data[map_data.ct_state_name.isin(['NJ'])]    

source = ColumnDataSource(map_data_m)

TOOLS="pan,wheel_zoom,box_zoom,reset,hover,save"

p = figure(title="Title", tools=TOOLS,
           x_axis_location=None, y_axis_location=None)
p.grid.grid_line_color = None

p.patches('x', 'y', source=source,
          fill_color='color', fill_alpha=0.7,
          line_color="white", line_width=0.5)

show(p)

anyone who is able to help me to resolve either of the question? I have been stuck for few days. Thanks a lot!

David Pu
  • 1
  • 1
  • 2
  • Are there any NaN or inf values in your dataset? Reference: https://stackoverflow.com/questions/38821132/bokeh-valueerror-out-of-range-float-values-are-not-json-compliant – Jesper1 Nov 14 '18 at 21:29
  • hello @user2908623. thank you os much for replying back. I checked and there is no NaN in both my x and y...>_ – David Pu Nov 14 '18 at 22:01

1 Answers1

0

Could you check if there are no infinite numbers in the dataset? Reference: https://stackoverflow.com/a/47085304/2908623

Jesper1
  • 78
  • 7
  • Hello @user2908623 thanks for replying back again. I have seen that reference and tried all the solutions. Somehow after I upgraded my Bokeh to the newest version. it is working now. Really thank you for your help! :D – David Pu Nov 19 '18 at 19:19