简体   繁体   English

使用 Python Bokeh 从同一数据集绘制多条线

[英]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 中,我尝试使用滑块以交互方式选择我喜欢查看的数据。

样品 1

Sample1样品 1

样品 2

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:你的代码中发生的事情太多了,所以我会用纯文本回答:

  • Use multi_line instead of line : https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#multiple-lines使用multi_line而不是linehttps : multi_line
  • Don't make your data flat - you're losing the very same information you need to separate the lines.不要让您的数据扁平化 - 您将丢失与分隔线所需的完全相同的信息。 multi_line accepts lists of lists multi_line接受列表列表
  • Your for loop doesn't work as intended because you're not using the j and i indices.您的for循环无法按预期工作,因为您没有使用ji索引。 But when you switch to multi_line , you won't even need the loop但是当你切换到multi_line ,你甚至不需要循环
  • Don't change the original data sources in CustomJS callbacks.不要更改CustomJS回调中的原始数据源。 You can limit the data, but expanding it will not be possible since the data will have already been lost.您可以限制数据,但无法扩展数据,因为数据已经丢失。 Instead, filter data with views and filters: https://docs.bokeh.org/en/latest/docs/user_guide/data.html#filtering-data相反,使用视图和过滤器过滤数据: https : //docs.bokeh.org/en/latest/docs/user_guide/data.html#filtering-data

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM