在本文中,你将学习如何使用Vizro编写一个低代码数据仪表板,Vizro是一个基于Dash、Plotly和Pydantic构建的开源框架。你将了解如何通过迭代生成AI提示来构建三个Plotly图表,然后将这些提示添加到PyCafe上的Vizro仪表板中,最后添加一些交互控件。
以下是该仪表板的预览:
关于使用生成式AI的说明
本教程的部分内容使用了OpenAI的模型。要亲自执行这些步骤,你必须拥有一个带有付费额度的OpenAI账户。免费账户无法满足需求。请在OpenAI的网站上查看其模型及定价。教程的后半部分使用生成的代码进行操作,你无需为此提供密钥。
在使用生成式AI模型之前,你应查阅OpenAI关于风险缓解的指南,以了解模型的潜在限制和最佳实践。
什么是PyCafe?
该项目托管在PyCafe上,这是一个免费平台,可以在浏览器中创建、运行、编辑和共享Python网络应用程序。它可用于构建Vizro仪表板,以及Streamlit和Dash应用程序。通过分享PyCafe项目的链接,任何人都可以在本地访问代码和可视化内容,而无需安装任何Python包。
数据
为了创建这个仪表板,我使用了一个包含我在LinkedIn上的所有联系人的数据集。我前往LinkedIn网站设置中的数据隐私部分,选择获取你的数据副本,然后选择联系人。几分钟后,我通过电子邮件收到了数据的链接。CSV文件包含多列字符串,每行代表一个联系人:他们的名字、姓氏、个人资料URL、电子邮件地址(如果他们已公开)、当前公司、当前职位以及我们建立联系的日期。在使用数据之前,我删除了前三行警告可能缺失的电子邮件,并将文件重命名为connections.csv。
我使用了我的真实数据来制作这个示例,但为了保护我联系人的隐私,在撰写和发布这篇文章之前,我创建了一组新的虚假数据。虚假数据的字段与真实的LinkedIn数据转储的布局相匹配,因此如果你下载了自己的LinkedIn数据,可以用我虚构的数据集替换它,并在PyCafe项目中完美运行(只要你删除那前三行)。
使用Vizro-AI生成图表
在第一步中,我们将使用Vizro-AI的托管版本(位于py.cafe/app/vizro-official/vizro-ai-charts)来原型设计一组Plotly图表。导航到该网站,该网站将打开一个设置窗格,你可以在其中为你选择的供应商设置API密钥。在撰写本文时,你可以使用OpenAI、Anthropic、Mistral或xAI:
原型设计一组Plotly图表
设置API密钥后,返回主屏幕并上传项目的虚假数据,该数据存储在我的GitHub仓库中。现在,我们可以通过迭代文本来构建一些图表,使用自然语言形成有效的提示来描述我们想要看到的内容。
常见的职位头衔
第一个图表应显示我的联系人中最常见的当前职位头衔。使用gpt-4o并输入以下提示:
创建一个水平条形图,显示最常见的20个职位,频率最高的条形位于图表顶部。
以下是用于生成该图表的代码:
import vizro.plotly.express as px
from vizro.models.types import capture
@capture("graph")
def custom_chart(data_frame):
# Count the frequency of each position
position_counts = data_frame["Position"].value_counts().head(20)
# Create a horizontal bar chart
fig = px.bar(
position_counts,
x=position_counts.values,
y=position_counts.index,
orientation="h",
title="Top 20 Most Common Positions",
)
# Update layout for better readability
fig.update_layout(
yaxis_title="Position",
xaxis_title="Frequency",
yaxis=dict(categoryorder="total ascending"),
)
return fig
常见的雇主
第二个图表展示了我的联系人中最常见的当前雇主公司。
使用“公司”数据创建一个环形图,以显示最常见的5家公司。
以下是用于生成该图表的代码:
import vizro.plotly.express as px
from vizro.models.types import capture
@capture("graph")
def custom_chart(data_frame):
# Count the occurrences of each company
company_counts = data_frame["Company"].value_counts().nlargest(5)
# Create a DataFrame for the top 5 companies
top_companies = company_counts.reset_index()
top_companies.columns = ["Company", "Count"]
# Create a doughnut chart
fig = px.pie(
top_companies,
values="Count",
names="Company",
hole=0.4,
title="Top 5 Most Common Companies",
)
return fig
累计联系人总数
第三个图表展示了多年来我的联系人的累计数量。这个提示经过几次迭代才得以正确。
在数据框中创建一个名为“Year”的新列,并为每一行添加一个值,通过从“Connected On”(建立连接的日期)数据中计算出年份。然后计算每年的联系人累计总和,并绘制一个条形图,显示每年的联系人总数。将年份绘制在x轴上,将联系人数量绘制在y轴上。
在图上叠加一个散点图,显示按年份的累计联系人总数,右侧y轴使用不同的刻度。
以下是代码:
import pandas as pd
import plotly.graph_objects as go
from vizro.models.types import capture
@capture("graph")
def custom_chart(data_frame):
# Convert 'Connected On' to datetime and extract the year
data_frame["Year"] = pd.to_datetime(data_frame["Connected On"]).dt.year
# Count connections per year
yearly_counts = data_frame["Year"].value_counts().sort_index()
# Calculate cumulative sum of connections
cumulative_counts = yearly_counts.cumsum()
# Create figure with secondary y-axis
fig = go.Figure()
# Add bar chart for yearly connections
fig.add_trace(go.Bar(x=yearly_counts.index, y=yearly_counts, name="Connections per Year"))
# Add scatter plot for cumulative connections
fig.add_trace(
go.Scatter(
x=cumulative_counts.index,
y=cumulative_counts,
name="Cumulative Connections",
yaxis="y2",
)
)
# Set up the layout for secondary y-axis
fig.update_layout(yaxis2=dict(title="Cumulative Total", overlaying="y", side="right"))
return fig
将图表添加到Vizro仪表板
此时,我们已经有了将放在交互式仪表板中的Plotly图表的代码,并且我们不需要再使用通用人工智能进行任何进一步的操作。我们将继续在PyCafe上使用Vizro来开发仪表板。
导航到py.cafe并创建一个新的Vizro项目,该项目预填充了一个样板教程项目。上传数据文件connections.csv,以将数据添加到项目中。
如果你想探索这个样板代码,Vizro文档会逐步讲解代码,解释常见功能和构建仪表板的方法。
然而,对于本教程,只需用以下骨架替换样板项目中的现有代码,我们将用我们的原型图表来丰富这个骨架:
import vizro.plotly.express as px
from vizro import Vizro
import vizro.models as vm
page = vm.Page(
title="My LinkedIn connections",
layout=vm.Layout(grid=[[0, 1], [0, 2]]),
components=[
],
)
dashboard = vm.Dashboard(pages=[page], theme="vizro_light")
Vizro().build(dashboard).run()
现在,我们将添加数据处理代码和Vizro-AI输出的三段代码。我们还将添加组件代码作为vm.Page的参数,以调用这些段落的生成AI代码。
components=[
vm.Graph(id="role_bar_chart_id", figure=common_jobs(data_frame=df)),
vm.Graph(id="company_pie_chart_id", figure=common_companies(data_frame=df)),
vm.Graph(id="growth_cumulative_chart_id", figure=cumulative_totals(data_frame=df)),
],
就这样!我做了一个在这个节点停止的PyCafe项目,方便查看和扩展。文章的其余部分将在另一个项目中继续,通过添加一些简单的控件来增加交互性。
添加交互性
让我们扩展仪表板,添加控件以说明如何交互和更改展示内容。Vizro文档有一组操作指南,作为示例,我们将添加两个滑块,使用户能够调整各自图表中显示的常见职位和公司数量。控件的代码如下(相关的图表函数也需要更新,以接受一个额外参数来反映用户选择的值):
controls=[
vm.Parameter(
targets=["role_bar_chart_id.top_n"],
selector=vm.Slider(min=0, max=30, step=5, value=20, title="Show top n positions:"),
),
vm.Parameter(
targets=["company_pie_chart_id.top_n"],
selector=vm.Slider(min=0, max=30, step=5, value=5, title="Show top n companies:"),
)
]
总结
本教程使用了100多行代码和注释,制作了一个具有一些交互功能的基本仪表板。我们使用Vizro-AI,通过自然语言提示生成了一组Plotly图表的代码,然后将它们插入到PyCafe上的骨架Vizro仪表板中。
该项目可以进一步扩展和改进,因为Vizro对布局、导航和图表模板的设计有独到的见解。如果你具备设计能力并希望修改仪表板的外观,可以在CSS中覆盖默认设置。想要更多自定义功能?你可以扩展默认代码以融入Dash或React.js自定义功能,或者只是插入自定义的Plotly图表、表格、仪表板组件、动作或响应式HTML组件。