如何使用Flask在与表单相同的屏幕上显示生成的matplotlib图像?

时间:2018-04-16 18:50:20

标签: python matplotlib web flask

基本上我使用matplotlib来生成我想要直接显示给用户的图表。用户填写表单,并将变量传递给创建图表的几个方法。我目前拥有的代码只显示图像并删除表单。是否可以在页面上显示图像,以便用户可以修改查询/连接并在每个后续表单提交时查看结果?

这是我的代码:

    from flask import Flask, request, render_template, send_file, redirect, url_for
import flask
import MultipleDatabasesLib as mdl
import subprocess
import pandas as pd
import matplotlib as plt
from matplotlib import pyplot as plt

app = Flask(__name__)

xlabel = ""
ylabel = ""
graph_title = ""

@app.route('/')
def my_form():
    return render_template('my-form.html')


@app.route('/get_form_vals', methods=['POST', 'GET'])
def form_vals():

    df = pd.DataFrame()
    df_group = pd.DataFrame()
    fig_size = plt.rcParams["figure.figsize"]
    fig_size[0] = 15
    fig_size[1] = 12
    plt.rcParams["figure.figsize"] = fig_size
    base = "C:/Python36-32/GraphFactory/Final_csv.csv"

    conn1 = flask.request.args.get('conn1')
    conn2 = flask.request.args.get('conn2')
    sql1 = flask.request.args.get('sql1')
    sql2 = flask.request.args.get('sql2')
    charttype = flask.request.args.get('charttype')
    xlabel = flask.request.args.get('xLabel')
    ylabel = flask.request.args.get('yLabel')
    groupBy = flask.request.args.get('groupBy')

    #graph_title = charttype + "Chart"
    mdl.gen_csv(conn1, conn2, sql1, sql2)
    df = pd.read_csv(base)
    df_group = df.groupby(['YR', 'INSTANCE']).size()


    if charttype == "bar":
        mdl.bar_plot(xlabel, ylabel, 'Plot', df_group)

    elif charttype == "pie":
        mdl.pie_plot(xlabel, ylabel, 'Plot', df_group)

    elif charttype == "line":
        mdl.line_plot(xlabel, ylabel, 'Plot', df_group)

    elif charttype == "hist":
        mdl.hist_plot(xlabel, ylabel, 'Plot', df_group)

    #return send_file("plt.png", mimetype='image/gif')
    return flask.jsonify({"result":"<div class='user_avatar' style='background-image:url('/static/images/figure.png');width:240px;height:240px;background-size:cover;border-radius:10px;'>"})


app.run(host='0.0.0.0', port=33)

HTML:

    <!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="/static/my-css.css">
<head>
    <meta charset="UTF-8">
    <title>Graph Factory</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>

<table class="headerTable" background="https://crunchify.com/bg.png"  width="100%">
    <tr>
        <td width="95%"><img src="static/SEILogo.png" /></td>
    </tr>
</table>


    <table style="width:50%" class="inputForm" align="center" cellspacing="0">
        <tr>
            <th>
                Connection
            </th>
            <th>
                Query
            </th>
        </tr>
        <tr>
            <td align="center">
                <input type="text" name="conn1" id="conn1"/>
            </td>
            <td align="center">
                <textarea name="sql1" cols="70" rows="8" id="sql1"></textarea>
            </td>
        </tr>
        <tr>
            <td align="center">
                <input type="text" name="conn2" id="conn2"/>
            </td>
            <td align="center">
                <textarea name="sql2" cols="70" rows="8" id="sql2"></textarea>
            </td>
            {#<td align="left">
                <a href="">Export CSV</a>
            </td>#}
        </tr>
        <tr class="top row">
            <td align="center">
                <label>X-axis Label</label>
            </td>
            <td align="center">
                <input type="text" name="xLabel" id="xLabel"/>
            </td>
        </tr>
        <tr>
            <td align="center">
                <label>Y-axis Label</label>
            </td>
            <td align="center">
                <input type="text" name="yLabel" id="yLabel"/>
            </td>
        </tr>
        <tr>
            <td align="center">
                <label>Group by Parameter</label>
            </td>
            <td align="center">
                <input type="text" name="groupBy" id="groupBy"/>
            </td>
        </tr>
        <tr>
            <td align="center">
                <label>Graph Type</label>
            </td>
            <td align="center">
                <select name="charttype" id="dropdownchart">
                  <option value="bar">Bar</option>
                  <option value="pie">Pie</option>
                  <option value="line">Line</option>
                  <option value="hist">Hist</option>
                </select>
            </td>
        </tr>
        <tr>
            <td colspan="20" align="center">
                <button type='button' class='get_result'>Show Graph</button>
            </td>
        </tr>
    </table>

 <div id='image_location'></div>
 <script>
   $(document).ready(function() {
      $('.get_result').click(function(){
         var conn1 = $('#conn1').val();
         var conn2 = $('#conn2').val();
         var sql1 = $('#sql1').val();
         var sql2 = $('#sql2').val();
         var xlabel = $('#xLabel').val();
         var ylabel = $('#yLabel').val();
         var groupBy = $('#groupBy').val();
         var dropdownchart = $('#dropdownchart').val();
         $.ajax({
       url: "/get_form_vals",
      type: "get",
      data: {conn1: conn1, conn2:conn2, sql1:sql1, sql2:sql2, xlabel:xlabel, ylabel:ylabel,
          groupBy:groupBy, dropdownchart:dropdownchart},
      success: function(img) {
        $("#image_location").html(img.result);
    },
      error: function(xhr) {
        print("error")
      }
      });
     });
   });
 </script>

</body>
</html>

1 个答案:

答案 0 :(得分:0)

您必须将flaskajax一起使用。为此,您需要创建一个单独的路径来创建图形,保存文件,并返回带有图像链接的HTML。下面是一个略微缩短的解决方案,展示了如何做到这一点。确保您创建了static/images目录,static与应用程序文件夹中的templates/处于同一级别:

main_app.py中的

import matplotlib.pyplot as plt
import flask
app = flask.Flask(__name__

@app.route('/', methods=['GET'])
def home():
 return render_template('my-form.html')

@app.route('/get_form_vals')
def form_vals():
  conn1 = flask.request.args.get('conn1')
  conn2 = flask.request.args.get('conn2'])
  #rest of vals follow
  plt.plot(x, y) #formulate your x, y values before
  plt.savefig('/app/static/images/filenameXYZ.png') #save to the images directory
  return flask.jsonify({"result":"<div class='user_avatar' style='background-image:url('/static/images/figure.png');width:240px;height:240px;background-size:cover;border-radius:10px;'>"})

然后,在my-form.html

<html>
  <head>
         <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  </head>
  <input type='text' id='conn1'>
  <input type='text' id='conn2'> 
  <!--rest of inputs follow -->
 <button type='button' class='get_result'></button>
 <div id='image_location'></div>
 <script>
   $(document).ready(function() {
      $('.get_result').click(function(){
         var conn1 = $('#conn1').val();
         var conn2 = $('#conn2').val();
         //get the rest of the vals
         $.ajax({
       url: "/get_form_vals",
      type: "get",
      data: {conn1: conn1, conn2:conn2}, //fill out rest of object
      success: function(response) {
       $("#image_location").html(response.message);
      },
      error: function(xhr) {
        //Do Something to handle error
      }
      });
     });
   });
 </script>

</html>