散景图 Hovertool 在测试中工作,但相同的代码在 Flask 应用程序中不起作用

Bokeh plot Hovertool working in test, but same code doesn't work in Flask app

我一直在尝试将 Bokeh 图合并到我的 Flask 网络应用程序中,并遇到 运行 问题,我的图在呈现为 html 文件时工作正常,但显示 ???在我的 Flask 应用程序中 运行ning 时在 Hovertool 中。其余情节正常。

起初,我认为我的 html 文件如何呈现情节有问题,但后来我注意到如果我重组我的代码并 运行 它直接在 Sublime 中而不是开始我的应用程序和页面中的 运行,我遇到了同样的问题。奇怪的是,如果我将所有内容都保存在一个 .py 文件中而不导入,那么该图将作为一个独立的 .html 文件正常工作。我宁愿不这样做是为了让我的代码更易于管理,因为我将生成大量图表。下面是我的文件代码。如果您在我导入的方式中看到的某些内容会导致 state_trend_month_mean() method/function.

中出现问题,请告诉我

此外,一旦我开始工作,我将把我的绘图格式移动到它自己的函数中。对不起,糟糕的代码。还在学习。另一件事,由于类似的问题,我正在将我的 df 转换为字典,这是我能够正确渲染绘图的唯一方法。我敢肯定这是因为我缺乏经验。

这是我生成图表的代码。 final_df.two_year_df() 是从另一个 .py 返回和导入的数据框。工具提示 @nti_per_day 是 df/dict 中的一列,但散景显示为 ???在悬停工具中

import pandas as pd
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, FactorRange, Label, Title, NumeralTickFormatter, BasicTickFormatter
from bokeh.models.tools import HoverTool
from bokeh.models.tickers import MonthsTicker
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.layouts import widgetbox, column
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
from vgt_web_app.final_df import FinalDF as final_df
from math import pi


class Graphs():

    def state_trend_month_mean():
        df = final_df.two_year_df()
        dict_1 = df.groupby(['month_year'], as_index=False).sum().to_dict('list')
        y_max = max(dict_1['nti_per_day_yoy']) * 1.1
        y_min = y_max * -.25

        source = ColumnDataSource(data=dict(dict_1))

        tooltips = [("Daily NTI", "@nti_per_day")]

        tools_to_show = 'pan,box_zoom, wheel_zoom,save,reset'
        p = figure(plot_width=600, plot_height=300, x_axis_type="datetime", name="bar1", sizing_mode='scale_both',
                             toolbar_location='below', toolbar_sticky=False, tools=tools_to_show, y_range=(y_min, y_max))
        p.vbar(x='month_year', top='nti_per_day_yoy', width=1800000000, source=source, color='#5886a5')

        p.title.text = 'Year over Year (YoY) - State Avg NTI Trend'
        p.xaxis.axis_label = 'Month/Year'
        p.yaxis.axis_label = 'Avg NTI YoY'
        p.xaxis.major_label_orientation = pi/4
        p.xaxis.ticker = MonthsTicker(months=list(range(1,13)))
        p.xaxis.fixed_location = 0
        p.yaxis.formatter = NumeralTickFormatter(format='[=10=],0')
        p.background_fill_alpha = 0.80
        p.xgrid.grid_line_color = None
        p.ygrid.grid_line_color = None
        p.add_tools(HoverTool(tooltips=tooltips, mode='mouse'))
        return(p)

这是routes.py

from flask import render_template, request, Blueprint
from bokeh.embed import components
from vgt_web_app.graphs import Graphs as graphs

reports = Blueprint('reports', __name__)

@reports.route('/reports')
def il_reports():
    g = graphs.state_trend_month_mean()
    # graph_data = g
    graph_data = g
    script, div = components(graph_data)
    return render_template('reports.html', title='Reports', graph_data=graph_data, script=script, div=div)

这里是html。仍然是基本的,一旦我能正确显示这个情节就会改进

{% extends "layout.html" %}
{% block content %}
<!DOCTYPE html>
<html lang="en">

<script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/2.1.1/bokeh.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/2.1.1/bokeh-widgets.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bokeh/2.1.1/bokeh-tables.min.js"></script>

<body>
    <h1>Reports</h1>

    {{ div | safe }}
    {{ script | safe }}


</body>

{% endblock content %}

同样,图表具有所有功能,除了它有 ???在悬停

看到 ??? 仅表示一件事:您在工具提示中指定的列名在 ColumnDataSource 中不存在。考虑到您在问题中指定了一个列名称:

@nti_per_day_yoy is a column in the df/dict

但在实际代码中您指定的内容略有不同:

tooltips = [("Daily NTI", "@nti_per_day")]

最可能的解释是您在工具提示中提供了错误的列名称。