santoku
santoku

Reputation: 3437

why I couldn't makes points shown on bokeh map in python?

I'm trying to plot some datapoint on a map in Bokeh but somehow nothing shows up, only the map background.

import pandas as pd
from IPython.core.display import HTML, display
%matplotlib inline
sample = pd.DataFrame({'Lat': [40.7260,40.7209], 'Lon': [-73.991,-74.0507], 'Count': 1})
from bokeh.plotting import figure, output_notebook, show
output_notebook()
from bokeh.tile_providers import STAMEN_TERRAIN

x_range, y_range = ((-8242000,-8210000), (4965000,4990000))
plot_width  = int(750)
plot_height = int(plot_width//1.2)

def base_plot(tools='pan,wheel_zoom,reset',plot_width=plot_width, plot_height=plot_height, **plot_args):
p = figure(tools=tools, plot_width=plot_width, plot_height=plot_height,
    x_range=x_range, y_range=y_range, outline_line_color=None,
    min_border=0, min_border_left=0, min_border_right=0,
    min_border_top=0, min_border_bottom=0, **plot_args)
p.axis.visible = False
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
return p    
p = base_plot()
p.add_tile(STAMEN_TERRAIN)
p.circle(x=samples['Lat'], y=samples['Lon'], **options)
show(p)

Thanks for advice.

Upvotes: 0

Views: 513

Answers (1)

bigreddot
bigreddot

Reputation: 34618

The plot ranges are in Web Mercator units:

((-8242000,-8210000), (4965000,4990000))

But the data points in your sample DataFrame are in lat/lon units. You can either:

  • add an "extra range" in lat/lon units (that match up!) and have p.circle reference the extra range instead of the default range.

  • Convert your circle coordinates to Web Mercator

The latter is probably easier. This page has a function that can do the conversion. Using it, you'd get

sample = pd.DataFrame({
    'easting': [-8236640.443285105, -8243286.216885463], 
    'northing': [4972010.345629457, 4971261.231184175]
})

Updating your code to use this:

import pandas as pd

from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.tile_providers import STAMEN_TERRAIN

samples = pd.DataFrame({
    'easting':  [-8236640.443285105, -8243286.216885463],
    'northing': [4972010.345629457, 4971261.231184175]
})

x_range, y_range = ((-8242000,-8210000), (4965000,4990000))
plot_width  = int(750)
plot_height = int(plot_width//1.2)

def base_plot(tools='pan,wheel_zoom,reset',plot_width=plot_width, plot_height=plot_height, **plot_args):
    p = figure(tools=tools, plot_width=plot_width, plot_height=plot_height,
        x_range=x_range, y_range=y_range, outline_line_color=None,
        min_border=0, min_border_left=0, min_border_right=0,
        min_border_top=0, min_border_bottom=0, **plot_args)
    p.axis.visible = False
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None
    return p
p = base_plot()

p.add_tile(STAMEN_TERRAIN)

p.circle(x=samples['easting'], y=samples['northing'], size=20, color="red")

output_file("map.html")
show(p)

yields this plot:

enter image description here

Upvotes: 1

Related Questions