在上个案例中,我们展示了如何来利用python实现折线图。众所周知,在数据可视化中,有着许许多多的不同情景,那么单靠我们一个折线图来去表示大量不同的数据情景,显然是不现实的。因此,本案例我们将介绍另外一种图形——动态柱形图。
想象一下,假设让你去把近几十年来每一年GDP全球前八的国家通过可视化展现出来,你会发现折线图在这种情况下并不好用,所以我们需要利用动态柱形图来进行展示。
对于数据可视化,可以分为两个步骤:
注:本篇文章针对的读者是入门级的Python选手,如果是小白的话呢,推荐b站先进行入门级的学习再来阅读哦。
本案例的数据百度网盘链接如下:
链接:https://pan.baidu.com/s/1LiQVYa93ZNJkERBlmqSeNg?pwd=1kzj
提取码:1kzj
首先第一步就是要从文件中把数据读取出来,利用open函数将文件以“读”的形式打开,然后就是读取文件内容。与上个案例不同的是,本案例的数据是按行分布的,所以在读取文件内容的时候,我们不是用read()函数来读取而是用readlines()来读取。数据样例以及代码示例如下:
# 打开文件,注意encoding的类型有可能不一定的是UTF-8
f=open("D:\学习资料\pythan\资料\可视化案例数据\动态柱状图数据\新建文本文档.txt","r",encoding="UTF-8")
# 由于数据是按行分布的,所以要用readlines来按行读取
data_lines=f.readlines()
# 关闭文件
f.close()
对于上图给出的数据中我们可以观察到,每一行仅仅是用逗号分割开的,这样的数据我们用python并不是很好处理。不过,好在我们学过python的一些基本的数据容器,像元组、列表、字典等等,这里根据我们的需求,我们需要将数据装进字典里。
原因就在于,我们案例的需求是把1960年-2019年中每一年的GDP前八的国家用柱状图表示出来。我们知道,在每一年的国家是不会发生变化(苏联例外),会发生变化的就是年份和GDP,那么根据我们的需求,不难看出年份是最为关键的,我们需要用年份来指向当年的国家以及其GDP。所以,字典中的key能够很好的满足我们的需求。
理解之后,我们的代码示例如下:
# 由于数据的第一行是没用的,所以利用pop来将其删除
data_lines.pop(0)
# 创建一个空的字典
data_dict={}
# 按行来对数据进行处理
for line in data_lines:
# 这里通过split函数先将每一行的数据转化成列表,以便于取出单个的数据
year=int(line.split(",")[0]) # 读取的出来的year是字符串格式,需要将其转化成整数格式
country=line.split(",")[1] # 取出国家
gdp=float(line.split(",")[2]) # 有的GDP数据是以科学计数法的形式出现的,为了统一全部转化成浮点型
# 这里是排除异常的操作
try:
data_dict[year].append([country,gdp])
except KeyError:
data_dict[year]=[]
data_dict[year].append([country,gdp])
注:可能有一些同学对于排除异常的操作有些不解,可能会觉得为啥不直接往字典中添加数据呢。这里的原因在于,假设说字典中存在你给的key值,那么我直接进行添加数据即可。如果不存在,那么编译器将会报错——出现"KeyError",那么这个时候我们就相当于重新创建了一个该key值的典,然后再进行添加数据操作。
暴力解法:如果你不想考虑那么多,或者你只是单纯嫌麻烦而已,其实还有一种暴力操作。就是在最开始的时候通过for循环直接将字典中的每个key值进行赋空操作,即不管字典中是否存在key值一律重新创建该key值的字典。代码示例如下:
# 由于数据的第一行是没用的,所以利用pop来将其删除
data_lines.pop(0)
# 创建一个空的字典
data_dict={}
# 对每个key值的字典赋空
for i in list(range(1960,2020)):
data_dict[i]=[]
# 按行来对数据进行处理
for line in data_lines:
year=int(line.split(",")[0]) # 读取的出来的year是字符串格式,需要将其转化成整数格式
country=line.split(",")[1] # 取出国家
gdp=float(line.split(",")[2]) # 有的GDP数据是以科学计数法的形式出现的,为了统一全部转化成浮点型
data_dict[year].append([country,gdp]) # 将每年的国家以及相应的GDP存入字典中
既然我们需要每一年GDP前八的国家,我们需要进行如下步骤:
代码示例如下:
sorted_year_list=sorted(data_dict.keys()) # 取出字典所有的key值,按照升序排序,keys()可以完成这项操作
# 按照1960年份来用for循环来取出每年GDP前八的国家
for year in sorted_year_list:
data_dict[year].sort(key=lambda element:element[1],reverse=True) # sort函数的使用,以及匿名函数lambda
year_data=data_dict[year][0:8] # 列表的切片
# 创建储存x,y轴数据的列表
x_data=[]
y_data=[]
for country_gdp in year_data:
x_data.append(country_gdp[0])
y_data.append(country_gdp[1]/100000000) #以亿为单位
至此,数据处理步骤全部完成。
绘制图表的操作大多都是些函数的使用,如果一些同学对于这些绘制图表的函数不熟悉的话,请自行百度吧。代码示例如下:
bar=Bar() # 创建柱状图对象
#为了使GDP高的国家排在最上面,直接将输入的数据进行反转操作
x_data.reverse()
y_data.reverse()
bar.add_xaxis(x_data)
bar.add_yaxis("GDP(亿)",y_data,label_opts=LabelOpts(position="right"))
bar.reversal_axis() # 将柱状图横过来
# 全局选项,设置标题
bar.set_global_opts(
title_opts=TitleOpts(title=f"{year}年全球前八GDP数据")
)
# 添加时间线
timeline.add(bar,str(year))
# 设置时间线自动播放
timeline.add_schema(
play_interval=1000, # 变换的时间间隔
is_timeline_show=True,
is_loop_play=True, # 是否循环播放
is_auto_play=True # 自动跳转
)
timeline.render("1960-2019全球GDP前八的国家.html")
整体代码实际上就是以上代码的一个连接,除此之外的,整体代码还多了一个导入第三方包的操作以及设置时间线的主题——【timeline=Timeline({"theme":ThemeType.LIGHT})】。
from pyecharts.charts import *
from pyecharts.options import *
from pyecharts.globals import *
# 打开文件,注意encoding的类型有可能不一定的是UTF-8
f=open("1960-2019全球GDP数据.txt","r",encoding="UTF-8")
# 由于数据是按行分布的,所以要用readlines来按行读取
data_lines=f.readlines()
# 关闭文件
f.close()
# 由于数据的第一行是没用的,所以利用pop来将其删除
data_lines.pop(0)
timeline=Timeline({"theme":ThemeType.LIGHT}) # 设置动态图的主题
# 创建一个空的字典
data_dict={}
# 对每个key值的字典赋空
for i in list(range(1960,2020)):
data_dict[i]=[]
# 按行来对数据进行处理
for line in data_lines:
year=int(line.split(",")[0]) # 读取的出来的year是字符串格式,需要将其转化成整数格式
country=line.split(",")[1] # 取出国家
gdp=float(line.split(",")[2]) # 有的GDP数据是以科学计数法的形式出现的,为了统一全部转化成浮点型
# data_dict[year].append([country,gdp]) # 将每年的国家以及相应的GDP存入字典中
# 这里是排除异常的操作
try:
data_dict[year].append([country,gdp])
except KeyError:
data_dict[year]=[]
data_dict[year].append([country,gdp])
sorted_year_list=sorted(data_dict.keys()) # 取出字典所有的key值,按照升序排序,keys()可以完成这项操作
# 按照1960年份来用for循环来取出每年GDP前八的国家
for year in sorted_year_list:
data_dict[year].sort(key=lambda element:element[1],reverse=True) # sort函数的使用,以及匿名函数lambda
year_data=data_dict[year][0:8] # 列表的切片
# 创建储存x,y轴数据的列表
x_data=[]
y_data=[]
for country_gdp in year_data:
x_data.append(country_gdp[0])
y_data.append(country_gdp[1]/100000000) #以亿为单位
bar=Bar() # 创建柱状图对象
#为了使GDP高的国家排在最上面,直接将输入的数据进行反转操作
x_data.reverse()
y_data.reverse()
bar.add_xaxis(x_data)
bar.add_yaxis("GDP(亿)",y_data,label_opts=LabelOpts(position="right"))
bar.reversal_axis() # 将柱状图横过来
# 全局选项,设置标题
bar.set_global_opts(
title_opts=TitleOpts(title=f"{year}年全球前八GDP数据")
)
# 添加时间线
timeline.add(bar,str(year))
# 设置时间线自动播放
timeline.add_schema(
play_interval=1000, # 变换的时间间隔
is_timeline_show=True,
is_loop_play=True,
is_auto_play=True
)
timeline.render("1960-2019全球GDP前八的国家.html")