【Python】可视化案例二——动态柱形图的实现

前言

在上个案例中,我们展示了如何来利用python实现折线图。众所周知,在数据可视化中,有着许许多多的不同情景,那么单靠我们一个折线图来去表示大量不同的数据情景,显然是不现实的。因此,本案例我们将介绍另外一种图形——动态柱形图。

想象一下,假设让你去把近几十年来每一年GDP全球前八的国家通过可视化展现出来,你会发现折线图在这种情况下并不好用,所以我们需要利用动态柱形图来进行展示。

对于数据可视化,可以分为两个步骤:

  1. 数据处理:包括对文件的读取、检查是否符合JSON规范以及规范化、JSON格式的转化等;
  2. 绘制图表:对于本案例来说就是,设置图像的x,y轴、设置全局选项(标题、工具箱等)。

注:本篇文章针对的读者是入门级的Python选手,如果是小白的话呢,推荐b站先进行入门级的学习再来阅读哦。


步骤一——数据处理

本案例的数据百度网盘链接如下:

链接:https://pan.baidu.com/s/1LiQVYa93ZNJkERBlmqSeNg?pwd=1kzj 
提取码:1kzj

1.读取文件中的数据

首先第一步就是要从文件中把数据读取出来,利用open函数将文件以“读”的形式打开,然后就是读取文件内容。与上个案例不同的是,本案例的数据是按行分布的,所以在读取文件内容的时候,我们不是用read()函数来读取而是用readlines()来读取。数据样例以及代码示例如下:

# 打开文件,注意encoding的类型有可能不一定的是UTF-8
f=open("D:\学习资料\pythan\资料\可视化案例数据\动态柱状图数据\新建文本文档.txt","r",encoding="UTF-8")
# 由于数据是按行分布的,所以要用readlines来按行读取
data_lines=f.readlines() 
# 关闭文件
f.close()  

 2.将数据装进字典容器中

对于上图给出的数据中我们可以观察到,每一行仅仅是用逗号分割开的,这样的数据我们用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存入字典中

3.将数据进一步处理成柱状图所需的形式

既然我们需要每一年GDP前八的国家,我们需要进行如下步骤:

  1. 将每一年的年份进行升序排序,这里的年份就是字典的key;
  2. 通过for循环将每一年的GDP进行排序操作,并通过列表的切片取出前八的国家;
  3. 通过for循环来生成柱状图所需的x,y轴所需的数据。

代码示例如下:

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")

总结 

  •  文件的读取操作以及按行读取f.readlines()
  • data_lines.pop(0)删除第一行操作,利用了pop()函数
  • 对于没有组织的数据形式,我们可以将其装进数据容器进行处理,例如用split转化为列表进行处理
  • 对于给字典的key值添加数据,需要利用捕获异常操作,再进行append添加的操作
  • 取出字典所有key值用dict.keys()
  • sorted是默认进行升序排序但不能自定义排序方式,sort可以自定义排序方式,常与lambda一起使用
  • 数据的反转reverse(),以及反转柱状图reversal_axis()
  • 添加标题全局选项,添加时间线,设置时间线自动播放
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值