6

【可视化】全运会历届金牌榜

 3 years ago
source link: https://zhuanlan.zhihu.com/p/411810602
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【可视化】全运会历届金牌榜

上海交通大学 计算机应用技术硕士

第十四届全国运动会已经开始了,大家有看比赛吗?你最喜欢哪项运动?各位家乡选手都表现得如何?

借这个机会,我来给大家演示一个基本的数据采集并可视化的案例:

将历届全运会的金牌榜可视化

1. 数据整理

我没有找到现成的结构化数据表格,不过找到这样一个文本数据:

v2-5cb1ae9d579171d2da023e79abff30b8_720w.jpghttp://blog.sina.com.cn/s/blog_4efe65c30102eik8.html

格式还算比较规整,稍微处理下就可以使用。(这里是1~12届,上一届第13届因为开始取消奖牌榜了,我就不管了,不影响我们展示)

于是我把数据全部复制下来,然后通过 SublimeText正则查找替换功能做一下初步的处理。平常一些简单的文本或数据处理,我都会这么做,不一定非要用代码处理。好一点的文本编辑器也都有类似的功能。

v2-c32a27da57646ee9e3202b8f074200fc_720w.jpg

把多余的文字删除掉之后,剩下的就是只有空行和 ┃ 符号分隔的数据,用代码很容易读取:

import pandas as pd
is_change = True
count = 12
all_data = []     # 记录历届成绩
data = []         # 记录一届成绩
writer = pd.ExcelWriter('history.xls')
watches = set()
with open('history.txt') as f:    
    for line in f:
        if line.strip():
            # 非空行
            if is_change:
                is_change = False
            # 读取、清理空格、记录数据
            data.append([l.strip() for l in line.split('┃')])
        else:
            # 遇到空行,结束一届的记录
            if not is_change:
                # 记录数据
                df = pd.DataFrame(data)
                all_data.append(df)
                # 写入文件
                df.to_excel(writer, sheet_name=f'No.{count}', index=False)
                # 把前3名加入集合
                top3 = list(df[1][:3])
                watches.update(top3)
                # 重置参数
                is_change = True
                count -= 1
                data = []
writer.save()

将每届的奖牌榜存成一个单独的 DataFrame,再全部放进一个 list 列表里。顺便我还把数据存成了 excel。(文末会提供数据和代码下载)

同时,为了展示方便,我只筛选出了历届曾经拿过前三的队伍,用于后续作图,分别是:

上海、北京、山东、广东、江苏、解放军、辽宁

从所有数据中,把这几支队伍的金牌数依次取出,保存成列表:

gold = {}
all_data.reverse()
for team in watches:
    gold[team] = []
    for data in all_data:
        gold[team].append(float(data[data[1]==team][2]))

2. Matplotlib 折线图

Python 做可视化图表最常用的库就是 matplotlib。代码很简单:

import matplotlib.pyplot as plt

for team in gold:
    plt.plot(gold[team], linewidth=4, label=team)
plt.legend()

折线图很适合展示随时间变化的数据,也适合多组同类数据的对比。

比如这张图上,可以直观地看出,解放军队在最初两届获得了远超其他队的金牌,而像山东、辽宁、江苏的金牌数量整体呈比较明显的上升趋势。

如果不做可视化,只是盯着密密麻麻的数字,那可能眼睛都要看瞎了。

顺便说下,图表上显示中文的时候会出现显示为 的情况,需要额外做处理,我这里用的方法是自己下载一个字体文件使用:

from pylab import mpl
font = mpl.font_manager.FontProperties(fname='simhei.ttf', size=15)
plt.legend(prop=font)

另外还有一种方法是:

plt.rcParams['font.sans-serif'] = ['SimHei']

3. PyEcharts 折线图

Matplotlib 的图表简单实用,功能也很强大,但都是静态的。如果需要可交互的动态图表,则可以使用 pyecharts 库。

用法也很简单:

from pyecharts.charts import Line

line = Line()
line.add_xaxis(xaxis_data=range(1, 13))
for team in gold:
    line.add_yaxis(team, gold[team])
line.render_notebook()

在这个图上,你可以选择隐藏/显示部分数据,鼠标移到某个节点上是也会显示详细信息。

特别提醒两点:

1. 我这里是在 jupyter notebook 上进行开发(数据分析可视化推荐使用),所以可以直接调用 .render_notebook() 显示动态图表。如果你是其他 IDE,可以改成 .render("文件名.html") 的方式输出结果页面。

2. PyEcharts 之前做过较大更新,以至于网上很多教程里的用法在新版本上已经无法使用了。所以你在通过网上资料学习 PyEcharts 时,一定要看清版本,建议看新出的教程或官网的例子。

以上就是将全运会历届金牌榜进行可视化展示的学习案例。有什么疑问,欢迎大家在留言中讨论,或将代码问题发至我们的答疑论坛上,我将会为大家解答。

数据及代码:

https://gitee.com/crossin/snippet/tree/master/sports

如果文章对你有帮助,欢迎转发/点赞/收藏~

获取更多教程和案例,

欢迎搜索及关注:Crossin的编程教室

每天5分钟,轻松学编程。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK