用PyEcharts实现数据可视化快速上手指南

1.为什么选择PyEcharts

最近在做一个数据可视化的任务,经过前期的调研,最终选择了PyEcharts。PyEcharts是百度可视化框架Echarts的Python版本,由于Python的“万能脚本”特性,PyEcharts沟通其他功能模块十分方便,支持“数据分析+数据展示”整套流程,但在炫酷方面,比不上原生的Echarts。Echarts基于JavaScript,动画效果与素材更多,它的社区里还有很多开源的可视化模板,在数据展示方面性能更强。如果你具有以下需求,PyEcharts是很不错的选择:

1)对可视化效果要求较高,Matplotlib所呈现的视效远远不够,而且需要“点击”、“拖拉”等交互效果。

2)同时具有数据分析的需求。Python在数据读取、科学计算方面也十分强劲,可直接完成数据分析,再通过PyEcharts可视化。

2.PyEcharts安装

PyEcharts和其他的包一样,可直接通过pip安装,我是通过PyCharm配置的。需要特别说明的是,如果想使用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
pip install echarts-united-kingdom-pypkg

3.PyEcharts绘制地图

可能是版本的原因,PyEcharts1.0与官网(pyecharts.org)的开发文档有些出入,本来想总结性的写出来,但是感觉有点抽象,还是直入主题,遇到了再讲吧。

用PyEcharts绘制地图需要先初始化一个Map对象,许多教程是这样做的:

map = Map("地图示例", width=1200, height=600)

“地图示例”是地图的标题,width与height是地图的长宽,这似乎不难理解。但运行时会报错:

TypeError: __init__() got an unexpected keyword argument 'width'

关于这个错误网上并没有相关资料,向开发者发邮件后也并没有回复,于是猜测width与height两个参数应该在目前版本中被移除了,于是我采用了官网中的另一种初始化方式:

map = (Map().add(data,'china').set_global_opts(title_opts=opts.TitleOpts(title="地图示例")))

首先用add()函数添加地图图表,然后用set_global_opts()函数传入标题参数。通过set_global_opts()还可以设置官网中除InitOpts的如下参数:

每个参数的功能点进去有详细解释,其中InitOpts()就是设置长宽这些参数的,然而PyEcharts1.0中没有这个函数了,也就是说现在无法设置图表的长宽,只能采用默认大小,这影响还蛮大的。如果是我理解错了,大家有别的办法,可以告诉我。

除此之外,添加一个地图就是用add(data,'china')方法了,'china'是地图类型,data是图表数据。具体而言,data是一个二元组的列表,比如:

data = [('北京',100),('湖北',200),('广东',300)……]

需要注明的是,每个省份只需要名字,不需要后面的行政称谓,如湖北不叫湖北省,内蒙古叫内蒙古,不叫内蒙古自治区。

地图创建完成后,通过render()方法可以将地图渲染为html或者图片,如:

map.render(path='./map.html')

以上就是用PyEcharts制作一个简单地图的流程,完整代码如下:

from pyecharts.charts import Map
from pyecharts import options as opts
from pyecharts.globals import ThemeType

value = [115.4,121.6,122,116,123.3,110.4,118.4,116.8,114.3,
         113.2,111.8,116.8,113.4,113,121.3,118.7,119,117.6,113.8,
         115.1,114.1,115.2,112.6,114.8,120.2,118.2,119.8,114.7,115.4,
         114.6,112.7]
attr = ['甘肃','广东', '广西','贵州','海南',
        '河南','湖北', '湖南','宁夏','青海',
        '陕西','四川', '西藏','新疆','云南',
        '重庆','北京', '天津','河北','山西','内蒙古',
        '辽宁','吉林', '黑龙江','上海','江苏','浙江','安徽','福建'
        ,'江西','山东']
sequence = list(zip(attr,value))

def map_visualmap(sequence,year) -> Map:
    c = (
        Map()
        .add(year,sequence, "china",)
        .set_global_opts(
            title_opts=opts.TitleOpts(title="地图"),
            visualmap_opts=opts.VisualMapOpts(max_=130,min_=95),
        )
    )
    return c

map = map_visualmap(sequence,'1993')
map.render(path='./test.html')

3.1 动态地图(Map+Timeline)

用PyEcharts制作一个随年份不断变化的地图也是可以的,这需要用到一个类似时间轴的的组件:Timeline。具体原理就是先创建一个时间轴,然后往里面添加制作好的不同年份地图,如果地图很多,写一个循环自动读取数据就行了。这就体现了PyEcharts的优越性,在JS里读取数据可不容易。

直接放完整代码:

from pyecharts.charts import Map
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from pyecharts.charts import Timeline
import xlrd

attr = ['甘肃','广东', '广西','贵州','海南',
        '河南','湖北', '湖南','宁夏','青海',
        '陕西','四川', '西藏','新疆','云南',
        '重庆','北京', '天津','河北','山西','内蒙古',
        '辽宁','吉林', '黑龙江','上海','江苏','浙江','安徽','福建'
        ,'江西','山东']

#读取Excel文件的函数
def read_excel(row_number):
    # 打开文件
    workbook = xlrd.open_workbook(r'C:\Users\Faker\Desktop\分省.xlsx')

    # 根据sheet索引或者名称获取sheet内容
    sheet2 = workbook.sheet_by_index(0)

    # 获取整行和整列的值(数组)
    rows = sheet2.row_values(row_number) # 获取第四行内容
    return rows

def map_visualmap(sequence, year) -> Map:
    c = (
        Map()
        .add(year, sequence, "china",)
        .set_global_opts(
            title_opts=opts.TitleOpts(title="分省汇总"),
            visualmap_opts=opts.VisualMapOpts(max_=130,min_=95),
        )
    )
    return c

#创建时间轴
timeline = Timeline()

for i in range(2,28):
    #读取Excel中的value
    row = read_excel(i)
    row = row[2:]
    #创建data序列
    sequence_temp = list(zip(attr,row))
    #创建地图的标题
    year = 1991+i
    #创建地图
    map_temp = map_visualmap(sequence_temp,str(year))
    #将地图加入时间轴
    timeline.add(map_temp,str(year)).add_schema(play_interval=360)

timeline.render(path='./map.html')

年份较多,因此用一个for循环自动读取Excel表里的数据,还是比较简单的。add_schema()函数可以控制时间轴自动播放的速度,单位为ms,可视化效果如下:

4 PyEcharts绘制饼图

Echarts设计的十分简洁,因此制作其他类型的柱图、饼图、雷达图等都大同小异,下面是以绘制饼图为例说明。创建一个饼图的代码如下:

def pie_rosetype_2(data) -> Pie:
    c = (
        Pie()
        .add(
        "城市居民",
        data,
        radius=["30%", "75%"],
        center=["23%", "50%"],
        rosetype="radius",
        label_opts=opts.LabelOpts(),
    )
    return c

与地图相似,data都是一个二元组的列表,格式为[('标签',value)……]。radius与center是控制饼图大小与位置的参数,rosetype='radius'则表明这是一个类型为’radius‘的玫瑰图。

下面直接放一个带时间轴的双饼图代码:

from pyecharts.charts import Pie
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from pyecharts.charts import Timeline
import xlrd

attr_city= ['家庭设备','交通通信','文教娱乐','居住','食品','衣着','医疗保健','其他商品']
attr_rual = ['其他商品','居住','食品','文教娱乐','衣着','医疗保健','家庭设备','交通通讯']

def read_city_excel(row_number):
    # 打开文件
    workbook = xlrd.open_workbook(r'C:\Users\Faker\Desktop\饼图.xlsx')

    # 根据sheet索引或者名称获取sheet内容
    sheet2 = workbook.sheet_by_index(0)

    # 获取整行和整列的值(数组)
    rows = sheet2.row_values(row_number)
    rows = rows[4:18:2]
    return rows

def read_rural_excel(row_number):
    # 打开文件
    workbook = xlrd.open_workbook(r'C:\Users\Faker\Desktop\农村居民各项消费占比.xlsx')

    # 根据sheet索引或者名称获取sheet内容
    sheet2 = workbook.sheet_by_index(0)

    # 获取整行和整列的值(数组)
    rows = sheet2.row_values(row_number)
    rows = rows[5:19:2]
    return rows

#创建两个饼图的函数
def pie_rosetype_2(sequence1,sequence2) -> Pie:
    c = (
        Pie()
        .add(
        "城市居民",
        sequence1,
        radius=["30%", "75%"],
        center=["23%", "50%"],
        rosetype="radius",
        label_opts=opts.LabelOpts(),
    ).add(
        "农村居民",
        sequence2,
        radius=["30%", "75%"],
        center=["75%", "50%"],
        rosetype="radius",
        label_opts=opts.LabelOpts()
        ).set_global_opts(title_opts=opts.TitleOpts(title="城市与农村居民各项消费占比"),
                          legend_opts=opts.LegendOpts(pos_left='30%'))
    )
    return c

timeline = Timeline()

for i in range(1,26):
    row1= read_city_excel(i)
    sequence1= list(zip(attr_city, row1))
    row2=read_rural_excel(i)
    sequence2 = list(zip(attr_rual,row2))
    year = 1992 + i
    map_temp = pie_rosetype_2(sequence1,sequence2)
    timeline.add(map_temp, str(year)).add_schema(play_interval=360)

timeline.render(path=r'./pie.html')

数据同样是从excel中读取,只不过双饼图就是在原有的add()函数后另加一个add()函数,多饼图同理,下面是可视化效果展示:

5.PyEcharts绘制3D散点图

讲完了两个常规图,下面说一个3D图。其实基本思路与2D图还是一样的,只是要注意输入的数据变成了一个三元组的列表,可以理解为散点的x,y,z坐标,例如[('1993','农村居民食物支出',30%),……]。直接上代码:

import xlrd
from pyecharts import options as opts
from pyecharts.charts import Scatter3D

attr = ['家庭设备','交通通信','文教娱乐','居住','食品','衣着','医疗保健','其他商品']
year = [1993:2017:1]

def read_city_excel(row_number):
    # 打开文件
    workbook = xlrd.open_workbook(r'C:\Users\Faker\Desktop\3D散点图.xlsx')

    # 根据sheet索引或者名称获取sheet内容
    sheet2 = workbook.sheet_by_index(0)

    # 获取整行和整列的值(数组)
    rows = sheet2.row_values(row_number)
    rows = rows[4:18:2]
    return rows

def read_rural_excel(row_number):
    # 打开文件
    workbook = xlrd.open_workbook(r'C:\Users\Faker\Desktop\3D散点图2.xlsx')

    # 根据sheet索引或者名称获取sheet内容
    sheet2 = workbook.sheet_by_index(0)

    # 获取整行和整列的值(数组)
    rows = sheet2.row_values(row_number)
    rows = rows[5:19:2]
    return rows


#创建散点数据列表
scatter_city = []
scatter_rural = []
for i in range(1,26):
    row_city = read_city_excel(i)
    row_rural = read_rural_excel(i)
    for _ in range(len(attr)):
        scatter_city.append([attr[_-1],1992+i,row_city[_-1]])
    for _ in range(len(attr)):
        scatter_rural.append([attr[_-1],1992+i,row_rural[_-1]])

#定义制作3D散点图的函数
def scatter3d_base() -> Scatter3D:
    c = (
        Scatter3D()
        .add("城镇居民", scatter_city).add('农村居民',scatter_rural)
        .set_global_opts(
            title_opts=opts.TitleOpts("Scatter3D-基本示例"),xaxis_opts=opts.AxisOpts(is_show=True)
        )
    )
    return c

scatter = scatter3d_base()
scatter.render(path='./3D_scatter.html')

如代码所示,在整张图中我创建了两个3D散点图,一个表示城市,一个表示农村,也是用的add().add()的方法,效果如下:

 

6.总结

在这篇博客中,我介绍了PyEcharts绘制三种图表的方法,并对一些常用的参数及组件进行了说明。可以看出,PyEcharts的架构非常简洁,使用起来也十分方便,可视化效果也很不错。使用过程中,一定要以官方文档为主,一些官方文档未详细说明的地方,通过名称与函数架构,其实也可以推理出来。如果本文有说得不对的地方,欢迎大家批评指正。

猜你喜欢

转载自blog.csdn.net/fun_always/article/details/89854150