How to add hover value in folium map

Viewed 32

I'm trying to create a folium map that contains Manhattan location clusters. I have a geojson file that contains clusters geometry of the and pandas data frame which contains the counts value

pandas dataframe

reading the geojson file

geojson

then I joined the two files merged file

then converted the merged file to json to json

now I created the folium map which contains the clusters and reflects the trips count by color.

m = folium.Map(location=[40.7831, -73.9712], zoom_start=11, tiles="cartodbpositron")
choropleth = folium.Choropleth(
    geo_data=geo_json_data,
    data=filter_data_new,
    columns=['LocationID', 'Trips_Forcast'],
    key_on='feature.properties.LocationID',
    fill_color='BuPu', 
    fill_opacity=0.7, 
    line_opacity=0.2,
    legend_name='Avg',
    reset=True,
    highlight=True,
).add_to(m)


m

map

now I'm trying to add hover to show the trip count value on the map using the following code.

m = folium.Map(location=[40.7831, -73.9712], zoom_start=11, tiles="cartodbpositron")
choropleth = folium.Choropleth(
    geo_data=geo_json_data,
    data=filter_data_new,
    columns=['LocationID', 'Trips_Forcast'],
    key_on='feature.properties.LocationID',
    fill_color='BuPu', 
    fill_opacity=0.7, 
    line_opacity=0.2,
    legend_name='Avg',
    reset=True,
    highlight=True,
).add_to(m)

choropleth.geojson.add_child(
    folium.features.GeoJsonTooltip(fields=['LocationID', 'Trips_Forcast'],
                                   aliases=['LocationID:', 'Trips_Forcast:'],
                                   labels=True,
                                   localize=True,
                                   sticky=False,
                                   style="""
                                   background-color: #F0EFEF;
                                   border: 2px solid black;
                                   border-radius: 3px;
                                   box-shadow: 3px;
                                   """,)
)


m

I got this error message and i can't solve it

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\miniconda3\envs\geo_env\lib\site-packages\IPython\core\formatters.py in __call__(self, obj)
    343             method = get_real_method(obj, self.print_method)
    344             if method is not None:
--> 345                 return method()
    346             return None
    347         else:

~\miniconda3\envs\geo_env\lib\site-packages\folium\folium.py in _repr_html_(self, **kwargs)
    297             self._parent = None
    298         else:
--> 299             out = self._parent._repr_html_(**kwargs)
    300         return out
    301 

~\miniconda3\envs\geo_env\lib\site-packages\branca\element.py in _repr_html_(self, **kwargs)
    324     def _repr_html_(self, **kwargs):
    325         """Displays the Figure in a Jupyter notebook."""
--> 326         html = escape(self.render(**kwargs))
    327         if self.height is None:
    328             iframe = (

~\miniconda3\envs\geo_env\lib\site-packages\branca\element.py in render(self, **kwargs)
    319         """Renders the HTML representation of the element."""
    320         for name, child in self._children.items():
--> 321             child.render(**kwargs)
    322         return self._template.render(this=self, kwargs=kwargs)
    323 

~\miniconda3\envs\geo_env\lib\site-packages\folium\folium.py in render(self, **kwargs)
    366             '</style>'), name='map_style')
    367 
--> 368         super(Map, self).render(**kwargs)
    369 
    370     def fit_bounds(self, bounds, padding_top_left=None,

~\miniconda3\envs\geo_env\lib\site-packages\folium\elements.py in render(self, **kwargs)
     19             figure.header.add_child(CssLink(url), name=name)
     20 
---> 21         super().render(**kwargs)

~\miniconda3\envs\geo_env\lib\site-packages\branca\element.py in render(self, **kwargs)
    626 
    627         for name, element in self._children.items():
--> 628             element.render(**kwargs)

~\miniconda3\envs\geo_env\lib\site-packages\folium\features.py in render(self, **kwargs)
   1305             self.color_scale._parent = self._parent
   1306 
-> 1307         super(Choropleth, self).render(**kwargs)
   1308 
   1309 

~\miniconda3\envs\geo_env\lib\site-packages\branca\element.py in render(self, **kwargs)
    626 
    627         for name, element in self._children.items():
--> 628             element.render(**kwargs)

~\miniconda3\envs\geo_env\lib\site-packages\folium\features.py in render(self, **kwargs)
    624                 self.highlight_map = mapper.get_highlight_map(
    625                     self.highlight_function)
--> 626         super(GeoJson, self).render()
    627 
    628 

~\miniconda3\envs\geo_env\lib\site-packages\branca\element.py in render(self, **kwargs)
    626 
    627         for name, element in self._children.items():
--> 628             element.render(**kwargs)

~\miniconda3\envs\geo_env\lib\site-packages\folium\features.py in render(self, **kwargs)
    914         if isinstance(self._parent, GeoJson):
    915             keys = tuple(self._parent.data['features'][0]['properties'].keys())
--> 916             self.warn_for_geometry_collections()
    917         elif isinstance(self._parent, TopoJson):
    918             obj_name = self._parent.object_path.split('.')[-1]

~\miniconda3\envs\geo_env\lib\site-packages\folium\features.py in warn_for_geometry_collections(self)
    898     def warn_for_geometry_collections(self):
    899         """Checks for GeoJson GeometryCollection features to warn user about incompatibility."""
--> 900         geom_collections = [
    901             feature.get('properties') if feature.get('properties') is not None else key
    902             for key, feature in enumerate(self._parent.data['features'])

~\miniconda3\envs\geo_env\lib\site-packages\folium\features.py in <listcomp>(.0)
    901             feature.get('properties') if feature.get('properties') is not None else key
    902             for key, feature in enumerate(self._parent.data['features'])
--> 903             if feature['geometry']['type'] == 'GeometryCollection'
    904         ]
    905         if any(geom_collections):

TypeError: 'NoneType' object is not subscriptable

<folium.folium.Map at 0x22b0be1cbe0>

all what i want to do is to add hover on the map that show the trips value, something like this enter image description here since days I can't figure it out. can anyone help with that

1 Answers

To add a tooltip in folium, it is folium.geoJson(), not choropleth. Since the data was not presented, the geoJson data was taken from here and used. Also, the user data is created similarly. One note on data creation is that the df must be merged into the gpd file. If this is reversed, it will be converted into a data frame.

import geopandas as gpd
import pandas as pd
import numpy as np

url = 'https://raw.githubusercontent.com/codeforgermany/click_that_hood/main/public/data/manhattan.geojson'
gpd_geo = gpd.read_file(url)

gpd_geo_new = gpd_geo[['cartodb_id', 'name', 'geometry']] 
filter_data_new = pd.DataFrame({'cartodb_id': gpd_geo_new['cartodb_id'].unique(), 'Trips_Forcast': np.random.randint(10,500,len(gpd_geo_new))})
filter_data_new = gpd_geo_new.merge(filter_data_new, on='cartodb_id', how='left')

import branca

colormap = branca.colormap.LinearColormap(
    vmin=filter_data_new["Trips_Forcast"].quantile(0.0),
    vmax=filter_data_new["Trips_Forcast"].quantile(1),
    colors=['aliceblue','purple'],
    caption="Trips Forcast",
)

import folium
from folium.features import GeoJsonTooltip

m = folium.Map(location=[40.7831, -73.9712], zoom_start=11, tiles="cartodbpositron")

tooltip = GeoJsonTooltip(fields=['cartodb_id', 'Trips_Forcast'],
                                   aliases=['cartodb_id:', 'Trips_Forcast:'],
                                   labels=True,
                                   localize=True,
                                   sticky=False,
                                   style="""
                                   background-color: #F0EFEF;
                                   border: 1px solid black;
                                   border-radius: 1px;
                                   box-shadow: 1px;
                                   """,)


g = folium.GeoJson(
    filter_data_new,
    style_function=lambda x: {
        "fillColor": colormap(x['properties']['Trips_Forcast']),
        "color": "grey",
        "fillOpacity": 0.4,
    },
    tooltip=tooltip,
).add_to(m)

colormap.add_to(m)

m

enter image description here

Related