Caching Folium Maps

Hi,

I’m looking for caching Folium Maps. Any guidelines in this matter? Thanks:

In looking at this further, I’m not sure it’s possible to cache Folium maps, as they seem to add a GUID-like value to the generated maps (possibly to avoid browser caching issues):

In [18]: import folium 
    ...:  
    ...: # center on Liberty Bell 
    ...: m = folium.Map(location=[39.949610, -75.150282], zoom_start=16) 
    ...:  
    ...: # add marker for Liberty Bell 
    ...: tooltip = "Liberty Bell" 
    ...: folium.Marker( 
    ...:     [39.949610, -75.150282], popup="Liberty Bell", tooltip=tooltip 
    ...: ).add_to(m) 
    ...:  
    ...: # center on Liberty Bell 
    ...: n = folium.Map(location=[39.949610, -75.150282], zoom_start=16) 
    ...:  
    ...: # add marker for Liberty Bell 
    ...: tooltip = "Liberty Bell" 
    ...: folium.Marker( 
    ...:     [39.949610, -75.150282], popup="Liberty Bell", tooltip=tooltip 
    ...: ).add_to(n)                                                                                                                                                                                                            
Out[18]: <folium.map.Marker at 0x7f0870657cc0>

In [19]: id(m)                                                                                                                                                                                                                  
Out[19]: 139674222164400

In [20]: id(n)                                                                                                                                                                                                                  
Out[20]: 139674222164288

In [21]: hash(m)                                                                                                                                                                                                                
Out[21]: 8729638885275

In [22]: hash(n)                                                                                                                                                                                                                
Out[22]: 8729638885268

In [23]: m.to_dict()                                                                                                                                                                                                            
Out[23]: 
OrderedDict([('name', 'Map'),
             ('id', '218e2effce0642fab72883e6caf445c4'),
             ('children',
              OrderedDict([('openstreetmap',
                            OrderedDict([('name', 'TileLayer'),
                                         ('id',
                                          '256adb569e0345ac9a17cee31ce04776'),
                                         ('children', OrderedDict())])),
                           ('marker_8fa3db966dd5471aaa0c093bb4304673',
                            OrderedDict([('name', 'Marker'),
                                         ('id',
                                          '8fa3db966dd5471aaa0c093bb4304673'),
                                         ('children',
                                          OrderedDict([('popup_3f74cd5125f646e78cff93046d045d2c',
                                                        OrderedDict([('name',
                                                                      'Popup'),
                                                                     ('id',
                                                                      '3f74cd5125f646e78cff93046d045d2c'),
                                                                     ('children',
                                                                      OrderedDict())])),
                                                       ('tooltip_65ab2fd3b7434aecac68ad5cd4d5531b',
                                                        OrderedDict([('name',
                                                                      'Tooltip'),
                                                                     ('id',
                                                                      '65ab2fd3b7434aecac68ad5cd4d5531b'),
                                                                     ('children',
                                                                      OrderedDict())]))]))]))]))])

In [24]: n.to_dict()                                                                                                                                                                                                            
Out[24]: 
OrderedDict([('name', 'Map'),
             ('id', '63ab30d4669345f9b74c4b5d97938e67'),
             ('children',
              OrderedDict([('openstreetmap',
                            OrderedDict([('name', 'TileLayer'),
                                         ('id',
                                          '54a72eab61c243d39cf56619dbd07b87'),
                                         ('children', OrderedDict())])),
                           ('marker_985282054e794fb89d84dbcb0a6ce7aa',
                            OrderedDict([('name', 'Marker'),
                                         ('id',
                                          '985282054e794fb89d84dbcb0a6ce7aa'),
                                         ('children',
                                          OrderedDict([('popup_b4d45c5ae086467fb24ab376f8325c38',
                                                        OrderedDict([('name',
                                                                      'Popup'),
                                                                     ('id',
                                                                      'b4d45c5ae086467fb24ab376f8325c38'),
                                                                     ('children',
                                                                      OrderedDict())])),
                                                       ('tooltip_599cdd0583a543ab941ecc142af1e153',
                                                        OrderedDict([('name',
                                                                      'Tooltip'),
                                                                     ('id',
                                                                      '599cdd0583a543ab941ecc142af1e153'),
                                                                     ('children',
                                                                      OrderedDict())]))]))]))]))])

In this example, you can see I use the same code to generate two identical objects, m and n. It’s expected that id won’t match (since this is a reference to the specific object), but hash() and m.to_dict() and n.to_dict() trivially don’t match.

I’ll link this in our internal messageboard so that someone else can check my logic here, but I think this means there isn’t a good way to hash Folium maps. Are you running into performance issues already, or is this a theoretical question?

Performance issues. I was trying to test a project I did for a client, with Streamlit.

The problem comes with the number of registers/rows, that goes from 10.000 to 100.000. You can clearly see the issue with the prove of concepto I did,more clearly changing to 50.000 more or less.

Thanks for your time!

That’s good to know, thanks for providing that data point.

I think this is a situation where it takes someone sitting down and really thinking through the goals here. It feels like the optimal solution is finding a way to use Folium as an API, but transferring the data to leaflet in a more optimized way than the current simple method of passing the entire HTML bundle from Folium.

In your example, are you able to get the performance you need via Jupyter? I’m just trying to understand whether this is a limitation in Folium or a limitation with how this works in Streamlit.

The limitation comes from Folium, from one side (time spending in processing), and Streamlit, in the other (rerunning all script with every change)

For dealing with a lot of values, I use folium.plugins.MarkerCluster() If not its a pain dealing with the map, in any deployment situation as I know. (FastMarkerCluster() has lower timings, but has function limitations that MarkerCluster() has not).

The problem with this function, MarkerCluster(), is time processing. Once rendered, goes like a charm. With Streamlit, if we cant cache, it can’t be an option. This is the reason I consider caching Folium maps important.