7. PyEcharts

1. json 数据格式的转换

什么是 json
json 是一种轻量级的数据交互格式。可以按照 json 指定的格式去组织和封装数据。
json 本质上是一个带有特定格式的字符串

json 主要功能
json 就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。

各种语言存储数据的容器不尽相同,在 Python 中有字典,而其它语言可能没有字典,这就为不同语言传递数据带来了不便。此时,json 作为一种非常好的中转数据格式,就发挥了作用。

如下图,以 Python 和 C 语言互传数据为例:
7. PyEcharts_第1张图片

json 数据格式
json 本质是字符串,字符串的内容分为两种:
(1) 字典
{"name":"admin","age":18}
(2) 内嵌字典的列表
[{"name":"admin","age":18},{"name":"root","age":16},{"name":"张三","age":20}]

Python 和 Json 数据的相互转化
(1) python 列表 / 字典 ➡ json 字符串:
data = json.dumps(data)
如果有中文,可以带上 ensure_ascii=False 参数来确保中文正常转换。

(2) json 字符串 ➡ python 列表 / 字典:
data = json.loads(data)

#导入json模块
import json

#准备符合json格式要求的python数据
data1 = {"name":"jack","age":20}
data2 = [{"name":"老王","age":16},{"name":"张三","age":20}]

print("把python数据转化为json数据")
#ensure_ascii=False:不使用ascii去转换,而是把内容直接输出,否则中文被转成Unicode字符输出
data1 = json.dumps(data1,ensure_ascii=False)
print(f"data1: {type(data1)}")
print(data1)
data2 = json.dumps(data2,ensure_ascii=False)
print(f"data2: {type(data2)}")
print(data2)

print("把json数据转化为python数据")
data1 = json.loads(data1)
print(f"data1: {type(data1)}")
print(data1)
data2 = json.loads(data2)
print(f"data2: {type(data2)}")
print(data2)

输出结果:

把python数据转化为json数据
data1: <class 'str'>
{"name": "jack", "age": 20}
data2: <class 'str'>
[{"name": "老王", "age": 16}, {"name": "张三", "age": 20}]
把json数据转化为python数据
data1: <class 'dict'>
{'name': 'jack', 'age': 20}
data2: <class 'list'>
[{'name': '老王', 'age': 16}, {'name': '张三', 'age': 20}]

2. PyEcharts 模块介绍

如果要做出数据可视化效果图,可以借助 PyEcharts 模块来完成。

Echarts 是由百度开源的数据可视化模块,凭借良好的交互性、精巧的图表设计,得到了众多开发者的认可。而 Python 是门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,PyEcharts 诞生了。

安装 PyEcharts
参照 6. Python 异常、模块与包 中的 3.2

查看官方示例
打开官方画廊:https://gallery.pyecharts.org/#/README

3. pyecharts 生成折线图

3.1 绘制简单折线图

from pyecharts.charts import Line
# 创建一个折线图对象
line = Line()
# 添加x轴数据
line.add_xaxis(["中国","美国","英国"])
# 添加y轴数据(GDP是图例中的字)
line.add_yaxis("GDP",[30,20,10])
# 将代码生成为图像
line.render()

运行完成后,pycharm 左侧项目窗口生成 render.html 文件:
7. PyEcharts_第2张图片
打开 render.html 文件,右上角有浏览器选项,任选一个自己已安装的:
7. PyEcharts_第3张图片
在浏览器中就能看到生成的折线图:
7. PyEcharts_第4张图片

3.2 PyEcharts 常用的两类配置选项

全局配置选项:针对整个图像,如:标题、图例、鼠标、工具箱。
系列配置选项:针对轴数据。

全局配置选项可以通过 set_global_opts 方法来配置,相应的选项和选项的功能如下:

from pyecharts.charts import Line
# 所有可配置的选项都在pyecharts.options中
# TitleOpts:标题配置项功能,LegendOpts:图例配置项,ToolboxOpts:工具箱配置项,VisualMapOpts:视觉映射配置项
from pyecharts.options import TitleOpts, LegendOpts, ToolboxOpts, VisualMapOpts
# 创建一个折线图对象
line = Line()
# 添加x轴数据
line.add_xaxis(["中国","美国","英国"])
# 添加y轴数据
line.add_yaxis("GDP",[30,20,10])
# 设置全局配置项set_global_opts
line.set_global_opts(#关键字参数
    # 标题是“GDP展示”,水平居中,距底部1%的距离
    title_opts=TitleOpts("GDP展示", pos_left="center", pos_bottom="1%"),
    # 图例是否展示, 默认就是显示的
    legend_opts=LegendOpts(is_show=True),
    # 工具箱是否展示
    toolbox_opts=ToolboxOpts(is_show=True),
    #视觉映射是否展示
    visualmap_opts=VisualMapOpts(is_show=True)
)
# 将代码生成为图像
line.render()

7. PyEcharts_第5张图片

3.3 折线图数据处理实例

所需资料:
链接:https://pan.baidu.com/s/1nI0lFNOxptAmQ3kh5UHMEQ?pwd=sumg
提取码:sumg

要求:读取美日印三国的疫情数据,提取2020年每天的疫情数据,并用折线图显示。

效果图:
7. PyEcharts_第6张图片
代码:

import json
from pyecharts.charts import Line
from pyecharts.options import TitleOpts, LabelOpts, VisualMapOpts
f_us = open("file/折线图数据/美国.txt", "r", encoding="utf-8")
f_jp = open("file/折线图数据/日本.txt", "r", encoding="utf-8")
f_in = open("file/折线图数据/印度.txt", "r", encoding="utf-8")
# 获取文件全部内容
us_data = f_us.read()
jp_data = f_jp.read()
in_data = f_in.read()
# 去掉不符合json格式的开头
us_data = us_data.replace("jsonp_1629344292311_69436(","")
jp_data = jp_data.replace("jsonp_1629350871167_29498(","")
in_data = in_data.replace("jsonp_1629350745930_63180(","")
# 去掉不符合json格式的结尾
us_data = us_data[:-2]
jp_data = jp_data[:-2]
in_data = in_data[:-2]
# json字符串转python字典
us_data = json.loads(us_data)
jp_data = json.loads(jp_data)
in_data = json.loads(in_data)
# 提取出美国2020年所有的日期,以及每天的确诊病例
us_trend_data = us_data["data"][0]["trend"]
us_x_data = us_trend_data["updateDate"][:314]
us_y_data = us_trend_data["list"][0]["data"][:314]
# 提取出日本2020年每天的确诊病例
jp_trend_data = jp_data["data"][0]["trend"]
jp_y_data = jp_trend_data["list"][0]["data"][:314]
# 提取出印度2020年每天的确诊病例
in_trend_data = in_data["data"][0]["trend"]
in_y_data = in_trend_data["list"][0]["data"][:314]
# 图表对象
line = Line()
# 添加x轴数据,三国公用即可
line.add_xaxis(us_x_data)
# 添加y轴数据
# label_opts是一个系列配置选项,用于配置折线上节点的数据是否显示
line.add_yaxis("美国",us_y_data,label_opts=LabelOpts(is_show=False))
line.add_yaxis("日本",jp_y_data, label_opts=LabelOpts(is_show=False))
line.add_yaxis("印度",in_y_data, label_opts=LabelOpts(is_show=False))
# 设置全局选项
line.set_global_opts(
    # 标题设置
    title_opts= TitleOpts("2020 年美日印三国新冠确诊病例趋对比",pos_left="center", pos_bottom="1%"),
)
# 调用render方法,生成图表
line.render()
# 关闭文件对象
f_us.close()
f_jp.close()
f_in.close()

4. 地图

4.1 地图的基础使用

from pyecharts.charts import Map
from pyecharts.options import VisualMapOpts
# 创建地图对象
map = Map()
# 准备数据
data = [
    ("北京", 4),
    ("上海", 20),
    ("山东", 90),
    ("江西", 200)
]
# 添加数据
map.add("测试地图",data,"china")
# 设置全局配置选项
map.set_global_opts(
    # 视觉映射
    visualmap_opts=VisualMapOpts(
        is_show=True,
        # 是否自定义视觉映射的分段
        is_piecewise=True,
        # 属于哪个段就显示哪个颜色
        pieces=[
            {"min": 1, "max": 9, "label": "1-9", "color": "#ccffff"},
            {"min": 10, "max": 99, "label": "10-99", "color": "#ff6666"},
            {"min": 100, "max": 500, "label": "100-500", "color": "#990033"}
        ]
    )
)
# 显示地图
map.render()

上面代码也会生成一个 render.html 文件,在浏览器中的查看方式与折线图相同。

7. PyEcharts_第7张图片

4.2 全国疫情地图绘制

要求:各省份确诊人数所在的范围不同,则显示的颜色不同。鼠标悬停于某个省份时,显示该省份的确诊人数。

效果图:
7. PyEcharts_第8张图片
代码:

import json
from pyecharts.charts import Map
from pyecharts.options import VisualMapOpts
# 文件读取
f = open("file/地图数据/疫情.txt", "r", encoding="utf-8")
data = f.read()
f.close()
# 将json字符串转换成python字典
data_dict = json.loads(data)
# 获取各省
province_data_list = data_dict["areaTree"][0]["children"]
# 用于存放元组,每个元组都含有一个省的数据(省名称, 确诊人数)
data_list = []
# 遍历各省,获取每个省份的名称、确诊人数, 添加到data_list
for provience_data in province_data_list:
    province_name = provience_data["name"]
    province_confirm = provience_data["total"]["confirm"]
    data_list.append((province_name, province_confirm))
# 创建地图对象
map = Map()
# 添加数据,第三个参数如果不写,构建的也是中国地图
map.add("疫情人数", data_list, "china")
# 设置全局配置选项
map.set_global_opts(
    visualmap_opts=VisualMapOpts(
        is_show=True,
        # 是否自定义视觉映射的分段
        is_piecewise=True,
        # 属于哪个段就显示哪个颜色
        pieces=[
            {"min": 1, "max": 99, "label": "1-99", "color": "#ccffff"},
            {"min": 100, "max": 999, "label": "100-999", "color": "#ffff99"},
            {"min": 1000, "max": 4999, "label": "1000-4999", "color": "#ff9966"},
            {"min": 5000, "max": 9999, "label": "5000-9999", "color": "#ff6666"},
            {"min": 10000, "max": 99999, "label": "10000-99999", "color": "#cc3333"},
            {"min": 100000, "label": "100000+", "color": "#990033"}
        ]
    )
)
# 显示地图, 自定义生成的html文件名称
map.render("全国疫情地图.html")

4.3 河南省疫情地图绘制

要求:各城市确诊人数所在的范围不同,则显示的颜色不同。鼠标悬停于某个城市时,显示该城市的确诊人数。

效果图:
7. PyEcharts_第9张图片
代码:

import json
from pyecharts.charts import Map
from pyecharts.options import VisualMapOpts
# 文件读取
f = open("file/地图数据/疫情.txt", "r", encoding="utf-8")
data = f.read()
f.close()
# 将json字符串转换成python字典
data_dict = json.loads(data)
# 获取河南各城市的数据
city_data_list = data_dict["areaTree"][0]["children"][3]["children"]
# 用于存放元组,每个元组都含有一个城市的数据(城市名称, 确诊人数)
data_list = []
# 遍历各城市,获取每个城市的名称、确诊人数, 添加到data_list
for city_data in city_data_list:
    # 一定要加市,否则疫情地图不显示颜色
    city_name = city_data["name"] + "市"
    city_confirm = city_data["total"]["confirm"]
    data_list.append((city_name, city_confirm))
# 文件没有济源市的疫情数据,这里可以手动添加上
data_list.append(("济源市", 5))
# 创建地图对象
map = Map()
# 添加数据
map.add("疫情人数", data_list, "河南")
# 设置全局配置选项
map.set_global_opts(
    visualmap_opts=VisualMapOpts(
        is_show=True,
        # 是否自定义视觉映射的分段
        is_piecewise=True,
        # 属于哪个段就显示哪个颜色
        pieces=[
            {"min": 1, "max": 99, "label": "1-99", "color": "#ccffff"},
            {"min": 100, "max": 999, "label": "100-999", "color": "#ffff99"},
            {"min": 1000, "max": 4999, "label": "1000-4999", "color": "#ff9966"},
            {"min": 5000, "max": 9999, "label": "5000-9999", "color": "#ff6666"},
            {"min": 10000, "max": 99999, "label": "10000-99999", "color": "#cc3333"},
            {"min": 100000, "label": "100000+", "color": "#990033"}
        ]
    )
)
# 显示地图, 自定义生成的html文件名称
map.render("河南省疫情地图.html")

5. 柱状图

5.1 基础柱状图的构建

通过 Bar 构架基础柱状图。

from pyecharts.charts import Bar
# 创建Bar对象
bar = Bar()
# 添加x轴数据
bar.add_xaxis(["中国", "美国", "英国"])
# 添加y轴数据, "GDP"为y轴数据的名字
bar.add_yaxis("GDP", [30, 20, 10])
# 显示(绘图)
bar.render("基础柱状图.html")

7. PyEcharts_第10张图片

反转 x、y 轴:可以使用 reversal_axis 方法。

效果:
7. PyEcharts_第11张图片
代码:

from pyecharts.charts import Bar
# 创建Bar对象
bar = Bar()
# 添加x轴数据
bar.add_xaxis(["中国", "美国", "英国"])
# 添加y轴数据, "GDP"为y轴数据的名字
bar.add_yaxis("GDP", [30, 20, 10])
# x、y轴反转
bar.reversal_axis()
# 显示(绘图)
bar.render("基础柱状图.html")

指定标签的显示位置:可以看到,上图中的数据标签(10,20,30)都是在柱状图上方显示。如果向让它们在右侧显示,可以在添加 y 轴数据的同时来指定标签的显示位置。

效果:
7. PyEcharts_第12张图片
代码:

from pyecharts.charts import Bar
from pyecharts.options import LabelOpts
# 创建Bar对象
bar = Bar()
# 添加x轴数据
bar.add_xaxis(["中国", "美国", "英国"])
# 添加y轴数据, "GDP"为y轴数据的名字; 并且让数据标签在右侧显示
bar.add_yaxis("GDP", [30, 20, 10], label_opts=LabelOpts(position="right"))
# x、y轴反转
bar.reversal_axis()
# 显示(绘图)
bar.render("基础柱状图.html")

5.2 基础时间线柱状图的绘制

Timeline()-时间线:普通的柱状图很难动态的描述一个趋势性的数据,pyecharts 就提供了一种解决方案——时间线。如果说一个 Bar、Line 对象是一张图表的话,时间线就是创建一个一维的 x 轴,轴上每一个点就是一个图表对象。

中美英三国 GDP 动态演示效果:
7. PyEcharts_第13张图片
代码:

from pyecharts.charts import Bar, Timeline
from pyecharts.options import LabelOpts
from pyecharts.globals import ThemeType

bar1 = Bar()
bar1.add_xaxis(["中国", "美国", "英国"])
bar1.add_yaxis("GDP", [30, 20, 10], label_opts=LabelOpts(position="right"))
bar1.reversal_axis()

bar2 = Bar()
bar2.add_xaxis(["中国", "美国", "英国"])
bar2.add_yaxis("GDP", [50, 50, 50], label_opts=LabelOpts(position="right"))
bar2.reversal_axis()

bar3 = Bar()
bar3.add_xaxis(["中国", "美国", "英国"])
bar3.add_yaxis("GDP", [40, 30, 20], label_opts=LabelOpts(position="right"))
bar3.reversal_axis()
# 设置时间线的主题(颜色)
timeline = Timeline(
    {"theme": ThemeType.LIGHT}#蓝黄粉
)
# 将柱状图添加到时间线中, 第二个参数为点的名称
timeline.add(bar1, "点1")
timeline.add(bar2, "点2")
timeline.add(bar3, "点3")
# 设置自动播放
timeline.add_schema(
    # 自动播放的时间间隔,单位毫秒
    play_interval=1000,
    # 是否在自动播放的时候显示时间线,默认
    is_timeline_show=True,
    # 是否自动播放
    is_auto_play=True,
    # 是否循环播放
    is_loop_play=True
)
# 绘图
timeline.render("基础时间线柱状图.html")

附:主题颜色
7. PyEcharts_第14张图片

5.3 动态 GDP 柱状图

列表的 sort 方法

在前面学习过 sorted 函数,可以对数据容器进行排序。
在后面的数据处理中,需要对列表进行排序,并指定排序规则,sorted 函数就无法完成了。这时就需要列表的 sort 方法。

使用方式:
列表.sort(key = 选择排序依据的函数,reverse = True | False)
参数 key:是要求传入的一个函数,表示将列表的每个元素都传入函数中,返回排序的依据。传入的函数有两种形式:普通带名函数、lambda 函数。
参数 reverse:是否反转排序结果,True 表示降序,False 表示升序。

(1) key 传入普通带名函数:

my_list = [["a", 33], ["b", 55], ["c", 11]]
# 定义排序方法
def choose_sort_key(element):
    return element[1]
# 排序,指定排序的依据、降序
my_list.sort(key=choose_sort_key, reverse=True)
print(my_list)

(2) key 传入 lambda 函数:

my_list = [["a", 33], ["b", 55], ["c", 11]]
# 排序,指定排序的依据、降序
my_list.sort(key=lambda element:element[1], reverse=True)
print(my_list)

输出结果:

[['b', 55], ['a', 33], ['c', 11]]

1960~2019 年各国 GDP 动态柱状图

效果:

代码:

from pyecharts.charts import Bar, Timeline
from pyecharts.options import LabelOpts, TitleOpts
from pyecharts.globals import ThemeType
f = open("file/动态柱状图数据/1960-2019全球GDP数据.csv", "r", encoding="GB2312")
# 逐行读取并保存在列表中,每行是列表的一个元素
data_lines = f.readlines()
f.close()
# 去掉第一行
data_lines.pop(0)
# 用于保存各年份内,各国的GDP数据
data_dict = {}
# 将各年份内,各国的GDP数据保存在字典data_dict中
for line in data_lines:#data_lines是一个列表
    year = int(line.split(",")[0])
    country = line.split(",")[1]
    #gdp以亿为单位
    gdp = float(line.split(",")[2]) / 100000000
    try:
        # 字典以year为key,year是列表,下面为该列表添加元素
        data_dict[year].append([country, gdp])
    except KeyError:
        # 若还没有该年份的key
        data_dict[year] = []
        data_dict[year].append([country, gdp])
# 创建时间线对象,设置主题(颜色)
timeline = Timeline(
    {"theme":ThemeType.LIGHT}
)
for year in data_dict:
    # 每年的都把各国按照gdp从大到小的顺序排序
    data_dict[year].sort(key=lambda element:element[1], reverse=True)
    # 取排序后的top8
    year_data = data_dict[year][:8]
    # 准备x、y轴所需数据
    x_data = []
    y_data = []
    for country_data in year_data:
        x_data.append(country_data[0])
        y_data.append(country_data[1])
    x_data.reverse()#元素反转,使gdp高的先显示
    y_data.reverse()
    # 创建柱状图对象
    bar = Bar()
    #为x轴添加数据
    bar.add_xaxis(x_data)
    #为y轴添加数据,y轴数据名称"GDP(亿)",数据标签在右侧显示
    bar.add_yaxis("GDP(亿)", y_data, label_opts=LabelOpts(position="right"))
    # x、y轴反转
    bar.reversal_axis()
    # 柱状图标题
    bar.set_global_opts(
        title_opts=TitleOpts(f"{year}年各国GDP(TOP8)")
    )
    # 将柱状图添加进时间线,方法的第二个参数是str类型,是时间点的名称
    timeline.add(bar, str(year))

timeline.add_schema(
    #时间线默认显示,可以不设置可见性
    play_interval=1000,#播放间隔时间1000ms
    is_auto_play=True,#是否自动播放
    is_loop_play=False#是否循环播放
)
# 绘图
timeline.render("1960-2019GDP前八名的国家.html")

你可能感兴趣的:(Python笔记,python,pyecharts,折线图,柱状图,时间线)