Search code examples
pythonbokeh

Merging Bokeh USCounties sample data with column values from my own dataframe


I'm using Python 3 and currently playing with the latest version of Bokeh.

I've imported everything necessary, but I'm a little bit stuck with a single (I hope) line of code.

I'm using the US County sample data. I want to hover over the map and for it to display the vote percentages for each respective county, as they're hovered over with the cursor.

I've searched on here for other bokeh examples and explicitly the US County data but I can only seem to find questions regarding issues with map shape.

from bokeh.models import LogColorMapper
from bokeh.palettes import Viridis6 as palette
from bokeh.sampledata.us_counties import data as counties


palette = tuple(reversed(palette))
color_mapper = LogColorMapper(palette=palette)

counties = {
    code: county for code, county in counties.items() if county['state'] == 'tx'
}

county_xs = [county['lons'] for county in counties.values()]
county_ys = [county['lats'] for county in counties.values()]


county_names = [county['name'] for county in counties.values()]

## Below is the variable I wish to create, and these are the columns and dataframe of importance. 

#county_vote_total =
#texasJbFinal['County Vote Percentage'] - where the vote percentages are
#texasJbFinal['County'] - What my own df county column is labelled as.


data = dict(
    x=county_xs,
    y=county_ys,
    name=county_names,
    voteP=county_vote_total
)


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

p = figure(
    title='Joe Biden Texas Vote Percentage',
    tools=TOOLS,
    x_axis_location=None, y_axis_location=None,
    tooltips=[
        ("Name", "@name"), ("Vote Percentage", "@voteP"), ("Long, lat", "($x, $y)")
    ]
)

p.grid.grid_line_color=None
p.hover.point_policy = "follow_mouse"

p.patches("x", "y", source=data, fill_color={"field": "voteP", "transform": color_mapper},
          fill_alpha=0.6, line_color="black", line_width=0.5)

show(p)

I have tried a few things but I can't seem to figure out how to match up each individual county from my texasJbFinal dataframe with the bokeh.sampledata.us_counties and then display the vote percentage as each is hovered over.

Here is a sample of my DF, using texasJbFinal.head(5).to_dict()


{'State': {0: 'Texas', 1: 'Texas', 2: 'Texas', 3: 'Texas', 4: 'Texas'},
'County': {0: 'Roberts County',
 1: 'Borden County',
 2: 'King County',
 3: 'Glasscock County',
 4: 'Armstrong County'},
'Candidate': {0: 'Joe Biden',
 1: 'Joe Biden',
 2: 'Joe Biden',
 3: 'Joe Biden',
 4: 'Joe Biden'},
'Total Votes': {0: 17, 1: 16, 2: 8, 3: 39, 4: 75},
'County Vote Percentage': {0: 3.091, 1: 3.846, 2: 5.031, 3: 5.972, 4: 6.745},
'Total Population': {0: 912, 1: 697, 2: 315, 3: 2171, 4: 2122},
'White Alone': {0: 782, 1: 598, 2: 234, 3: 1003, 4: 1833},
'White Alone Percent': {0: 85.74561403508771,
 1: 85.79626972740316,
 2: 74.28571428571428,
 3: 46.19990787655458,
 4: 86.38077285579642},
'Black or African American Alone': {0: 0, 1: 0, 2: 0, 3: 0, 4: 5},
'Black or African American Alone Percent': {0: 0.0,
 1: 0.0,
 2: 0.0,
 3: 0.0,
 4: 0.23562676720075398},
'American Indian and Alaska Native Alone': {0: 0, 1: 0, 2: 0, 3: 0, 4: 22},
'Asian Alone': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0},
'Native Hawaiian and Other Pacific Islander Alone': {0: 0,
 1: 0,
 2: 0,
 3: 0,
 4: 0},
'Some other race Alone': {0: 0, 1: 0, 2: 3, 3: 507, 4: 42},
'Two or more races': {0: 23, 1: 15, 2: 0, 3: 0, 4: 71},
'Hispanic or Latino Alone': {0: 107, 1: 84, 2: 78, 3: 661, 4: 149},
'Hispanic or Latino Alone Percent': {0: 11.732456140350877,
 1: 12.051649928263988,
 2: 24.76190476190476,
 3: 30.446798710271764,
 4: 7.021677662582469}}


Solution

  • Here's how I'd tackle it:

    1. Turn the Bokeh counties data into a DataFrame to merge with your existing df. Something like:

    bokeh_counties = pd.DataFrame.from_records([county for key, county in counties.items()])

    ...and then you'd have to do some regex matching or other text manipulation to merge, since your values are all appended with " County" and those in the Bokeh dataset are not.

    1. Once you've got the merged DataFrame with all the data you need, convert to a ColumnDataSource for use by the Bokeh glyphs and hovertool. While CDSes aren't absolutely required for a lot of Bokeh tasks, they tend to make things much easier.