[英]Plot multiple lines with Python Bokeh fom the same dataset
Is there a possibility to achive plots like sample1 with Bokeh?是否有可能用 Bokeh 获得像 sample1 这样的图? Sample1 was created with Matplotlib.
Sample1 是用 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).我已经写了一个小脚本,但结果不是很好......(参见示例 2)。 My skript draws 3 different lines on the map.
我的脚本在地图上绘制了 3 条不同的线。 Unfortunally the lines are linked together.
不幸的是,这些线是连在一起的。
In Matplotlib it worked with for loops.在 Matplotlib 中,它使用 for 循环。 But in Bokeh I try to use a slider to chose interactivly which data I like to see.
但在 Bokeh 中,我尝试使用滑块以交互方式选择我喜欢查看的数据。
Sample1样品 1
Sample2样品 2
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)
Anything that can be plotted with Matplotlib, can be plotted with Bokeh.任何可以用 Matplotlib 绘制的东西,都可以用 Bokeh 绘制。 Sometimes with a bit more code, sometimes with a bit less.
有时代码多一点,有时代码少一点。
There are too many things going on in your code, so I'll answer in plain text:你的代码中发生的事情太多了,所以我会用纯文本回答:
multi_line
instead of line
: https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#multiple-linesmulti_line
而不是line
: https : multi_line
multi_line
accepts lists of lists multi_line
接受列表列表for
loop doesn't work as intended because you're not using the j
and i
indices.for
循环无法按预期工作,因为您没有使用j
和i
索引。 But when you switch to multi_line
, you won't even need the loopmulti_line
,你甚至不需要循环CustomJS
callbacks.CustomJS
回调中的原始数据源。 You can limit the data, but expanding it will not be possible since the data will have already been lost.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.