python-3.x 如何在散景中用悬停文本填充div?

elcex8rz  于 2023-03-13  发布在  Python
关注(0)|答案(1)|浏览(118)

我正在开发一个散景地理 Jmeter 板。它是相当容易使用悬停工具提示在散景,但我想填充一个div当我悬停在一个领域。
Python版本:3.5.2
散景版本:0.13.0

1.这是 Jmeter 板的主视图。

2.所需产出

我想加上两个相互作用,
1.当我将鼠标悬停在一个地区上时,它应该只填充地区名称字段。
1.当我点击一个地区,它应该填充地区名称和信息字段(面积,人口,密度)。

3.数据:

4.代码:

from bokeh.io import show, output_notebook, output_file
from bokeh.models import (
    GeoJSONDataSource,
    HoverTool,
    LinearColorMapper,
    ColorBar,
    BasicTicker,
    PrintfTickFormatter,
    LogColorMapper,
    Range1d,
    Plot,
    Text
)
from bokeh.plotting import figure
import geopandas as gpd
    with open('/home/drogon/Desktop/Rescue-1122-project/punjab_districts(area_pop_den).geojson', 'r') as f:
        geo_source = GeoJSONDataSource(geojson=f.read())
    
    df = gpd.read_file('/home/drogon/Desktop/Rescue-1122-project/punjab_districts(area_pop_den).geojson')
    print(df.density)
    density = df['density']
    
    colors = ['#000003', '#3B0F6F', '#8C2980', '#DD4968', '#FD9F6C']
    colors.reverse()
    color_mapper = LogColorMapper(palette=colors, low=density.min(), high=density.max())
    
    TOOLS = "pan,wheel_zoom,box_zoom,reset,hover,save"
    
    p = figure(title="Punjab Districts", tools=TOOLS, x_axis_location=None, y_axis_location=None, width=800, height=800)
    p.grid.grid_line_color = None
    p.title.text_font_size = '30pt'
    
    p.patches('xs', 'ys', fill_alpha=0.9, fill_color={'field': 'density', 'transform': color_mapper},
              line_color='white', line_width=1, source=geo_source)
    
    
    hover = p.select_one(HoverTool)
    hover.point_policy = "follow_mouse"
    hover.tooltips = [("District", "@district"),
                      ("Density", "@density"),
                      ("Area", "@area")]
    
    color_bar = ColorBar(color_mapper=color_mapper, major_label_text_font_size="10pt",
                         ticker=BasicTicker(desired_num_ticks=8),
                         formatter=PrintfTickFormatter(format="%d"),
                         label_standoff=10, border_line_color=None, location=(0, 0))
    p.add_layout(color_bar, 'right')
    show(p)
91zkwejq

91zkwejq1#

由于您的问题中没有包含它,因此我无法获得与您完全相同的数据,而是使用了Kaggle上的json文件以及Wikipedia上可用的信息
由于这是一个老问题,请注意版本与您的不同:
Python版本:3.8.2
散景版本:3.0.1
为了在绘图中添加交互,需要实现JavaScript回调来更改Div对象的文本。有关该主题的更多详细信息,请查看Bokeh documentation on JavaScript callbacks

from bokeh.io import show, output_notebook, output_file
from bokeh.models import (
    GeoJSONDataSource,
    HoverTool,
    LinearColorMapper,
    ColorBar,
    BasicTicker,
    PrintfTickFormatter,
    LogColorMapper,
    Range1d,
    Plot,
    Text,
    Div,
    CustomJS,
    TapTool
)
from bokeh.plotting import figure
from bokeh.layouts import column, row
from bokeh import events

import geopandas as gpd

with open('data/punjab_districts_updated.geojson', 'r') as f:
    geo_source = GeoJSONDataSource(geojson=f.read())

df = gpd.read_file('data/punjab_districts_updated.geojson')
density = df['density']
    
colors = ['#000003', '#3B0F6F', '#8C2980', '#DD4968', '#FD9F6C']
colors.reverse()
color_mapper = LogColorMapper(palette=colors, low=density.min(), high=density.max())
    
TOOLS = "pan,wheel_zoom,box_zoom,tap,reset,save"

p = figure(title="Punjab Districts", tools=TOOLS, x_axis_location=None, y_axis_location=None, width=800, height=800)
p.grid.grid_line_color = None
p.title.text_font_size = '30pt'

div_district = Div(width=300, height=400)
div_info = Div(width=300)

# You need a layout to combine your map plot with the text boxes
layout = row(p, column(div_district, div_info))
p.patches('xs', 'ys', fill_alpha=0.9, fill_color={'field': 'density', 'transform': color_mapper},
              line_color='white', line_width=1, source=geo_source)

# This JavaScript code will update the district name at the top right of your plot
code = """
const indices = cb_data.index.indices;
if (indices.length > 0){
    div_text.text = "<span style='float: left; clear: left; font-size: 25pt'><b>District name</b><br>" + district[indices[0]] + "</span>";
}
else {
    div_text.text = "<span style='float: left; clear: left; font-size: 25pt'><b>District name</b><br>  </span>";
}
"""
callback = CustomJS(args={'district': df.district, 'div_text': div_district}, code=code)

# When you add the Hover tool to the plot, you can specify a callback to keep the hover tooltips
p.add_tools(HoverTool(tooltips=[("District", "@district"),
                      ("Density", "@density"),
                      ("Area", "@area")],
                      point_policy= "follow_mouse",
                      callback=callback))

# In this case, we will display pieces of information on the district each time the selection changes in the data source of the plot
callback_tap = CustomJS(args=dict(s=geo_source, district=df.info_district, div_text=div_info), code="""
    const indices = s.selected.indices;
    if (indices.length > 0) {
        div_text.text = "<span style='float: left; clear: left; font-size: 25pt'><b>District info</b><br>" + district[indices[0]] + "</span>";
    }
    else {
        div_text.text = "<span style='float: left; clear: left; font-size: 25pt'><b>District info</b><br></span>";
    }
""")
geo_source.selected.js_on_change('indices', callback_tap)

color_bar = ColorBar(color_mapper=color_mapper, major_label_text_font_size="10pt",
                         ticker=BasicTicker(desired_num_ticks=8),
                         formatter=PrintfTickFormatter(format="%d"),
                         label_standoff=10, border_line_color=None, location=(0, 0))
p.add_layout(color_bar, 'right')
show(layout)

当您选择一个地区时,结果如下:

相关问题