Dash仪表盘:从网页抓取到交互式图形集成
立即解锁
发布时间: 2025-09-03 00:55:38 阅读量: 8 订阅数: 16 AIGC 


数据可视化:R与Python实战
### Dash 仪表盘:从网页抓取到交互式图形集成
#### 1. 网页表格的网络抓取
在 Python 中进行网络抓取相对容易,特别是对于从静态页面收集 HTML 表格这类基本操作。主要借助 pandas 的 `pd.read_html()` 函数,只需指定一个 URL 即可。例如,我们从维基百科页面“按国际游客数量排名的城市列表”(https://en.wikipedia.org/wiki/List_of_cities_by_international_visitors)读取 HTML 表格:
```python
import pandas as pd
url = "https://en.wikipedia.org/wiki/List_of_cities_by_international_visitors"
dfs = pd.read_html(url)
```
`dfs` 数组包含抓取结果,`dfs[0]` 是对应表格的数据框。不过,`Growth in arrivals (Euromonitor)` 列的值带有 `%` 符号,需要将其移除才能转换为数值类型。同时,该列中的负号使用的是连字符而非减号,也需要替换为正确符号,否则在类型转换时无法被识别为负数值。操作如下:
```python
dfs[0]['Growth in arrivals (Euromonitor)'] = dfs[0]['Growth in arrivals (Euromonitor)'].str.replace('%', '')
dfs[0]["Growth in arrivals (Euromonitor)"] = dfs[0]["Growth in arrivals (Euromonitor)"].str.replace("[-]", "-", regex=True)
dfs[0]['Growth in arrivals (Euromonitor)'] = pd.to_numeric(dfs[0]['Growth in arrivals (Euromonitor)'])
```
此外,部分国家名称需要进行调整,以确保能与侧边栏联合国旅游数据下拉小部件中的名称正确匹配:
```python
dfs[0]['Country / Territory'] = dfs[0]['Country / Territory'].str.replace('United States', 'United States of America')
dfs[0]['Country / Territory'] = dfs[0]['Country / Territory'].str.replace('Turkey', 'Türkiye')
```
为简便起见,该表格以静态表格形式呈现,不关联响应式事件。但实际上,也可像处理第一个数据表那样使其具有响应性。
#### 2. 第三个 Dash 仪表盘:标签页与网页表格抓取
##### 2.1 第二个标签页布局
相较于之前的仪表盘版本,第二个标签页是新增的。我们计划在其中放置两个条形图(`id=bar2` 和 `id=bar3`)以及通过网络抓取维基百科页面生成的数据表(`id=datatable2`)。布局组织并不复杂,数据表的样式选项可在附加在线材料中找到。
```python
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import dash_table
# 第一行
content_first_row_tab2 = dbc.Row(
[
dbc.Col([
html.P("2018 年游客增长最多的前 20 个城市"),
dcc.Graph(id="bar2"),
], width=6),
dbc.Col([
html.P("2018 年游客到访最多的前 20 个城市"),
dcc.Graph(id="bar3")
], width=6)
], className="g-0"
)
# 第二行
content_second_row_tab2 = dbc.Row(
[
dbc.Col(
html.Div(
dash_table.DataTable(
data=dfs[0].to_dict('records'),
id="datatable2",
# 省略部分样式选项
)
)
)
]
)
# 标签页内容
content_tab2 = html.Div(
[
content_first_row_tab2,
html.Hr(),
content_second_row_tab2,
],
style=CONTENT_STYLE
)
```
##### 2.2 第二个标签页的响应式事件
接下来,需要为条形图指定响应式操作,使其填充从维基百科收集的数据。两个条形图的描述如下:
- **条形图(`id=bar2`)**:该条形图按游客到访增长顺序展示国家(`Growth in arrivals [Euromonitor]` 列)。国家可通过下拉菜单列表或“所有国家”复选框进行选择。逻辑为:若选中复选框,则考虑所有国家,并按游客到访增长降序展示前 20 个国家;若未选中复选框,则展示下拉菜单中所选的国家。同时,为使条形图根据正负增长呈现不同颜色,我们创建一个新的 `Color` 列。添加动态工具提示,并使用 `px.bar()` 函数的 `barplot='relative'` 属性绘制相对于零值的条形图,即正负值的条形图方向相反,这是一种发散型条形图,Plotly 原生支持。
- **条形图(`id=bar3`)**:与第一个条形图的区别在于,当选中“所有国家”复选框时,国家按欧睿国际排名(`Rank (Euromonitor)` 列)排序,并展示排名前 20 的国家。在 Plotly 条形图中,添加 `color_discrete_map()` 属性为 `Color` 列的 `Negative` 和 `Positive` 值分配不同颜色。
以下是两个条形图的回调函数代码:
```python
import plotly.express as px
import numpy as np
from dash.dependencies import Input, Output
import dash
app = dash.Dash(__name__)
# 第一个条形图:bar2
@app.callback(
Output("bar2", "figure"),
Input("dropdown", "value"),
Input("checklist", "value")
)
def update_barplot2(dropdown_selection, checkbox_value):
temp1 = dfs[0].copy(deep=True)
temp1["Color"] = np.where(temp1["Growth in arrivals (Euromonitor)"] < 0, 'Negative', 'Positive')
# 选择行的逻辑条件
if checkbox_value:
data = temp1.sort_values(by='Growth in arrivals (Euromonitor)', ascending=False).head(20)
else:
mask = temp1['Country / Territory'].isin(dropdown_selection)
data = temp1[mask].sort_values(by='Growth in arrivals (Euromonitor)', ascending=False)
# 条形图
fig = px.bar(data, x="Growth in arrivals (Euromonitor)",
y="City", barmode='relative',
orientation='h', color="Color",
hover_data={'Color': False, 'City': False,
"Country / Territory": True,
"Arrivals 2018 (Euromonitor)": True
```
0
0
复制全文
相关推荐










