Is there a possibility to achive plots like sample1 with Bokeh? Sample1 was created with Matplotlib. My goal is to plot multiple short lines which are separated from each other on the map. But the lines share the same source and are just different parts from the source within.
I already wrote a small script but with not so great results... (see Sample2). My skript draws 3 different lines on the map. Unfortunally the lines are linked together.
In Matplotlib it worked with for loops. But in Bokeh I try to use a slider to chose interactivly which data I like to see.
Sample1
Sample2
Here is my code:
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, GMapOptions, CustomJS
from bokeh.plotting import gmap, ColumnDataSource, figure
from bokeh.layouts import column, row
from bokeh.models.widgets import RangeSlider
import numpy as np
# data set
lon = [[48.7886, 48.7887, 48.7888, 48.7889, 48.789],
[48.7876, 48.7877, 48.78878, 48.7879, 48.787],
[48.7866, 48.7867, 48.7868, 48.7869, 48.786]]
lat = [[8.92, 8.921, 8.922, 8.923, 8.924],
[8.91, 8.911, 8.912, 8.913, 8.914],
[8.90, 8.901, 8.902, 8.903, 8.904]]
# convert data set in 1D for callback function (JS slice)
lat1D = []
lon1D = []
for k in range(len(lon)):
lat1D += lat[k]
lon1D += lon[k]
# define source and map
source = ColumnDataSource(data = {'x': lon1D, 'y': lat1D})
map_options = GMapOptions(lat=48.7886, lng=8.92, map_type="satellite", zoom=13)
p = gmap("MY_API_KEY", map_options, title="Trajectory Map")
# plot lines on map
# for loops do not work like in matplotlib...
for j in range(0, len(lon1D), len(lon)):
for i in range(j, j + len(lon)):
p.line('y', 'x', source=source, line_width=0.4)
# slider to limit plotted data
range_slider = RangeSlider(title="Data Range Slider: ", start=0, end=len(lon1D), value=(0, len(lon1D)), step=1)
callback = CustomJS(args=dict(source=source, slider=range_slider, long=lon1D, lati=lat1D, lenght=len(lon)), code="""
var data = source.data;
const start = slider.value[0];
const end = slider.value[1];
data['x'] = long.slice(start, end)
data['y'] = lati.slice(start, end)
source.change.emit();
""")
range_slider.js_on_change('value', callback)
# Layout to plot and output
layout = row(
p, range_slider)
output_file("diag_plot_bike_data.html")
show(layout)