Search code examples
python-3.xfolium

Using Folium to display multiple maps


I have some GPS data that I am plotting on maps. I was able to successfully use Folium and Jupyter to plot this data one group at a time:

mapPoints = [ [lat1, lng1], [lat2, lng2], ... ]
m = folium.Map(location=location, zoom_start=15)
folium.PolyLine(mapPoints).add_to(m)
m

This will display exactly the map I want / expect it to. When I try to generate multiple maps:

maps = []
for item in clustersOfPoints:
  mapPoints = getListOfLatLngs(item)
  m = folium.Map(location=location, zoom_start=15)
  folium.PolyLine(mapPoints).add_to(m)
  maps.append(m)
  m
...
for map in maps:
  map

Nothing displays. The list of mapPoints inside the loop is correct (I've verified by inspecting the value), and the map variable contains a list of folium.folium.Map objects (also verified by inspection).

How can I get it to generate the series of map renderings I want?


Solution

  • Did you try to adjust the last section of your code block where you loop on your maps to specify to display each? Like this:

    for map in maps:
      display(map)
    

    (You can remove the m line below maps.append(m) in your generating loop. It doesn't do anything there.)

    Explanation

    Your first code block works because the last line (or more specifically the last expression or object called) in a Jupyter notebook cell is special. You've probably come across the REPL model the is pertinent to the last line in each cell. Whatever the last line is it will be evaluated and the result displayed in a manner that is optimally how that type of data should be displayed. Without you needing to do anything. That is why if you put in a cell 2 + 2 on one line and then 3 + 3 on the second line of a single cell, when you run that cell, you'll just see 6 as the output.

    You can though change the two lines to print(2 + 2) and print(3 + 3) or display(2 + 2) and display(3 + 3) and re-run the cell and see the result for each calculation displayed on successive lines.

    So with the change I suggest above, you are saying explicitly you want to display each folium map. And not relying on the last thing evaluated to be handled by the special Jupyter display handling. What often trips people up expecting the last line to be handled is that the for loop, or any indentation, such as by an if - then conditional clause, makes it not the outermost thing evaluated and so it isn't handled by the special handling of Jupyter for the last expression, See here for a more full explanation of that. Your for loop example is even more clear that the last evaluation in that cell is the for loop exhausting the list of maps and nothing is returned from that and so nothing is specially handled & displayed by Jupyter in that case.

    To make it a little more of a confusing situation though, lately any matplotlib code detected in a cell will try to be displayed. There is no longer a need for plot.show() at the end to get handled by the special Jupyter display handling. This isn't the case with folium though. I think Matplotlib is exception as it the only place that more unique, convenient handling has been integrated for now.