В Боке, как я могу отображать различную информацию для точек и патчей? - PullRequest
0 голосов
/ 17 мая 2019

Я хочу отобразить различную информацию для разных слоев (точек и участков), используя bokeh.

Я загрузил шейп-файл и информацию о населении городов Гаити соответственно из здесь и из здесь и я их объединил.

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd

import osmnx as ox

from bokeh.layouts import row, column
from bokeh.models import Select
from bokeh.palettes import Spectral5
from bokeh.plotting import curdoc, figure, save
from bokeh.sampledata.autompg import autompg_clean as df


from bokeh.io import show
from bokeh.models import LogColorMapper
from bokeh.palettes import Viridis6 as palette
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource

from bokeh.sampledata.us_counties import data as counties
from bokeh.sampledata.unemployment import data as unemployment

import pandas as pd
import geopandas as gpd
import shapely

color_mapper = LogColorMapper(palette=palette)

Некоторые функции

 def getPolyCoords(row, geom, coord_type):
        """Returns the coordinates ('x' or 'y') of edges of a Polygon exterior"""

        # Parse the exterior of the coordinate
        exterior = row[geom].exterior

        if coord_type == 'x':
            # Get the x coordinates of the exterior
            return list( exterior.coords.xy[0] )
        elif coord_type == 'y':
            # Get the y coordinates of the exterior
            return list( exterior.coords.xy[1] )
def getPointCoords(row, geom, coord_type):
    """Calculates coordinates ('x' or 'y') of a Point geometry"""
    if coord_type == 'x':
        return row[geom].x
    elif coord_type == 'y':
        return row[geom].y

Данные городов

haiti = gpd.read_file(hti_admbnda_adm2_cnigs_20181129.shp')
haiti = haiti.to_crs({'init': 'epsg:32618'})
haiti = haiti[haiti.index != 98].reset_index(drop=True) ## i=98 is corrupted

pop = pd.read_csv('hti_admnbnda_adm2_cnigs2013c.csv')
level = 2
left = 'adm%dcode'%level
right = 'ADM%d_PCODE'%level
h_geom = pd.merge(pop, haiti, left_on=left, right_on=right)

Затем я создал данные для bokeh

grid = pd.DataFrame()
grid['x'] = h_geom.apply(getPolyCoords, geom='geometry', coord_type='x', axis=1)
grid['y'] = h_geom.apply(getPolyCoords, geom='geometry', coord_type='y', axis=1)
grid['Name'] = h_geom['adm2_en']
grid['Population'] = h_geom['TOTAL']
data=dict(
    x=list(grid['x'].values),
    y=list(grid['y'].values),
    name=list(grid['Name'].values),
    rate=list(grid['Population'].values),
)

С osmnx Я получаю баллы школ

selected_amenities = ['school']
place = 'Haiti'
schoolOSM = ox.pois_from_place(place=place, amenities=selected_amenities)
schools = gpd.GeoDataFrame(schoolOSM)
idxok = []
for i in schools.index:
    if type(schools['geometry'][i]) == shapely.geometry.point.Point:
        idxok.append(i)
schools = schools[schools.index.isin(idxok)]
schools['x'] = schools.apply(getPointCoords, geom='geometry', coord_type='x', axis=1)
schools['y'] = schools.apply(getPointCoords, geom='geometry', coord_type='y', axis=1)

data1=dict(
    x=list(schools['x'].values),
    y=list(schools['y'].values),
)

Затем я хочу показать информацию: Я хотел бы показать Имя, Население и координаты для городов, в то время кактолько координаты для школ.

TOOLS = "pan,wheel_zoom,reset,hover,save"

p = figure(title="Schools Point in Haiti", tools=TOOLS,
    x_axis_location=None, y_axis_location=None,
    tooltips=[("Name", "@name"), ("Population", "@rate"), ("(Long, Lat)", "($x, $y)")])

p.hover.point_policy = "follow_mouse"
p.patches('x', 'y', source=data,
         fill_color={'field': 'rate', 'transform': color_mapper},
         fill_alpha=1.0, line_color="black", line_width=1)
# Add points on top (as black points)
p.circle('x', 'y', size=3, source=data1, color="black")

show(p)

При этом я получаю информацию Name, Population, Long, Lat как для школ, так и для городов.Но в школах нет информации Name и Population, поэтому я получаю что-то вроде

enter image description here

1 Ответ

1 голос
/ 17 мая 2019

Вам необходимо создать два отдельных источника данных и два отдельных HoverTools.

from bokeh.models import HoverTool

data_cities = dict(x = list(cities['x'].values),  y = list(cities['y'].values))
data_schools = dict(x = list(schools['x'].values),  y = list(schools['y'].values))

cities = p.circle('x', 'y', size = 3, source = data_cities, color = "green")
schools = p.circle('x', 'y', size = 3, source = data_schools, color = "blue")

hover_cities = HoverTool(renderers = [cities], tooltips = [("Name", "@name"), ("Population", "@rate"), ("(Long, Lat)", "($x, $y)")]))
hover_schools = HoverTool(renderers = [schools], tooltips = [("(Long, Lat)", "($x, $y)")]))

p.add_tools(hover_cities)
p.add_tools(hover_schools)
...