【Python使用笔记】——Pyxley 包下的Dashboard开发

by. Zhang.J

本文简介

本篇将基于Python开源的Pyxley包,从MySQL数据库读取信息,并将数据以线图(ploty)的形式展示出来。

Pyxley是基于Flask框架开发的开源的Web Dashboard平台,包下集成多种数据可视化模块。不用书写复杂的JS、HTML和CSS就能通过调用Python接口实现一个Web应用。官方网站()给出了详细的说明并给出了一个线图(ploty)的例子,但由于给的是代码段且有部分有Bug,于是我从Github开源站()下载了源码包,并对源码包中的Example做了解读。


正文

一、MySQL连接及数据收集

import MySQLdb as mysql
import pandas as pd

# 建立 sql链接
conn = mysql.connect(host="172.17.11.188",user="root",passwd="root",db="wind_analysis")
sql = conn.cursor()
# 获取表为DataFrame
sql.execute('select FARM_NAME,FAN_TYPE,FAN_NO,DATA_DATE,WIND_SPEED,AC_POWER from pcbin_month')
rows = sql.fetchall()
df = pd.DataFrame([[ij for ij in i] for i in rows])
df.rename(columns={0:'farm',1:'type',2:"no",3:"date",4:"windspeed",5:"power"},inplace=True)
二、Pyxley  example 下的 ploty案例解读

 1.案例概述

【Python使用笔记】——Pyxley 包下的Dashboard开发_第1张图片

example下的ploty文件目录

 前文提到Pyxley是基于Flask开发的,所有工程必有两个核心文件

 __init__.py :初始化应用,需要再此声明应用目录,数据来源等核心设置

 buildui.py  :应用的UI设计,在这里通过调用Flask和Pyxley的接口实现将初始化

             类传来的数据可视化(下图为数据预览)

 【Python使用笔记】——Pyxley 包下的Dashboard开发_第2张图片

 2.案例代码解读

 __init__.py

from os import path
from buildui import get_layouts
from pyxley.utils import create_app, default_static_path, default_template_path

# create the flask app
# #获取文件路径
here = path.abspath(path.dirname(__file__))
# #调用Pyxley接口创建应用
app = create_app(here, default_static_path(), default_template_path())

# build the layout
# #调用buildui.py的自定义方法,将依赖的应用、数据文件传入
get_layouts(app, here+"/fitbit_data.csv")

if __name__ == "__main__":
    app.run(debug=True)
 buildui.py

from pyxley.charts.plotly import PlotlyAPI
from pyxley.filters import SelectButton
from pyxley import UILayout, register_layouts
import pandas as pd

from flask import jsonify, request

def make_ui(filename):
    df = pd.read_csv(filename)

    # Make a UI
    # #新建 UI模板
    ui = UILayout("FilterChart")

    # Read in the data and stack it, so that we can filter on columns
    # 将 Date作为 Index 方便按其余列拆分
# 实现以Date为X轴
 以其他任意列为Y轴  
    _stack = df.set_index("Date").stack().reset_index()
    _stack = _stack.rename(columns={"level_1": "Data", 0: "value"})

    # Make a Button
    # 按钮选项集
    cols = [c for c in df.columns if c != "Date"]
    # SelectButton(按钮默认填充,标签元素,标签别名(底层 API会用),默认选择)
    btn = SelectButton("Data", cols, "Data", "Steps")

    # add the button to the UI
    # 按钮置入UI
    ui.add_filter(btn)

    # 初始选择的按钮 {按钮名:按钮某个选项}
    init_params = {"Data": "Steps"}

    # 根据按钮选项调整数据集 返回实现线性接口
    def get_data():
        args = {}
        # 调用Flask的 request实现获取页面选项参数
        for c in init_params:
            if request.args.get(c):
                args[c] = request.args[c]
            else:
                args[c] = init_params[c]
        return jsonify(
            # 实现线性接口(输入的 DF,元组型列值对应的列表,界面类型,属性参数)
            PlotlyAPI.line_plot(
                PlotlyAPI.apply_filters(_stack, args),
                [("Date", "value")],
                "lines+markers",
                {}
            ))

    # 创建 plot接口型(ChartId,URL链接,初始化时执行的方法,初始化参数)
    _plot = PlotlyAPI(
        "plotly_chart",
        "/api/plotly_line_plot/",
        get_data,
        init_params=init_params
    )
    ui.add_chart(_plot)
    return ui


def get_layouts(mod, filename):

    # plotly
    # 调用 make_ui(数据文件)
    plotly_ui = make_ui(filename)
    # UI适用于APP(APP)
    plotly_ui.assign_routes(mod)
    # 获取属性
    plotly_props = plotly_ui.build_props()
    # 创建界面 类型:{UI属性,标题}
    _layouts = {
        "plotly": {
            "layout": [plotly_props],
            "title": "Plotly"
        }
    }
    # 返回注册好的界面
    register_layouts(_layouts, mod)
运行__init__.py 进入localhost:5000查看

【Python使用笔记】——Pyxley 包下的Dashboard开发_第3张图片

3.自己应用

 数据预览

【Python使用笔记】——Pyxley 包下的Dashboard开发_第4张图片

  



需求简介:通过选择FARM_NAME、FAN_TYPE、FAN_NO、DATA_DATE

将对应的WIND_SPEED--AC_POWER图画出来。

可以看出,案例给的相当于“一个X对应多个Y,通过Y标签确定Y”,

但这个需求是“多个属性确定一组对应的XY”。于是我将问题

转化为“多个X对应多组Y,通过属性标签确认X”


 __init__.py

 这里我采用从MySQL数据库中读取数据,并直接以Data Frame的格式扔给buildui.py

# -coding:utf-8
from os import path
from buildui import get_layouts
import MySQLdb as mysql
import pandas as pd
from pyxley.utils import create_app, default_static_path, default_template_path

# 建立 Flask 类型APP
# 获取文件路径
here = path.abspath(path.dirname(__file__))
# 创建 APP(项目路径,默认路径,默认缓存路径)
app = create_app(here, default_static_path(), default_template_path())

# 建立 sql链接
conn = mysql.connect(host="172.17.11.188",user="root",passwd="root",db="wind_analysis")
sql = conn.cursor()
# 获取表为DataFrame
sql.execute('select FARM_NAME,FAN_TYPE,FAN_NO,DATA_DATE,WIND_SPEED,AC_POWER from pcbin_month')
rows = sql.fetchall()
df = pd.DataFrame([[ij for ij in i] for i in rows])
df.rename(columns={0:'farm',1:'type',2:"no",3:"date",4:"windspeed",5:"power"},inplace=True)


# 获取界面(APP,数据文件)
get_layouts(app, df)

if __name__ == "__main__":
    print here
    app.run(debug=True)
 buildui.py

#- coding:utf-8
from pyxley.charts.plotly import PlotlyAPI
from pyxley.filters import SelectButton
from pyxley import UILayout, register_layouts
import pandas as pd
import json

from flask import jsonify, request,session

# 自定义过滤数据矩阵方法,来根据属性筛选对应的XY,而不使用它自己的Filter
def dataFilter(data,filters):
    rel = data[(data.farm==filters.get("farm"))&
               (data.type==filters.get("type"))&
               (data.no == filters.get("no"))&
               (data.date == filters.get("date"))]
    rel = rel.sort_values(by="windspeed",ascending=True)
    return rel

# 创建 UI 
def make_ui(DF):
    # # # 数据层==============================================================================================
    # 数据读入
    df = DF
    # 将 Date作为 Index 方便按其余列拆分 
    # 这里将X和X的属性列 测试风场 GW50-750 WT02287 2015-10-01 一起作为Index
    _stack = df.set_index(["windspeed","farm","type","no","date"]).stack().reset_index()
    # 改个名
    _stack = _stack.rename(columns={"level_5": "Data", 0: "value"})

    # # # UI层=================================================================================================
    # 新建 UI模板
    ui = UILayout("FilterChart")

    # # 制作按钮选项-------------------------------------------------------------------------------------------
    # 按钮选项集
    cols1 = list(set(_stack.farm))
    cols2 = list(set(_stack.type))
    cols3 = list(set(_stack.no))
    cols4 = list(set(_stack.date))

    # SelectButton(按钮默认填充,标签元素,标签别名(底层 API会用),默认选择)
    btn1 = SelectButton("风机风场", cols1, "farm", "????")
    btn2 = SelectButton("风机型号", cols2, "type", "GW50-750")
    btn3 = SelectButton("风机编号", cols3, "no", "WT02309")
    btn4 = SelectButton("数据日期", cols4, "date", "201601")

    # 按钮置入UI
    ui.add_filter(btn1)
    ui.add_filter(btn2)
    ui.add_filter(btn3)
    ui.add_filter(btn4)

    # 初始选择的按钮 {按钮名:按钮某个选项}
    global params
    params = {"farm": "????", "type": "GW50-750","no":"WT02309","date":"201601"}

    # # 制作线图-----------------------------------------------------------------------------------------------
    # 根据按钮选项调整数据集 返回实现线性接口
    def get_data():
        global params
        # 通过收集每次按钮事件请求,更新整体属性选择
        params_in = request.args
        for k in  params_in:
            v = params_in[k]
            params.update({k: v})

        # 返回 json
        return jsonify(
            # 实现线性接口(输入的 DF,元组型列值对应的列表,界面类型,属性参数)
            PlotlyAPI.line_plot(
                # (数据集,过滤的{列:值})返回df,而不调用它自己的Filter
                dataFilter(_stack, params),
                [("windspeed", "value")],
                "lines+markers",
                {}
            ))

    # 创建 plot接口型(ChartId,URL链接,初始化时执行的方法,初始化参数)
    _plot = PlotlyAPI(
        "plotly_chart",
        "/api/plotly_line_plot/",
        get_data,
        init_params=params
    )
    _plot2 = PlotlyAPI(
        "plotly_chart",
        "/api/plotly_line_plot/",
        get_data,
        init_params=params
    )
    ui.add_chart(_plot)
    ui.add_chart(_plot2)

    # 返回 UI
    return ui

# 主要函数 创建界面(APP 数据文件)
def get_layouts(mod, DF):

    # 调用 make_ui(数据文件)
    plotly_ui = make_ui(DF)
    # UI适用于APP(APP)
    plotly_ui.assign_routes(mod)
    # 获取属性
    plotly_props = plotly_ui.build_props()
    # 创建界面 类型:{UI属性,标题}
    _layouts = {
        "plotly": {
            "layout": [plotly_props],
            "title": "NEU_LightBuld    Hadoop实验结果数据演示"
        }
    }
    # 返回注册好的界面
    register_layouts(_layouts, mod)
 结果预览

【Python使用笔记】——Pyxley 包下的Dashboard开发_第5张图片【Python使用笔记】——Pyxley 包下的Dashboard开发_第6张图片









反思

对于数据库极大的可以采用在__init___.py接受请求,直接利用SQLConnector得到需要的部分发给buildui.py


个人学习,欢迎各位大佬指教

你可能感兴趣的:(Python)