外行學(xué) Python 第十一篇 數(shù)據(jù)可視化

外行學(xué) Python 爬蟲 第九篇 讀取數(shù)據(jù)庫(kù)中的數(shù)據(jù) 中完成了使用 API 從數(shù)據(jù)庫(kù)中讀取所需要的數(shù)據(jù),但是返回的是 JSON 格式,看到的是一串的字符串?dāng)?shù)據(jù)不是很好理解,這篇將介紹如何將數(shù)據(jù)進(jìn)行可視化。

數(shù)據(jù)可視化選用 pyecharts 來(lái)完成,通過(guò)將 pyecharts 集成到 Flask 中完成數(shù)據(jù)從數(shù)據(jù)庫(kù)到網(wǎng)頁(yè)可視化顯示的過(guò)程。最終完成后通過(guò)選擇框選中相應(yīng)的生產(chǎn)商后,即可查看在立創(chuàng)商城上該廠商所生產(chǎn)各種元件的數(shù)量,如下圖所示:


image

pyecharts 是利用 Echarts 生成圖標(biāo)的 Python 類庫(kù),是一款強(qiáng)大的數(shù)據(jù)可視化工具。更多信息請(qǐng)查閱 pyecharts 官網(wǎng)

準(zhǔn)備工作

pyecharts 安裝

pyecharts 可使用 pip 進(jìn)行安裝

pip install pyecharts

也可以使用源碼進(jìn)行安裝

$ git clone https://github.com/pyecharts/pyecharts.git
$ cd pyecharts
$ pip install -r requirements.txt
$ python setup.py install

推薦使用 pip 進(jìn)行安裝,特別是對(duì)于初學(xué)者來(lái)說(shuō)。

集成到 Flask 中

需要將 pyecharts 中的模板拷貝到 Flask 目錄下的 templates 目錄中,模板文件位于 pyecharts/pyecharts/render/templates/目錄中。

實(shí)際上此時(shí)即可在 Flask 中使用 pyecharts 了,但是根據(jù) pyecharts 文檔中的介紹,在實(shí)際使用過(guò)程中遇到了以下錯(cuò)誤

jinja2.exceptions.TemplateNotFound: simple_chart.html

該錯(cuò)誤是由以下配置引起的

CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates"))

將該配置從代碼中刪除,重新運(yùn)行程序即可看到完整的圖標(biāo)信息。

爬蟲數(shù)據(jù)可視化

在這里將完成從數(shù)據(jù)庫(kù)中讀取各生產(chǎn)商所生產(chǎn)各類元件的數(shù)據(jù),通過(guò) Echarts 進(jìn)行可視化的操作。為了實(shí)現(xiàn)能夠通過(guò)選擇生產(chǎn)商實(shí)時(shí)更新圖表數(shù)據(jù),最終使用前后端分離的方法實(shí)現(xiàn)數(shù)據(jù)顯示。

首先,先看下 HTML 文件

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Awesome-pyecharts</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
    <select id="brand_name" onchange="showBrandBar()">
      {% for brand in brands %}
      <option value="{{brand}}">{{brand}}</option>
      {% endfor %}
    </select>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script>
        $(
          showBrandBar()
        )

        function showBrandBar() {
          var selId = document.getElementById("brand_name");
          var value = selId.options[selId.selectedIndex].value;

          console.log(value)
          postBrandBar(value)
        }

        function postBrandBar(brand_name) {
          var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
          $.ajax({
              type: "POST",
              url: "http://127.0.0.1:5000/brand/bar",
              dataType: 'json',
              data:JSON.stringify({
                name: brand_name
              }),
              success: function (result) {
                  chart.setOption(result);
              }
          });
        }
    </script>
</body>
</html>

采用 ajax 來(lái)響應(yīng) select 標(biāo)簽的改變事件,通過(guò) ajax 向服務(wù)端提交當(dāng)前選中的生產(chǎn)商,同時(shí)從服務(wù)器獲取該廠商的信息。可以看到在 javascrpit 腳本中默認(rèn)執(zhí)行了一次 showBrandBar() 函數(shù),是為了在第一次加載頁(yè)面時(shí)能夠正常顯示圖標(biāo),否則第一次加載頁(yè)面時(shí)圖表位置將是空白。

在 Flask 的后端需要實(shí)現(xiàn)一個(gè) get 方法和一個(gè) post 方法。get 方法用來(lái)獲取所有的生產(chǎn)商名稱,同時(shí)向?yàn)g覽器發(fā)送 html 頁(yè)面;post 方法用來(lái)相應(yīng) html 頁(yè)面中的 ajax 請(qǐng)求,發(fā)送該生產(chǎn)商所提供的各類元件的數(shù)量。

get 方法的代碼如下

    def get(self):
        brands = [name[0] for name in db.session.query(Brands.name).all()]
        return render_template('brand_bar.html', brands=brands)

post 方法的代碼如下

    def post(self):
        jsons = request.get_json(force=True)
        brand_name = jsons['name']
        brand_id = db.session.query(Brands.id).filter(Brands.name == brand_name).one()[0]

        catalog_ids = db.session.query(Catalog.id, Catalog.name).filter(Catalog.parent_id==None).all()

        catalog_name = []
        catalog_count = []
        for cata_id, name in catalog_ids:
            catalog_name.append(name)
            count = db.session.query(Materials).join(Catalog).filter(
                    Materials.brand_id == brand_id).filter(
                    Catalog.parent_id == cata_id).count()
            catalog_count.append(count)

        c = (
            Bar()
            .add_xaxis(catalog_name)
            .add_yaxis('數(shù)量', catalog_count)
            .set_global_opts(
                xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-90)),
                title_opts=opts.TitleOpts(title=brand_name, subtitle="物料數(shù)量"),
            )
        )
        return c.dump_options_with_quotes()

在 post 方法中主要做的是數(shù)據(jù)的查詢,通過(guò)生產(chǎn)商名稱來(lái)查詢出該生產(chǎn)商在數(shù)據(jù)中的 id,從而獲取其所提供的所有元件,然后按照 Catalog 中的分類獲取其各個(gè)分類中的元件數(shù)據(jù)。將相應(yīng)的數(shù)據(jù)填入 pyecharts 的 Bar 對(duì)象中回傳給 ajax 請(qǐng)求。

至此,執(zhí)行程序在瀏覽器中即可看到在文章開頭所看到的頁(yè)面,選擇不同的生產(chǎn)商圖標(biāo)將實(shí)時(shí)更新到該生產(chǎn)商的信息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容