Plotly.py: Create country choropleth hover regression

Created on 8 Feb 2019  路  6Comments  路  Source: plotly/plotly.py

Originally reported at https://community.plot.ly/t/county-choropleths-not-displaying-hoverinfo-in-offline-mode/19241

The hover tooltips for the figure produced by create_choropleth are sometimes not being displayed properly with recent versions of plotly.js.

import plotly as py
import plotly.figure_factory as ff

import numpy as np
import pandas as pd

df_sample = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/minoritymajority.csv')
df_sample_r = df_sample[df_sample['STNAME'] == 'California']

values = df_sample_r['TOT_POP'].tolist()
fips = df_sample_r['FIPS'].tolist()

colorscale = [
    'rgb(193, 193, 193)',
    'rgb(239,239,239)',
    'rgb(195, 196, 222)',
    'rgb(144,148,194)',
    'rgb(101,104,168)',
    'rgb(65, 53, 132)'
]

fig = ff.create_choropleth(
    fips=fips, values=values, scope=['CA', 'AZ', 'Nevada', 'Oregon', ' Idaho'],
    binning_endpoints=[14348, 63983, 134827, 426762, 2081313], colorscale=colorscale,
    county_outline={'color': 'rgb(255,255,255)', 'width': 0.5}, round_legend_values=True,
    legend_title='Population by County', title='California and Nearby States'
)

Plotting this figure in the most recent version of plotly.js (1.44.3) results in no hover tooltips

py.offline.plot(fig,
                filename='choropleth_california_and_surr_states_outlines',
                include_plotlyjs='https://cdn.plot.ly/plotly-1.44.3.min.js')

But using 1.42.3 the tooltips are dipslayed as expected

py.offline.plot(fig,
                filename='choropleth_california_and_surr_states_outlines',
                include_plotlyjs='https://cdn.plot.ly/plotly-1.42.3.min.js')
bug

Most helpful comment

It looks like the bug creates duplicate hover tooltips and stores their x, y coordinates as lists instead of floats.

e.g.

[-86.1224], [-88.2717], [-94.2067], [-84.6049]

instead of

-86.1224, -88.2717, -94.2067, -84.6049

De-duplicating and flattening restores functionality. Building on the code snippet from @jonmmease's original post..

hover_ix, hover = [(ix, t) for ix, t in enumerate(fig['data']) if t.text][0]

# mismatching lengths indicates bug
if len(hover['text']) != len(df_sample_r):

    ht = pd.Series(hover['text'])

    no_dupe_ix = ht.index[~ht.duplicated()]

    hover_x_deduped = np.array(hover['x'])[no_dupe_ix]
    hover_y_deduped = np.array(hover['y'])[no_dupe_ix]

    new_hover_x = [x if type(x) == float else x[0] for x in hover_x_deduped]
    new_hover_y = [y if type(y) == float else y[0] for y in hover_y_deduped]

    fig['data'][hover_ix]['text'] = ht.drop_duplicates()
    fig['data'][hover_ix]['x'] = new_hover_x
    fig['data'][hover_ix]['y'] = new_hover_y

All 6 comments

FYI the workaround does not work when using iplot in jupyter notebook because there is no include_plotlyjs argument.

Any update on when this bug might be fixed?

Also, using this old version of the Javascript causes the title to not show up on plots (see https://github.com/plotly/dash/issues/539)

Hi all. I don't think anyone has taken a look at this issue yet. We're definitely open to help if someone would like to take a look at https://github.com/plotly/plotly.py/blob/master/plotly/figure_factory/_county_choropleth.py and try to work through what's going wrong.

I'm also encountering this issue with the following app dependencies

dash==1.0.0"
flask_caching==1.7.2"
geopandas==0.3.0"
plotly-geo==1.0.0a1"
pyshp==1.2.10"
shapely==1.6.3"

The hover info works fine on choropleths with < ~20 counties. Anything bigger than that breaks the tooltips.

It looks like the bug creates duplicate hover tooltips and stores their x, y coordinates as lists instead of floats.

e.g.

[-86.1224], [-88.2717], [-94.2067], [-84.6049]

instead of

-86.1224, -88.2717, -94.2067, -84.6049

De-duplicating and flattening restores functionality. Building on the code snippet from @jonmmease's original post..

hover_ix, hover = [(ix, t) for ix, t in enumerate(fig['data']) if t.text][0]

# mismatching lengths indicates bug
if len(hover['text']) != len(df_sample_r):

    ht = pd.Series(hover['text'])

    no_dupe_ix = ht.index[~ht.duplicated()]

    hover_x_deduped = np.array(hover['x'])[no_dupe_ix]
    hover_y_deduped = np.array(hover['y'])[no_dupe_ix]

    new_hover_x = [x if type(x) == float else x[0] for x in hover_x_deduped]
    new_hover_y = [y if type(y) == float else y[0] for y in hover_y_deduped]

    fig['data'][hover_ix]['text'] = ht.drop_duplicates()
    fig['data'][hover_ix]['x'] = new_hover_x
    fig['data'][hover_ix]['y'] = new_hover_y
Was this page helpful?
0 / 5 - 0 ratings

Related issues

astrojuanlu picture astrojuanlu  路  4Comments

suciokhan picture suciokhan  路  3Comments

vlizanae picture vlizanae  路  4Comments

jisaacso picture jisaacso  路  4Comments

binaryfunt picture binaryfunt  路  5Comments