原文:
www.kdnuggets.com/2023/08/create-dashboard-python-dash.html
在数据科学和分析的领域中,数据的力量不仅在于提取洞察力,还在于有效地传达这些洞察力;这就是数据可视化发挥作用的地方。
数据可视化是信息和数据的图形化表现。它使用图表、图形和地图等视觉元素,使得更容易看出原始数据中的模式、趋势和异常值。对于数据科学家和分析师而言,数据可视化是一个重要工具,它有助于更快、更准确地理解数据,支持数据故事讲述,并有助于做出数据驱动的决策。
在这篇文章中,你将学习如何使用Python和Dash框架创建一个仪表盘来可视化 Netflix 的内容分布和分类。
Dash 是一个由Plotly开发的开源低代码框架,用于在纯 Python 中创建分析性 Web 应用程序。传统上,为了实现这些目的,人们可能需要使用JavaScript 和 HTML,这需要你在后台(Python)和前端(JavaScript、HTML)技术方面都有专业知识。
然而,Dash 弥补了这一差距,使数据科学家和分析师能够仅使用 Python构建交互式、美观的仪表盘。这种低代码开发的特点使 Dash 成为创建分析仪表盘的合适选择,尤其是对于那些主要使用 Python 的人。
现在你已经了解了 Dash,让我们开始我们的实践项目。你将使用Netflix 电影和电视节目数据集,该数据集由Shivam Bansal创建,并可以在Kaggle上获得。
该数据集包含了截至 2021 年 Netflix 上可用的电影和电视节目的详细信息,如内容类型、标题、导演、演员、制作国家、发行年份、评级、时长等。
尽管数据集创建于 2021 年,但它仍然是发展数据可视化技能和理解媒体娱乐趋势的宝贵资源。
使用该数据集,你的目标是创建一个仪表盘,允许可视化以下几点:
-
地理内容分布:一张地图图表展示了内容生产在不同国家之间的年度变化。
-
内容分类:这个可视化将 Netflix 的内容分为电视节目和电影,以查看哪些类型最为突出。
让我们开始创建一个名为netflix-dashboard的项目目录,然后通过以下命令初始化和激活 Python 虚拟环境:
# Linux & MacOS
mkdir netflix-dashboard && cd netflix-dashboard
python3 -m venv netflix-venv && source netflix-venv/bin/activate
# Windows Powershell
mkdir netflix-dashboard && cd netflix-dashboard
python -m venv netflix-venv && .\netflix-venv\Scripts\activate
接下来,你需要安装一些外部包。你将使用pandas
进行数据处理,dash
创建仪表板,plotly
绘制图表,以及dash-bootstrap-components
为仪表板添加一些样式:
# Linux & MacOS
pip3 install pandas dash plotly dash-bootstrap-components
# Windows Powershell
pip install pandas dash plotly dash-bootstrap-components
在 Netflix 数据集中,你会发现director
、cast
和country
列中有缺失值。将date_added
列的string
值转换为datetime
以便于分析也会很方便。
要清理数据集,你可以创建一个新的文件clean_netflix_dataset.py,其中包含以下代码,然后运行它:
import pandas as pd
# Load the dataset
df = pd.read_csv('netflix_titles.csv')
# Fill missing values
df['director'].fillna('No director', inplace=True)
df['cast'].fillna('No cast', inplace=True)
df['country'].fillna('No country', inplace=True)
# Drop missing and duplicate values
df.dropna(inplace=True)
df.drop_duplicates(inplace=True)
# Strip whitespaces from the `date_added` col and convert values to `datetime`
df['date_added'] = pd.to_datetime(df['date_added'].str.strip())
# Save the cleaned dataset
df.to_csv('netflix_titles.csv', index=False)
设置好工作空间并清理数据集后,你准备开始制作仪表板了。创建一个新的文件app.py,其中包含以下代码:
from dash import Dash, dash_table, html
import pandas as pd
# Initialize a Dash app
app = Dash(__name__)
# Define the app layout
app.layout = html.Div([
html.H1('Netflix Movies and TV Shows Dashboard'),
html.Hr(),
])
# Start the Dash app in local development mode
if __name__ == '__main__':
app.run_server(debug=True)
让我们解析一下app.py中的代码:
-
app = Dash(__name__)
:这一行初始化了一个新的 Dash 应用程序。可以把它看作是你应用的基础。 -
app.layout = html.Div(…)
:app.layout
属性允许你编写类似 HTML 的代码来设计应用的用户界面。上述布局使用了html.H1(…)
标题元素作为仪表板标题,并在标题下方添加了一个水平规则html.Hr()
元素。 -
app.run(debug=True)
:这一行启动了一个开发服务器,在本地开发模式下提供你的 Dash 应用。Dash 使用Flask,一个轻量级的 web 服务器框架,将你的应用提供给 web 浏览器。
运行app.py后,你会在终端中看到一条消息,指示你的 Dash 应用正在运行并可以在127.0.0.1:8050/
访问。打开此 URL 以在你的 web 浏览器中查看:
你的第一个 Dash 应用程序!
结果看起来很简单,对吧?别担心!这一部分旨在展示最基本的 Dash 应用结构和组件。你很快会添加更多功能和组件,使其成为一个令人惊叹的仪表板!
下一步是编写仪表板布局的代码并为其添加一些样式!为此,你可以使用Dash Bootstrap Components (DBC),一个为 Dash 提供 Bootstrap 组件的库,使你能够开发具有响应式布局的样式化应用。
仪表板将以选项卡布局样式化,这提供了一种在同一空间内组织不同类型信息的紧凑方式。每个选项卡将对应于一个独特的可视化。
让我们继续修改app.py的内容以纳入 DBC:
from dash import Dash,dcc, html
import pandas as pd
import dash_bootstrap_components as dbc
# Initialize the Dash app and import the Bootstrap theme to style the dashboard
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container(
[
dcc.Store(id='store'),
html.H1('Netflix Movies and TV Shows Dashboard'),
html.Hr(),
dbc.Tabs(
[
dbc.Tab(label='Geographical content distribution', tab_id='tab1'),
dbc.Tab(label='Content classification', tab_id='tab2'),
],
id='tabs',
active_tab='tab1',
),
html.Div(id='tab-content', className='p-4'),
]
)
if __name__ == '__main__':
app.run(debug=True)
在这个修改后的布局中,你会看到新的组件:
-
dbc.Container
:使用dbc.Container
作为顶级组件将整个仪表板布局包裹在一个响应式和灵活的容器中。 -
dcc.Store
:这个 Dash Core 组件允许你将数据存储在客户端(用户的浏览器)上,通过本地存储数据来提升应用性能。 -
dbc.Tabs
和dbc.Tab
:每个dbc.Tab
代表一个独立的标签页,包含不同的可视化内容。label
属性显示在标签页上,tab_id
用于标识标签页。dbc.Tabs
的active_tab
属性用于指定 Dash 应用启动时的活动标签页。
现在运行app.py。生成的仪表板将具有 Bootstrap 样式布局,包含两个空标签页:
集成 Bootstrap 以实现标签样式布局
干得不错!你终于准备好将可视化内容添加到仪表板中。
在使用 Dash 时,通过回调函数实现交互性。回调函数是在输入属性变化时自动调用的函数。之所以称为“回调”,是因为它是一个被 Dash 在应用发生变化时“回调”的函数。
在这个仪表板中,你将使用回调函数在选定的标签页中呈现相关的可视化,每个可视化将存储在components目录下的独立 Python 文件中,以便更好地组织和模块化项目结构。
创建一个名为components的新目录,在其中创建一个geographical_content.py文件,该文件将生成一个区域图,展示 Netflix 的内容生产如何随年份在各国之间变化:
import pandas as pd
import plotly.express as px
from dash import dcc, html
df = pd.read_csv('netflix_titles.csv')
# Filter out entries without country information and if there are multiple production countries,
# consider the first one as the production country
df['country'] = df['country'].str.split(',').apply(lambda x: x[0].strip() if isinstance(x, list) else None)
# Extract the year from the date_added column
df['year_added'] = pd.to_datetime(df['date_added']).dt.year
df = df.dropna(subset=['country', 'year_added'])
# Compute the count of content produced by each country for each year
df_counts = df.groupby(['country', 'year_added']).size().reset_index(name='count')
# Sort the DataFrame by 'year_added' to ensure the animation frames are in ascending order
df_counts = df_counts.sort_values('year_added')
# Create the choropleth map with a slider for the year
fig1 = px.choropleth(df_counts,
locations='country',
locationmode='country names',
color='count',
hover_name='country',
animation_frame='year_added',
projection='natural earth',
title='Content produced by countries over the years',
color_continuous_scale='YlGnBu',
range_color=[0, df_counts['count'].max()])
fig1.update_layout(width=1280, height=720, title_x=0.5)
# Compute the count of content produced for each year by type and fill zeros for missing type-year pairs
df_year_counts = df.groupby(['year_added', 'type']).size().reset_index(name='count')
# Create the line chart using plotly express
fig2 = px.line(df_year_counts, x='year_added', y='count', color='type',
title='Content distribution by type over the years',
markers=True, color_discrete_map={'Movie': 'dodgerblue', 'TV Show': 'darkblue'})
fig2.update_traces(marker=dict(size=12))
fig2.update_layout(width=1280, height=720, title_x=0.5)
layout = html.Div([
dcc.Graph(figure=fig1),
html.Hr(),
dcc.Graph(figure=fig2)
])
上述代码通过'country'
和'year_added'
过滤和分组数据,然后计算每个国家在df_counts
数据框中每年的内容生产量。
然后,px.choropleth
函数使用df_counts
数据框中的列作为其参数值来构建地图图表:
-
locations='country'
:允许你指定'country'
列中包含的地理位置值。 -
locationmode='country names'
:这个参数“告诉函数”提供的locations
是国家名称,因为 Plotly Express 也支持其他位置模式,如 ISO-3 国家代码或美国州名。 -
color='count'
:用于指定用于着色地图的数值数据。这里,它指的是'count'
列,该列包含每个国家每年的内容生产量。 -
color_continuous_scale='YlGnBu'
:为地图中的每个国家构建一个连续的颜色比例,当color
指定的列包含数值数据时。 -
animation_frame='year_added'
:这个参数在'year_added'
列上创建动画。它在地图图表中添加一个年份滑块,允许你查看表示各国内容生产演变的动画。 -
projection='natural earth'
:这个参数没有使用df_counts
DataFrame 中的任何列;然而,'natural earth'
值用于设置地球世界地图的投影。
在层析图地图下方,还包含了一个带标记的折线图,展示了内容数量的变化情况,按类型(电视节目或电影)分类,显示多年变化。
为了生成折线图,创建了一个新的 DataFramedf_year_counts
,该 DataFrame 通过'year_added'
和'type'
列对原始df
数据进行分组,统计每种组合的内容数量。
然后使用px.line
处理这些分组数据,其中'x'
和'y'
参数分别分配给'year_added'
和'count'
列,'color'
参数设置为'type'
以区分电视节目和电影。
下一步是创建一个名为 content_classification.py的新文件,该文件将生成一个树图图表,以从类型和类别的角度可视化 Netflix 的内容:
import pandas as pd
import plotly.express as px
from dash import dcc, html
df = pd.read_csv('netflix_titles.csv')
# Split the listed_in column and explode to handle multiple genres
df['listed_in'] = df['listed_in'].str.split(', ')
df = df.explode('listed_in')
# Compute the count of each combination of type and genre
df_counts = df.groupby(['type', 'listed_in']).size().reset_index(name='count')
fig = px.treemap(df_counts, path=['type', 'listed_in'], values='count', color='count',
color_continuous_scale='Ice', title='Content by type and genre')
fig.update_layout(width=1280, height=960, title_x=0.5)
fig.update_traces(textinfo='label+percent entry', textfont_size=14)
layout = html.Div([
dcc.Graph(figure=fig),
])
在上述代码中,数据加载后,对'listed_in'
列进行调整,通过拆分和展开每个内容的多种类型来处理多个类型,为每个类型创建一个新行。
接下来,创建df_counts
DataFrame,以'type'
和'listed_in'
列对数据进行分组,并计算每种类型-类别组合的数量。
然后,将df_counts
DataFrame 中的列用作px.treemap
函数参数的值,如下所示:
-
path=['type', 'listed_in']
:这些是树图中表示的层次类别。'type'
和'listed_in'
列分别包含内容的类型(电视节目或电影)和类别。 -
values='count'
:树图中每个矩形的大小对应于'count'
列,表示每种类型-类别组合的内容数量。 -
color='count'
:'count'
列也用于为树图中的矩形着色。 -
color_continous_scale='Ice'
:当由color
表示的列包含数字数据时,为树图中的每个矩形构建一个连续的颜色刻度。
在创建了两个新的可视化文件后,你当前的项目结构应该如下所示:
netflix-dashboard
├── app.py
├── clean_netflix_dataset.py
├── components
│ ├── content_classification.py
│ └── geographical_content.py
├── netflix-venv
│ ├── bin
│ ├── etc
│ ├── include
│ ├── lib
│ ├── pyvenv.cfg
│ └── share
└── netflix_titles.csv
最后一步是修改app.py,以导入components目录中的两个新可视化,并实现回调函数,以在选择标签时渲染图表:
from dash import Dash, dcc, html, Input, Output
import dash_bootstrap_components as dbc
from components import (
geographical_content,
content_classification
)
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container(
[
dcc.Store(id='store'),
html.H1('Netflix Movies and TV Shows Dashboard'),
html.Hr(),
dbc.Tabs(
[
dbc.Tab(label='Geographical content distribution', tab_id='tab1'),
dbc.Tab(label='Content classification', tab_id='tab2'),
],
id='tabs',
active_tab='tab1',
),
html.Div(id='tab-content', className='p-4'),
]
)
# This callback function switches between tabs in a dashboard based on user selection.
# It updates the 'tab-content' component with the layout of the newly selected tab.
@app.callback(Output('tab-content', 'children'), [Input('tabs', 'active_tab')])
def switch_tab(at):
if at == 'tab1':
return geographical_content.layout
elif at == 'tab2':
return content_classification.layout
if __name__ == '__main__':
app.run(debug=True)
回调装饰器@app.callback
监听'tabs'
组件的'active_tab'
属性的变化,由Input
对象表示。
每当'active_tab'
发生变化时,switch_tab
函数会被触发。这个函数检查'active_tab'
的 id,并返回要在'tab-content'
Div 中渲染的相应布局,如Output
对象所示。因此,当你切换标签时,相关的可视化会出现。
最后,再次运行app.py以查看包含新可视化的更新仪表板:
Netflix 电影和电视节目仪表板 — 最终结果
本文教会了您如何创建一个仪表板来探索和可视化 Netflix 的内容分布和分类。通过利用 Python 和 Dash 的力量,您现在已经能够创建自己的可视化,从而为您的数据提供宝贵的洞察。
您可以在以下 GitHub 仓库查看此项目的完整代码:github.com/gutyoh/netflix-dashboard
如果您觉得这篇文章对您有帮助,并且想扩展对 Python 和数据科学的知识,考虑查看 Hyperskill 上的数据科学入门课程。
如果您对本博客有任何问题或反馈,请在下面的评论中告诉我。
赫尔曼·罗斯 是 Hyperskill Go 编程课程的技术作者,他将对教育科技的热情与赋能下一代软件工程师的使命融合在一起。同时,作为伊利诺伊大学厄本那-香槟分校的硕士生,他还深入数据领域。
原始. 经许可转载。
1. 谷歌网络安全证书 - 快速进入网络安全职业生涯。
2. 谷歌数据分析专业证书 - 提升您的数据分析技能
3. 谷歌 IT 支持专业证书 - 支持您的组织 IT