部门有很多业务数据都需要进行可视化展示,一方面是方便团队成员进行监控和分析,另一方面也是为了和业务部门共享分析成果,让数据产生更多的价值。虽然公司已经准备部署Tableau,但我们经过讨论后认为团队自己开发的大屏可以更灵活、也可以和Tableau形成互补。在寻找解决方案的时候,我们首先明确了以下几条原则,并且最终选定了pyecharts。
注:出于保密和效果考虑,BI版面和图表类型有调整,使用的数据全部为虚构。
ECharts是由百度开源的基于JS的商业级数据图表库,具有简洁美观、交互丰富、高度定制等特点,我们可以在ECharts官网看到其具有非常丰富的图表类型和实例。pyecharts基于ECharts为我们提供了python的调用接口,可以生成“html”、“svg”、“png”、“jpeg”、“gif”和“pdf”格式的图表。
pyecharts可以直接通过pip安装:
pip install pyecharts
需要使用地图类图表的,还需要安装以下地图数据包:
pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg
pip install echarts-china-counties-pypkg
pip install echarts-china-misc-pypkg
下面我们来尝试使用pyecharts制作单个图表。以下代码首先创建了一个Bar类型的柱状图实例bar,指定了图表的主标题和副标题;然后用add的方法为bar传入了数据标签、x值和y值;最后,我们把图表保存成了html格式。
from pyecharts import Bar
bar=Bar("商品销量","各季度的商品销量")
bar.add("2018Q4",["轴承","弹簧","齿轮","导轨","丝杠"],[19,21,23,19,13])
bar.render("bar.html")
对于柱状图、折线图、散点图等图表类型,我们可以通过多次add的方法传入数据,制作多列柱状图。
bar=Bar("商品销量","各季度的商品销量")
bar.add("2018Q3",["轴承","弹簧","齿轮","导轨","丝杠"],[17,23,25,14,17])
bar.add("2018Q4",["轴承","弹簧","齿轮","导轨","丝杠"],[19,21,23,19,13])
bar.render("bar.html")
同时,我们还可以在创建bar和add数据的时候为图表和数据项设置各类参数。如主标题的字体颜色,x值的字体大小
bar=Bar("商品销量","各季度的商品销量",title_color ="#c1392b")
bar.add("2018Q3",["轴承","弹簧","齿轮","导轨","丝杠"],[17,23,25,14,17])
bar.add("2018Q4",["轴承","弹簧","齿轮","导轨","丝杠"],[19,21,23,19,13],xaxis_label_textsize=24)
bar.render("bar.html")
此外,pyecharts还支持主题色系的更换,你可以理解为变更主题:
bar=Bar("商品销量","各季度的商品销量",title_color ="#c1392b")
bar.use_theme('dark')
bar.add("2018Q3",["轴承","弹簧","齿轮","导轨","丝杠"],[17,23,25,14,17])
bar.add("2018Q4",["轴承","弹簧","齿轮","导轨","丝杠"],[19,21,23,19,13],xaxis_label_textsize=24)
bar.render("bar.html")
关于echarts的调用方法和更多图表的配置,建议大家参考pyecharts官网,里面有非常详细的介绍。这里需要再补充的是pyecharts的“多图表Page”功能,这是我们实现BI监控大屏的基础。如下代码,我们构建了一个page实例,然后将构建的bar和gauge添加进page,最后将page保存获得一个包含柱状图和仪表盘的html文件。
from pyecharts import Page,Bar,Funnel
page=Page()
bar=Bar("商品销量","各季度的商品销量")
bar.add("2018Q3",["轴承","弹簧","齿轮","导轨","丝杠"],[25,23,17,14,17])
bar.add("2018Q4",["轴承","弹簧","齿轮","导轨","丝杠"],[23,21,19,19,13])
page.add_chart(bar,name="bar")
funnel=Funnel("订单转化效率","今日用户的订单转化效率")
funnel.add("",["访问","搜索","点击","加购","订单"],[100.00,78.12,35.74,17.17,2.62])
page.add_chart(funnel,name="funnel")
page.render("page.html")
使用Chrome打开“page.html”文件,使用开发者工具(F12)查看该文件,发现pyecharts实际上帮我们生成了两个div,对应刚才绘制的柱状图和仪表盘。我们可以把整个html理解成画布,div理解成两个图表,图表的主要内容已经通过pyecherts完成,接下来还需要继续对图表和画布进一步修改。
前面介绍了pyecharts的安装和使用,借助多图表Page功能,我们可以首先绘制多个图表并对每个图表进行修改,然后调整每个图表在画布中的大小和位置,最后借助html追加标题、边框等元素实现BI大屏。
图表的配置主要包括图形初始化、通用配置项和图表配置项,具体的配置参数大家可以参考官方教程,以下供参考。
图形初始化:创建图表时传入的配置项,如“title”、“subtitle”、“title_pos”等。
bar=Bar("商品销量","各季度的商品销量",title_pos="center")
通用配置项:图表通过add接受的参数(所有类型的图表都有的参数)。
bar.add("A",data_x,data_y,xaxis_name=“x_axis”,xaxis_name_pos=“middle”)
图表配置项:图表通过add接受的参数(指定类型的图表特有的参数)。
bar.add("A",data_x,data_y,bar_category_gap=“20%”)
pyecharts只提供了部分图表配置参数,当不能满足修改需求时,我们还可以参考echarts官网示例通过_option接口追加配置选项。以漏斗图为例,我们可以修改“top”、“bottom”、“left”和“width”四个参数选项来调整漏斗的大小,代码如下:
funnel=Funnel("订单转化效率","今日用户的订单转化效率")
funnel.add("",["访问","搜索","点击","加购","订单"],[100.00,78.12,35.74,17.17,2.62])
funnel._option['series'][0]["top"]=70
funnel._option['series'][0]["bottom"]=20
funnel._option['series'][0]["left"]="5%"
funnel._option['series'][0]["width"]="90%"
借助html,我们可以调整每个图表在画布中的大小和位置、追加标题、边框等元素,实现BI大屏。以一个完整的例子来说明:
from pyecharts import Page,Bar,Funnel
import os as os
from bs4 import BeautifulSoup
page=Page()
bar=Bar("商品销量","各季度的商品销量",title_pos="center")
bar.use_theme("dark") #修改图表主题
bar.add("2018Q3",["轴承","弹簧","齿轮","导轨","丝杠"],[25,23,17,14,17],mark_point=["min","max"]) #追加最大值标记点、最小值标记点
bar.add("2018Q4",["轴承","弹簧","齿轮","导轨","丝杠"],[23,21,19,19,13],mark_point=["min","max"],bar_category_gap=45,is_legend_show=False) #追加最大值标记点、最小值标记点、修改柱间隔、是否显示图例
page.add_chart(bar,name="bar")
funnel=Funnel("订单转化效率","今日用户的订单转化效率",title_pos="center") #修改标题位置
funnel.use_theme("dark") #修改图表主题
funnel.add("",["访问","搜索","点击","加购","订单"],[100.00,78.12,35.74,17.17,2.62],is_label_show=True,is_legend_show=False,label_pos="outside") #是否显示标签、是否显示图例、标签位置
funnel._option['series'][0]["top"]=70 #修改漏斗图上间隔
funnel._option['series'][0]["bottom"]=20 #修改漏斗图下间隔
funnel._option['series'][0]["left"]="5%" #修改漏斗图左间隔
funnel._option['series'][0]["width"]="90%" #修改漏斗图宽度
page.add_chart(funnel,name="funnel")
page.render("page.html")
with open(os.path.join(os.path.abspath("."),"page.html"),'r+',encoding="utf8") as html:
html_bf=BeautifulSoup(html,"lxml")
divs=html_bf.find_all("div")
divs[0]["style"]="width:600px;height:400px;position:absolute;top:70px;left:0px;border-style:solid;border-color:#444444;border-width:3px;" #修改图表大小、位置、边框
divs[1]["style"]="width:600px;height:400px;position:absolute;top:70px;left:600px;border-style:solid;border-color:#444444;border-width:3px;" #修改图表大小、位置、边框
body=html_bf.find("body")
body["style"]="background-color:#333333;"
div_title="\n基于pyecharts的BI监控大屏" #修改页面背景色、追加标题
body.insert(0,BeautifulSoup(div_title,"lxml").div)
html_new=str(html_bf)
html.seek(0,0)
html.truncate()
html.write(html_new)
html.close()
这里我们已经实现了比较简单的图表组合和画布设置,在此基础上结合业务需要,就可以制作我们需要的BI大屏,然后通过对浏览、上传和加载该html文件进行分享