Plotly.offline plot output_type = 'div' не работает внутри HTML - Как встроить Plotly в HTML - PullRequest
0 голосов
/ 08 мая 2020

Я создал простое приложение Flask, которое отображает шаблон index. html, и в этом HTML я пытаюсь перечислить различные графики как своего рода веб-страницу в стиле приборной панели с другим контентом. Я знаю основы Flask и Da sh, хотя я не использую Da sh, поскольку я хочу иметь больший контроль над HTML / CSS, следовательно, используя Flask для создания веб-сайта для встраивания графиков с помощью Plotly .

До сих пор мне не везло ни с какой официальной документацией, ни с medium.com, ни с подобными статьями. Ближайший, к которому я пришел, - это ответ: Встраивание da sh графиков в html

Однако он не работает, когда я запускаю свое приложение и браузер запускается в localhost. Вместо этого он просто дает мне много текста, который явно является графиком, но он не превращается в график.

Вот все мои py / html / css, даже если на панели навигации нет t актуально; на всякий случай (я все еще учусь, поэтому уверен, что найдутся более эффективные способы сделать что-то ...)

Спасибо за любую помощь.

Класс DataFrame, который собирает последние данные о коронавирусе и возвращается как pandas .dataframe:

import pandas as pd
import requests


    class DataFrame:
        """
        Class which grabs the data live from the ECDC and returns it in a pandas dataframe
        """

        def __init__(self):
            """
            Creating the pandas dataframe of the ECDC JSON data
            """
            self.url = "https://opendata.ecdc.europa.eu/covid19/casedistribution/json"
            self.file = requests.get(self.url).json()
            self.file = self.file['records']
            self.df = pd.DataFrame(data=self.file)

        def converter(self):
            """
            Converting the dtypes from object to int for ints, and date to date
            Also renames the columns to more visual-friendly names
            :return: None
            """
            self.df['cases'] = self.df['cases'].astype(int)
            self.df['deaths'] = self.df['deaths'].astype(int)
            self.df['popData2018'] = self.df['popData2018'].astype(str).replace('', 0).astype(int)
            self.df['dateRep'] = self.df['dateRep'].to_timestamp
            cols_rename = 'date day month year cases deaths country geo_id country_id population continent'.split()
            cols_rename = [s.capitalize() for s in cols_rename]
            self.df.columns = cols_rename

        def return_df(self):
            """
            :return: pandas DataFrame
            """
            self.converter()
            return self.df

app.py

from plotly.offline import plot
import plotly.graph_objects as go
from dataframe.dataframe import DataFrame
from flask import Flask, render_template, redirect, request, url_for

app = Flask(__name__)


def graph_maker():
    df = DataFrame().return_df()
    data = []

    for continent in df['Continent'].unique():
        df_filt = df[df['Continent'] == continent]
        data.append(go.Scatter(x=df_filt["Cases"],
                               y=df_filt["Deaths"],
                               mode='markers',
                               text=df_filt['Country'],
                               name=continent))

    layout = go.Layout(title="Deaths (Y) v Cases (X) by continent")

    fig = go.Figure(data=data, layout=layout)

    return plot(figure_or_data=fig,
                include_plotlyjs=False,
                output_type='div')


@app.route('/')
def index():
    graph = graph_maker()
    return render_template('index.html',
                           graph=graph)


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

index. html

{% extends "navbar.html" %}
<head>
    <meta charset="UTF-8">
    <link type="text/css" rel="stylesheet" href="..\static\master.css">
    <link href="https://fonts.googleapis.com/css2?family=Maven+Pro&display=swap" rel="stylesheet">
    <!-- Plotly.js -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

</head>
{% block nbar %}
<body>
<div class="global-box" id="global-stats">
    <h1>Global charts</h1>
    <p>Title here</p>
    <ul class="global-box-ul">
        <li class="global-box-ul-li">
            {{ graph }}
        </li>
        <li class="global-box-ul-li">
            Another chart here
        </li>
    </ul>
</div>
</body>
{% endblock %}

navbar. html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>C19DB</title>
    <meta charset="UTF-8">
    <link type="text/css" rel="stylesheet" href="..\static\master.css">
    <link href="https://fonts.googleapis.com/css2?family=Maven+Pro&display=swap" rel="stylesheet">
</head>

<nav class="navbar">
    <div class="logo">c19db</div>
    <div class="list">
    <ul class="navbar_items">
       <li class="navbar_item"><a href="#">Dashboard</a></li>
       <li class="navbar_item"><a href="#">About</a></li>
       <li class="navbar_item"><a href="#">Register</a></li>
    </ul>
    </div>
</nav>

{% block nbar %}

{% endblock %}
</html>

мастер. css

html, body {
    font-family: 'Maven Pro';
    height: 700px;
    margin: 0;
}

.navbar {
    background: rgb(237, 232, 232);
    vertical-align: middle;
}

.logo {
    vertical-align: middle;
    display: inline-block;
    color: rgb(196, 69, 69);
    font-size: 50px;
    width: 250px;
    padding: 5px 15px 5px 15px;
}

.list{
    vertical-align: middle;
    display: inline-block;
    width: calc(100% - 285px);
    text-align: right;
}

.navbar_items {
    list-style: none;
    font-size: 20px;
    color: rgb(61, 61, 61)
}

.navbar_item{
    display: inline-block;
    padding: 5px 15px 5px 15px;
}

a {
    text-decoration: none;
}

.navbar_item > a{
    display: inline-block;
    padding: 5px 15px 5px 15px;
    color: rgb(61, 61, 61);
}

.navbar_item > a:hover {
    display: inline-block;
    padding: 5px 15px 5px 15px;
    color: rgb(196, 69, 69);
}

.footer, .footer a {
    position: relative;
    background: rgb(237, 232, 232, 0.2);
    width: 100%;
    color: rgb(61, 61, 61, 0.2);
    text-align: center;
}

span {
    font-weight: bold;
}

.global-box {
    text-align: center;
    border: 2px black solid;
    list-style: none;
    margin: auto;
}

.global-box > h1, .global-box > p {
    margin: 1px;
}

ul {
    display: contents;
}

.global-box-ul-li {
    display: inline-block;
    border: 2px lightblue solid;
    list-style: none;
    margin: auto;
    width: 48%;
    height: 100%;
}

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 26 июля 2020

Я решил эту проблему.

Краткое описание:

  1. Создать диаграмму
  2. Вызов pyo.plot() как обычно, проходя через рис, output_type='div' и include_plotlyjs=False
  3. Пропустите этот вывод в переменную через Markup() (импорт из flask)
  4. Передайте Markup(variable) через render_template, как через форму
  5. Сделайте рендеринг переменной в html с помощью {{ jinja template }}

Сначала создайте диаграмму Plotly как обычно. Я не буду приводить полный пример, а только ключевые моменты. Я создаю диаграммы в функциях для импорта и использования при необходимости на нескольких страницах. В этом случае это необходимо, потому что диаграмма должна быть назначена переменной.

def my_bar_chart():
    *snip irrelevant*
    my_bar_chart = pyo.plot(fig, output_type='div', include_plotlyjs=False)
    return Markup(my_bar_chart)

Теперь импортируйте свою функцию в свой app.py /, где бы ни находились ваши представления, и передайте ее через шаблон рендеринга, как и любую форму , например.

Вот пример:

def my_page():
return render_template('my_page.html',
                        bar_chart_1=my_bar_chart)

Затем на html для этой страницы просто пропустите bar_chart_1 в шаблоне jinja, например:

{{ bar_chart_1 }}

Готово.

...