feat(matplotlib) Added matplotlib page

This commit is contained in:
Walker Waylon Scott 2017-05-21 10:48:38 -05:00
parent 129e98b383
commit 6bec8d8f25
5 changed files with 494 additions and 8 deletions

View file

@ -1,8 +1,13 @@
import os import os
from flask import Flask, render_template, g, jsonify, request import io
import base64 as b64
from flask import Flask, render_template, g, jsonify, request, redirect
import pandas as pd import pandas as pd
import settings import settings
from random import choice from random import choice
import matplotlib.pyplot as plt
from matplotlib.pyplot import rcParams
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import StringField, SelectField from wtforms import StringField, SelectField
@ -13,20 +18,81 @@ df['Year'] = df['Year'].str[4:].astype(int)
df2 = df.groupby(['Year', 'Nation']).sum().unstack() df2 = df.groupby(['Year', 'Nation']).sum().unstack()
df2.columns = df2.columns.droplevel() df2.columns = df2.columns.droplevel()
nations = df2.columns nations = df2.columns
choices = zip(nations, nations) choices = list(zip(nations, nations))
images = ['mpl/' + nation for nation in df2.columns]
images = list(zip(images, images))
app = Flask(__name__) app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey' app.config['SECRET_KEY'] = 'secretkey'
rcParams['lines.linewidth'] = 1
rcParams["font.family"] = "Tunga"
rcParams['font.size'] = 14
rcParams['axes.labelsize'] = 12
rcParams['xtick.labelsize'] = 12
rcParams['ytick.labelsize'] = 12
rcParams['font.size'] = 14
rcParams['figure.titlesize'] = 18
rcParams['axes.titlesize'] = 18
rcParams['legend.fontsize'] = 12
rcParams['figure.figsize'] = (8, 5)
class MyForm(FlaskForm): class MyForm(FlaskForm):
nation = SelectField('nation', choices=choices) nation = SelectField('nation', choices=choices)
class MplForm(FlaskForm):
nation = SelectField('nation', choices=images)
def hide_spines(ax, alpha=0.4):
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_alpha(alpha)
ax.spines['bottom'].set_alpha(alpha)
def fig_to_html(fig):
"""
converts a matplotlib figure into an html image
@app.route('/', methods=['GET', 'POST']) :param fig: matplotlibe figure object
:returns: STR html string
"""
buf = io.BytesIO()
fig.savefig(buf, format='png')
img = ('data:image/png;base64,{}'
.format(b64.b64encode(buf.getvalue()))
.replace("b'",'')
.replace("'",''))
return img
@app.route('/')
def index(): def index():
global nations return redirect('/home')
@app.route('/home')
def home():
return render_template('home.html')
@app.route('/matplotlib', methods=['GET', 'POST'])
def matplotlib_plot():
form = MyForm()
head_scripts = render_template('chartist_head_scripts.html')
body = render_template('matplotlib.html', form=form)
scripts = render_template('matplotlib.js')
return render_template('home.html',head_scripts=head_scripts, body=body, scripts=scripts)
@app.route('/chartist', methods=['GET', 'POST'])
def chartist():
form = MyForm()
head_scripts = render_template('chartist_head_scripts.html')
body = render_template('chartist.html', form=form)
scripts = render_template('chartist.js')
return render_template('home.html', head_scripts=head_scripts, body=body, scripts=scripts)
@app.route('/chartist1', methods=['GET', 'POST'])
def chartist1():
form = MyForm() form = MyForm()
return render_template('chart.html', form=form) return render_template('chart.html', form=form)
@ -36,6 +102,13 @@ def data(nation):
data = '{' + 'labels:{}, series: {}'.format(df2.index.astype(int).tolist(), df2[nation].astype(float).tolist()) + '}' data = '{' + 'labels:{}, series: {}'.format(df2.index.astype(int).tolist(), df2[nation].astype(float).tolist()) + '}'
return jsonify({'results':df2[nation].astype(float).tolist(), 'labels':df2.index.astype(float).tolist()}) return jsonify({'results':df2[nation].astype(float).tolist(), 'labels':df2.index.astype(float).tolist()})
@app.route('/mpl/<string:nation>')
def mpl(nation):
fig, ax = plt.subplots()
df2[nation].astype(float).plot(ax=ax, color='#D95D39', title=nation + ' population')
hide_spines(ax)
return jsonify({'src': fig_to_html(ax.figure)})
if __name__ == '__main__': if __name__ == '__main__':
port = int(os.environ.get("PORT", 5000)) port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port) app.run(host='0.0.0.0', port=port)

51
app/templates/home.html Normal file
View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
{{ head_scripts | safe}}
<style>
body {margin:0;}
.topnav {
overflow: hidden;
background-color: #1F271B;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: #D95D39;
color: white;
}
</style>
</head>
<body>
<div class="topnav">
<a class="active" href="#home">Home</a>
<a href="/home">Home</a>
<a href="/chartist">Chartist</a>
<a href="/matplotlib">Matplotlib</a>
</div>
{{ body | safe}}
</body>
<script>
{{ scripts | safe}}
</script>
</html>

View file

@ -0,0 +1,21 @@
{% from "_render_field.html" import render_field %}
<h1>Population by Nation</h1><br>
data from
<a href="https://data.world/nrippner/population-by-country1980-2010">data.world</a>
<br><br>
Created with Flask and matplotlib
<span class='nation' value='nation'></span>
<fieldset>
<legend>World Population</legend>
{{ render_field(form.nation) }}
<img src="" name="population">
</div>

View file

@ -0,0 +1,11 @@
function updateChartSrc(){
var nation = $("#nation option:selected").text()
var updatedData = $.get('/mpl/'.concat(nation));
updatedData.done(function(results){
$("img[name=population]").attr("src", results.src)
});
}
$("#nation").on('change', updateChartSrc);

File diff suppressed because one or more lines are too long