1. 程式人生 > >numpy pandas matplotlib和django結合,將matplotlib圖片顯示到HTML上

numpy pandas matplotlib和django結合,將matplotlib圖片顯示到HTML上

首先進行效果展示:

Django檔案佈局:

views.py

from django.shortcuts import render,HttpResponse
from app1 import BPLackAnalysis
import pandas as pd
import matplotlib.pyplot as plt
import base64
from io import BytesIO

def multiChart(data,sigma_spec):
    plt.figure(figsize=(12,9))
    plt.subplot(311)
    plt.title("CTC Array FAB H3PO4 Monitor for BP Lack")
    plt.plot(data["time"],data["mean"],color="b",marker="*")
    plt.subplot(312)
    data["slope_spec"]=0
    plt.title("$mean{(y2-y1)}$")
    plt.plot(data["time"],data["slope"],color="b")
    plt.plot(data["time"],data["slope_spec"],color="r")
    plt.subplot(313)
    data["sigma_spec"]=sigma_spec
    plt.title("3$sigma$")
    plt.plot(data["time"],data["3sigma"],color="b")
    plt.plot(data["time"],data["sigma_spec"],color="r")
    buffer = BytesIO()
    plt.savefig(buffer)
    plot_data = buffer.getvalue()
    return plot_data

def aaa():
    pass

def index(request):
    if request.method=="POST":
        group_num = 120
        sigma_spec = 0.5
        file_in_path = request.POST.get("file_in_path")
        file_out_path = request.POST.get("file_out_path")
        group_num = request.POST.get("group_num")
        sigma_spec = request.POST.get("sigma_spec")
        print(file_in_path)
        print(group_num)
        try:
            in_file = pd.read_excel(file_in_path)
            print("123")
            data = BPLackAnalysis.dataArrange(in_file,int(group_num))
            data["time"] = data["time"].astype(str)
            print(data.head())
            #將matplotlib圖片轉換為HTML
            plot_data = multiChart(data,sigma_spec)
            imb = base64.b64encode(plot_data)#對plot_data進行編碼
            ims = imb.decode()
            imd = "data:image/png;base64,"+ims
            #iris_im = """<img src="%s">""" % imd
            temp_time = []
            temp_H3PO4 = []
            cnt=0
            for i in range(len(data["slope"])-3):
                if data["slope"][i] < 0 and data["slope"][i+1] < 0 and data["slope"][i+2] < 0:
                    cnt+=1
                    temp_time.insert(0,data["time"][i+2])
                    #只保留兩位小數
                    temp_H3PO4.insert(0,round(data["mean"][i+2],2))
                    i+=3
            # 儲存清洗後資料
            data.to_excel(file_out_path, sheet_name="data")
            print("OK",temp_time,cnt)
            return render(request, "bplack.html",{"img":imd,"temp_time":temp_time,"cnt":cnt,"temp_H3PO4":temp_H3PO4})
        except:
            ret= "檔案讀取失敗,請確認檔案路徑是否正確!"+r"正確格式示範:C:\Users\raylu\Desktop\ArrayBP\BPLack.xlsx"
            return HttpResponse(ret)
    else:
        return render(request, "index.html")

 

BPLackAnalysis.py

import numpy as np
import pandas as pd
import xlrd
import datetime
import matplotlib.pyplot as plt

#資料清洗,num為定義母數
def dataArrange(data,num):
    new_data = pd.DataFrame({"time":data["start"],"mean":data["mean"]})
    ls1,ls2,ls3,ls4 = [],[],[],[]
    len_data = len(new_data["time"])
    for i in range(0,int(len_data/num)):
        ls1.insert(0,new_data["time"][len_data-1-i*num])
        #H3PO4 mean
        ls2.insert(0,new_data["mean"][(len_data-1-(i+1)*num):(len_data-1-i*num)].mean())
        #H3PO4 mean: this - last
        if i == 0:
            ls3.insert(0,0)
        else:
            ls3.insert(0,ls2[1]-ls2[0])
        #3 sigma
        ls4.insert(0,new_data["mean"][(len_data-1-(i+1)*num):(len_data-1-i*num)].std()*3)
    return pd.DataFrame({"time":ls1,"mean":ls2,"slope":ls3,"3sigma":ls4})

#時間轉換
def timeTrans(data):
    data["time"] = data["time"].apply(
        lambda x:datetime.datetime.strptime(
            x[0:4]+"-"+x[4:6]+"-"+x[6:8]+" "+x[8:10]+":"+x[10:12]+":"+x[12:14],
            "%Y-%m-%d %H:%M:%S")
    )
    return data

#多圖繪製
def multiChart(data,sigma_spec):
    plt.figure(figsize=(12,10))
    plt.subplot(311)
    plt.title("CTC Array FAB H3PO4 Monitor for BP Lack")
    plt.plot(data["time"],data["mean"],color="b",marker="*")
    plt.subplot(312)
    data["slope_spec"]=0
    plt.title("$mean{(y2-y1)}$")
    plt.plot(data["time"],data["slope"],color="b")
    plt.plot(data["time"],data["slope_spec"],color="r")
    plt.subplot(313)
    data["sigma_spec"]=sigma_spec
    plt.title("3$sigma$")
    plt.plot(data["time"],data["3sigma"],color="b")
    plt.plot(data["time"],data["sigma_spec"],color="r")
    return plt

if __name__ == "__main__":
    file = r"C:\Users\mayn\Desktop\ArrayBP\BPLack.xlsx"
    read_file = pd.read_excel(file)
    print(read_file.head())
    data = dataArrange(read_file,120)
    print(data.head())
    data["time"] = data["time"].astype(str)
    # data = timeTrans(data)
    # print(data.head())
    #輸出清洗後資料
    file_path=r"C:\Users\mayn\Desktop\ArrayBP\new_data.xlsx"
    data.to_excel(file_path,sheet_name="data")
    multiChart(data,0.5)

 

index.html

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! -->
    <title>CTC Array FAB H3PO4監控系統</title>

    <!-- Bootstrap -->
    <link href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim 和 Respond.js 是為了讓 IE8 支援 HTML5 元素和媒體查詢(media queries)功能 -->
    <!-- 警告:通過 file:// 協議(就是直接將 html 頁面拖拽到瀏覽器中)訪問頁面時 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
      <script src="https://cdn.jsdelivr.net/npm/
[email protected]
/dist/html5shiv.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dest/respond.min.js"></script> <![endif]--> </head> <body class="container text-center"> <h3>歡迎使用CTC Array FAB H3PO4監控系統,首先進行您的資料配置</h3> <p> <form action="/index.html/" method="post"> {% csrf_token %} <table class="table"> <tr> <td class="col-md-3">原始檔案路徑</td> <td class="col-md-9" style="text-align: left"><input type="text" name="file_in_path" style="width: 600px;" placeholder="C:\Users\raylu\Desktop\ArrayBP"></td> </tr> <tr> <td class="col-md-3">輸出檔案路徑</td> <td class="col-md-9" style="text-align: left"><input type="text" name="file_out_path" style="width: 600px;" placeholder="C:\Users\raylu\Desktop\ArrayBP"></td> </tr> <tr> <td class="col-md-3">group筆數</td> <td class="col-md-9" style="text-align: left"><input type="number" name="group_num" style="width: 600px;" placeholder="120"></td> </tr> <tr> <td class="col-md-3">sigma_spec</td> <td class="col-md-9" style="text-align: left"><input type="number" step="0.1" name="sigma_spec" style="width: 600px;" placeholder="0.5"></td> </tr> </table> <p><input type="reset" value="重置">&nbsp;<input type="submit" value="提交配置"></p> </form> </p> <!-- jQuery (Bootstrap 的所有 JavaScript 外掛都依賴 jQuery,所以必須放在前邊) --> <script src="/static/js/jquery-3.3.1.min.js"></script> <!-- 載入 Bootstrap 的所有 JavaScript 外掛。你也可以根據需要只加載單個外掛。 --> <script src="/static/plugins/bootstrap/js/bootstrap.min.js"></script> </body> </html>

 

bplack.html

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! -->
    <title>CTC Array FAB H3PO4監控系統</title>

    <!-- Bootstrap -->
    <link href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim 和 Respond.js 是為了讓 IE8 支援 HTML5 元素和媒體查詢(media queries)功能 -->
    <!-- 警告:通過 file:// 協議(就是直接將 html 頁面拖拽到瀏覽器中)訪問頁面時 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html5shiv.min.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dest/respond.min.js"></script>
    <![endif]-->
  </head>
  <body class="container text-center">

  <h4>歡迎使用<span style="color: blue; font-size: 30px">CTC Array FAB H3PO4</span>監控系統,
      <a onclick="show_persons(this)">本案技術支援人員:</a></h4>
        <table class="table table-hover table-striped" id="persons">
            <thead class="info">
                <td>No</td>
                <td>Dept.</td>
                <td>Name</td>
                <td>Tele</td>
                <td>email</td>
            </thead>
            <tbody>
                <tr class="warning">
                    <td class="col-md-1">1</td>
                    <td class="col-md-2">QA/QS</td>
                    <td class="col-md-2">王玉</td>
                    <td class="col-md-2">12345</td>
                    <td class="col-md-5">[email protected]</td>
                </tr>
                <tr class="info">
                    <td>2</td>
                    <td>CF/INSP</td>
                    <td>路XX</td>
                    <td>12345</td>
                    <td>[email protected]</td>
                </tr>
            </tbody>
        </table>
        {% if cnt >= 1 %}
        <h4 style="text-align: left">
            連續3筆資料mean(y2-y1)<0筆數:
            <span style="color: red; font-size: 30px">{{ cnt }}</span>&nbsp;
            最近一筆發生時間:
            <span style="color: red; font-size: 20px">{{ temp_time.0 }}</span>&nbsp;
            H3PO4值為:
            <span style="color: red; font-size: 20px">{{ temp_H3PO4.0 }}</span>&nbsp;
            請立即確認是否有異常!</h4>
        {% endif %}
    <p>
        <img src="{{ img }}">
    </p>
    <!-- jQuery (Bootstrap 的所有 JavaScript 外掛都依賴 jQuery,所以必須放在前邊) -->
    <script src="/static/js/jquery-3.3.1.min.js"></script>
    <!-- 載入 Bootstrap 的所有 JavaScript 外掛。你也可以根據需要只加載單個外掛。 -->
    <script src="/static/plugins/bootstrap/js/bootstrap.min.js"></script>
    <script>
        function show_persons(ths){

            if ($("#persons").css("display")=="none"){
                $("#persons").show();
            }else{
                $("#persons").hide();
            }
        }
    </script>
  </body>
</html>