引言
pyecharts作为Python的数据可视化包,其强大的功能不言而喻,Python + Echart,想想就觉得牛叉。目前pyecharts有两个大的版本,一个是0.5.x版本的,一个是1.0以后版本,而且这两个版本差别很大。如果是有的选,肯定优先选择1.0版本的,功能要比0.5.x版本的强大得多,而且支持链式调用。
但是肯定也有不少用不惯1.0及后续版本的同仁。博主因为之前一直用的是0.5.x版本的,如果要改成1.0版本的,很多项目都要大改,所以一直没有狠下心来换成1.0版本的包。
下面我介绍一下如何用pyecharts制作数据看板。
照样上编译环境:
- Python3.7
- 编译器Spyder或者pycharm都可以
另外,本文需要读者对pyecharts有一定的了解,不了解的可以去看看文档,文中有文档的链接,注意仔细看哦。
数据看板
数据看板意思就是,在一块大屏上显示多项数据图,比如地图,折线图,柱状图,漏斗图等等。
其实pyecharts0.5.x版本是支持数据看板功能的,请看pyecharts0.5.x版本的自定义图表接口,其中grid(并行显示多张图表)是最合适做数据看板的,但是开发人员说了:
用户可以自定义结合 Line/Bar/Kline/Scatter/EffectScatter/Pie/HeatMap/Boxplot 图表,将不同类型图表画在多张图上。第一个图需为 有 x/y 轴的图,即不能为 Pie,其他位置顺序任意。
也就是说,只能并行显示Line/Bar/Kline/Scatter/EffectScatter/Pie/HeatMap/Boxplot这几种图,如果要加入地图或者地理信息图,图表的位置就会乱,但是我现在又必须要在我的首页上加上地图,怎么办呢?博主一度无解。
先来看看1.0及后续版本的pyecharts是如何解决这个问题的。
代码请看这里,因为是官方的教程,大家直接去看就行了,我不再贴上来。原理就是用grid来添加各种基础图形,展示结果如下:
看起来还是很炫很震撼的,也就是博主要实现的功能
现在来介绍一下如何在低版本的pyecharts包里实现这个功能,主要是要把地图加进去。
0.5.x版本的pyecharts程序实现含地图的数据看板
导入包
from pyecharts import *
import os as os
from bs4 import BeautifulSoup
import pandas as pd
import datetime
可能已经有同学看出一些问题来了,导入了bs4,是不是要对网页进行编辑处理呢?
导入数据
我自己做了个excel数据,有3个sheet,其中的数据分别对应三个图,另外一个图,我要画仪表盘图,不需要数据。也就是说,我的数据看板上,有四张图。
首先,定义一个page图
page=Page()
对pyecharts有所了解的同学可能已经知道了,我这是想用page来生成数据看板,但是page图是翻页的,没法在一个页面上展示这么多图,继续看操作。
数据是自己随机生成的,命名为"数据.xlsx"。
f = pd.ExcelFile('数据.xlsx')
sheet = f.sheet_names
分别画出自己想要的四个图
如上面说的,我要在数据看板上画4个图,左上是地图,右上是一个折线图,左下是一个仪表板图,右下是个日历图
地图
直接上代码
d1 = pd.read_excel('数据.xlsx',sheet_name = sheet[0])
map_ = Map('地图数据', title_pos = 'center', title_top = '1%')
province = d1.iloc[:,0]
deaths = pd.Series.tolist(d1.iloc[:,1])
map_.add('', province, deaths, visual_range=[0, max(deaths)], maptype='china', is_visualmap=True,visual_text_color='#000')
page.add_chart(map_, 'map')
画完map图后,记得把map图加到page中去哦(代码块最后一句)
折线图
d3 = pd.read_excel('数据.xlsx',sheet_name = sheet[1])
line = Line('数据1&数据2','', title_pos = 'center', title_top = '2%')
def request_date(x):return x[0:10]
index = d3.iloc[:,0].apply(str).apply(request_date)
series1 = pd.Series.tolist(d3.iloc[:, 1])
series2 = pd.Series.tolist(d3.iloc[:, 2])
line.add('数据1',index,series1,mark_point = ['max'],is_datazoom_show=True, xaxis_rotate=90)
line.add('数据2',index,series2,mark_point = ['max'],is_datazoom_show=True, xaxis_rotate=90,legend_pos = 'left',)
page.add_chart(line, name = 'line')
这里为啥要写个函数request_date,你可以自己试试不写的后果,excel读数据不像读csv数据,如果数据是时间格式的,那么用pandas读出来的数据自带时间格式,后面有时分秒,如果不处理一下,折线图一直出不来.
仪表盘图
gauge = Gauge('同期比例',title_pos = 'center', title_top = '1%')
gauge.add('','同比',67.3)
page.add_chart(gauge, 'gauge')
这个最简单,不解释
日历图
d4 = pd.read_excel('数据.xlsx',sheet_name = sheet[2])
begin = datetime.date(2020,1,1)
end = datetime.date(2020,3,31)
data = [[str(begin + datetime.timedelta(days=i)), d4.iloc[i,1]]for i in range((end - begin).days + 1)
]
heatmap = HeatMap("日历分布", "", title_pos = 'center', title_top = '2%')
heatmap.add("",data,is_calendar_heatmap=True,visual_text_color="#000",visual_range_text=["", ""],visual_range=[0, max(d4['数据'])],calendar_cell_size=["auto", 30],is_visualmap=True,calendar_date_range=["2020-1-1",'2020-4-30'],visual_orient="horizontal",visual_pos="center",visual_top="80%",is_piecewise=True,
)
page.add_chart(heatmap, name = 'heatmap')
这个图有点复杂,有很多参数的设置需要去看文档,文档在这里
好了,画好4个图了,并且都添加到page里面去了,下面渲染成网页
page.render("page.html")
如果只是到这里,那就是文档中最简单的page图,需要从上往下翻页,而不是直观的展示是一个页面上,结果如下:
没达到目标是吧,别着急,bs4一直还没用呢
对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:750px;height:350px;position:absolute;top:70px;left:0px;border-style:solid;border-color:#FFFFFF;border-width:3px;" #修改图表大小、位置、边框divs[1]["style"]="width:750px;height:350px;position:absolute;top:70px;left:750px;border-style:solid;border-color:#FFFFFF;border-width:3px;" #修改图表大小、位置、边框divs[2]["style"]="width:750px;height:350px;position:absolute;top:420px;left:0px;border-style:solid;border-color:#FFFFFF;border-width:3px;" #修改图表大小、位置、边框divs[3]["style"]="width:750px;height:350px;position:absolute;top:420px;left:750px;border-style:solid;border-color:#FFFFFF;border-width:3px;" #修改图表大小、位置、边框body=html_bf.find("body")#body["style"]="background-color:#333333;"div_title="<div align=\"center\" style=\"width:1500px;\">\n<span style=\"font-size:32px;font face=\'黑体\';color:#000000\"><b>第一季度总体情况</b></div>" #修改页面背景色、追加标题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()
再看结果:
这就对了
今天没空了,后面有时间,我在仔细解释beautifulsoup是如何来对网页进行修改的。