首页 > 解决方案 > 如何在烧瓶应用程序中嵌入一个情节地图框?

问题描述

我一直在尝试将 Plotly Mapbox 嵌入到用 Flask 开发的网络应用程序中。

我正在生成如下所示的地图,当我在应用程序之外执行此操作时效果很好。我知道我可以在我的烧瓶应用程序中嵌入一个破折号应用程序,但我试图避免这种情况。这是我生成地图的完整烧瓶路线:

@app.route('/stats')
def stats():
    sujetos = Sujeto.query.all()
    headers = [
        'identificador',
        'usuario',
        'tiempo',
        'edad',
        'estatura',
        'cintura',
        'diabhist',
        'diag2006',
        'psis',
        'pdias',
        'gluc',
        'temp',
        'peso',
        'cadera',
        'icc',
        'imc',
        'territorial',
        'colonia',
        'genero'
    ]
    rows = []
    for sujeto in Sujeto.query.all():
        rows.append(
            {
                'identificador': sujeto.curp,
                'usuario': sujeto.user_id,
                'tiempo': sujeto.timestamp,
                'edad': sujeto.edad,
                'estatura': sujeto.estatura,
                'cintura': sujeto.cintura,
                'diabhist': sujeto.diabHist,
                'diag2006': sujeto.diag2006,
                'psis': sujeto.psis,
                'pdias': sujeto.pdias,
                'gluc': sujeto.gluc,
                'temp': sujeto.temp,
                'peso': sujeto.peso,
                'cadera': sujeto.cadera,
                'icc': sujeto.icc,
                'imc': sujeto.imc,
                'territorial': sujeto.territorial,
                'colonia': sujeto.colonia,
                'genero': sujeto.genero
            }
        )
    df = pd.DataFrame(rows)

    lat = [19.368894, 19.378639, 19.356536,
           19.352141, 19.376943, 19.351838,
           19.377563, 19.340928, 19.319919,
           19.308241, 19.351663, 19.336423,
           19.350884]

    lon = [-99.005523, -99.107726, -99.101254,
           -99.041698, -99.058977, -99.091929,
           -99.071414, -99.061082, -99.119510,
           -99.066347, -99.010367, -99.050018,
           -98.996826]

    territoriales = ['ACATITLA-ZARAGOZA', 'ACULCO', 'ATLALILCO-AXOMULCO',
                     'AZTAHUACAN', 'CABEZA DE JUAREZ', 'ESTRELLA-HUIZACHEPETL',
                     'LEYES DE REFORMA', 'LOS ANGELES-AGRARISTA', 'LOS CULHUACANES',
                     'SAN LORENZO TEZONCO', 'SANTA CATARINA', 'SANTA CRUZ-QUETZALCOATL',
                     'TEOTONGO-ACAHUALTEPEC']

    dict_map = {'territorial': territoriales, 'lat': lat, 'lon': lon}
    df_alto = df.loc[df['diag2006'] == True]
    df_alto_terr = df_alto.groupby(['territorial']).count().reset_index()
    geopd = pd.DataFrame.from_dict(dict_map)
    geopd['Casos'] = df_alto_terr['identificador']
    #print(geopd.head())

    px.set_mapbox_access_token(
        'pk.eyJ1IjoiZ2ZlbGl4IiwiYSI6ImNrZTNsbnYzMTBraG0zMnFuZXNjOWZhdDgifQ.5sMKH7NQ6_oVyU4oJlcBUw')
    fig = px.scatter_mapbox(geopd, lat="lat", lon="lon", hover_name="territorial",
                            hover_data=["Casos"], size="Casos", color="Casos",
                            zoom=11, width=500, height=300,
                            text="territorial", center={'lat': 19.340928, 'lon': -99.061082})
    fig.update_layout(mapbox_style='outdoors',
                      margin={"r": 0, "t": 0, "l": 0, "b": 0},
                      )

    div = fig.to_html(full_html=False)

    return render_template('stats.html', div_placeholder=div)

这是我的模板(我知道,非常基本,但我需要先显示地图!):

{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
<head>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
</head>
<body>
....some html...

{{ div_placeholder }}

...more html...
</body>

我没有收到有关此的错误消息。该页面仅显示导航栏,其他所有内容均为空。在浏览器中检查源代码,模板似乎没有正确获取地图 div。

<!DOCTYPE html>
<html>
  <head>
    <title>
     DiabetesID
</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Bootstrap -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    
    <nav class="navbar navbar-default">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                

                <a class="navbar-brand" rel="home" href="/index" title="DiabetesID">
                    <img style="max-width:150px; margin-top: -6px;" src="static/img/logo_diabetesid_gray.png">
    </a>

            </div>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    
                    <li><a href="/reporte">Generar reporte</a></li>
                    <li><a href="/territorial">Crear perfil</a></li>
                    <li><a href="/medicion_hb">Mediciones de laboratorio</a></li>
                        <li><a href="/consultar_curp">Consultar perfil</a></li>
                        <li><a href="/about">Acerca de</a></li>
                    <li><a href="/logout">Salir</a></li>
                    
                </ul>
                <ul class="nav navbar-nav navbar-right">
                </ul>
            </div>
        </div>
    </nav>

    
    <link rel="stylesheet" href="/static/css/style.css">
    <link rel="manifest" href="/static/manifest.json">
    <div class="container">
        
        
        

        
        
    </div>



    
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
  </body>
</html>

我错过了什么?我只是一个初学者,而不是正式的程序员或开发人员,所以任何帮助理解我做错了什么都会非常感激。

标签: pythonflaskplotlymapbox

解决方案


你没有描述问题是什么。我不知道您是否在页面或其他内容上收到错误消息或错误数据 - 所以我可以猜测。


我将您的代码减少到可以运行的最小工作代码,我得到的唯一问题是它作为flask不安全HTML的字符串并将其转义并将其作为纯文本放置。我不得不用safe得到预期HTML

{{ div_placeholder | safe }}

最少的工作代码。

我使用render_template_string而不是render_template仅将所有内容放在一个文件中-因此每个人都可以轻松测试此代码。

from flask import Flask, render_template_string
import pandas as pd
import plotly.express as px

app = Flask(__name__)

@app.route('/')
def stats():
    lat = [19.368894, 19.378639, 19.356536,
           19.352141, 19.376943, 19.351838,
           19.377563, 19.340928, 19.319919,
           19.308241, 19.351663, 19.336423,
           19.350884]

    lon = [-99.005523, -99.107726, -99.101254,
           -99.041698, -99.058977, -99.091929,
           -99.071414, -99.061082, -99.119510,
           -99.066347, -99.010367, -99.050018,
           -98.996826]

    territoriales = ['ACATITLA-ZARAGOZA', 'ACULCO', 'ATLALILCO-AXOMULCO',
                     'AZTAHUACAN', 'CABEZA DE JUAREZ', 'ESTRELLA-HUIZACHEPETL',
                     'LEYES DE REFORMA', 'LOS ANGELES-AGRARISTA', 'LOS CULHUACANES',
                     'SAN LORENZO TEZONCO', 'SANTA CATARINA', 'SANTA CRUZ-QUETZALCOATL',
                     'TEOTONGO-ACAHUALTEPEC']

    dict_map = {'territorial': territoriales, 'lat': lat, 'lon': lon}
    geopd = pd.DataFrame.from_dict(dict_map)
    #print(geopd.head())

    px.set_mapbox_access_token('pk.eyJ1IjoiZ2ZlbGl4IiwiYSI6ImNrZTNsbnYzMTBraG0zMnFuZXNjOWZhdDgifQ.5sMKH7NQ6_oVyU4oJlcBUw')

    fig = px.scatter_mapbox(geopd, lat="lat", lon="lon", zoom=11, width=500, height=300,
                            text="territorial", center={'lat': 19.340928, 'lon': -99.061082})

    fig.update_layout(mapbox_style='outdoors', margin={"r": 0, "t": 0, "l": 0, "b": 0})

    div = fig.to_html(full_html=False)

    return render_template_string('''
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>    
</head>
<body>
{{ div_placeholder|safe }}
</body>''', div_placeholder=div)

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

在此处输入图像描述


推荐阅读