Insert the folium maps into the jinja template

Question:

I want to insert follium map into the jinja template.

run.py

from flask import Flask, render_template

app = Flask(__name__)



@app.route('/')
def index():
    start_coords = (46.9540700, 142.7360300)
    folium_map = folium.Map(location=start_coords, zoom_start=14)
    folium_map.save()
    return render_template('index.html', folium_map=folium_map)


    if __name__ == '__main__':
    app.run(debug=True)

template/index.html – jinja template for Flask

{% extends "layout.html" %}
{% block title %}Test{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
**<div><!--Folium map here-->{{ folium_map }}</div>**
{% endblock %}

My site shows current line:

<folium.folium.Map object at 0x00000000069D5DA0>

But I need map that generate method follium_map.save(‘map.html’) in this div block.

How can I do this?

Asked By: Andrei

||

Answers:

You could save your generated html with folium_map.save('templates/map.html'). Then you can use jinja2 to {% include "map.html" %}. The generated html does not render a map when wrapped in div tags as indicated, if encapsulation is necessary consider using iframes or custom folium templates.

file structure

myapp
├── run.py
└── templates
    ├── index.html
    └── layout.html

run.py

from flask import Flask, render_template
import folium

app = Flask(__name__)

@app.route('/')
def index():
    start_coords = (46.9540700, 142.7360300)
    folium_map = folium.Map(location=start_coords, zoom_start=14)
    folium_map.save('templates/map.html')
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

layout.html

<!DOCTYPE HTML>
<head>
  <title>{% block title %}{% endblock %}</title>
</head>
<body>
  <header>{% block head %}{% endblock %}</header>
  {% block body %}{% endblock %}
</body>
</html>

index.html

{% extends "layout.html" %}
{% block title %} Test {% endblock %}
{% block head %} {{ super() }} {% endblock %}
{% block body %}
    {% include "map.html" %}
{% endblock %}
Answered By: brennan

A different solution using iframe and render_template

<iframe class="map", src="/get_map" width="1100" height="600"></iframe>

Plus python flask code

# a hack going on here as web servers are caching folium generated template
# randomly move to a new name and then use render_template
@app.route('/get_map')
def get_map():
    r = int(random.triangular(0,100))
    t = "templates/map_{i}.html"
    for i in range(0,100):
        f = t.format(i=i)
        if os.path.exists(f):
            os.remove(f)
    f = t.format(i=r)
    shutil.copy("templates/map.html", f)

    r = make_response(render_template(os.path.split(f)[1]))
    r.cache_control.max_age = 0
    r.cache_control.no_cache = True
    r.cache_control.no_store = True
    r.cache_control.must_revalidate = True
    r.cache_control.proxy_revalidate = True
    return r

Without the copy to a random filename before rendering httpd (on AWS beanstalk) / flask debug environment was not picking up new instance of folium html template. cache_control is not needed but was part of what I trialed to come to a solution. Clearly this solution is not thread safe

Answered By: Rob Raymond

Maybe it can be the solution. First we save a Folium map as an html file on templates folder. Then we create a Flask route to render another html file. On that html file, we create an iframe element that call our map.

Here is the file structure:

proectApp
├── app.py
└── templates
    ├── index.html
    └── map.html

Folium map file (map.html) will be created automatically from my app.py. On app.py I’ll create 2 main route: the first one is the home route which will render index.html & create map.html. Then the other is to render folium map (map.html). Here are the codes:

app.py

from flask import Flask, render_template
import folium

app = Flask(__name__)

@app.route('/')
def index():
    start_coords = (-6.1753924, 106.8271528)
    folium_map = folium.Map(
        location=start_coords, 
        zoom_start=17
    )
    folium_map.save('templates/map.html')
    return render_template('index.html')

@app.route('/map')
def map():
    return render_template('map.html')

if __name__ == '__main__':
    app.run(debug=True)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Folium Map</title>
</head>
<body>
    <h1>Render Folium on Flask  </h1>
    <iframe class="map", src="/map" width="600" height="600"></iframe>
    <h3><b style="background-color: lightcoral; color: lightcyan;">
        Render Folium on Flask done!
    </b></h3>
</body>
</html>

The result will be shown on browser like this:

folium on flask

Hope it helps you.

Answered By: Lintang Wisesa

Indeed, the best way to do that is following the documentation of Folium:

  1. Insert in your Flask file this:

    @app.route('/**map**')
    def flask_map():
        return **your_folium_map**._repr_html_()
    
  2. Insert in you HTML file this: <iframe class="**map**", src="/map" width="900" height="600"></iframe>

DONE!

you don’t need to convert your folium map in a html and you shouldn’t use it as source to render it in your html page. use the 1) instead if you don’t want to have future problems in rendering it.

Answered By: Bruhlickd

This may help in your jinja template:

{{ folium_map | safe }}
Answered By: Vitalii Mytenko
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.