I am working on Flask web application, where I am trying to include a Plotly scatter plot as part of two very similar webpages.
- The first page corresponds to a running experiment where an input time is editable, and the plot shows available results from experiment start and up to the current time.
- The second page corresponds to a completed experiment, where the same input fields are shown, now as read-only, and the same plot is done for the entire dataset for that experiment
Given the similarities I use - the same function to create the json code for the graph - same html to define the div where the plot should show
FUNCTION FOR CREATING THE JSON Graph
def CreatePlot(experiment_name):
query=Result.query.filter_by(experiment=experiment_name)
results_df=pd.read_sql_query(query.statement, query.session.bind)
ind=0
color=["#2B4141","#B80C09","#0EB1D2","#8AEA92","#91CB3E","#E3C0D3","#6B2737"]
fig = go.Figure()
buttonslist=[dict(label="All",
method="update",
args=[{"visible": [True]*len(cf.resultlabels),
}])]
for label in cf.resultlabels:
resultslabel=results_df.columns[ind+1]
fig.add_trace(go.Scatter(
x=results_df['runningtime'],
y=results_df[resultslabel],
name=label,
visible=True,
line=dict(color=color[ind])))
visible=[False]*len(cf.resultlabels)
visible[ind]=True
buttonslist.append(dict(label=label,
method="update",
args=[{"visible": visible}]))
ind=ind+1
fig.update_layout(
updatemenus=[go.layout.Updatemenu(active=0,buttons=list(buttonslist))],
xaxis=go.layout.XAxis(title=go.layout.xaxis.Title(text="Time (min)")))
graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
print(graphJSON)
return graphJSON
HTML:
Common html layout file for both webpages includes reference to plotl-latest.min.js and d3.js
{% block head %}
{% block refresh %}{% endblock refresh %}
<script src={{ url_for('static', filename='js/plotly-latest.min.js') }}>
</script>
<script src={{ url_for('static', filename='js/d3.min.js') }}></script>
{% endblock head %}
common code for plot: included in both experimentrun.html and experimentresults.html
{% if plot!=None %}
<div class="chart" id="scatter">
<script>
var graphs = {{plot | safe}};
Plotly.plot('scatter',graphs,{});
</script>
</div>
</div>
{% endif %}
ROUTES:
page for running experiment
@app.route("/experiment/<string:experiment_name>/running",methods=['GET','POST'])
def exprun(experiment_name):
experiment=Experiment.query.filter_by(name=experiment_name).first_or_404()
...
results=Result.query.filter_by(experiment=experiment.name).all()
if results:
#Generate results plot
plot = CreatePlot(experiment.name)
else:
resultform=ResultTableForm()
plot=None
flash(resultform.errors)
flash(form.errors)
return render_template('experimentrun.html', form=form, resultform=resultform, forcesave=forcesave, runningtime=runningtime, plot=plot)
page for completed experiment
@app.route("/experiment/<string:experiment_name>/completed",methods=['GET'])
def expresults(experiment_name):
experiment=Experiment.query.filter_by(name=experiment_name).first_or_404()
...
results=Result.query.filter_by(experiment=experiment.name).all()
if results:
#Generate results plot
plot = CreatePlot(experiment.name)
else:
plot = None
#General
flash(form.errors)
return render_template('experimentresults.html', form=form, plot=plot)
ISSUE:
RUNNING route shows graphs as desired
I get Console error on COMPLETED route (using Chrome): Uncaught ReferenceError: Plotly is not defined
I cannot figure out why it works in one case and not the other.
Any help would be much appreciated