繁体   English   中英

如何使用散景回调更新数据框?

[英]How to update dataframe with bokeh callback?

我正在尝试重新计算两个坐标之间的距离,一个是通过 2 个 TextInput 类给出的,另一个是在数据框中。 我想解决这个问题,以便根据邻近条件选择数据,也许选择选项,但除非距离根据 2 个 TextInput 输入动态更新,否则这些都不起作用。

我遵循了文档和示例,但由于某种原因df['distance']没有改变。

我的代码在下面,我在回调中定义了一个函数来计算距离。

import numpy as np
import pandas as pd
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS, TextInput
import math
from bokeh.layouts import column, row
from bokeh.io import show

df = pd.DataFrame(np.random.rand(100,2),columns=list('Xy'))

def distance(origin, destination):
   
    lat1, lon1 = origin
    lat2, lon2 = destination
    radius = 6371  # km

    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = (math.sin(dlat / 2) * math.sin(dlat / 2) +
         math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
         math.sin(dlon / 2) * math.sin(dlon / 2))
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    d = radius * c

    return d


cord_1, cord_2 = 30.56289,70.38185

df['distance'] = [distance((cord_1,cord_2),(df['X'][i],df['y'][i])) for i in range(0,len(df['X']))]
source=ColumnDataSource(df)



cord_x = TextInput(title="X-Coordinates")
cord_y = TextInput(title="Y-Coordinates")


TOOLTIPS = [

    ('Distance','@distance')
        ]


p = figure(title='Sample Distance',width = 800, height = 600,tooltips = TOOLTIPS)
p.circle(x='X',y='y',size = 10,source=source)

callback = CustomJS(args=dict(source=source, cord_x=cord_x, cord_y=cord_y),
                    code="""
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}
                     
var data = source.data;
var distance = 0;
var A = cord_x.value;
var B = cord_y.value;
    
 //apply function
for(var i = 1; i < data['X'].length ; i++) {
    distance = getDistanceFromLatLonInKm(A,B,data['X'][i],data['y']);
    data['distance'][i] = distance;
}
source.change.emit()

""")

source.js_on_change('data', callback)

layout = row(
    p,
    column(cord_x, cord_y),
)

show(layout)

因此,如果我理解这一点,您是否希望动态更新用作基础坐标的cord_xcord_y来计算与数据框中各点的距离? 并且坐标本身保持不变,而工具提示中的距离会发生变化。

做了几个小改动:首先,需要将js_on_change应用于小部件。 其次,它需要调用“价值”作为第一个参数。 最后,您缺少data['y'][i]中的[i]部分。 这是完整的代码:

import numpy as np
import pandas as pd
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS, TextInput
import math
from bokeh.layouts import column, row
from bokeh.io import show

df = pd.DataFrame(np.random.rand(100,2),columns=list('Xy'))

def distance(origin, destination):
   
    lat1, lon1 = origin
    lat2, lon2 = destination
    radius = 6371  # km

    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = (math.sin(dlat / 2) * math.sin(dlat / 2) +
         math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
         math.sin(dlon / 2) * math.sin(dlon / 2))
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    d = radius * c

    return d


cord_1, cord_2 = 30.56289,70.38185

df['distance'] = [distance((cord_1,cord_2),(df['X'][i],df['y'][i])) for i in range(0,len(df['X']))]
source=ColumnDataSource(df)

cord_x = TextInput(title="X-Coordinates")
cord_y = TextInput(title="Y-Coordinates")


TOOLTIPS = [

    ('Distance','@distance')
        ]


p = figure(title='Sample Distance',width = 800, height = 600,tooltips = TOOLTIPS)
p.circle(x='X',y='y',size = 10,source=source)

callback = CustomJS(args=dict(source=source, cord_x=cord_x, cord_y=cord_y),
                    code="""
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}
                     
var data = source.data;
var distance = 0;
var A = cord_x.value;
var B = cord_y.value;
    
 //apply function
for(var i = 1; i < data['X'].length ; i++) {
    distance = getDistanceFromLatLonInKm(A,B,data['X'][i],data['y'][i]);
    data['distance'][i] = distance;
}
source.change.emit()

""")

cord_x.js_on_change('value', callback)
cord_y.js_on_change('value', callback)

layout = row(
    p,
    column(cord_x, cord_y),
)

show(layout)

暂无
暂无

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

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