數(shù)據(jù)可視化Pyecharts的實際使用方式
一個多月前參加公司的一個產(chǎn)品會的時候,有和同事聊到日常巡檢報表的一些東西,現(xiàn)在雖然項目上搭建的有監(jiān)控平臺、數(shù)據(jù)稽核平臺、調(diào)度平臺等業(yè)務(wù)系統(tǒng),每天運維人員也做定期的巡檢,但是細想來說這其中有2成左右的工作可能是一個重復(fù)性的工作,做完以后要生成巡檢報告,有時候可能還要發(fā)給客戶。這部分工作屬于是做了沒有成績,不做可能出事的活。
本身這樣的事情就應(yīng)該盡量自動化,而且我們也用Grafana對數(shù)據(jù)做了圖表展示,但是領(lǐng)導(dǎo)就是喜歡看報告,覺得大屏這種東西是線上看的,報告是留檔看的,而且讓我們天天出報告也能讓我們累一點(懂的都懂)。
再說自動化報表這個事情,最好是能夠有一個連接全局數(shù)據(jù)源的引擎來自動生成,對數(shù)據(jù)有一定分析能力,不過公司沒這個開發(fā)能力,而且開源項目也調(diào)研過,對接自研的各個平臺也需要開發(fā)投入。
綜合來看,先臨時做一個程序解決眼下問題會好點。
環(huán)境分析
做之前,先分析下實際環(huán)境上有的各種問題,能想到的大概有這幾個:
- 數(shù)據(jù)來源不唯一,比如對集群資源進行監(jiān)控的數(shù)據(jù)可能存在Prometheus,其他的可以通過各種后端接口獲取
- 網(wǎng)絡(luò)不一定通,由于網(wǎng)絡(luò)限制,沒有一臺服務(wù)器能同時訪問所有數(shù)據(jù)源,可能需要考慮數(shù)據(jù)獲取時使用代理
- 可視化圖形,通過接口獲取的各種數(shù)據(jù),需要自己再畫圖
最主要的幾個問題就是上面的三個,各有各的解決方案,本文主要說的是可視化繪圖這部分,而這里畫圖的話就是使用Pyecharts來做的。
Prometheus數(shù)據(jù)處理
先說下針對Prometheus的數(shù)據(jù)處理,Prometheus的查詢接口常用的有query和query_range,按照這樣進行封裝,方便獲取數(shù)據(jù)時直接調(diào)用,不用再做額外處理:
import sys import os import requests QUERY_ENDPOINT = "query" QUERY_RANGE_ENDPOINT = "query_range" class PrometheusQueryAPI: """Class Create Prometheus query api""" def __init__(self, api, proxy=None) -> None: self.api = api self.endpoint = "query" self.params = {} self.result = None self.proxy = proxy def clean(self): """清理查詢參數(shù) """ self.params = {} def query(self, query, time=None): """Create the query""" self.params["query"] = query if time: self.params["time"] = time self.endpoint = QUERY_ENDPOINT return self def query_range(self, query, start=None, end=None, step=None): """Create the Query range""" self.params["query"] = query if start: self.params["start"] = start if end: self.params["end"] = end if step: self.params["step"] = step self.endpoint = QUERY_RANGE_ENDPOINT return self def run(self): """Run the prometheus query""" url = os.path.join(self.api, self.endpoint) if sys.platform.startswith('win'): url = url.replace('\\', '/') res = requests.get(url=url, params=self.params, proxies=self.proxy, timeout=30) self.result = res.json() self.clean() return self
當(dāng)執(zhí)行query或者query_range的查詢時,使用對應(yīng)的方法構(gòu)造查詢語句,然后調(diào)用run進行語句運行即可,封裝的比較。
Gauge圖
Gauge圖就是儀表盤圖,這里就不說官方示例了,以我的用法來說,先通過Prometheus獲取數(shù)據(jù):
p = prometheus.PrometheusQueryAPI( PROMETHEUS, proxy=PROXY) p.query("yarn_exporter_allocateMem/(yarn_exporter_availableMem+yarn_exporter_allocateMem)") p.run() data = round(float(p.result["data"]["result"][0]["value"][1])*100, 2)
這里獲取到一個瞬時向量的指標(biāo),然后做數(shù)據(jù)類型的轉(zhuǎn)換和處理方便接下來繪圖:
from pyecharts.charts import Gauge gauge1 = ( Gauge() .add( # 必要配置 series_name="內(nèi)存使用率", data_pair=[["內(nèi)存使用率", data]], # 設(shè)置儀表盤的條例 axisline_opts=opts.AxisLineOpts( linestyle_opts=opts.LineStyleOpts( # 設(shè)置不同區(qū)間的顏色,color中劃分不通區(qū)間的顏色,width為線條粗細 color=[(0.3, "#E9EB2E"), (0.9, "#37a2da"), (1, "#fd666d")], width=10 ) ), # tooltip的設(shè)置,進行顯示的格式化 tooltip_opts=opts.TooltipOpts( is_show=True, formatter=" : {c}%"), max_=100, min_=0, # 設(shè)置相對位置,橫縱坐標(biāo),當(dāng)使用Grid組合Gauge時必須設(shè)置,否則圖表會重合 center=["25%", "50%"], # 儀表盤內(nèi)的指標(biāo)名稱字體設(shè)置 title_label_opts=opts.GaugeTitleOpts( font_weight="bold", font_size=20 ), # 儀表盤內(nèi)的指標(biāo)數(shù)值的設(shè)置 detail_label_opts=opts.GaugeDetailOpts( formatter="{value}%", color="#1267CB", font_weight="bold", font_size="20", offset_center=["0%", "40%"], ) ) .set_global_opts( # Gauge的標(biāo)題設(shè)置 title_opts=opts.TitleOpts( title="內(nèi)存使用率", ), # 設(shè)置圖例格式 legend_opts=opts.LegendOpts(is_show=False), ) )
這里主要需要注意的是進行數(shù)據(jù)的格式化的時候,在TooltipOpts
中設(shè)置使用" : {c}“這樣的內(nèi)置變量,如果是在GaugeDetailOpts
中進行設(shè)置,就要使用”{value}"這個內(nèi)置變量。
Bar圖-橫向
有的時候在使用條形圖的時候,需要使用橫向的條形圖,官方的示例比較少,可以這樣設(shè)置:
bar = ( Bar(init_opts=opts.InitOpts(width="850px", height="800px")) .add_xaxis(xaxis_data=province) .add_yaxis("HDFS", values) .set_global_opts( title_opts=opts.TitleOpts(title="HDFS使用情況"), visualmap_opts=opts.VisualMapOpts( min_=0, max_=100, # 組件映射維度 dimension=0, # 是否為分段型,如果設(shè)置為False,會出現(xiàn)一個完整的分段條可以拖動調(diào)節(jié) is_piecewise=True, # 設(shè)置不同取值區(qū)間的顏色 range_color=[ "#00EC00", "#00A600", "#FFD306", "#FF8000", "#FF2D2D"], orient="horizontal", pos_top="0%", pos_left="40%" ), legend_opts=opts.LegendOpts( is_show=False ), xaxis_opts=opts.AxisOpts( max_=100 ) ) .set_series_opts( # 設(shè)置標(biāo)記線,如果進行了行列轉(zhuǎn)置,這里的操作就要對X軸進行了而不是Y軸! markline_opts=opts.MarkLineOpts( data=[ opts.MarkLineItem( x=80, name="使用率過高", linestyle_opts=opts.LineStyleOpts( color="red", ) ) ] ), ) # 翻轉(zhuǎn)XY軸 .reversal_axis() )
使用reversal_axis()
設(shè)置XY軸翻轉(zhuǎn),使用VisualMapOpts
設(shè)置視覺映射,這樣可以根據(jù)自己的需要,對不同區(qū)間的數(shù)據(jù)設(shè)置顏色,使用MarkLineOpts
可以設(shè)置標(biāo)記線,比如警戒線,尤其要注意的是,當(dāng)進行行列轉(zhuǎn)置后,警戒線的設(shè)置要對X軸的值設(shè)置了,不能對原先設(shè)置的Y軸進行設(shè)置。
效果圖如下:
如何整合進Flask中
很多時候可視化并不只要圖,報告還需要加入一些結(jié)論性的文字,也就是圖文結(jié)合,類似這樣:
在進行圖表初始化的時候,可以添加InitOpts進行圖表大小的設(shè)置:
Bar( opts.InitOpts(width="850px", height="800px") )
在做模板渲染的時候,這樣進行設(shè)置:
return render_template("view.j2", data=bar.render_embed())
在對應(yīng)的模板view.j2中只需要這樣寫就可以:
<div>{{ data|safe }}</div>
附錄
- Echarts官網(wǎng):Apache ECharts
- PyEcharts文檔:簡介 - pyecharts - A Python Echarts Plotting Library built with love.
- PyEcharts示例:中文簡介 - Document (pyecharts.org)
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python urllib request模塊發(fā)送請求實現(xiàn)過程解析
這篇文章主要介紹了Python urllib request模塊發(fā)送請求實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-12-12pycharm 主題theme設(shè)置調(diào)整仿sublime的方法
今天小編就為大家分享一篇pycharm 主題theme設(shè)置調(diào)整仿sublime的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05Python整型運算之布爾型、標(biāo)準整型、長整型操作示例
這篇文章主要介紹了Python整型運算之布爾型、標(biāo)準整型、長整型操作,結(jié)合具體實例形式分析了Python中布爾型、標(biāo)準整型、長整型等相關(guān)運算技巧,代碼備有詳盡注釋,需要的朋友可以參考下2017-07-07教你如何用python開發(fā)一款數(shù)字推盤小游戲
這篇文章主要介紹了教你如何用python開發(fā)一款數(shù)字推盤小游戲,文中有非常詳細的代碼示例,喜對歡玩小游戲的或者正在學(xué)習(xí)python小游戲開發(fā)的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04