大数据毕设选题 - 疫情数据分析可视化系统(python flask 爬虫)

文章目录

  • 0 前言
  • 1 课题背景
  • 2 实现效果
    • 2.1 整体界面展示
    • 2.2 31省病例柱形图
    • 2.3 全国现有确诊人数趋势
    • 2.4 中国累计确诊时间线
    • 2.5 中国疫情情况饼状图
    • 2.6 高风险树状图
  • 3 相关理论及技术
    • 3.1爬虫
    • 3.2 Django
    • 3.3 Echarts
    • 3.4 MySQL
  • 4 最后

0 前言

Hi,大家好,这里是丹成学长的毕设系列文章!

对毕设有任何疑问都可以问学长哦!

这两年开始,各个学校对毕设的要求越来越高,难度也越来越大… 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定要提前准备,避免到后面措手不及,草草了事。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的新项目是

基于python 爬虫 flask的疫情数据可视化系统

学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分

选题指导, 项目分享:

https://gitee.com/yaa-dc/BJH/blob/master/gg/cc/README.md

1 课题背景

自2019年12月12日武汉确诊新型冠状病毒患者开始,历时三年之久的新冠疫情仍未结束。新型冠状病毒肺炎(COVID-19)存在人畜跨界传播、传染性强、影响因素多样、传播途径复杂等特点,导致肺炎疫情发病急、发展快、溯源分析难、社会危害大等问题。随着新型冠状病毒毒株的不断变异,现出现了传播性极强、免疫逃逸能力极高的变异病毒。
为更直观、更专业地了解疫情的变化,本文设计了基于爬虫、Dianjo、Pyecharts的COVID-19疫情信息可视化系统。该系统主要包括疫情模型预测、疫情信息可视化以及防疫措施指南三大功能,能够实时动态展示疫情发展趋势,并根据预测模型进行疫情预测以及提供有效的防疫措施。

2 实现效果

2.1 整体界面展示

整体界面展示如下:

大数据毕设选题 - 疫情数据分析可视化系统(python flask 爬虫)_第1张图片

2.2 31省病例柱形图

利用爬虫从百度、丁香网等网站收集了全国31个省份多个城市的确诊病例数量,保存为CSV文件如下图:

在这里插入图片描述

柱形图相关代码:

# 近31省市区现有病例
def confirmed_of_provive():
    c = (
        Bar(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
        .add_xaxis(address)
        .add_yaxis('', xyqz)
        .set_series_opts(markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="max", name="max"), opts.MarkLineItem(type_="min", name="min")]),
                         markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max", name="max"), opts.MarkPointItem(type_="min", name="min")]))
        .set_global_opts(title_opts=opts.TitleOpts(title='近期31省区市本土现有病例', title_textstyle_opts=opts.TextStyleOpts(color='#ffffff'), pos_left='35%', pos_top='5%'),
                         visualmap_opts=opts.VisualMapOpts(textstyle_opts=opts.TextStyleOpts(color='#ffffff'),
                                                           max_=int(max(xyqz)), min_=int(min(xyqz)), is_piecewise=True, pos_right='5%', pos_top='40%'),
                         xaxis_opts=opts.AxisOpts(name="省市区", axislabel_opts=opts.LabelOpts(rotate=90, color='#ffffff'),
                                                  axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow")),
                         tooltip_opts=opts.TooltipOpts(
            trigger='axis', axis_pointer_type='cross'),
            datazoom_opts=opts.DataZoomOpts(
            is_show=False, type_='inside', range_start=30),
            legend_opts=opts.LegendOpts(
            pos_right='5%', pos_top='5%', textstyle_opts=opts.TextStyleOpts(color='#ffffff')),
            yaxis_opts=opts.AxisOpts(name="数量",  axislabel_opts=opts.LabelOpts(rotate=90, color='#ffffff'), splitline_opts=opts.SplitLineOpts(is_show=True)))
    )
    return c.dump_options_with_quotes()

在这里插入图片描述

2.3 全国现有确诊人数趋势

收取全国现有确诊人数,绘制人数趋势图

相关代码:

def xyqz():  # 新增确诊/现有确诊
    xxx = ['新增确诊', '现有确诊']
    y = [y, y1]
    for i in range(len(xxx)):
        bar = (
            Line()
            .add_xaxis(x)
            .add_yaxis(xxx[i], y[i], symbol='circle',
                       is_smooth=True,
                       is_symbol_show=True,
                       symbol_size=6,
                       linestyle_opts=opts.LineStyleOpts(width=2),
                       label_opts=opts.LabelOpts(
                is_show=True, position="top", color="white"),
                itemstyle_opts=opts.ItemStyleOpts(
                color="skyblue", border_color="#fff", border_width=2
            ))
            .set_series_opts(markline_opts=opts.MarkLineOpts(
                data=[opts.MarkLineItem(type_="max", name="max"), opts.MarkLineItem(type_="min", name="min")]),
                markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max", name="max"),
                                                        opts.MarkPointItem(type_="min", name="min")]))
            .set_global_opts(title_opts=opts.TitleOpts(title='全国' + xxx[i] + '人数趋势',
                                                       title_textstyle_opts=opts.TextStyleOpts(color='#ffffff')),
                             visualmap_opts=opts.VisualMapOpts(textstyle_opts=opts.TextStyleOpts(color='#ffffff'),
                                                               max_=int(max(y[i])), is_piecewise=True,
                                                               pos_right='5%', pos_top='60%'),
                             xaxis_opts=opts.AxisOpts(
                axislabel_opts=opts.LabelOpts(rotate=45, color='#ffffff')),
                tooltip_opts=opts.TooltipOpts(
                trigger='axis', axis_pointer_type='cross'),

                yaxis_opts=opts.AxisOpts(name="Y", splitline_opts=opts.SplitLineOpts(is_show=True),
                                         axislabel_opts=opts.LabelOpts(rotate=90, color='#ffffff')),

                legend_opts=opts.LegendOpts(pos_left='50%',
                                            textstyle_opts=opts.TextStyleOpts(color='#ffffff')),
            )
        )
        tl.add(bar, xxx[i])
        tl.add_schema(is_auto_play=True, pos_bottom='88%', pos_left='25%',
                      label_opts=opts.LabelOpts(color='#ffffff', font_size=12))
    return tl.dump_options_with_quotes()

大数据毕设选题 - 疫情数据分析可视化系统(python flask 爬虫)_第2张图片

2.4 中国累计确诊时间线

利用echart中的map属性,根据确诊数量绘制中国热力图及各时间线

相关代码:

Map()
            .add('累计确诊', [list(i) for i in zip(df1['province'], df1['confirm'])], 'china')
            .set_global_opts(title_opts=opts.TitleOpts(title='中国累计确诊时间线', pos_left='38%', title_textstyle_opts=opts.TextStyleOpts(color='#ffffff')),
                             visualmap_opts=opts.VisualMapOpts(pos_right='0%', textstyle_opts=opts.TextStyleOpts(color='#ffffff'),
                                                               is_piecewise=True, max_=int(df1['confirm'].max()), min_=int(df1['confirm'].min()),
                                                               pieces=[
                                 {"min": 5001},
                                 {"min": 2001, 'max': 5000},
                                 {"min": 1801, "max": 2000},
                                 {"min": 1401, "max": 1800},
                                 {"min": 1001, "max": 1400},
                                 {"min": 801, "max": 1000},
                                 {"min": 601, "max": 800},
                                 {"min": 401, "max": 600},
                                 {"min": 201, "max": 400},
                                 {"min": 5, "max": 200, },
                                 {"max": 5}
                             ]
            ), toolbox_opts=opts.ToolboxOpts(), legend_opts=opts.LegendOpts(textstyle_opts=opts.TextStyleOpts(color='#ffffff'), pos_right='85%'))
        )

在这里插入图片描述

2.5 中国疫情情况饼状图

绘制各地区疫情饼状图

相关代码:

Pie()
            .add(x[i], data_pair=[list(i) for i in zip(df['provincename'], df[y[i]])],
                 radius=['15%', '35%'],  center=["55%", "60%"])
            .set_global_opts(title_opts=opts.TitleOpts(title='中国疫情情况', pos_left='75%', pos_top='5%', title_textstyle_opts=opts.TextStyleOpts(color='#ffffff')),
                             legend_opts=opts.LegendOpts(is_show=False))
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
        )
        tl.add(c, x[i])
        tl.add_schema(is_auto_play=True, pos_bottom='85%', orient='vertical', width='80px', height='400px', pos_right='5%', pos_top='16%',
                      label_opts=opts.LabelOpts(color='#ffffff', font_size=12), is_inverse=True)

在这里插入图片描述

2.6 高风险树状图

用树形图表示高风险地区更加直观

相关代码:

def high_risk(t):
    import json
    from pyecharts import options as opts
    from pyecharts.charts import Tree

    with open(f"demo/data/{t}.json", "r", encoding="utf-8") as f:
        j = json.load(f)
    if t == '高风险':
        x = 'orangered'
        y = 1.5
    elif t == '中风险':
        x = 'darkorange'
        y = 1
    c = (
        Tree()
        .add("", [j], collapse_interval=20, is_roam=True, layout="radial", initial_tree_depth=y,  label_opts=opts.LabelOpts(color='#ffffff', font_size=9))
        .set_global_opts(title_opts=opts.TitleOpts(title=f"{t}地区", title_textstyle_opts=opts.TextStyleOpts(color=x, font_size=16),))
    )
    return c.dump_options_with_quotes()

在这里插入图片描述

3 相关理论及技术

3.1爬虫

简介

网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。爬虫对某一站点访问,如果可以访问就下载其中的网页内容,并且通过爬虫解析模块解析得到的网页链接,把这些链接作为之后的抓取目标,并且在整个过程中完全不依赖用户,自动运行。若不能访问则根据爬虫预先设定的策略进行下一个 URL的访问。在整个过程中爬虫会自动进行异步处理数据请求,返回网页的抓取数据。在整个的爬虫运行之前,用户都可以自定义的添加代理,伪 装 请求头以便更好地获取网页数据。爬虫流程图如下:

在这里插入图片描述

相关代码

#爬虫部分代码
import datetime
import json
import re
import pandas as pd
import requests
from bs4 import BeautifulSoup
from sqlalchemy import create_engine


headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36'
}
con = create_engine("mysql+mysqlconnector://root:147123@localhost:3306/ksh")
# 历史数据
def lishishuju():
    df = pd.read_csv('demo/csv/丁香园国内疫情.csv', engine='c') # 读取数据

    df = df.sort_values('累计确诊', ascending=False) # 根据累计确诊去排序-降序

    df = df.drop_duplicates('省份', keep='first') # 根据省份去重,取第一次出现的数据

    df['省份'] = df['省份'].str.strip('省').str.strip('市').str.strip('壮族自治区').str.strip('自治区').str.strip('回族自治区').str.strip('维吾尔自治区')

    url = 'https://api.inews.qq.com/newsqa/v1/query/pubished/daily/list?province=湖北'
    data = json.loads(requests.get(url, headers=headers).content.decode())['data']

    for i in df['省份']:
        if i != '湖北':
            url = 'https://api.inews.qq.com/newsqa/v1/query/pubished/daily/list?province=' + i
            x = json.loads(requests.get(url).content.decode())['data']
            data = data + x

    def funx(x):
        if len(x) == 3:
            x = x + '0'
        return x

    df = pd.DataFrame(data)
    x = df['year'].astype('str') + '.'
    y = (df['date'].astype('str'))
    y = y.apply(lambda x: funx(x))

    df['dateId'] = x + y
    df['dateId'] = pd.DatetimeIndex(df['dateId']).astype('str').str[:7]

    df.to_csv('demo/csv/国内疫情数据.csv', index=False, encoding='utf-8-sig')
    df.to_sql('gnlssj', if_exists='replace', con=con, index=False)
    con.execute('ALTER TABLE gnlssj ADD id INT(16) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;')  # 添加自增字段id

3.2 Django

Django是一个基于Web的应用框架,由python编写。Web开发的基础是B/S架构,它通过前后端配合,将后台服务器的数据在浏览器上展现给前台用户的应用。Django本身是基于MVC模型,即Model(模型)+View(视图)+ Controller(控制器)设计模式,View模块和Template模块组成了它的视图部分,这种结构使动态的逻辑是剥离于静态页面处理的。 Django框架的Model层本质上是一套ORM系统,封装了大量的数据库操作API,开发人员不需要知道底层的数据库实现就可以对数据库进行增删改查等操作。Django强大的QuerySet设计能够实现非常复杂的数据库查询操作,且性能接近原生SQL语句。Django支持包括PostgreSQL、My Sql、SQLite、Oracle在内的多种数据库。Django的路由层设计非常简洁,使得将控制层、模型层和页面模板独立开进行开发成为可能。基于Django的Web系统工程结构示意图如图所示。

在这里插入图片描述

从图中可以看到,一个完整的Django工程由数个分应用程序组成,每个分应用程序包括四个部分:

(1)urls路由层:决定Web系统路由结构,控制页面间的跳转和数据请求路径

在这里插入图片描述

(2)views视图层:业务层,主要进行逻辑操作和运算,是前端页面模板和后端数据库之间的桥梁。Django框架提供了大量的数据库操作API,开发人员甚至不需要使用SQL语句即可完成大部分的数据库操作。

在这里插入图片描述

(3)models模型层:Web应用连接底层数据库的关键部分,封装了数据库表结构和实现。开发人员可以在Model层按照Django的指令要求进行建表,无须使用SQL语句或者第三方建表工具进行建表。建表的过程类似于定义变量和抽象编程语言中的类,非常方便。

在这里插入图片描述

(4)templates模板层:HTML模板文件,后端数据会填充HTML模板,渲染之后返回给前端请求。考虑到项目周期尽可能小,尽快完成平台的搭建,项目决定采用开源的Django框架开发整个系统的Web应用层。

在这里插入图片描述

3.3 Echarts

ECharts(Enterprise Charts)是百度开源的数据可视化工具,底层依赖轻量级Canvas库ZRender。兼容了几乎全部常用浏览器的特点,使它可广泛用于PC客户端和手机客户端。ECharts能辅助开发者整合用户数据,创新性的完成个性化设置可视化图表。支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)等,通过导入 js 库在 Java Web 项目上运行。

安装

pip install pyecharts

简单使用,实例:

from pyecharts.charts import Bar,Line 
from pyecharts import options as opts 
from pyecharts.globals import ThemeType 
 
line = ( 
    Line(init_opts=opts.InitOpts(theme=ThemeType.LIGHT, width='1000px',height='300px' )) 
    .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]) 
    .add_yaxis("商家A", [5, 20, 36, 10, 75, 90]) 
    .add_yaxis("商家B", [15, 6, 45, 20, 35, 66]) 
    .set_global_opts(title_opts=opts.TitleOpts(title="主标题", subtitle="副标题"), 
                        datazoom_opts=opts.DataZoomOpts(is_show=True)) 
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True)) 
) 
line.render('test.html') 
line.render_notebook() 

各种属性方法

add() 主要方法,用于添加图表的数据和设置各种配置项

render() 默认将会在根目录下生成一个 render.html 的文件,文件用浏览器打开

图表配置:图形初始化,通用配置项

  • xyAxis:平面直角坐标系中的 x、y 轴。(Line、Bar、Scatter、EffectScatter、Kline)
  • dataZoom:dataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。(Line、Bar、Scatter、EffectScatter、Kline、Boxplot)
  • legend:图例组件。图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
  • label:图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
  • lineStyle:带线图形的线的风格选项(Line、Polar、Radar、Graph、Parallel)
  • grid3D:3D笛卡尔坐标系组配置项,适用于 3D 图形。(Bar3D, Line3D, Scatter3D)
  • axis3D:3D 笛卡尔坐标系 X,Y,Z 轴配置项,适用于 3D 图形。(Bar3D, Line3D, Scatter3D)
  • visualMap:是视觉映射组件,用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)
  • markLine&markPoint:图形标记组件,用于标记指定的特殊数据,有标记线和标记点两种。(Bar、Line、Kline)
  • tooltip:提示框组件,用于移动或点击鼠标时弹出数据内容

3.4 MySQL

简介

MySQL是一个关系型数据库,由瑞典MySQL AB公司开发,目前已经被Oracle收购。

Mysql是一个真正的多用户、多线程的SQL数据库。其使用的SQL(结构化查询语言)是世界上最流行的和标准化的数据库语言,每个关系型数据库都可以使用MySQL是以客户机/服务器结构实现的,也就是俗称的C/S结构,它由一个服务器守护程序mysqld和很多不同的客户程序和库组成。

Python操作mysql数据库

本项目中我们需要使用python来操作mysql数据库,因此需要用到pymysql这个库

安装:

pip install pymysql

数据库连接实例:

# 导入pymysql
import pymysql

# 定义一个函数
# 这个函数用来创建连接(连接数据库用)
def mysql_db():
    # 连接数据库肯定需要一些参数
    conn = pymysql.connect(
        host="127.0.0.1",
        port=3307,
        database="ksh",
        charset="utf8",
        user="root",
        pass="123456"
    )

if __name__ == '__main__':
    mysql_db()

数据库连接实例:

```python
# 导入pymysql
import pymysql

# 定义一个函数
# 这个函数用来创建连接(连接数据库用)
def mysql_db():
    # 连接数据库肯定需要一些参数
    conn = pymysql.connect(
        host="127.0.0.1",
        port=3307,
        database="ksh",
        charset="utf8",
        user="root",
        pass="123456"
    )

if __name__ == '__main__':
    mysql_db()

4 最后

你可能感兴趣的:(大数据,毕业设计,python,flask,大数据)