#313 Bubble map with Folium

This page describes how to add bubbles to your folium map. It is done using the folium.Circle function. Each bubble has a size related to a specific value. Note that if you zoom on the map, the circle will get bigger. If you want the circle to stay the same size whatever the zoom, you have to use the folium.CircleMarker (exactly the same arguments!).

# import the library
import folium
import pandas as pd

# Make a data frame with dots to show on the map
data = pd.DataFrame({
   'lat':[-58, 2, 145, 30.32, -4.03, -73.57, 36.82, -38.5],
   'lon':[-34, 49, -38, 59.93, 5.33, 45.52, -1.29, -12.97],
   'name':['Buenos Aires', 'Paris', 'melbourne', 'St Petersbourg', 'Abidjan', 'Montreal', 'Nairobi', 'Salvador'],

# Make an empty map
m = folium.Map(location=[20,0], tiles="Mapbox Bright", zoom_start=2)

# I can add marker one by one on the map
for i in range(0,len(data)):
      location=[data.iloc[i]['lon'], data.iloc[i]['lat']],

# Save it as html
  • Sponsors


    • The variable radius doesn’t work for some reason. If I set a fixed integer value (i.e. radius=10) it works fine. But I can’t seem to get the radius to change according to the ‘value’ field using iloc.

      When I try it as it is, I get the following error: TypeError: 100000 is not JSON serializable.

      Can you help please?

      • Hello,

        just add str at the end .

        # Make a data frame with dots to show on the map
        data = pd.DataFrame({
        ‘lat’: [-58, 2, 145, 30.32, -4.03, -73.57, 36.82, -38.5],
        ‘lon’: [-34, 49, -38, 59.93, 5.33, 45.52, -1.29, -12.97],
        ‘name’: [‘Buenos Aires’, ‘Paris’, ‘melbourne’, ‘St Petersbourg’, ‘Abidjan’, ‘Montreal’, ‘Nairobi’, ‘Salvador’],
        ‘value’: [10, 12, 40, 70, 23, 43, 100, 43],

    • Very nice tutorial. Works perfectly.

      However, how do I how to I change the popup content to display integers? I think it only takes strings. For example, I want to display only ‘Values’. How should I do that?


    • this does not work, throws an error on “add marker” loop

      TypeError Traceback (most recent call last)
      7 color=’crimson’,
      8 fill=True,
      —-> 9 fill_color=’crimson’
      10 ).add_to(new_map)

      /anaconda3/lib/python3.7/site-packages/folium/vector_layers.py in __init__(self, location, radius, popup, tooltip, **kwargs)
      272 tooltip=tooltip)
      273 self._name = ‘circle’
      –> 274 self.options = _parse_options(line=False, radius=radius, **kwargs)

      /anaconda3/lib/python3.7/site-packages/folium/vector_layers.py in _parse_options(line, radius, **kwargs)
      105 def _parse_options(line=False, radius=False, **kwargs):
      106 options = path_options(line=line, radius=radius, **kwargs)
      –> 107 return json.dumps(options, sort_keys=True, indent=2)

      /anaconda3/lib/python3.7/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
      236 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
      237 separators=separators, default=default, sort_keys=sort_keys,
      –> 238 **kw).encode(obj)

      /anaconda3/lib/python3.7/json/encoder.py in encode(self, o)
      199 chunks = self.iterencode(o, _one_shot=True)
      200 if not isinstance(chunks, (list, tuple)):
      –> 201 chunks = list(chunks)
      202 return ”.join(chunks)

      /anaconda3/lib/python3.7/json/encoder.py in _iterencode(o, _current_indent_level)
      429 yield from _iterencode_list(o, _current_indent_level)
      430 elif isinstance(o, dict):
      –> 431 yield from _iterencode_dict(o, _current_indent_level)
      432 else:
      433 if markers is not None:

      /anaconda3/lib/python3.7/json/encoder.py in _iterencode_dict(dct, _current_indent_level)
      403 else:
      404 chunks = _iterencode(value, _current_indent_level)
      –> 405 yield from chunks
      406 if newline_indent is not None:
      407 _current_indent_level -= 1

      /anaconda3/lib/python3.7/json/encoder.py in _iterencode(o, _current_indent_level)
      436 raise ValueError(“Circular reference detected”)
      437 markers[markerid] = o
      –> 438 o = _default(o)
      439 yield from _iterencode(o, _current_indent_level)
      440 if markers is not None:

      /anaconda3/lib/python3.7/json/encoder.py in default(self, o)
      178 “””
      –> 179 raise TypeError(f’Object of type {o.__class__.__name__} ‘
      180 f’is not JSON serializable’)

      TypeError: Object of type int64 is not JSON serializable

    • The df column “values” needs to have float values.

      But I have another problem, I am geting no error, the code runs and creates a grey background with the circles in red. However, it is not showing the map itself.

    • Alternative fix of above 2 issues from original code.

      The first issue,
      TypeError: Object of type int64 is not JSON serializable

      The reason is that, data.iloc[i][‘value’] returns numpy.int64 type value. But the radius, from folium.Circle, accepts float value. To fix this, we have 2 solutions. Solution 1, convert the element’s type as Mantej Singh’s comment “data[‘value’]=data.value.astype(float)”. Solution 2, convert numpy.int64 as float via float() while set radius.

      The second issue,
      tiles=”Mapbox Bright” does not work for my env. We could using the default value ‘OpenStreetMap’, as Allan Sklarow’s comment. Or just skip setting tiles, since current tiles’s default value is ‘OpenStreetMap’.

      Revise as following:
      #Using default tiles
      -m = folium.Map(location=[20,0], tiles=”Mapbox Bright”, zoom_start=2)
      +m = folium.Map(location=[20,0], zoom_start=2)

      #An alternative approach to set radius.
      – radius=data.iloc[i][‘value’]*10000,
      + radius=float(data.iloc[i][‘value’]*10000),

      Hop this could help you all.

      • Here the radius=str(data.iloc[i][‘value’]*10000) also works fine, Can anyone explain how radius argument can accept string values?

    • Here radius=str(data.iloc[i][‘value’]*10000) also works fine, Can anyone explain how does the radius argument accepts string values?


    Leave a Reply

    Your email address will not be published.