全球恐怖主义数据大屏制作步骤详解

  • 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文件中样式修改
    • 4.3 filteritem.py文件中样式修改
    • 4.4 stackbarline.py文件样式修改
    • 4.5 piechart.py文件中样式修改
    • 4.6 mapchart.py文件中样式修改
  • 5 小优化

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

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

1 项目效果图

整个项目的页面包含三部分,由上中下三栏构成。项目已上传至 个人Github仓库 。 项目头部是整个面板的标题,中间左侧是筛选条件,中间后两个是依据筛选条件生成的堆叠条状折线图和饼图,下面是地图可视化。

2 项目架构

项目中各文件名称与对应功能见下表

3 文件介绍和功能完善

3.1 assets文件夹介绍

assets文件夹中就是加载的样式和图片,样式这里可以使用之前已经下载好的bootstrap.min.css样式(也可以按照 项目6.2bootstrap组件 中的介绍下载其它的样式模板),本次项目中不需要加载本地图片。

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

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

index.py文件中引入初始化后的应用,然后进行布局及运行初始化设置。布局的主体是上中下三个部分,上面是项目的头部信息,中间是一行三列,下面是一个整体地图。

头部只有一个信息,使用HeaderInfo()填充内容,该函数分配在header.py文件中;而中间左侧是有三个筛选组件,直接用一个函数FilterInfo()填充内容,此函数分配在filteritem.py文件中,中间后两个图形分别用StackBarLineInfo()、PieInfo()两个函数填充,对应分配在stackbarline.py和piechart.py文件中; 下面只有一个图形展示,使用MapInfo()填充内容,该函数分配在mapchart.py文件中,该文件的全部代码如下。

from dash import html
import dash_bootstrap_components as dbc
from app import appfrom header import HeaderInfo
from filteritem import FilterInfo
from stackbarline import StackBarLineInfo
from piechart import PieInfo
from mapchart import MapInfoapp.layout = html.Div([html.Div([HeaderInfo()]),html.Div([dbc.Row([dbc.Col([FilterInfo()]),dbc.Col([StackBarLineInfo()]),dbc.Col([PieInfo()])])]),html.Div([MapInfo()])]
)if __name__ == '__main__':app.run_server(debug=True)

剩下的5个文件中的函数初始化内容如下。(api.py和api.ipynb文件初始化是空)

3.3 header.py文件完善

该文件的功能就是显示项目标题,并居中,设置相对简答,全部代码如下。

保存文件后,运行index.py,提示点击网址:http://127.0.0.1:8050/,刷线页面后,输出结果如下。

3.4 filteritem.py文件完善

该文件功能是实现筛选条件的设置,共两个Dropdown组件和一个Rangeslider组件,配合着文字提示,数据使用简单的内容先进行填充,全部代码如下。

from dash import html,dccdef FilterInfo():return html.Div([html.Div([html.H3([f'Select Region:']),dcc.Dropdown(['a','b','c'],'a',id='Region')]),html.Div([html.H3([f'Select Country:']),dcc.Dropdown(['usa','china','japan'],'usa',id='Country')]),html.Div([html.H3('Select Year:'),dcc.RangeSlider(min=1970,max=2017,step=1,marks=None,value=[2000,2010],tooltip={"placement": "bottom", "always_visible": True},id='Span-year')])])

保存文件后,刷新网页,输出的内容如下。

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

在api.ipynb文件中读取数据,并获取筛选组件中需要的内容:时间跨度、区域和国家信息。首先读取本地的文件,代码及输出内容如下。

文件中的数据是每次恐怖主义发生的记录,因此一年中某一国家可能会发生多起恐怖主义事件,需要将数据进行分组汇总。汇总之前,留心观察数值字段存在着缺失值,因此需要先进行缺失值处理(这里缺失数据默认就是0),然后按照区域、国家和年份进行分组求和统计,代码及输出结果如下。

获取时间跨度。对iyear字段进行最大、最小值求解即可,代码及输出结果如下。

获取区域标签。直接对region_txt字段进行唯一值计数,并排除缺失值None

获取国家标签。直接对country_txt字段进行唯一值计数,并排除缺失值None

获取完毕后,把内容转移到api.py文件中,并导入到filteritem.py文件中更新数据,此时api.py文件中的代码如下。

import os
os.chdir(r'd:/Data Science/plotly学习/个人/【12. Global terrorism】 Dropdown-Rangeslider-stackbarline-pie-map/')import pandas as pd
data = pd.read_csv('data/modified_globalterrorismdb_0718dist.csv')#首先对需要统计的字段进行缺失值填充,然后按照国家、地区、年份对死亡、受伤和攻击类型进行统计
data[['nkill','nwound','attacktype1']] = data[['nkill','nwound','attacktype1']].fillna(0)
df= data.groupby(['region_txt','country_txt','iyear'])[['nkill','nwound','attacktype1']].sum().reset_index()#获取数据的时间跨度
year_min,year_max = df['iyear'].min(),df['iyear'].max()#获取Dropdown组件中的标签信息,第一个是区域标签,核实没有缺失值None
region_ls = df['region_txt'].unique().tolist()#获取Dropdown组件中的标签信息,第二个是国家标签,核实也没有缺失值None
country_ls = df['country_txt'].unique().tolist()

filteritem.py文件中的更新数据的代码修改如下。

保存文件后,刷新网页,输出内容如下。此处可以优化,区域和国家联动,即选择区域后,国家里面的标签会随着变化,因为国家有区域属性,可以参考官网给的示例Dash App With Chained Callbacks。 这里使用区域和国家同时作为筛选条件相当于也是相同的结果,比如选择北美区域后,再选择中国,依次为筛选条件一定没有结果输出。

3.6 staclbarline.py文件完善

该文件的功能是依据中间左侧的筛选条件进行堆叠条状折线图的绘制。先进行基础架构的搭建,关于plotly绘制堆叠条状图,首先要在go.Figure()中添加两个Bar图,然后使用update_layout()方法指定barmode='stack',绘制代码如下。

由于StackBarLineInfo()函数是需要回调生成的内容,所以只需要创建一个容器保留id即可, 下面回调是依据前面设置的三个组件。数据使用简单的示例,测试是否可以正常显示出想要的图形,下一步才是从api.py中导入已经处理好的数据加以应用。此文件的全部代码如下。

from dash import html
from dash import html,dcc,Input,Output
from app import app
import plotly.graph_objects as godef StackBarLineInfo():return html.Div(id='stack-content')@app.callback(Output('stack-content','children'),[Input('Region','value'),Input('Country','value'),Input('Span-year','value')]
)
def update(region,country,span_year):fig = go.Figure([go.Bar(x=[1,2,3],y=[1,2,3]),go.Bar(x=[1,2,3],y=[2,3,4]),go.Scatter(mode='markers + lines',x=[1,2,3],y=[7,8,9])])fig.update_layout(barmode = 'stack')return [html.H3(f'Death,Injured and Attack: {country}'),dcc.Graph(figure=fig)]

保存文件后,刷新网址,输出的内容如下。

图形可以满足要求后,更新数据。其中x是代表着Rangeslider组件的筛选年份跨度,第一个Bar图对应着死亡人数,第二个Bar图对应着受伤人数,折线图对应着攻击类型计数汇总(比如:炸弹 武装袭击 暗杀 人质 基础设施袭击 )。在api.ipynb文件中封装一个获取数据的函数get_data(),括号中的参数就是筛选组件输入的值,代码及应用输出如下。

进一步把死亡、受伤和攻击类型的数据也获取到,融合到get_data()函数中。

数据获取成功后,将此函数转移到api.py文件中,并导入到stackbarline.py文件中。此时文件中的全部代码和修改内容如下。

保存文件后,刷新网址,输出的内容如下。基本上和最终项目案例效果图中的图形趋势一致,缺乏样式的修改。

3.7 piechart.py文件完善

该文件针对筛选的条件,对数据中的死亡、受伤和攻击类型进行饼图占比输出。前面已经封装了get_data()函数,这里直接拿来就可以使用。该文件中的全部代码和修改内容如下。

保存文件后,刷新网址,输出的内容如下。中间的堆叠条状折线图也可以指定name参数,显示图例的名称,这里在后续的样式中统一进行设置也没有问题。

3.8 mapchart.py文件完善

该文件的功能是根据筛选条件绘制散点地图。plotly中绘制散点地图的官方示例,代码如下。其中第一种方式中的px绘图是对go绘图的进一步简化封装,相当于把里面的一些过程直接封装成函数调用。

(1)使用px快速绘制

(2)使用go绘制

首先获取数据,之前的df数据集中只有地区和国家,不包含经纬度信息,需要重新按照需要字段进行分组统计求和,代码及输出结果如下。

将获取地理数据集的代码转移到api.py文件中,并导入到mapchart.py文件中。进一步依据回调的内容筛选数据,并根据官方示例代码中的(1)借助px绘图,此文件的全部代码及修改地方如下。其中使用maxbox绘制地图时,如果要进行风格的选择需要先注册,获取钥匙,然后赋值给accesstoken参数。具体注册的过程可以参照 plotly绘图进阶篇(地图可视化,动态数据可视化)

保存文件后,刷新网址,输出的内容如下。

4 样式修改

4.1 整体样式修改

在assets文件夹下新建一个setting.css文件,设置整体风格。主要是背景、边缘和字体颜色的设置。

保存文件后,刷新网址,输出的内容如下。

4.2 header.py文件中样式修改

文字已经居中了,就只需要调整一下头部信息与中间信息和浏览器顶部的间距即可,修改样式内容如下。

保存文件后,刷新网址,输出的内容如下。此时头部信息距离中间部分的距离就增大一些。

4.3 filteritem.py文件中样式修改

提示的文字信息左对齐,然后把Dropdown组件和Rangeslider组件的样式设置都可以直接参照项目11中所示。修改的css样式如下。

.card_container {border-radius: 5px;background-color: #070707;margin: 16px;padding: 15px;position: relative;box-shadow: 2px 2px 2px #292929;}/* 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;
}#Region *,#Country * {background-color: #191a1a !important;color: #f7f8f9 !important;font-size: 18px !important;text-align: center;
}.Select-control{border: 3px solid #323844 !important;
}.Select-menu-outer{overflow: hidden !important;border-color: #373838 !important;
}.rc-slider-track{background-color: rgb(234, 13, 112) !important;
}.rc-slider-handle{border-color: rgb(234, 13, 112) !important;
}.filter_item{padding-bottom: 30px;text-align: left;margin-left: 10px;
}

filteritem.py该文件的修改内容如下。

保存文件后,刷新网址,输出的内容如下。中间部分的筛选组件就设置完成了。

4.4 stackbarline.py文件样式修改

首先添加卡片属性,再修改图像背景以及显示的文字刻度,图例等小细节问题,此文件的全部代码如下。

from dash import html
from dash import html,dcc,Input,Output
from app import app
import plotly.graph_objects as go
from api import get_datadef StackBarLineInfo():return html.Div([html.Div(id='stack-content')],className='card_container')@app.callback(Output('stack-content','children'),[Input('Region','value'),Input('Country','value'),Input('Span-year','value')]
)
def update(region,country,span_year):death,injured,attack = get_data(region,country,span_year)span_year_ls = list(range(span_year[0],span_year[1]+1))fig = go.Figure([go.Bar(x=span_year_ls,y=death,name='Death'),go.Bar(x=span_year_ls,y=injured,name='Injured'),go.Scatter(mode='markers + lines',x=span_year_ls,y=attack,name='Attack')])fig.update_layout(barmode = 'stack',titlefont = {'color':'white','size':20},font = {'family':'sans-serif','color':'white','size':12},hovermode = 'closest',paper_bgcolor = '#070707',plot_bgcolor = '#070707',legend = {'orientation':'h','bgcolor':'#070707','xanchor':'center','x': 0.5, 'y': -0.2},margin = {'r':0,'l':60,'b':100,'t':20},xaxis = {'title':'<b>Year</b>','color':'white','showline':True,'showgrid':True,'tick0':0,'dtick':1,'gridcolor':'#010915','showticklabels':True,'linecolor':'white','linewidth':1,'ticks':'outside','tickfont':{'family':'sans-serif','color':'white','size':12}},yaxis = {'title':'<b>Death</b>','color':'white','showline':True,'showgrid':True,'gridcolor':'#010915','showticklabels':True,'linecolor':'white','linewidth':1,'ticks':'outside','tickfont':{'family':'sans-serif','color':'white','size':12}})return [html.H3(f'Death,Injured and Attack: {country}'),dcc.Graph(figure=fig)]

保存文件后,刷新网址,输出的内容如下。

虽然样式都满足要求,但是留心观察发现左侧的图形和中间的图形形状并没有对齐,因此应当考虑是不是card_container属性放置错误,先把所有的该属性放置文件代码全部删除,然后在index.py文件中指定如下。

保存所有修改文件后,再次刷新网页,输出结果如下。此时对齐的问题就全部解决了,样式的设置就是一个微工程,需要根据实际的网页输出再进行调整。

4.5 piechart.py文件中样式修改

修改图形背景颜色,和图例信息等。

保存所有修改文件后,再次刷新网页,输出结果如下。

4.6 mapchart.py文件中样式修改

添加card_container属性(这个需要在index.py中),背景颜色,字体样色,然后丰富一些交互显示信息hover_data(需要是展示地理数据集中的字段名称),也可以使用go绘制图形后使用hovertext丰富交互信息,参照项目10。


最后修改一下最后的图形的边距,如下。

保存所有修改文件后,再次刷新网页,输出结果如下。

5 小优化

在进行Dropdown组件获取区域和国家信息时,如果不把区域和国家进行关联,那么很可能后续图形都是空白,因为没有满足条件的数据。比如选个北美地区,再选个中国,自然也就没有数据。因此参照官网中关于链式回调 Chained Callbacks的案例,把此处的区域和国家联系起来,即选择区域后,国家只能在对应区域中选取。

按照官网中的示例需要首先有一个all_options字典变量,其中的键是第一个筛选组件中的元素,值是第二个筛选组件中的元素。值api.ipynb文件中对数据进行处理,将区域和国家也转化成为此类型。

第一步就是按照地区的唯一值把国家进行合并,那么结果就是区域为一列,国家为一列,国家的信息都放置在列表中,并去重。

第二步就是以第一列为键,第二列为值构建字典变量。

第三步把所有的字典数据放置在一个字典中,构建all_options字典变量。输出只截取部分。

把获取all_options的代码转移到api.py文件中,并导入到filteritem.py文件中,在最下面添加回调函数。此时filteritem.py文件中的全部代码更新如下。

from dash import html,dcc,Input,Output
from api import year_min,year_max,all_options
from app import appdef FilterInfo():return html.Div([html.Div([html.H3('Select Region:',className='filter_item'),dcc.Dropdown(list(all_options.keys()),'South Asia',id='Region')]),html.Div([html.H3(f'Select Country:',className='filter_item'),dcc.Dropdown(id='Country')],style={'paddingTop':'40px'}),html.Div([html.H3('Select Year:',className='filter_item'),dcc.RangeSlider(min=year_min,max=year_max,step=1,marks=None,value=[2000,2010],tooltip={"placement": "bottom", "always_visible": True},id='Span-year')],style={'paddingTop':'40px'})])@app.callback(Output('Country', 'options'),Input('Region', 'value'))
def set_cities_options(selected_country):return [{'label': i, 'value': i} for i in all_options[selected_country]]@app.callback(Output('Country', 'value'),Input('Country', 'options'))
def set_cities_value(available_options):return available_options[0]['value']

保存所有修改文件后,再次刷新网页,输出结果如下。

项目完结,撒花✿✿ヽ(°▽°)ノ✿

【Dash搭建可视化网站】项目12:全球恐怖主义数据大屏制作步骤详解相关推荐

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

    疫情数据可视化大屏制作步骤详解 1 项目效果图 2 项目架构 3 文件介绍和功能完善 3.1 assets文件夹介绍 3.2 app.py和index.py文件完善 3.3 header.py文件完善 ...

  2. 【Dash搭建可视化网站】项目13:销售数据可视化大屏制作步骤详解

    销售数据可视化大屏制作步骤详解 1 项目效果图 2 项目架构 3 文件介绍和功能完善 3.1 assets文件夹介绍 3.2 app.py和index.py文件完善 3.3 header.py文件完善 ...

  3. 【Dash搭建可视化网站】项目1:使用Dash创建简单网页

    项目1 :使用Dash创建简单网页 项目1 :使用Dash创建简单网页 1.1 官网示例 1.2 绘制简单网页的基本步骤 1.3 创建一个稍微有意思的页面 手动反爬虫,禁止转载: 原博地址 https ...

  4. 【Dash搭建可视化网站】项目4: 利用Dash Plotly实现数据图表可视化

    手动反爬虫,禁止转载:原博地址 https://blog.csdn.net/lys_828/article/details/122073681(CSDN博主:Be_melting) 知识梳理不易,请尊 ...

  5. 【Dash搭建可视化网站】项目11:世界自杀率数据看板

    世界自杀率数据看板 1 项目效果图 2 项目架构 3 文件介绍和功能完善 3.1 assets文件夹介绍 3.2 app.py和index.py文件完善 3.3 header.py文件完善 3.4 a ...

  6. 【Dash搭建可视化网站】项目5: 利用Dash 实现动态图表

    手动反爬虫,禁止转载:原博地址 https://blog.csdn.net/lys_828/article/details/122075142(CSDN博主:Be_melting) 知识梳理不易,请尊 ...

  7. Python+Flask框架搭建可视化网站

    Python+Flask框架搭建可视化网站 一.项目结构 二.app.py from flask import Flask,render_template import sqlite3app = Fl ...

  8. 【花雕动手做】有趣好玩的音乐可视化系列项目(31)--LCD1602液晶屏

    偶然心血来潮,想要做一个音乐可视化的系列专题.这个专题的难度有点高,涉及面也比较广泛,相关的FFT和FHT等算法也相当复杂,不过还是打算从最简单的开始,实际动手做做试验,耐心尝试一下各种方案,逐步积累 ...

  9. 华为云平台零代码搭建物联网可视化大屏体验:疫情防控数据大屏

    目录 一.介绍 二.准备 三.搭建 1.创建疫情防控大屏应用 2.组件放置 3.组件配置 4.应用打包 一.介绍 零代码搭建物联网可视化大屏 :自定义物联网场景,根据个人理解实现基于华为云IoT以及可 ...

最新文章

  1. Android OpenCV 边缘检测 Canny 的使用
  2. 浅谈C#中常见的委托Func,Action,Predicate(转)
  3. LiberOJ #6210. 「美团 CodeM 决赛」tree 树形DP
  4. java字节流复制_Java使用字节流复制文件的方法
  5. 关于数论【莫比乌斯反演】
  6. 你能在windows上创建一个叫做AUX的文件夹吗?
  7. AutoTile 自动拼接(四) 学习与实践
  8. 使用 SQL Server 代理来计划 SSAS 管理任务
  9. 使用ConfigurationManager来写自己的配置文件
  10. 修改Windows系统管理员Administrator的名称
  11. 如何修改图片尺寸,分辨率大小,三种方式对比。
  12. Swift最新的AES加密解密
  13. python里offset啥意思_深度理解Jquery 中 offset() 方法
  14. matlab 周期卷积,matlab连续时间信号卷积和离散时间信号卷积程序
  15. 计算机界的“武林秘籍”——经典教材推荐
  16. c语言sizeof用法计算char,C语言里sizeof(char)是什么意思
  17. WSA(win11子系统)安卓应用抢先体验
  18. python租房_如何用Python爬租房网站信息
  19. int.TryParse 方法
  20. libusb android pc,libusb: android上集成libusb库

热门文章

  1. 【Nodejs】外研社一年级起各年级英语音频下载(缺456年级上)
  2. 人走人留--大浪淘沙--又是辞职高峰
  3. 查看MySql数据库密码
  4. git 命令查看分支的创建者是谁
  5. 来自一个Python小白写的DNF手搓脚本
  6. 补丁服务器同步不上微软,WSUS服务器从Microsoft update同步更新失败
  7. Phase Sensitive Filter
  8. Docker网络资源详解 ---(四种网络模式)
  9. 计算机辅助药物设计 中药,基于系统生物学的计算机辅助药物设计中药研发新模式...
  10. 中药好,还是西药好?中医好,还是西医好?