目录
文章目录
前言
一、数据爬取
二、数据预处理
三、Pyecharts可视化
3.1 2020东京奥运会各国金牌分布图
3.2 2020东京奥运会奖牌榜详情
3.3 2020东京奥运会中国各项目获奖详情
四、数据大屏布局
总结
前言
本文基于requests库爬取的奥运会相关数据,利用pandas库对数据进行处理之后,最后介绍了如何利用pyecharts库制作可视化大屏。
一、数据爬取
import requests
import pandas as pd
from pprint import pprint
导入相关库
requests库用于发起网页请求,获取网页中的源代码;
pandas库用于存储和读取获取到的信息;
pprint库是漂亮的打印,对于json格式的数据,能够很好的展示结构,方便我们解析;
url = 'https://app-sc.miguvideo.com/vms-livedata/olympic-medal/total-table/15/110000004609' data1 = requests.get(url).json() # pprint(data1)
这里利用三行代码就可以获取到网页的源代码,利用pprint库,可以清晰的展示json结构,对于我们解析数据很有帮助。
df1 = pd.Dataframe()
for info in data1['body']['allMedalData']:
name = info['countryName']
name_id = info['countryId']
rank = info['rank']
gold = info['goldMedalNum']
silver = info['silverMedalNum']
bronze = info['bronzeMedalNum']
total = info['totalMedalNum']
# 组织数据
orangized_data = [[name,name_id,rank,gold,silver,bronze,total]]
# 然后追加df
df1 = df1.append(orangized_data)
df1.columns = ['名称', 'ID', '排名', '金牌', '银牌', '铜牌', '奖牌总数']
df1
这里利用pandas库对爬取的数据进行处理,转变成结构更清楚的数据框结构。
url = 'https://app-sc.miguvideo.com/vms-livedata/olympic-medal/detail-total/15/110000004609'
data2 = requests.get(url).json()
#pprint(data2)
df2 = pd.Dataframe()
for info in data2['body']['medalTableDetail']:
english_name = info['countryName']
name_id = info['countryId']
award_time = info['awardTime']
item_name = info['bigItemName']
sports_name = info['sportsName']
medal_type = info['medalType']
# 组织数据
orangized_data = [[english_name,name_id,award_time,item_name,sports_name,medal_type]]
# 然后追加df
df2 = df2.append(orangized_data)
df2.columns = ['英文缩写', 'ID', '获奖时间', '项目名', '运动员', '金牌类型']
df2
对于另外一个网页,我们采取同样的方式对数据进行爬取和处理。
二、数据预处理
由于使用pyecharts绘制世界地图时,名称必须是英文的,所以我们需要将这里的中文名称映射为英文名称。 我们要做的就是将它与表格中的数据,做个映射转换。先把它转换为一个Excel文件,方便我们以后直接使用。
with open("D:/和鲸数据/数据可视化大屏!绘制全流程!/国家名中英文对照表.txt","r",encoding="utf-8") as f:
x = f.read()
df3 = pd.Dataframe()
for i in x.split("n"):
x = i.split(":")[0].strip()
y = i.split(":")[1].strip()
orangined_data = [[x,y]]
df3 = df3.append(orangined_data)
df3.columns = ["名称","英文名称"]
df3.to_excel("D:/和鲸数据/数据可视化大屏!绘制全流程!/国家名中英文对照表.xlsx",index=None)
表格df1表示各国奖牌数,表格df3表示国家名中英文对照表,利用上述两张表,我们可以左连接,将英文名称添加到df1表上。
df4 = pd.merge(df1,df3,on="名称",how="left") df4.head(10)
表格df5表示运动项目获奖详情。
df5 = df2 df5
此时,我们又可以将df4和df5做一个左连接,将这两张表合成一张大表,就可以得到不同国家不同项目获得的奖牌数。
df6 = pd.merge(df4,df5,on="ID",how="left") df6.head(10)
上面得到的表df6,表中金牌类型是数字1、2、3,分别代表金牌、银牌、铜牌。因此,我们自己再定义一个df7。
x = {"获奖名次":["金牌","银牌","铜牌"],"金牌类型":[1,2,3]}
df7 = pd.Dataframe(x)
df7
我们拿df6与自己构造得到的df7再做一个左连接,就可以的到最后完整的表了。
df8 = pd.merge(df6,df7,on="金牌类型",how="left") df8.head(10)
三、Pyecharts可视化
本文选用2020东京奥运会各国金牌分布图、2020东京奥运会奖牌榜详情、2020东京奥运会中国各项目获奖详情。
这类图表都很简单,参照官方文档就可以学习。图表配色都使用的Pyecharts默认颜色,实际使用时可以选择合适的风格。
# 方法一 data_list = [[i,j] for i,j in zip(df4['英文名称'], df4['奖牌总数'])] data_list[:5] # 方法二 data_list1 = [list(z) for z in zip(df4['英文名称'], df4['奖牌总数'])] data_list1[:5]
3.1 2020东京奥运会各国金牌分布图
数据准备好了,开始利用pyecharts绘制世界地图。
from pyecharts import options as opts
from pyecharts.charts import Map
c = (
Map()
.add("", data_list, "world",
is_map_symbol_show=False,
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="2020东京奥运会各国金牌分布图"),
visualmap_opts=opts.VisualMapOpts(max_=100)
)
)
c.render_notebook()
3.2 2020东京奥运会奖牌榜详情
from pyecharts import options as opts
from pyecharts.charts import Bar
c = (
Bar()
.add_xaxis(df4['名称'].head(25).tolist())
.add_yaxis("金牌", df4['金牌'].head(25).tolist(), stack="stack1")
.add_yaxis("银牌", df4['银牌'].head(25).tolist(), stack="stack1")
.add_yaxis("铜牌", df4['铜牌'].head(25).tolist(), stack="stack1")
.set_series_opts(
label_opts=opts.LabelOpts(
is_show=True,
position="inside",
font_size=12,
color='#FFFFFF'
)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="2020东京奥运会奖牌榜详情"),
xaxis_opts=opts.AxisOpts(
type_='category',
axislabel_opts=opts.LabelOpts(rotate=45)
)
)
)
c.render_notebook()
3.3 2020东京奥运会中国各项目获奖详情
将中国各项目获奖详情进行汇总,并进行降序排列,最后转换成列表格式。
df9 = df8[df8['名称'] == '中国'].groupby('项目名')['项目名'].count()
df9
df9 = df9.sort_values(0, ascending=False)
df9
df10 = [[i,j] for i,j in zip(df9.index,df9.values)]
df10
from pyecharts import options as opts
from pyecharts.charts import Pie
c = (
Pie()
.add("", [['跳水', 12], ['射击', 11], ['举重', 8], ['竞技体操', 8], ['乒乓球', 7], ['游泳', 6], ['羽毛球', 6], ['田径', 5], ['静水皮划艇', 3], ['蹦床体操', 3], ['自由式摔跤', 3], ['赛艇', 3], ['空手道', 2], ['拳击', 2], ['帆船', 2], ['花样游泳', 2], ['跆拳道', 1], ['场地自行车赛', 1], ['古典式摔跤', 1], ['击剑', 1], ['三人篮球', 1]],
center=["50%", "60%"],)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
c.render_notebook()
四、数据大屏布局
from pyecharts import options as opts
from pyecharts.charts import Bar, Grid, Page, Pie, Map
from pyecharts.commons.utils import JsCode
from pyecharts.components import Table
Pyecharts进行可视化大屏第二步就是组合图表,大致可分为四类:
Grid:并行多图
Page:顺序多图
Tab:选项卡多图
Timeline:时间线轮播多图
官方文档:pyecharts - A Python Echarts Plotting Library built with love.
这里用Page(顺序多图)居多,在组合图表之前,还要先把前面的图表绘制代码改为函数。
def map_world() -> Map:
c = (
Map(init_opts=opts.InitOpts(chart_id=2, bg_color='#ADD8E6'))
.add("", data_list, "world",
is_map_symbol_show=False,
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="2020东京奥运会各国金牌分布图"),
visualmap_opts=opts.VisualMapOpts(max_=100)
)
)
return c
def bar_medals() -> Bar:
c = (
Bar(init_opts=opts.InitOpts(chart_id=3, bg_color='#ADD8E6'))
.add_xaxis(df4['名称'].head(25).tolist())
.add_yaxis("金牌", df4['金牌'].head(25).tolist(), stack="stack1")
.add_yaxis("银牌", df4['银牌'].head(25).tolist(), stack="stack1")
.add_yaxis("铜牌", df4['铜牌'].head(25).tolist(), stack="stack1")
.set_series_opts(label_opts=opts.LabelOpts(is_show=True, position="inside", font_size=12, color='#FFFFFF'))
.set_global_opts(title_opts=opts.TitleOpts(title="2020东京奥运会奖牌榜详情"),
xaxis_opts=opts.AxisOpts(type_='category',
axislabel_opts=opts.LabelOpts(
rotate=45),
))
)
return c
def pie_china() -> Pie:
c = (
Pie(init_opts=opts.InitOpts(chart_id=4, bg_color='#ADD8E6'))
.add("", [['跳水', 12], ['射击', 11], ['举重', 8], ['竞技体操', 8], ['乒乓球', 7], ['游泳', 6], ['羽毛球', 6], ['田径', 5], ['静水皮划艇', 3], ['蹦床体操', 3], ['自由式摔跤', 3], ['赛艇', 3], ['空手道', 2], ['拳击', 2], ['帆船', 2], ['花样游泳', 2], ['跆拳道', 1], ['场地自行车赛', 1], ['古典式摔跤', 1], ['击剑', 1], ['三人篮球', 1]],
center=["50%", "60%"],)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
return c
def title():
c = (
Pie(init_opts=opts.InitOpts(chart_id=1, bg_color='#ADD8E6'))
.set_global_opts(
title_opts=opts.TitleOpts(title="2020东京奥运会奖牌榜",
title_textstyle_opts=opts.TextStyleOpts(font_size=36, color='#000000'),
pos_left='center',
pos_top='middle'))
)
return c
page = Page(layout=Page.DraggablePageLayout, page_title="2020东京奥运会奖牌榜")
# 在页面中添加图表
page.add(
title(),
map_world(),
bar_medals(),
pie_china(),
)
page.render('D:/和鲸数据/数据可视化大屏!绘制全流程!/可视化大屏.html')
调用绘制函数后生成一个 可视化大屏.html 文件。
打开后可以其中的图片进行拖拽,来实现自定义布局。
对图片布局完毕后,点击左上角“save config”对布局文件进行保存。
最后,运行下面这行代码,调用保存好的布局文件,重新生成html。
a = page.save_resize_html('可视化大屏.html', cfg_file='chart_config.json', dest='奥运.html')
总结
这样就实现了一次数据可视化——大屏展示。
但还有还有很多不足之处,比如图表配色没有特殊去做调整。
整张大屏只是一个静态的展示,而非具有商业场景的数据仪表盘。同时,数据可视化大屏仪表盘往往更倾向于用BI软件生成,例如Tableau只需拖拽既可实现相同的功能,操作更加便捷。



