数据可视化基础案例[Python]

摘要

这是一篇人类低质量python数据分析文章,于20年暑假学习完成。
参考文章
2020年,世界各地爆发了一起新型冠状病毒肺炎公共卫生事件,给全世界的人民带来了不可估量的损失。时至今日,经过全国人民的共同努力,国内疫情现阶段处于可控的局面。本文将通过使用Python获取百度疫情实时大数据报告中的数据,对获取的数据进行整理,然后绘制成疫情地图进行数据可视化,实现实时的疫情动态记录,便于更精确了解疫情实时情况。

内容结构

在这里插入图片描述
创建get_data.py模块,使用Python的requests库请求数据, 目标网址
,然后对数据进行初步整理,输出数据表;创建execution.py模块用于整理各省份的实时数据;创建draw_map.py模块用于绘制实时疫情地图;最后,编写main.py总模块,对各模块进行整合,实现对整个流程的控制。

内容详情

下面介绍各模块,首先会贴出在Typora中的源码截图,便于直观进行源码阅读,其后附上写入记事本的文本代码和源文件以及各个模块的输出文件。

(1) 获取数据:get_data.py

导入相关模块,创建一个Get_data类,用于封装获取数据的所有函数,其中第一个函数,是一个简单的爬虫,用于爬取目标网站的数据,并将获取的数据写入一个本地目录的文本文件。

import requests
from lxml import etree
import json
import re
import openpyxl


class Get_data():
    def get_data(self):
        # 目标url
        url = "https://voice.baidu.com/act/newpneumonia/newpneumonia/"

        # 伪装请求头
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/80.0.3987.149 Safari/537.36 '
        }

        # 发出get请求
        response = requests.get(url,headers=headers)

        # 将请求的结果写入文件,便于分析
        with open('html.txt', 'w') as file:
            file.write(response.text)

    def get_time(self):
        with open('html.txt','r') as file:
            text = file.read()
        # 获取更新时间
        time_in = re.findall('"mapLastUpdatedTime":"(.*?)"',text)[0]
        time_out = re.findall('"foreignLastUpdatedTime":"(.*?)"',text)[0]
        print('国内疫情更新时间为 '+time_in)
        print('国外疫情更新时间为 '+time_out)
        return time_in,time_out

    def parse_data(self):
        with open('html.txt','r') as file:
            text = file.read()
        # 生成HTML对象
        html = etree.HTML(text)
        # 解析数据
        result = html.xpath('//script[@type="application/json"]/text()')
        # print(type(result))
        result = result[0]
        # print(type(result))
        result = json.loads(result)
        # print(type(result))
        result = json.dumps(result['component'][0]['caseList'])
        # print(result)
        # print(type(result))
        with open('data.json','w') as file:
            file.write(result)
            print('数据已写入json文件...')

        response = requests.get("https://voice.baidu.com/act/newpneumonia/newpneumonia/")
        # 将请求的结果写入文件,便于分析
        with open('html.txt', 'w') as file:
            file.write(response.text)

        # 获取时间
        time_in = re.findall('"mapLastUpdatedTime":"(.*?)"', response.text)[0]
        time_out = re.findall('"foreignLastUpdatedTime":"(.*?)"', response.text)[0]
        print(time_in)
        print(time_out)

        # 生成HTML对象
        html = etree.HTML(response.text)
        # 解析数据
        result = html.xpath('//script[@type="application/json"]/text()')
        print(type(result))
        result = result[0]
        print(type(result))
        result = json.loads(result)
        print(type(result))
        # 以每个省的数据为一个字典
        data_in = result['component'][0]['caseList']
        for each in data_in:
            print(each)
            print("\n" + '*' * 20)

        data_out = result['component'][0]['globalList']
        for each in data_out:
            print(each)
            print("\n" + '*' * 20)

接下来,获取爬取数据的时间,用于体现实时性,其后,设置一个解析函数,将获取的数据写入一个本地目录的.json文件。

       '''
       area --> 大多为省份
       city --> 城市
       confirmed --> 累计
       died --> 死亡
       crued --> 治愈
       relativeTime --> 
       confirmedRelative --> 累计的增量
       curedRelative --> 治愈的增量
       curConfirm --> 现有确诊
       curConfirmRelative --> 现有确诊的增量
       diedRelative --> 死亡的增量
       '''

       # 规律----遍历列表的每一项,可以发现,每一项(type:字典)均代表一个省份等区域,这个字典的前11项是该省份的疫情数据,
       # 当key = 'subList'时,其结果为只有一项的列表,提取出列表的第一项,得到一系列的字典,字典中包含该城市的疫情数据.

       # 将得到的数据写入excel文件
       # 创建一个工作簿
       wb = openpyxl.Workbook()
       # 创建工作表,每一个工作表代表一个area
       ws_in = wb.active
       ws_in.title = "国内疫情"
       ws_in.append(['省份', '累计确诊', '死亡', '治愈', '现有确诊', '累计确诊增量', '死亡增量', '治愈增量', '现有确诊增量'])
       for each in data_in:
           temp_list = [each['area'], each['confirmed'], each['died'], each['crued'], each['curConfirm'],
                        each['confirmedRelative'], each['diedRelative'], each['curedRelative'],
                        each['curConfirmRelative']]
           for i in range(len(temp_list)):
               if temp_list[i] == '':
                   temp_list[i] = '0'
           ws_in.append(temp_list)

导入html.txt文件,进一步解析数据,描述国内的疫情,将疫情中的具体情况体现出来,编写“累计确诊”,“死亡”,“治愈”等字段,然后将其写入xlsx文件中。

	  # 获取国外疫情数据
        for each in data_out:
            print(each)
            print("\n" + '*' * 20)
            sheet_title = each['area']
            # 创建一个新的工作表
            ws_out = wb.create_sheet(sheet_title)
            ws_out.append(['国家', '累计确诊', '死亡', '治愈', '现有确诊', '累计确诊增量'])
            for country in each['subList']:
                list_temp = [country['country'], country['confirmed'], country['died'], country['crued'],
                             country['curConfirm'], country['confirmedRelative']]
                for i in range(len(list_temp)):
                    if list_temp[i] == '':
                        list_temp[i] = '0'
                ws_out.append(list_temp)

            # 保存excel文件
            wb.save('./data.xlsx')

在这里插入图片描述

(2)整理数据:execution.py

导入相关模块,导入前面获取的data.json文件,定义一个函数,用于写入中国疫情各地区实时数据(地区和确诊人数),分别写入两个列表中。同样的,下面定义一个函数,用于写入中国各个省份、直辖市的实时数据。

import draw_map
import json

map = draw_map.Draw_map()
# 格式
# map.to_map_china(['湖北'],['99999'],'1584201600')
# map.to_map_city(['荆门市'],['99999'],'湖北','1584201600')

# 获取数据
with open('data.json', 'r') as file:
    data = file.read()
    data = json.loads(data)


# 中国疫情地图
def china_map(update_time):
    area = []
    confirmed = []
    for each in data:
        print(each)
        area.append(each['area'])
        confirmed.append(each['confirmed'])
        print(area)
    map.to_map_china(area, confirmed, update_time)


# 23个省、5个自治区、4个直辖市、2个特别行政区 香港、澳门和台湾的subList为空列表,未有详情数据

# 省、直辖市疫情地图
def province_map(update_time):
    for each in data:
        city = []
        confirmeds = []
        province = each['area']
        for each_city in each['subList']:
            city.append(each_city['city'] + "市")
            confirmeds.append(each_city['confirmed'])
            map.to_map_city(city, confirmeds, province, update_time)
        if province == '上海' or '北京' or '天津' or '重庆':
            for each_city in each['subList']:
                city.append(each_city['city'])
                confirmeds.append(each_city['confirmed'])
                map.to_map_city(city, confirmeds, province, update_time)

(3)绘制地图:draw_map.py

导入相关模块,创建一个绘制地图的类,封装所有绘图需要的函数,再对数值进行区间划分,对每个区间,给予不同深浅的颜色进行标注。通过数值控制地图标识性的元素,即地图的颜色深浅,我们通过地图上区域的深浅了解该区域疫情情况,颜色越深,表示此地区的数值越大,相应地,该地区的疫情越严重。

from pyecharts import options as opts
from pyecharts.charts import Map
import os


class Draw_map():
    # relativeTime为发布的时间,传入时间戳字符串
    # def get_time(self):
    # relativeTime = int(relativeTime)
    # return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(relativeTime))

    def __init__(self):
        if not os.path.exists('./map/china'):
            os.makedirs('./map/china')

    def get_colour(self, a, b, c):
        result = '#' + ''.join(map((lambda x: "%02x" % x), (a, b, c)))
        return result.upper()

    '''
    参数说明——area:地级市 variate:对应的疫情数据 province:省份(不含省字)
    '''

    def to_map_city(self, area, variate, province, update_time):
        pieces = [
            {"max": 99999999, "min": 10000, "label": "≥10000", "color": self.get_colour(102, 2, 8)},
            {"max": 9999, "min": 1000, "label": "1000-9999", "color": self.get_colour(140, 13, 13)},
            {"max": 999, "min": 500, "label": "500-999", "color": self.get_colour(204, 41, 41)},
            {"max": 499, "min": 100, "label": "100-499", "color": self.get_colour(255, 123, 105)},
            {"max": 99, "min": 50, "label": "50-99", "color": self.get_colour(255, 170, 133)},
            {"max": 49, "min": 10, "label": "10-49", "color": self.get_colour(255, 202, 179)},
            {"max": 9, "min": 1, "label": "1-9", "color": self.get_colour(255, 228, 217)},
            {"max": 0, "min": 0, "label": "0", "color": self.get_colour(255, 255, 255)},
        ]

        c = (
            # 设置地图大小
            Map(init_opts=opts.InitOpts(width='1000px', height='880px'))
                .add("累计确诊人数", [list(z) for z in zip(area, variate)], province, is_map_symbol_show=False)
                # 设置全局变量  is_piecewise设置数据是否连续,split_number设置为分段数,pices可自定义数据分段
                # is_show设置是否显示图例
                .set_global_opts(
                title_opts=opts.TitleOpts(title="%s地区疫情地图分布" % (province),
                                          subtitle='截止%s  %s省疫情分布情况' % (update_time, province), pos_left="center",
                                          pos_top="10px"),
                legend_opts=opts.LegendOpts(is_show=False),
                visualmap_opts=opts.VisualMapOpts(max_=200, is_piecewise=True,
                                                  pieces=pieces,
                                                  ),
            )
                .render("./map/china/{}疫情地图.html".format(province))
        )

    def to_map_china(self, area, variate, update_time):
        pieces = [{"max": 999999, "min": 1001, "label": ">10000", "color": "#8A0808"},
                  {"max": 9999, "min": 1000, "label": "1000-9999", "color": "#B40404"},
                  {"max": 999, "min": 100, "label": "100-999", "color": "#DF0101"},
                  {"max": 99, "min": 10, "label": "10-99", "color": "#F78181"},
                  {"max": 9, "min": 1, "label": "1-9", "color": "#F5A9A9"},
                  {"max": 0, "min": 0, "label": "0", "color": "#FFFFFF"},
                  ]

        c = (
            # 设置地图大小
            Map(init_opts=opts.InitOpts(width='1000px', height='880px'))
                .add("累计确诊人数", [list(z) for z in zip(area, variate)], "china", is_map_symbol_show=False)
                .set_global_opts(
                title_opts=opts.TitleOpts(title="中国疫情地图分布", subtitle='截止%s 中国疫情分布情况' % (update_time), pos_left="center",
                                          pos_top="10px"),
                legend_opts=opts.LegendOpts(is_show=False),
                visualmap_opts=opts.VisualMapOpts(max_=200, is_piecewise=True,
                                                  pieces=pieces,
                                                  ),
            )
                .render("./map/中国疫情地图.html")
        )

(4)模块控制:main.py

通过main.py模块控制总流程,运行总模块,即可在本地目录下,获得中国实时疫情的数据地图,并保存到本地,该地图已经链接在下面,使用chrome即可浏览。

from get_data import Get_data


data = Get_data()
data.get_data()
time_in,time_out = data.get_time()
data.parse_data()

import execution
execution.china_map(time_in)
execution.province_map(time_in)

import draw_map
draw_map.Draw_map()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
该地图反映的是累计的确诊案例,从疫情初期到现在,一年又5个月之久,我们可以看到湖北省的累计确诊人数最多,达到68,159人。通过该地图,我们可以实时了解累计确诊人数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值