【Dash搭建可视化网站】项目10:疫情数据可视化大屏制作步骤详解

14 篇文章 68 订阅
订阅专栏

手动反爬虫: 原博地址 https://blog.csdn.net/lys_828/article/details/128605640

 知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息

1 项目效果图

整个项目的页面包含四部分,由头部信息,卡片数据,多图表以及动态地图可视化组成,项目代码已上传 个人Github仓库。
请添加图片描述

2 项目架构

项目中各文件名称与对应功能见下表
在这里插入图片描述

3 文件介绍和功能完善

3.1 assets文件夹介绍

assets文件夹中就是加载的样式和图片,样式这里可以使用之前已经下载好的bootstrap.min.css样式(也可以按照 项目6.2bootstrap组件 中的介绍下载其它的样式模板),图片就是Covid的一个模型图片,对应如下。
在这里插入图片描述

3.2 app.py和index.py文件完善

主框架就是app.py项目初始化文件和index.py主程序运行文件,其中app.py文件中的信息较为简单,就是创建一个dash的应用,代码如下

from dash import Dash

app = Dash('__name__')

index.py文件中引入初始化后的应用,然后进行布局及运行初始化设置。

from app import app
import dash_bootstrap_components as dbc


from header import HeaderInfo
from cards import CardInfo
from indicators import IndicatorInfo
from piechart import PieInfo
from barlinechart import BarLineInfo
from mapchart import MapInfo


app.layout = dbc.Col(
    [
        dbc.Row([HeaderInfo()]),
        dbc.Row([CardInfo()]),
        dbc.Row([IndicatorInfo(),PieInfo(),BarLineInfo()]),
        dbc.Row([MapInfo()]),
    ]
)

if __name__ == '__main__':
    app.run_server(debug=True)

对应的index.py文件截图如下。
在这里插入图片描述

然后在对应的文件中创建函数,搭建基本的框架,各文件的基础信息如下。
在这里插入图片描述

3.3 header.py文件完善

项目的头部信息包含了三个部分,可以按照一行三列的布局设置,第一列放置图片居左,第二列放置标题居中,第三列放置更新时间居右。

import dash_bootstrap_components as dbc

def HeaderInfo():
    return dbc.Row(
        [
            dbc.Col([None]),
            dbc.Col([None]),
            dbc.Col([None]),
        ]
    )

其中图片的加载和位置设置,以及标题文字的大小及距离的设置相对简单,最主要解决第三列更新时间的问题,首先给定一个今天的时间作为样例,后续根据接口数据获取的具体时间再更换,在api.ipynb文件中将时间转化为目标样式的代码如下。

import pandas as pd

today = pd.to_datetime('today').strftime('%B %d %Y')
today

输出结果为:
在这里插入图片描述

将上述代码复制粘贴到api.py文件中并通过语句导入到header.py文件,完善此文件的信息,代码如下。

import dash_bootstrap_components as dbc
from dash import html
from api import today

def HeaderInfo():
    return dbc.Row(
        [
            dbc.Col(
                [
                    html.Img(src='assets/corona-logo-1.jpg',height='100px',width='100px')
                ],style = {'textAlign':'left','paddingLeft':'6rem','paddingTop':'1rem'}
            ),
            dbc.Col(
                [
                    html.H1('Covid - 19'),
                    html.H6('Track Covid - 19 Cases',className='p-2')
                ],style = {'textAlign':'center','paddingTop':'1rem'}
            ),
            dbc.Col(
                [
                    html.H5(f'Last Updated: {today} (UTC)'),
                ],style = {'textAlign':'right','paddingRight':'6rem','paddingTop':'3rem'}
            ),
        ]
    )

保存修改后,回到index.py文件执行,并刷新网址:http://127.0.0.1:8050/。此时界面输出内容如下:
在这里插入图片描述
左右两侧的距离浏览器的距离也太远了,问题就在于最开始使用了dbc.Container()容器,在默认加载css样式中,导致添加的内容自动居中,因此可以把容器调整为html.Div(),修改后的index.py文件中的代码内容如下:
在这里插入图片描述

保存后刷新网址,此时左右两侧的内容距离浏览器的距离正常了。
在这里插入图片描述

3.4 cards.py文件完善

通过观察最终的图片样式,卡片数据部分的内容基本布局一致,包含了上中下三个部分,第一部分就是文字说明统计类型,中间为该类型的数据,最下面是增加数量和百分比。可封装一个函数card(),保留数据接口,设置参数为typenumdiffdiff_per四个参数,先用简单示例数据进行赋值,设置完毕后,再处理数据。

def card(type,num,diff,diff_per,color):

    return dbc.Col(
        [
            html.H6(f'Global {type}'),
            html.H3(num,style={'color':color}),
            html.Span(f'New {diff} ({diff_per})%',style={'color':color})
        ]
    )

接着完善该文件,此时全部代码如下。

在这里插入图片描述

保存文件后,刷新网址,此时界面显示信息如下。
在这里插入图片描述

3.5 api.py和api.ipynb文件完善

其中api.py文件是为提供数据接口,api.iypnb文件方便进行数据处理和调式工作。前面已经用来处理更新的时间格式,这里就针对真实的Covid数据进行数据导入。此项目使用的数据来自于约翰霍普金斯大学系统科学与工程中心(JHU CSSE)运营的2019年新型冠状病毒可视化仪表盘的数据存储库,数据来源网址: COVID-19

3.5.1 数据获取

Covid数据中的确诊、死亡、治愈信息所在网址:

url_confirmed = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv'
url_deaths = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv'
url_recovered = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv'

使用pandas可以直接读取网址链接中的数据,但是前提是用户可以正常访问github。如果无法正常访问Github网址,后续会把读取到的数据保存到本地,并放置在assets文件夹下新建的data文件夹下, 读者可以在下载项目案例后使用本地csv文件读取数据。读取数据的代码如下:

#读取数据
confirmed = pd.read_csv(url_confirmed)
deaths = pd.read_csv(url_deaths)
recovered = pd.read_csv(url_recovered)

数据存放在confirmeddeathsrecovered三个变量中,分别查看前5条数据,输出结果如下:
在这里插入图片描述

根据输出结果发现对于治愈人数最近的时期中前5行数据均为0,需要核实一下是不是所有的国家的数值均为0,如果是,说明对于治愈的数据该数据库就不再进行统计。比如选取最近20天的数据,进行数值汇总,发现输出结果中个字段的总和均为0,说明该数据库已经不再更新治愈数据。
在这里插入图片描述

考虑进一步提取有治愈数据的信息,首先确定何时该数据库不再统计此部分数据。此处判断的方式就是对每个数值字段进行求和汇总,如果连续5个字段的汇总值都是0,说明连续5个字段中的第一个字段就是数据库停止更新的日期。

ls = recovered[recovered.columns[4:]].sum().to_list()
for i in range(len(ls)):
    if ls[i] == ls[i+1] == ls[i+2] == ls[i+3] == ls[i+4]:
        print(i)
        break

输出结果如下:(字段计算是从第5列开始,因为前4个字段都不是数值字段)
在这里插入图片描述

输出结果中显示从第561+4也就是565个字段位置开始停止数据更新,可以进一步核实情况,对该字段的前5个字段和后5个字段计数汇总输出如下。
在这里插入图片描述

为了更严谨一些,可以对2021年8月5日往后的数据进行汇总值计算,核实是否为0。结果为-8,有点出人意料,进一步,找出汇总值不为0的字段的统计值,发现结果都是-1,代表着未收录数据。因此可以断定治愈数据在2021年8月5日停止更新。
在这里插入图片描述

可以把数据保存到本地assets文件夹下的data文件夹中,由于没有data文件夹,需要先创建,可以手动在assets文件夹中创建,也可以使用代码进行创建,并把数据保存到此文件夹中,代码如下及输出结果如下。

#首先把执行路劲转换到项目的assets文件夹下
import os
os.chdir(r'D:\Data Science\plotly学习\个人\【10. Covid data visualizing】Dropdown-pie-line-map-indicator-bar\assets')

#判断该路径下是否有data文件夹,如果没有就创建
if not os.path.exists('data'):
    os.mkdir('data')

#把数据生成到对应的文件中,并取消index列,这里index就是数值序号
confirmed.iloc[:,:565].to_csv('data/confirmed.csv',index=False)
deaths.iloc[:,:565].to_csv('data/death.csv',index=False)
recovered.iloc[:,:565].to_csv('data/recovered.csv',index=False)

对应的界面和data文件中的内容如下。
在这里插入图片描述

3.5.2 数据处理

重新读取本地文件数据(当然也可以直接使用iloc[:,:565]获取的数据。由于已经在data文件生成了数据文件,所以在api.py文件中就不需要再重新获取数据,直接读入数据就行,此处的重新读取本地文件数据就是为了方便把代码直接复制粘贴到api.py文件中)

在这里插入图片描述
由于获取的数据都是“长数据”,需要转化为“短数据”,即把全部日期的字段变成一个字段,实现数据的逆透视。借助pandas下的melt()函数功能可以实现。

#数据逆透视:把在标题上的信息转化成为单元格中信息(即行转列)
total_confirmed = pd.melt(confirmed,id_vars=confirmed.columns[:4],value_vars=confirmed.columns[4:],var_name='date',value_name='confirmed')
total_deaths = pd.melt(deaths,id_vars=deaths.columns[:4],value_vars=deaths.columns[4:],var_name='date',value_name='death')
total_recovered = pd.melt(recovered,id_vars=recovered.columns[:4],value_vars=recovered.columns[4:],var_name='date',value_name='recovered')

输出结果如下:(函数中的第一个参数是要进行转化的DataFrame,第二个参数就是指定的不变的字段,第三个参数就是变化的字段,第四个参数就是个变化的字段进行合并成一个字段后的字段名称,最后一个参数就是值汇总后的字段名称)
在这里插入图片描述
同样也可以输出转化后的死亡和治愈数据,但是发现治愈数据的记录条数要比确诊和死亡的数据量要少一些。
在这里插入图片描述

为了保证同一性,把三个数据进行合并,最终的数据量以死亡和确诊数据量为准,把治愈数据合并进来,最终形成完整数据covid_data

#数据合并
covid_data = total_confirmed.merge(right = total_deaths, how = 'left', on = ['Province/State', 'Country/Region', 'date', 'Lat', 'Long'])
covid_data = covid_data.merge(right = total_recovered, how = 'left', on = ['Province/State', 'Country/Region', 'date', 'Lat', 'Long'])
covid_data

代码及输出结果如下。
在这里插入图片描述
接着创建衍生字段,也就是项目卡片数据中的第四个卡片的内容数据,即active,该字段的数据是确诊数据-死亡数据-治愈数据。由于治愈字段在合并之前没有那么多数据量,所以在合并后系统默认以缺失值标记,因此在创建字段之前需要先处理缺失值。

#缺失值处理
covid_data['recovered'] = covid_data['recovered'].fillna(0)

#衍生字段创建
covid_data['active'] = covid_data['confirmed'] - covid_data['death'] - covid_data['recovered']
covid_data

代码及输出结果如下。
在这里插入图片描述
按照日期字段进行汇总,求解comfirmed、death、recovered和active字段的数据。

#将日期转化为时间格式(会自动进行解析)
covid_data['date'] = pd.to_datetime(covid_data['date'])

#获取按照日期汇总得到的确诊,死亡和治愈和active的人员
covid_data_1 = covid_data.groupby('date')[['confirmed','death','recovered','active']].sum().reset_index()
covid_data_1

代码及输出结果如下:(为了方便后续的时间字段的操作,可以将date字段转变datetime数据类型)
在这里插入图片描述
卡片数据中的汇总数据就得到了,只需要获取最后一行数据即可,接着就是求解卡片下方的增加值和百分比数据。

#获取最近一天的确诊,死亡和治愈和active的人员值
confirmed_num = covid_data_1['confirmed'].iloc[-1]
rate_confirmed = (confirmed_num - covid_data_1['confirmed'].iloc[-2])

death_num = covid_data_1['death'].iloc[-1]
rate_death = death_num - covid_data_1['death'].iloc[-2]

recovered_num = 'No data available' if covid_data_1['recovered'].iloc[-1] ==0 else covid_data_1['recovered'].iloc[-1]
rate_recovered = 'No data available' if recovered_num == 'No data available' else  recovered_num - covid_data_1['recovered'].iloc[-2]

active_num = covid_data_1['active'].iloc[-1]
rate_active = active_num - covid_data_1['active'].iloc[-2]

代码及输出结果如下:(百分比数据是基于倒数第二行和倒数第一行之间数据之比,但是需要强调的是,数据为0 代表着没有数据可获取,此外,增幅百分比的计算,需要考虑分母为0的情况,因此百分比计算就不放在接口文件中,而是在cards.py进行计算)
在这里插入图片描述

3.5.3 接口数据导入header.py和cards.py文件中使用

在api.ipynb文件中核实无误后,把代码转移到api.py文件中,此时api.py文件中的代码如下。

import pandas as pd

today = pd.to_datetime('today').strftime('%B %d %Y')

import os
os.chdir(r'D:\Data Science\plotly学习\个人\【10. Covid data visualizing】Dropdown-pie-line-map-indicator-bar\assets')
confirmed = pd.read_csv('data/confirmed.csv')
deaths = pd.read_csv('data/death.csv')
recovered = pd.read_csv('data/recovered.csv')

#数据逆透视:把在标题上的信息转化成为单元格中信息(即行转列)
total_confirmed = pd.melt(confirmed,id_vars=confirmed.columns[:4],value_vars=confirmed.columns[4:],var_name='date',value_name='confirmed')
total_deaths = pd.melt(deaths,id_vars=deaths.columns[:4],value_vars=deaths.columns[4:],var_name='date',value_name='death')
total_recovered = pd.melt(recovered,id_vars=recovered.columns[:4],value_vars=recovered.columns[4:],var_name='date',value_name='recovered')

#数据合并
covid_data = total_confirmed.merge(right = total_deaths, how = 'left', on = ['Province/State', 'Country/Region', 'date', 'Lat', 'Long'])
covid_data = covid_data.merge(right = total_recovered, how = 'left', on = ['Province/State', 'Country/Region', 'date', 'Lat', 'Long'])

#缺失值处理
covid_data['recovered'] = covid_data['recovered'].fillna(0)

#衍生字段创建
covid_data['active'] = covid_data['confirmed'] - covid_data['death'] - covid_data['recovered']

#将日期转化为时间格式(会自动进行解析)
covid_data['date'] = pd.to_datetime(covid_data['date'])

#获取按照日期汇总得到的确诊,死亡和治愈和active的人员
covid_data_1 = covid_data.groupby('date')[['confirmed','death','recovered','active']].sum().reset_index()

#获取最近一天的确诊,死亡和治愈和active的人员值
confirmed_num = covid_data_1['confirmed'].iloc[-1]
rate_confirmed = (confirmed_num - covid_data_1['confirmed'].iloc[-2])

death_num = covid_data_1['death'].iloc[-1]
rate_death = death_num - covid_data_1['death'].iloc[-2]

recovered_num = 'No data available' if covid_data_1['recovered'].iloc[-1] ==0 else covid_data_1['recovered'].iloc[-1]
rate_recovered = 'No data available' if recovered_num == 'No data available' else  recovered_num - covid_data_1['recovered'].iloc[-2]

active_num = covid_data_1['active'].iloc[-1]
rate_active = active_num - covid_data_1['active'].iloc[-2]

然后将api.py中的数据导入到cards.py文件和header.py文件中,进行数据替换。首先更换header.py文件中的数据更新时间,为简化header.py文件内容,数据处理工作在api.py文件中完成后再传入,保证后续使用时候只需要修改数据接口文件,而不用动其它文件。在api.py文件中添加如下代码获取数据最近的更新时间。

#更新header.py中的数据获取时间
updata_time = covid_data_1['date'].iloc[-1].strftime('%B %d %Y')

然后把update_time导入到header.py文件中,顺带修改一下文件中样式,使之和最终效果的布局一致。

import dash_bootstrap_components as dbc
from dash import html
from api import updata_time

def HeaderInfo():
    return dbc.Row(
        [
            dbc.Col(
                [
                    html.Img(src='assets/corona-logo-1.jpg',height='100px',width='100px')
                ],style = {'textAlign':'left','paddingLeft':'6rem','paddingTop':'1rem'}
            ),
            dbc.Col(
                [
                    html.H1('Covid - 19'),
                    html.H6('Track Covid - 19 Cases',className='p-2')
                ],style = {'textAlign':'center','paddingTop':'1rem'}
            ),
            dbc.Col(
                [
                    html.H5(f'Last Updated: {updata_time}'),
                    html.H5('00:01(UTC)',style={'paddingRight':'5rem'})
                ],style = {'textAlign':'right','paddingRight':'6rem','paddingTop':'2rem'}
            ),
        ]
    )

保存文件修改后,刷新网址,当前界面中头部信息更新时间完美实现数据更新。
在这里插入图片描述
接着处理卡片中的数据和样式。考虑到缺失值的问题,在card()函数中删掉百分比参数diff_per,而是进一步判断后再确定,防止因缺失数据导致程序运行保存的现象,最终cards.py中的代码如下。


from dash import html
import dash_bootstrap_components as dbc
from api import *

def card(type,num,diff,color):

    if num == 'No data available':
        diff_per = 'No data available'
    else:
        diff_per = diff/num * 100

    return dbc.Col(
        [
            html.H6(f'Global {type}'),
            html.H2(num,style={'color':color}),
            html.P(f'New {int(diff)} ({diff_per:.2f})%',style={'color':color,'fontSize':5})
        ]
    )

def CardInfo():
    return dbc.Row(
        [
            card('cases',confirmed_num,rate_confirmed,'orange'),
            card('death',death_num,rate_death,'red'),
            card('recovered',recovered_num,rate_recovered,'green'),
            card('active',active_num,rate_active,'black')
        ],style = {'textAlign':'center','paddingTop':'1rem'}
    )

保存代码后,刷新网页,界面输出结果如下。
在这里插入图片描述

3.6 indicators文件完善

该文件中主要是由Dropdown组件搭配着Indicators图像构成,搭建主体框架,使之满足正常功能。先把第三部分的布局完善,该部分可以分为1行3列,在三个函数中均输入如下内容,查看是否水平排列。
在这里插入图片描述

保存文件修改后,刷新网页,此时界面上输出结果如下。
在这里插入图片描述
此时本应三列的内容,变成三行输出了, 因此需要在index.py文件中修改一下配置,在第三部分添加一个行设置,如下
在这里插入图片描述

此时保存文件后再刷新网址,发现布局样式满足一行三列的排布。
在这里插入图片描述
布局解决后,开始处理indicators.py文件中的功能完善,基础先把文字和Dropdown组件信息设置出来,由于indicators图像是回调产生,因此只设置一个容器增加id即可,后续设置回调函数即可。

首先获取Dropdown组件的标签信息,此处选择的是国家或者地区,因此可以在covid_data中获取Country/Region字段的唯一值。特别要注意标签信息不能包含None值,不然程序会报错,所以在构建Dropdown组件时,特别留意列表中不包含None值。
在这里插入图片描述
然后把这部分代码复制粘贴到api.py文件中,再导入到indicators.py文件中。完善Dropdown组件和文字信息,代码如下

import dash_bootstrap_components as dbc
from dash import html,Input,Output,dcc
from api import country_ls,updata_time

def IndicatorInfo():
    return dbc.Col(
        [
            html.H6('Select Country:'),
            dcc.Dropdown(
                country_ls,
                'China',
                id = 'dpd'
            ),
            html.H6(f'New cases: {updata_time}'),
            dcc.Graph(id='fig1')

        ],width=3,style={'textAlign':'center'}
    )

保存文件后,刷新网页,此时页面显示结果如下
在这里插入图片描述

正常显示后,可以设置回调函数,输出Indicators图形,比如先以中国的确诊数据为例,绘制出对比数据更新日期当天的indicator图形(即今天相对于昨天的涨跌指标图),借鉴 官方的示例代码。
在这里插入图片描述

有了图像示例代码后,就需要构建数据接口,在api.ipynb文件中获取每个国家/地区每天的疫情信息,代码及输出结果如下。
在这里插入图片描述

以中国为例,数据更新之日的新增确诊数据和较昨日新增的确诊数据获取方式如下。

today_new_add = covid_data_2[covid_data_2['Country/Region'] == 'China'].iloc[-1]['confirmed'] - covid_data_2[covid_data_2['Country/Region'] == 'China'].iloc[-2]['confirmed'] 
yesterday_new_add = covid_data_2[covid_data_2['Country/Region'] == 'China'].iloc[-2]['confirmed'] - covid_data_2[covid_data_2['Country/Region'] == 'China'].iloc[-3]['confirmed'] 
print('今日新增:{},昨日新增{},indicator指标{}'.format(today_new_add,yesterday_new_add,today_new_add-yesterday_new_add))

输出结果如下。
在这里插入图片描述

进一步将获取的过程封装为函数indicator(),传入国家country和covid数据类型type,最后函数返回就是要绘制的figure对象。先把获取每个国家/地区每天的信息covid_data_2变量复制粘贴到api.py文件汇总,然后导入到indicators.py文件里。
在这里插入图片描述

此时indicators.py文件中的代码如下。

import dash_bootstrap_components as dbc
from dash import html,Input,Output,dcc
from api import country_ls,updata_time,covid_data_2
import plotly.graph_objects as go
from app import app

def IndicatorInfo():
    return dbc.Col(
        [
            html.H6('Select Country:'),
            dcc.Dropdown(
                country_ls,
                'China',
                id = 'dpd'
            ),
            html.H6(f'New cases: {updata_time}'),
            dcc.Graph(id='confirmed'),
            dcc.Graph(id='death'),
            dcc.Graph(id='recovered'),
            dcc.Graph(id='active'),

        ],width=3,style={'textAlign':'center'}
    )

def indicator(country,type):
    today_new_add = covid_data_2[covid_data_2['Country/Region'] == country].iloc[-1][type] - covid_data_2[covid_data_2['Country/Region'] == country].iloc[-2][type] 
    yesterday_new_add = covid_data_2[covid_data_2['Country/Region'] == country].iloc[-2][type] - covid_data_2[covid_data_2['Country/Region'] == country].iloc[-3][type] 

    return go.Figure(go.Indicator(
                title = {'text': f'New {type}'},
                mode = "number+delta",
                value = today_new_add,
                delta = {'position': "bottom", 'reference': yesterday_new_add},
                domain = {'x': [0, 1], 'y': [0, 1]}))

@app.callback(
    [Output('confirmed','figure'),Output('death','figure'),Output('recovered','figure'),Output('active','figure')],
    [Input('dpd','value')]
)
def update(value):
    return (
        indicator(value,'confirmed'),
        indicator(value,'death'),
        indicator(value,'recovered'),
        indicator(value,'active'),
    ) 

保存文件后刷新网址,界面运行结果如下。(此时三个indicator图像均可以正常加载,点击下拉菜单可以实现数据更新,但是样式和大小需要进一步调整)
在这里插入图片描述

对于两个数值的大小和位置,可以通过number和delta两个参数进行控制。
在这里插入图片描述

修改后保存,刷新网址,此时界面显示出数值的大小适合,但是标题太小了,因此需要再修改一下标题样式。
在这里插入图片描述
标题颜色也需要进行修改,因此需要在indicator()函数中添加一个color参数。此次修改的地方如下:

  • 对于indictors图形容器和后面回调的Output的内容存在了重复,可以考虑列表推导式简化
  • 然后对于颜色参数可以添加到字体和数值中
  • 图像的高度也需要调整
import dash_bootstrap_components as dbc
from dash import html,Input,Output,dcc
from api import country_ls,updata_time,covid_data_2
import plotly.graph_objects as go
from app import app

ls = ['confirmed','death','recovered','active']

def IndicatorInfo():
    return dbc.Col(
        [
            html.H6('Select Country:',style={'paddingTop':20}),
            dcc.Dropdown(
                country_ls,
                'China',
                id = 'dpd'
            ),
            html.H6(f'New cases: {updata_time}',style={'paddingTop':20}),
            html.Div(
                [
                    dcc.Graph(id=type,config={'displayModeBar': False}) for type in ls
                ],
            )
        ],width=3,style={'textAlign':'center','paddingLeft':45,'paddingRight':45}
    )

def indicator(country,type,color):
    today_new_add = covid_data_2[covid_data_2['Country/Region'] == country].iloc[-1][type] - covid_data_2[covid_data_2['Country/Region'] == country].iloc[-2][type] 
    yesterday_new_add = covid_data_2[covid_data_2['Country/Region'] == country].iloc[-2][type] - covid_data_2[covid_data_2['Country/Region'] == country].iloc[-3][type] 

    fig = go.Figure(go.Indicator(
                title = {'text': f'New {type}','font': {'size': 15,'color':color}},
                mode = "number+delta",
                number = {'valueformat': ',',
                    'font': {'size': 15,'color':color}},
                value = today_new_add,
                delta = {'position': "right", 'reference': yesterday_new_add,'valueformat': ',',
                    'relative': False,
                    'font': {'size': 15}},
                domain = {'x': [0, 1], 'y': [0, 1]}))
                    
    fig.update_layout(
        height = 75  #这个地方卡了很久,如果添加weight属性就不会居中,所以直接去掉就可
    )
    return fig

@app.callback(
    [Output(type,'figure') for type in ls],
    [Input('dpd','value')]
)
def update(value):
    return (
        indicator(value,'confirmed','orange'),
        indicator(value,'death','red'),
        indicator(value,'recovered','green'),
        indicator(value,'active','black')
        )

保存文件后,刷新网址,界面显示内容如下。
在这里插入图片描述

3.7 piechart.py文件完善

此文件功能就是对Dropdown组件选中的标签,进行疫情四项指标的占比输出。主要的问题在于获取各项指标数据,由于各指标名称和字段名称是相同的,所以还是使用列表推导式的方式进行简化代码。构建pie图核心参数一个是values,还有一个names,这两参数都与四个指标相关,最终的代码如下。

import dash_bootstrap_components as dbc
from dash import html,Input,Output,dcc
from app import app
from api import covid_data_2
import plotly.express as px

ls = ['confirmed','death','recovered','active']
def PieInfo():
    return dbc.Col(id = 'pie',width=4,
    style={'textAlign':'center','paddingTop':20})

@app.callback(
    Output('pie','children'),
    [Input('dpd','value')]
)
def update(value):
    lastest_record = covid_data_2[covid_data_2['Country/Region'] == value].iloc[-1]
    fig = px.pie(values=[lastest_record[i] for i in ls],names=ls)
    fig.update_layout(
        legend={
            'orientation':'h',
            'xanchor':'center',
            'yanchor':'bottom',
            'x':0.5,
            'y':-0.15
            },
        margin=dict(
            t=25,
            b=125
        )
    )
    return [
        html.H6(f'Total Cases: {value}'),
        dcc.Graph(figure=fig,config={'displayModeBar': False})
    ]

保存修改后,刷新网址,此时界面中输出的内容如下。(费时间的地方在于pie图的位置和legend的位置放置,需要慢慢调整参数,达到自己满意的一个样式)
在这里插入图片描述

3.8 barlinechart.py文件完善

该文件的功能是按照Dropdown组件选取的标签,绘制对应国家/地区的最近30天的疫情确诊数据,以及近七天的平滑数据曲线。首先在api.ipynb文件中获取最近30天的疫情确诊数据,以中国为例。

先提取中国确诊的疫情数据,并借助shift(1)方法,求解每日新增的确诊数量。
在这里插入图片描述
然后借rolling(7)方法获取数据7日曲线数据。
在这里插入图片描述
最后就是对最后30条数据进行切片即可获取对应的数据。把此过程封装为函数get_30_days_data(),然后保存在api.py文件中,方便调用。
在这里插入图片描述
数据都准备完毕后,开始完善barlinechart.py文件。其中go.Figure()中可以绘制多个图形,图形之间用列表存放;还有重点关于交互图中的hover_text的设置,此处可以根据自己需要任意设定显示信息,比如这里显示的有日期、数量和国家,扩宽了数据的可视化的角度;此外还有y轴相关信息的设置,同理x轴的设置也是同理,该文件中全部的代码如下。

import dash_bootstrap_components as dbc
from dash import html,Input,Output,dcc
from app import app
from api import get_30_days_data
import plotly.graph_objects as go

def BarLineInfo():
    return dbc.Col(id='barline',style={'textAlign':'center','paddingTop':20})

@app.callback(
    Output('barline','children'),
    [Input('dpd','value')]
)
def update(value):

    covid_data_30 = get_30_days_data(value)

    fig = go.Figure([
                go.Bar(
                    x = covid_data_30['date'].tail(30),
                    y = covid_data_30['confirmed new add'].tail(30),
                    name='Daily Confirmed Cases',
                    marker = {'color':'orange'},
                    hoverinfo='text',
                    hovertext=
                    '<b>Date</b>: ' + covid_data_30['date'].tail(30).astype(str)+'<br>' +
                    '<b>Daily Confirmed Cases</b>:' + [f'{i:.0f}' for i in covid_data_30['confirmed new add'].tail(30)]+'<br>' +
                    '<b>Country</b>: ' + covid_data_30['Country/Region'].tail(30).astype(str) + '<br>'
                ),
                go.Scatter(
                    x=covid_data_30['date'].tail(30),
                    y=covid_data_30['Rolling Ave.'].tail(30),
                    mode='lines',
                    name='Rolling Average of the last 7 days - Daily Confirmed Cases',
                    marker={'color': 'pink'},
                    hoverinfo='text',
                    hovertext=
                    '<b>Date</b>: ' + covid_data_30['date'].tail(30).astype(str) + '<br>' +
                    '<b>Rolling Ave.</b>:' + [f'{i:.0f}' for i in covid_data_30['Rolling Ave.'].tail(30)] + '<br>'
                )
            ]
    )
    fig.update_layout(
        legend={
            'orientation':'h',
            'xanchor':'center',
            'yanchor':'bottom',
            'x':0.5,
            'y':-0.25
            },
        margin=dict(
            t=25,
            b=150,
            l=0,
            r=70
        ),
        yaxis={
                'title': '<b>Daily Confirmed Cases</b>',
                'color': 'black',
                'showline': True,
                'showgrid': True,
                'showticklabels': True,
                'linecolor': 'white',
                'linewidth': 1,
                'ticks': 'outside',
                'tickfont': {
                    'family': 'Aerial',
                    'color': 'white',
                    'size': 12
                }
            }
    )

    return [
        html.H6(f'Last 30 Days Confirmed Cases: {value}'),
        dcc.Graph(
            figure=fig,config={'displayModeBar': False}
        )
    ]

保存文件后刷新网页,界面中显示的内容如下。
在这里插入图片描述

3.9 mapchart.py文件完善

该文件的功能实现各国家地区确诊数据随着时间变化的地图可视化。关于地图可视化,可以参考 官方示例代码。由于地理数据是属于面数据(区别于具体的点数据),因此可以采用px.choropleth()方法绘制。
在这里插入图片描述

现在关键点落到地理信息的匹配上,获取的数据中虽然有国家/区域信息,但是和px.choropleth()方法绘制地图时需要的地理数据不一致,因此需要将目前手上的数据通过某一特定标识进行转化。

px.choropleth()方法中的location参数指定的iso_alpha就可以作为参考,国家/地区的iso编码都是唯一的,因此可以用过地理位置信息。而所有国家的iso编码信息,项目中提供iso编码.txt文件,如下。
在这里插入图片描述
从中提取iso编码(对应第一列)、国家/地区名称(英文是倒数第二列,中文是倒数第一列),代码如下。
在这里插入图片描述

经过仔细观察后发现,获取的数据库中的疫情数据对应的国家/地区,与iso编码中的国家/地区并不完全匹配。
在这里插入图片描述
可以创建一个替换字典,将国家/地区名称化为一致,然后借助replace()方法进行数据替换。
在这里插入图片描述
核实数据是否替换成功。以韩国,朝鲜为例,数据清洗完毕。
在这里插入图片描述
接着就是把iso数据和疫情数据进行合并,合并的依据,一个是以Country/Region字段,一个是以country字段,合并的代码和输出结果如下
在这里插入图片描述
至此把绘制地图可视化的数据准备完毕,接着就是把以上处理数据的代码转移到api.py文件中,并把最终的geo_data变量导入到mapchart.py文件汇总。 在实际测试的过程中发现针对演示的时间字段也需要进行处理,只提取数据的年月,并把数据转化为字符串格式(原来时间的格式是datetime数据格式)
在这里插入图片描述
然后把这两行代码更新到api.py中,然后完善mapchart.py文件,全部代码如下

from dash import html,Input,Output,dcc
from app import app
from api import geo_data
import plotly.express as px

def MapInfo():

    #考虑到测试计算机的性能,可以指定数据采样,比如只取十分之一的数据进行演示
    geo_data_resample = geo_data.sample(frac = 0.1)

    fig = px.choropleth(geo_data_resample.sort_values('date_play'),               
                                locations="iso",               
                                color="confirmed",
                                hover_name="Country/Region",  
                                animation_frame="date_play",    
                                color_continuous_scale='amp',  
                                height=600)

    fig.update_layout(
        margin=dict(
            l=0,
            r=0,
            b=0,
            t=25,
            pad=0
        )
    )
    return dcc.Graph(
            figure= fig
    )

保存文件后,刷新网址,页面输出结果如下。(受限于测试计算机的性能,使用所有的数据量会导致演示地图稍微卡顿,项目中设置了一个采样方法,这里使用了十分之一的数据量。此外还发现在地图的动态演示中,发现格陵兰岛的数据始终空白)
在这里插入图片描述
可以考虑补充这部分数据,假定都是以0进行填充。(这里是实现某一地区数据缺失时的处理方式,如果有真实数据,直接用真实数据按照此方法填补即可),在api.py文件中添加格陵兰岛的数据,并把数据合并到geo_data变量中,如下
在这里插入图片描述
此时保存文件后,刷新网页,动态演示过程中,格陵兰岛的颜色不再是灰白色了,数据值为0。
在这里插入图片描述

4 样式修改

4.1 整体样式的修改

在assets文件夹下新建一个setting.css文件,设置整体风格。最后一行的overflow-y设置是参照 实战7中3.4 table.py文件完善部分 防止全部全局撑开后网页抖动的设置,具体介绍可以参考实战7。 背景设置为一种蓝色调,字体颜色设置为白色。
在这里插入图片描述

setting.py文件中的全部代码如下。(其中只有两个属性是项目9中没有的属性,div_container属性控制四部分的整体布局,card_container属性用于控制组件的样式)

html,body{ 
    background:#0d0247;
    color: white;
    overflow-y:scroll;} 

.div_container{
    text-align: center;
    margin:  20px;
    padding: 20px;
    margin-top: 5px;
}

.card_container{
    border-radius: 5px;
    background-color: #182757;
    margin: 16px;
    padding: 20px;
    position: relative;
    box-shadow: 2px 2px 2px #1e294e;
}   

 /* width */
 ::-webkit-scrollbar {
    width: 10px !important;
    display: block !important;
  }


/* Track */
::-webkit-scrollbar-track {
    background: #232c37 !important;
    border-radius: 10px !important;
    display: block !important;
    }
    
/* Handle */
::-webkit-scrollbar-thumb {
background: #363535 !important;
}

/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: white !important;
}

#dpd * {
    background-color: #182757 !important;
    color: #7f9ab4 !important;
    font-size: 10px !important;
}

.Select-control{
    border: 3px solid #323844 !important;
}

.Select-menu-outer{
    overflow: hidden !important;
    border-color: #36425e !important;
}

4.2 index.py中样式的修改

把div_container属性应用于整个Div,也就是核心四部分的对齐和布局上。
在这里插入图片描述

4.3 header.py中样式修改

只需要修改一下更新时间的颜色。剩下的一些样式根据实际调试过程中的变化进行修改,比如把00:01(UTC)单独另起一行,然后调整距离右侧的边距,使之与上面的日期文字呈现中间对齐的样子。
在这里插入图片描述

4.4 indicators.py中样式修改

在Col容器中应用卡片属性card_container,并根据实际显示调整width的值,原来是3,现在调整为2.5。
在这里插入图片描述

关于绘制的图形中白色背景去除的问题,只需要添加两行代码即可(其余图形中的背景去除也是相同方式)。#182757就是卡片属性中的背景颜色。
在这里插入图片描述

4.5 piechart.py中样式修改

和4.4部分修改的内容一致。
在这里插入图片描述

4.6 barlinechart.py中样式修改

和4.4和4.5中一样
在这里插入图片描述

4.7 mapchart.py中样式修改

和前面的修改一致。
在这里插入图片描述
但是不知怎么最后一个地图的部分总是显示左右无法和前面部分的组件对齐,因此在index.py中单独设置一下左右边距,实测左侧少了15px,右侧多了15px,如下
在这里插入图片描述

至此,整个项目就梳理完毕,撒花✿✿ヽ(°▽°)ノ✿

疫情数据可视化大屏.zip
01-10
展示中国新冠疫情数据,建立时间序列模型分析预测未来30天新增,通过flask,echarts进行大屏展示
Dash搭建可视化网站项目12:全球恐怖主义数据大屏制作步骤详解
lys_828的博客
01-11 1907
1 项目效果图 2 项目架构 3 文件介绍和功能完善3.1 assets文件夹介绍 3.2 app.py和index.py文件完善 3.3 header.py文件完善 3.4 filteritem.py文件完善 3.5 api.py文件和api.ipynb文件完善 3.6 staclbarline.py文件完善 3.7 piechart.py文件完善 3.8 mapchart.py文件完善 4 样式修改4.1 整体样式修改 4.2 header.py文件中样式修改
推荐项目Dash Bootstrap Components —— 让数据可视化应用的界面设计更加得心应手...
gitblog_00524的博客
09-03 327
推荐项目Dash Bootstrap Components —— 让数据可视化应用的界面设计更加得心应手 dash-bootstrap-componentsdash-bootstrap-components - 这是一个基于 Plotly.js 和 Bootstrap 的开源 Python 组件库,可以用于构建交互式数据可视化仪表板。适用于 Data Science、Python Web 开发...
基于Hadoop的疫情信息分析与可视化研究——包含大屏可视化及预测算法
迷茫与徘徊只会让你陷入绝境,欢迎私信博主,带你开始提升变现价值!
06-30 4300
基于Hadoop的疫情信息分析与可视化研究在国内外都有较为广泛的应用。国外研究主要集中在疫情数据的处理和分析,以及疫情预测模型的构建。而国内研究则主要集中在疫情数据的可视化和知识图谱的构建。未来,基于Hadoop的疫情信息分析与可视化研究还有很大的发展空间,可以进一步提高对疫情的监测和预警能力,为政府部门和医疗机构提供更加准确的数据支持和决策依据。另外,未来可以将Hadoop技术与人工智能、机器学习等技术相结合,开发更加智能化、自适应的疫情信息分析和预测模型。
Pyecharts实现新冠肺炎疫情数据大屏可视化
weixin_43975035的博客
12-15 8049
Author:龙箬 数据科学与大数据技术专业 用数据改变世界! CSDN@weixin_43975035 “我可以怀疑一切,但我却不能怀疑我正在怀疑。” 我思故我在 Pyecharts实现新冠肺炎疫情数据大屏可视化 由于腾讯疫情数据源的不断更新,本实验代码根据https://blog.csdn.net/qq_43613793/article/details/104356935 进行修改而成。 啥也不说,先上图: 实验步骤及代码如下: 首先程序里面用到的世界各国中英文对照.xlsx 链接: https:.
智慧监控vue实现的新型冠状病毒肺炎疫情可视化统计分析大屏前端案例
xyjkhrq的专栏
02-08 3496
2020年春节前后,新型冠状病毒肺炎疫情的消息牵动着全国人民的心,大家都非常关注疫情的变化和发展,非常关注疫情。在春节期间,针对疫情的发展变化集合在我们的专门的网页,实现一个可视化统计分析大屏前端,基于Vue技术实现,基于此项目可以做一些调整和二次开发,实现技术的实景应用,也可当做一个学习案例,了解Vue技术和可视化相关知识。 在线预览地址:http://yuanbaoshuju...
轻松高效搭建可视化数据网站
商务合作 / 项目定制 / 学习交流。个人vx:lovely_wml
11-14 4729
此文主要通过HTML+JS+CSS搭建可视化数据网站,可应用于数据中台或统计展示。
Python制作数据可视化仪表盘:使用Dash与Plotly构建实时交互式仪表盘
最新发布
一个被知识诅咒的人
10-07 1502
本文详细介绍了如何使用PythonDash和Plotly库构建交互式数据可视化仪表盘,适用于实时数据展示和动态图表生成。首先,介绍了Dash的基本布局和使用Plotly生成图表的基础知识。随后,通过具体示例展示了如何构建复杂的仪表盘,集成折线图、柱状图和饼图等多种图表类型,并且结合yfinance库实现股票市场的历史数据可视化。最后,本文演示了如何使用 dcc.Interval 实现数据的实时自动更新,构建具有动态交互的仪表盘应用。
数据可视化教程、案例与项目
07-08
在这个项目中,我们利用Python和Plotly构建了一个新冠疫情数据可视化仪表板。通过这个项目,我们可以了解如何使用Python处理大规模数据,以及如何使用Plotly创建交互式图表。此外,通过Dash框架,我们实现了将多个...
Python 数据分析:基于Plotly 的动态可视化绘图,557页
09-07
Python数据分析在现代信息技术领域扮演着至关重要的角色,而Plotly是一个强大的数据可视化工具,尤其适合创建交互式的图表和仪表板。本教程将深入探讨如何利用Plotly进行动态可视化绘图,帮助你提升数据分析的洞察力...
PYTHON数据可视化编程实战_13720859_python_shujukeshihua_数据可视化_
10-02
标题中的“PYTHON数据可视化编程实战”表明这是一份关于Python数据可视化的实战教程,而描述中的“数据可视化教程,可供经典入门练习题目,可供基础入门使用”则强调了该资源适用于初学者,提供了实践性的学习材料。...
Python实现数据的可视化.zip python数据可视化
01-09
Python数据可视化是一个重要的领域,它将复杂的数据集转化为易于理解的图形或图像,帮助人们快速洞察数据中的模式、趋势和关联。在这个过程中,Python库如Matplotlib、Seaborn、Plotly和Pandas等起到了关键作用。让...
纸壳CMS可视化建站系统搭建多语言网站
weixin_33840661的博客
09-12 357
纸壳CMS是可视化建站系统,现已经从架构上支持多语言。但是多语言功能默认是没有开启的。您可以从设置中开启多语言,或者随时关闭它,您可以随时进行切换。 开启多语言 如果您没有在系统设置中看到多语言设置菜单,首先先确认一下您的登录角色是否有多语言设置的权限: 添加权限后就可以看到多语言设置的菜单了 勾选是否启用?选项来启用多语言功能: 设置说明 多语言模式单域名模式,即所有的语言都使用同一个域...
新冠疫情数据可视化分析大屏
csbysj2020
01-17 522
项目采用Python Django作为后端框架,Vue.js作为前端框架,结合ECharts进行数据可视化展示。系统将利用Scrapy爬虫技术自动抓取最新的疫情数据,包括国内疫情地图、世界疫情地图、疫情走势等,以实现对疫情数据的实时更新。同时,系统提供用户登录注册功能,以及后台管理界面,方便管理员进行数据管理和系统维护。1. Python Django:一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。
基于Vue3+ECharts5+datav的疫情数据可视化大屏/地图项目
qq_44096635的博客
10-12 4379
基于Vue3+ECharts5+datav的疫情数据可视化大屏/地图项目,每日新增,国外新增排行
Pyecharts制作疫情可视化数据大屏
qq_25834057的博客
10-12 2662
本文灵感来源:https://blog.csdn.net/qq_43613793/article/details/104268536 感谢博主提供学习文章!
【毕业设计】基于Vue+ECharts的疫情数据可视化大屏/地图项目(附论文目录结构参考)酷炫大屏
coderYYY的博客
05-30 7225
Vue+echarts做的一个中国疫情数据可视化网站,附源码和论文参考
Flask+Echarts搭建全国疫情可视化大屏
m0_64336780的博客
09-20 5976
项目适合flask初学者来进行练手,当然前提也要会一些前端的知识,关于Echarts的使用可以去官网进行学习。关于页面的布局,可自由发挥来进行设计,或者在此基础上来进行创新,开发新的功能。
python flask大作业,疫情数据大屏可视化展示
段一的博客
06-24 3169
python flask大作业,疫情数据大屏可视化展示
豆瓣读书TOP250数据爬取与可视化Python项目
资源摘要信息:"Python课程设计-豆瓣读书TOP250的数据爬取及可视化设计源码.zip是一个包含了豆瓣读书TOP250图书信息的爬取与数据可视化设计的完整项目。该资源已经得到了导师的指导,并且评分高达97分,被认定为高...
写文章

热门文章

  • 【机器学习15】决策树模型详解 37654
  • 【python】将python代码打包成系统可执行文件(Pyinstaller模块) 34305
  • 【线性代数(3)】行列式的七大性质及推论 26761
  • 【线性代数(4)】行列式按行展开,异乘变零,拉普拉斯定理 21905
  • 【python实现网络爬虫(14)】python爬取酷狗中多类型音乐步骤详解(附全部源代码) 21864

分类专栏

  • python科研数据处理及绘图 付费 42篇
  • NLP自然语言处理 付费 30篇
  • 云服务 付费 6篇
  • python科学计量数据可视化 付费 60篇
  • python办公自动化 付费 37篇
  • 安全工程中的事故研究 2篇
  • 数据科学中事故分析与建模 1篇
  • 船舶建造工艺 4篇
  • Dash玩转可视化网站 14篇
  • 各种问题解决 11篇
  • 数据分析师 43篇
  • python爬虫
  • python网络爬虫 25篇
  • python爬虫专项 31篇
  • 爬虫高阶 9篇
  • scrapy爬虫 6篇
  • python数据分析 33篇
  • python数据分析实战 13篇
  • python数据处理 18篇
  • 大数据开发工程师 16篇
  • SPSS学习 1篇
  • 深度学习 2篇
  • 机器视觉 5篇
  • 宋浩B站线性代数课程笔记 13篇
  • 机器学习实例详解 2篇
  • 机器学习 18篇
  • tkinter项目 5篇
  • Kaggle实战 5篇
  • python 13篇

最新评论

  • 【机器学习】KNN算法实战项目一:婚恋对象分类

    lys_828: 数据资源:https://download.csdn.net/download/lys_828/85177124

  • 【机器学习】KNN算法实战项目一:婚恋对象分类

    Sixzh: 请问数据在哪

  • 【机器学习】线性回归实战案例三:股票数据价格区间预测模型(国外+国内数据)

    666%: Python:import pandas as pd # 读取CSV文件 df = pd.read_csv('600519.SH.csv', index_col='Date', parse_dates=True) # 假设复权因子已经计算好了,我们直接用一个常数来示例 adjust_factor = 1.1 # 这个应该根据实际情况来计算 # 应用复权因子 df['adj_open'] = df['open'] * adjust_factor df['adj_high'] = df['high'] * adjust_factor df['adj_low'] = df['low'] * adjust_factor df['adj_close'] = df['close'] * adjust_factor # 保存或查看结果 df[['adj_open', 'adj_high', 'adj_low', 'adj_close']].to_csv('adjusted_600519.SH.csv') print(df.head())

  • 【线性代数(7)】矩阵概念和矩阵运算

    -yccc: 写的太好辣

  • 【python】关于input语句和数值大小判断的问题

    End _: 如果我键入一个浮点数呢 比如18.5

大家在看

  • 问:数据库并发控制→隔离级别
  • C语言 | Leetcode C语言题解之第503题下一个更大元素II
  • 密钥管理方法DUKPT的OpenSSL代码实现Demo
  • Python | Leetcode Python题解之第502题IPO 100
  • ​​中国员工和老板的诉求 433

最新文章

  • 【科研笔记】中国知网高级检索与专业检索针对同一检索内容返回的结果对比
  • 【科学文献计量】中国知网(CNKI) 文献素材库生成软件详细使用说明
  • 【科学文献计量】使用Endnote软件打开中国知网导出的文献期刊解析不正确问题解决
2024年9篇
2023年63篇
2022年76篇
2021年81篇
2020年207篇
2019年6篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lys_828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

深圳坪山网站建设公司网站制作优化推广价格奉贤区公司网站优化平台seo优化和网站推广嘉兴网站优化真的有用吗如何优化移动端网站丰南网站优化哪家专业seo独立站优化网站优化商丘关键词网站优化报价一个小时的网站优化新乡外贸网站优化怎么选河南网站优化郑州网站搭建收费梅州企业网站优化公司如何湖北专业网站优化系统奉贤区公司网站优化方案谷城优化网站乐清网站优化企业许昌优化网站推广市场前景如何荣成网站优化选哪家技术好的百度seo网站优化天津网站竞价优化案例游戏行业网站优化运营利于优化的网站模板网站推广优化欢迎咨询郴州运营营销型网站优化寒亭网站关键词优化云南网站seo优化收费贵吗上海网站优化培训河源首页网站关键词优化报价优化服务网站餐饮行业网站优化好处香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化