It is very easy and convenient to plot in matplotlib
which is very powerful for plotting. however, if it is mainly for plotting on the local machine. if want to plot online, then other tools should be utilized.
If you want to show your graph online, you need to do these things:
- build your server to let others browse your page
- edit the html page to get the input(parameters) and the output(plots)
- show the html page on your server
Flask
is microframework for python that enables you to build your web pages.
bokeh
is used to plot on the webpage
Here an example of drawing the damping vibration is shown. It needs four input values: amplitude, damping factor, frequency and time interval. On the webpage these will be forms for the user to input from keyboard. After input, submit is needed to submit the input value and plot the graphs.
1. build the web frame with falsk
The structure of the folder for this project is like
--app
--templates
--view.html
--static
--bokeh_in_flask.py
The sample code of bokeh_in_flask.py
is
from flask import Flask, render_template, request
from wtforms import Form, FloatField, validators
from math import pi
from numpy import exp, cos, linspace
import bokeh.plotting as plt
import os, re
class InputForm(Form):
A = FloatField(
label='amplitude (m)', default=1.0,
validators=[validators.InputRequired()])
b = FloatField(
label='damping factor (kg/s)', default=0,
validators=[validators.InputRequired()])
w = FloatField(
label='frequency (1/s)', default=2*pi,
validators=[validators.InputRequired()])
T = FloatField(
label='time interval (s)', default=18,
validators=[validators.InputRequired()])
def damped_vibrations(t, A, b, w):
return A*exp(-b*t)*cos(w*t)
def compute(A, b, w, T, resolution=500):
"""Return filename of plot of the damped_vibration function."""
t = linspace(0, T, resolution+1)
u = damped_vibrations(t, A, b, w)
# create a new plot with a title and axis labels
TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select,lasso_select"
p = plt.figure(title="simple line example", tools=TOOLS,
x_axis_label='t', y_axis_label='y')
# add a line renderer with legend and line thickness
p.line(t, u, legend="u(t)", line_width=2)
from bokeh.resources import CDN
from bokeh.embed import components
script, div = components(p)
head = """
<link rel="stylesheet"
href="http://cdn.pydata.org/bokeh/release/bokeh-0.9.0.min.css"
type="text/css" />
<script type="text/javascript"
src="http://cdn.pydata.org/bokeh/release/bokeh-0.9.0.min.js">
</script>
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
"""
return head, script, div
app = Flask(__name__)
@app.route('/vib3', methods=['GET', 'POST'])
def index():
form = InputForm(request.form)
if request.method == 'POST' and form.validate():
for field in form:
# Make local variable (name field.name)
exec('%s = %s' % (field.name, field.data))
result = compute(A, b, w, T)
else:
result = None
return render_template('view.html', form=form,
result=result)
if __name__ == '__main__':
app.run(debug=True)
2. the html page for input and showing plto
this is the sample code of view.html
. it will get the input and submit(post
method) to the compute
funciton and then plot the graph.
<!DOCTYPE html>
<html lang="en">
<head>
{{ result[0]|safe }}
</head>
<body>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
TeX: {
equationNumbers: { autoNumber: "AMS" },
extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js"]
}
});
</script>
<script type="text/javascript" src=
"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
This web page visualizes the function \(
u(t) = Ae^{-bt}\sin (w t), \hbox{ for } t\in [0,T]
\).
<form method=post action="">
<table>
{% for field in form %}
<tr>
<td class="name">\( {{ field.name }} \) </td>
<td>{{ field(size=12) }}</td>
<td>{{ field.label }}</td>
{% if field.errors %}
<td><ul class=errors>
{% for error in field.errors %}
<li><font color="red">{{ error }}</font></li>
{% endfor %}</ul></td>
{% endif %}
</tr>
{% endfor %}
</table>
<p><input type="submit" value="Compute"></form></p>
<p>
{% if result != None %}
<!-- script and div elements for Bokeh plot -->
{{ result[1]|safe }}
{{ result[2]|safe }}
{% endif %}
</p>
</body>
</html>