西电-数据可视化-实验四-地理数据可视化
一、实验内容:
利用已有数据CityData.xlsx(请于课程资料库中下载)与已有工具,设计可视化方案,展示2020年全国新冠患者人数随时间的变化过程(下图仅供参考),并完成以下任务:
任务一:统计截止4月1日各省的累计确诊数量,并通过图表展示。
任务二:对每日各省的累计确诊患者数量进行统计,为图像添加时间轴,通过时间轴自动播放演示疫情发展的整个过程。
二、解决思路
(1) 进入pyecharts官网修改demo即可:
实验涉及到的三个图表类型如下:
TimeLine
MapBar
(2) 代码实现:
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Map, Bar, Timeline
# 存放数据的列表
provinces = [] # 省份->去重->排序->bar
confirmed = [] # 某省某地区某天确诊人数
date = [] # 日期->去重->排序->timeline
info = [] # 省份-确诊人数-日期 用于遍历
# 读取文件中的数据
def read_excel(file_name):
df = pd.read_excel(file_name)
# 遍历excel文件的每一行
for _, data in df.iterrows():
global date, provinces, confirmed, info
provinces.append(data[1])
confirmed.append(data[3])
# 格式化日期 如:2021/4/1=>2021/04/01
data[7] = str(data[7].year) + "-" + str("{:0>2d}".format(data[7].month)) + "-" + str(
"{:0>2d}".format(data[7].day))
# my_date = datetime.datetime.strptime(data[7], '%Y-%m-%d')
date.append(data[7])
# info 用于存储excel每一行的完整信息,包括省、确诊人数、日期
info = list(zip(provinces, confirmed, date))
# 对省份去重 便于后续建立字典用于统计同一省份的累计确诊人数
provinces = list(set(provinces))
provinces.sort()
# 对日期去重排序 便于后续建立时间线轮播多图
date = list(set(date))
date.sort()
# # -----------------------task_1----------------------------------
data_for_bar = []
def draw_Bar_for_04_01():
(
Bar()
.add_xaxis(
xaxis_data=provinces
)
.add_yaxis(
series_name="截止4.1日各省累计确诊人数",
y_axis=data_for_bar
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="截止4.1日全国疫情条形图"
),
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(rotate=-45)
),
visualmap_opts=opts.VisualMapOpts(
min_=-1,
max_=1
)
)
.render("bar_04_01.html")
)
# ------------------------task_2------------------------------------
# 下边这些代码是实现整个功能的核心
# 初始化一个字典 动态更新 每当有新的数据读进来时,这个字典里的数据也随即更新
# 这样做的目的就是避免某一天某省数据缺失而导致人数为0
my_dict_map = {
province: 0 for province in provinces}
def creat_data_for_map(day):
# 初始化字典:每个省的累计确诊人数预置为0
my_dict_map_thisday = {
province: 0 for province in provinces}
for elem in info:
if elem[2] == day:
my_dict_map_thisday[elem[0]] += elem[1]
# 用新读入的数据来更新my_dict_map
for key, value in my_dict_map_thisday.items():
# 有新的数据
if value != 0:
my_dict_map[key] = value
# excel中的省必须删除后缀省/市/自治区/壮族/回族/维吾尔才能使用
# 因为Map()里的data_pair接收的参数就是这种格式,否则识别不了
my_data = [[key.strip("省").strip("市").strip("自治区").strip("壮族").strip("回族").strip("维吾尔"), value]
for key, value in my_dict_map.items()]
# 当day="2020-04-01"时调用函数完成任务一bar的绘制
if day == "2020-04-01":
global data_for_bar
data_for_bar = [my_dict_map[province] for province in provinces]
draw_Bar_for_04_01()
return my_data
def draw_Timeline():
# 创建一个时间线轮播图对象
t1 = Timeline()
# 循环创建与时间点相应的map
for day in date:
my_map = (
Map()
.add(
series_name="截止{}全国疫情确诊数量".format(day),
data_pair=creat_data_for_map(day)
)
.set_global_opts(
title_opts=opts.TitleOpts(
title=day + "全国疫情确诊地图",
),
visualmap_opts=opts.VisualMapOpts(
# 是否为分段型
is_piecewise=True,
pieces=[
{
"min": 1, "max": 99, "label": "1-99人", "color": "#FFEFD5"},
{
"min": 100, "max": 999, "label": "100-999人", "color": "#FFD700"},
{
"min": 1000, "max": 9999, "label": "1000-9999人", "color": "#FF6347"},
{
"min": 10000, "max": 999999, "label": ">10000人", "color": "#B22222"},
]
)
)
)
t1.add(my_map, day)
t1.add_schema(
# 是否自动播放
is_auto_play=True,
# 是否循环播放
is_loop_play=True,
# 间隔
play_interval=1000
)
t1.render("timeline_map.html")
if __name__ == '__main__':
filename = "CityData.xlsx"
read_excel(filename)
draw_Timeline()
draw_Bar_for_04_01()
(3)实验细节:
@在本实验中,核心是使用动态更新字典的方法,当某省有最新的数据时,替换掉原先的数据。这样做的一个好处是:如果某省某天没有更新数据,不会出现这一天数据为0的情况。
@本实验的的一个易错点: