Folium: RecursionError: maximum recursion depth exceeded in comparison when coordinates are of type object

Created on 19 Mar 2019  路  4Comments  路  Source: python-visualization/folium

Please add a code sample or a nbviewer link, copy-pastable if possible

#!/usr/bin/env python3

import sys
import numpy as np
import pandas as pd
import folium
from folium import plugins

datafile = "/tmp/test.json"
df = pd.read_json(datafile)

stops_map = folium.Map(location=[44.409748, 8.930819], zoom_start=11)
marker_cluster = folium.plugins.MarkerCluster().add_to(stops_map)
counter = 0
for name, row in df.iloc[:].iterrows():
        if counter % 10000 == 1:
                print(counter, row["latitudine"], row["longitudine"], row["temperatura"])
        folium.Marker([row["latitudine"], row["longitudine"]], popup=row["temperatura"]).add_to(marker_cluster)
        counter += 1
stops_map.save('/tmp/folium-test.html')

Problem description

I'm quite a python newbie so maybe this could be obvious to most people, but reading a json file (with lot of blanks instead of valid GPS coordinates) and trying to copy from this tutorial leads to a big bold error: RecursionError: maximum recursion depth exceeded in comparison.

I think this is because variables are passed as objects instead of float64 or other base types.

Adding this code after pd.read_json() converts blanks to valid GPS coordinates and downscales variable types to float64 and folium works as expected.

df['longitudine'] = df['longitudine'].replace(r'\s+', np.nan, regex=True)
df['longitudine'] = df['longitudine'].replace(r'^$', np.nan, regex=True)
df['longitudine'] = df['longitudine'].fillna(-0.99999)
df['longitudine'] = pd.to_numeric(df['longitudine'])
df['latitudine'] = df['latitudine'].replace(r'\s+', np.nan, regex=True)
df['latitudine'] = df['latitudine'].replace(r'^$', np.nan, regex=True)
df['latitudine'] = df['latitudine'].fillna(-0.99999)
df['latitudine'] = pd.to_numeric(df['latitudine'])

Sample output can be found here.

Expected Output

No error, or at least a warning such as "Folium can't directly work on object types: pass base types such as float64 or expect problems".

Output of folium.__version__

0.8.3

bug

Most helpful comment

ERROR MESSAGE

---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-3-3e3f80e964ea> in <module>
     33                 fill=True,
     34                 popup="testing!",
---> 35                 tooltip=tooltip
     36             ).add_to(mc)
     37             line_count+=1

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/vector_layers.py in __init__(self, location, radius, popup, tooltip, **kwargs)
    309     def __init__(self, location, radius=10, popup=None, tooltip=None, **kwargs):
    310         super(CircleMarker, self).__init__(location=location, popup=popup,
--> 311                                            tooltip=tooltip)
    312         self._name = 'CircleMarker'
    313         self.options = _parse_options(line=False, radius=radius, **kwargs)

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/map.py in __init__(self, location, popup, tooltip, icon, draggable)
    256         super(Marker, self).__init__()
    257         self._name = 'Marker'
--> 258         self.location = _validate_coordinates(location)
    259         self.draggable = draggable
    260         if icon is not None:

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _validate_coordinates(coordinates)
     51 def _validate_coordinates(coordinates):
     52     """Validates multiple coordinates for the various markers in folium."""
---> 53     if _isnan(coordinates):
     54         raise ValueError('Location values cannot contain NaNs, '
     55                          'got:\n{!r}'.format(coordinates))

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _isnan(values)
     77 def _isnan(values):
     78     """Check if there are NaNs values in the iterable."""
---> 79     return any(math.isnan(value) for value in _flatten(values))
     80 
     81 

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in <genexpr>(.0)
     77 def _isnan(values):
     78     """Check if there are NaNs values in the iterable."""
---> 79     return any(math.isnan(value) for value in _flatten(values))
     80 
     81 

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _flatten(container)
     69     for i in container:
     70         if _is_sized_iterable(i):
---> 71             for j in _flatten(i):
     72                 yield j
     73         else:

... last 1 frames repeated, from the frame below ...

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _flatten(container)
     69     for i in container:
     70         if _is_sized_iterable(i):
---> 71             for j in _flatten(i):
     72                 yield j
     73         else:

RecursionError: maximum recursion depth exceeded in comparison

This is the error that I get. All that I am doing is getting some data from dataset and marking the location to the map using a for loop.

I had the same issue, in my case, the value in latitude and longitude were string values so I mapped it to float which solved the issue.

All 4 comments

Hi @aviogit, thanks for bringing this up. I suspect it has to do with strings in your data. We had a data validation function that looked whether objects had an __iter__ attribute, and if so assume it's a container like a list or something and loop over it's items. But strings also have an __iter__ attribute, and the function would just keep on looping over the characters in the string.

Funny thing, we just merged a PR that should solve this issue. Can you install folium from the git master branch and try again? It should at least give a better error message. Note that folium cannot handle strings/None/NaN where it expects numerical coordinates.

ERROR MESSAGE

---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-3-3e3f80e964ea> in <module>
     33                 fill=True,
     34                 popup="testing!",
---> 35                 tooltip=tooltip
     36             ).add_to(mc)
     37             line_count+=1

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/vector_layers.py in __init__(self, location, radius, popup, tooltip, **kwargs)
    309     def __init__(self, location, radius=10, popup=None, tooltip=None, **kwargs):
    310         super(CircleMarker, self).__init__(location=location, popup=popup,
--> 311                                            tooltip=tooltip)
    312         self._name = 'CircleMarker'
    313         self.options = _parse_options(line=False, radius=radius, **kwargs)

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/map.py in __init__(self, location, popup, tooltip, icon, draggable)
    256         super(Marker, self).__init__()
    257         self._name = 'Marker'
--> 258         self.location = _validate_coordinates(location)
    259         self.draggable = draggable
    260         if icon is not None:

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _validate_coordinates(coordinates)
     51 def _validate_coordinates(coordinates):
     52     """Validates multiple coordinates for the various markers in folium."""
---> 53     if _isnan(coordinates):
     54         raise ValueError('Location values cannot contain NaNs, '
     55                          'got:\n{!r}'.format(coordinates))

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _isnan(values)
     77 def _isnan(values):
     78     """Check if there are NaNs values in the iterable."""
---> 79     return any(math.isnan(value) for value in _flatten(values))
     80 
     81 

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in <genexpr>(.0)
     77 def _isnan(values):
     78     """Check if there are NaNs values in the iterable."""
---> 79     return any(math.isnan(value) for value in _flatten(values))
     80 
     81 

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _flatten(container)
     69     for i in container:
     70         if _is_sized_iterable(i):
---> 71             for j in _flatten(i):
     72                 yield j
     73         else:

... last 1 frames repeated, from the frame below ...

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _flatten(container)
     69     for i in container:
     70         if _is_sized_iterable(i):
---> 71             for j in _flatten(i):
     72                 yield j
     73         else:

RecursionError: maximum recursion depth exceeded in comparison

This is the error that I get. All that I am doing is getting some data from dataset and marking the location to the map using a for loop.

@SooluThomas

Funny thing, we just merged a PR that should solve this issue. Can you install folium from the git master branch and try again? It should at least give a better error message. Note that folium cannot handle strings/None/NaN where it expects numerical coordinates.

ERROR MESSAGE

---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-3-3e3f80e964ea> in <module>
     33                 fill=True,
     34                 popup="testing!",
---> 35                 tooltip=tooltip
     36             ).add_to(mc)
     37             line_count+=1

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/vector_layers.py in __init__(self, location, radius, popup, tooltip, **kwargs)
    309     def __init__(self, location, radius=10, popup=None, tooltip=None, **kwargs):
    310         super(CircleMarker, self).__init__(location=location, popup=popup,
--> 311                                            tooltip=tooltip)
    312         self._name = 'CircleMarker'
    313         self.options = _parse_options(line=False, radius=radius, **kwargs)

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/map.py in __init__(self, location, popup, tooltip, icon, draggable)
    256         super(Marker, self).__init__()
    257         self._name = 'Marker'
--> 258         self.location = _validate_coordinates(location)
    259         self.draggable = draggable
    260         if icon is not None:

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _validate_coordinates(coordinates)
     51 def _validate_coordinates(coordinates):
     52     """Validates multiple coordinates for the various markers in folium."""
---> 53     if _isnan(coordinates):
     54         raise ValueError('Location values cannot contain NaNs, '
     55                          'got:\n{!r}'.format(coordinates))

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _isnan(values)
     77 def _isnan(values):
     78     """Check if there are NaNs values in the iterable."""
---> 79     return any(math.isnan(value) for value in _flatten(values))
     80 
     81 

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in <genexpr>(.0)
     77 def _isnan(values):
     78     """Check if there are NaNs values in the iterable."""
---> 79     return any(math.isnan(value) for value in _flatten(values))
     80 
     81 

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _flatten(container)
     69     for i in container:
     70         if _is_sized_iterable(i):
---> 71             for j in _flatten(i):
     72                 yield j
     73         else:

... last 1 frames repeated, from the frame below ...

/anaconda3/envs/dataViz/lib/python3.6/site-packages/folium/utilities.py in _flatten(container)
     69     for i in container:
     70         if _is_sized_iterable(i):
---> 71             for j in _flatten(i):
     72                 yield j
     73         else:

RecursionError: maximum recursion depth exceeded in comparison

This is the error that I get. All that I am doing is getting some data from dataset and marking the location to the map using a for loop.

I had the same issue, in my case, the value in latitude and longitude were string values so I mapped it to float which solved the issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sangyh picture sangyh  路  60Comments

achourasia picture achourasia  路  19Comments

olibchr picture olibchr  路  19Comments

agravier picture agravier  路  26Comments

EMarcantonio picture EMarcantonio  路  41Comments