首页 > 解决方案 > 在按钮单击事件中更新 Bokeh 中的地理可视化

问题描述

我对 Python 中的 Bokeh 可视化库非常陌生。我使用 Bokeh 和 Google Maps API 构建了一个地理地图可视化,它允许我查看美国特定位置(城市)的数据分布。我进一步按性别分解了这些数据(对我的数据集中的每个性别使用不同的颜色,男性、女性和未知)。我现在的目标是在按钮单击事件上呈现此可视化。在浏览了 Bokeh 中的各种文档、对堆栈溢出和其他类似站点的研究之后,我到目前为止提出了以下代码,

from bokeh.plotting import figure, output_file, show
from bokeh.models import *
from bokeh.plotting import gmap
from bokeh.io import output_notebook, curdoc
from bokeh.transform import factor_cmap
from bokeh.models.widgets import Panel, Tabs
from bokeh.events import ButtonClick
from bokeh.models import Button
from bokeh.layouts import column
from bokeh.events import ButtonClick

import pandas as pd
import numpy as np
import pyodbc

output_file("gmap.html")

#parameters
server = 'x.x.x.x\abc'
db = 'abc'

# Create the connection
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=' + server + ';DATABASE=' + db + ';Trusted_Connection=yes')
map_options = GMapOptions(lat=37.686293, lng=-97.3614409, map_type="roadmap", zoom=13)
p = gmap("My_Google_Maps_API_Key", map_options, title="Client_Distribution", plot_width=1000, plot_height=600)


def callback(event):
    print ('abc')
    global p, map_options
    sql = """
        with CTE AS
            (SELECT
            CR.ClientID, CR.Latitude, CR.Longtitude
            FROM 
            Company C LEFT JOIN ClientRegistration CR on C.CompanyID = CR.CompanyID
            WHERE
            C.CompanyID = xxx AND (CR.Latitude IS NOT NULL AND CR.Longtitude IS NOT NULL)
            )
        SELECT
        C.ClientID, C.Latitude, C.Longtitude, CL.Sex
        FROM
        CTE C LEFT JOIN Clients CL on C.ClientID = CL.ClientID
    """
    df = pd.read_sql(sql, conn)

    print (df)

    df[['Latitude','Longtitude']] = df[['Latitude','Longtitude']].apply(pd.to_numeric)
    df['Sex'] = df['Sex'].astype('str')

    map_options = GMapOptions(lat=37.686293, lng=-97.3614409, map_type="roadmap", zoom=13)
    p = gmap("My_Google_Maps_API_Key", map_options, title="Client_Distribution", plot_width = 1000, plot_height = 600)

    lat = df['Latitude'].tolist()
    lon = df['Longtitude'].tolist()
    sex = df['Sex'].tolist()

    source = ColumnDataSource(
    data=dict(latitude = lat,
              longitude = lon,
              gender = sex
               )
    )

    print (source)
    color_mapper = CategoricalColorMapper(factors=['M', 'F', 'U'], palette=['Red', 'Blue', 'Green'])

    print("reached end")

    p.circle(x="longitude", y="latitude", size=4, fill_alpha=0.9, source=source,
             fill_color={'field': 'gender', 'transform': color_mapper},
             line_color={'field': 'gender', 'transform': color_mapper})

    x = np.linspace(0, 4 * np.pi, 100)
    y = np.sin(x)

    p.circle(x, y, legend="Male", color="red")
    p.circle(x, 2 * y, legend="Female", color="Blue")
    p.circle(x, 3 * y, legend="Unknown", color="Green")

    curdoc().clear()
    curdoc().add_root(column(p))


    print("reached the very end")



# add a button widget and configure with the call back
button = Button(label="Gender")
button.on_event(ButtonClick, callback)

# put the button and plot in a layout and add to the document

curdoc().add_root(column(button, p))

我可以获得底层的谷歌地图可视化和要显示的按钮,但我无法按性别显示客户的分解以及单击按钮时这些数据点的标签。当我单击按钮时,我的地图没有任何反应。谁能让我知道我做错了什么?

谢谢!

标签: pythonevent-handlingvisualizationgeocodingbokeh

解决方案


推荐阅读