使用 Streamlit 和 Plotly 创建多页交互式仪表板
Streamlit 的伟大之处在于,它不仅美观,而且简单。
几个月前,我写了一篇关于如何使用 Plotly 和 Flask 编写仪表板的文章——这是使用 Dash 的另一种方法,我对此非常满意。该应用程序由两个文件组成,一个 20 多行的 Python/Flask 应用程序和一个近 30 行的 HTML/Javascript 文件。你可以在这里看到这篇文章:
带有 Plotly 和 Flask 的交互式 Web 仪表板指向datascience.com
然后我决定尝试使用 Streamlit 实现相同的东西:结果是一个大约十几行的 Python 文件。四分之一大小!不仅写起来简单快捷,而且看起来也更好看。
所以,我想我会分享我的经验,首先是使用 Plotly 图表创建一个简单的交互式 Streamlit 应用程序,然后将其开发成一个更复杂(但仍然很简单)的多页应用程序。在此过程中,我研究了如何绘制 Plotly 图表、在 Streamlit 中控制布局以及使用下拉菜单进行导航。
第一个应用程序将是我的 Flask 应用程序的克隆,如下所示:
一个简单的 Streamlit 应用程序 - 作者的图像
用户从左侧的下拉菜单中选择一个国家,并在右侧绘制相应的图表。
Streamlit 应用程序只是一个 Python 程序,它使用 Streamlit 库并在终端窗口中使用 Streamlit 命令运行。例如
streamlit run myapp.py
然后它将启动您的浏览器并在那里运行应用程序。
不过,第一件事。要使用 Streamlit,您显然必须安装它:
pip3 install streamlit
或 conda,或任何其他用于安装 Python 包的神秘方法。
一个简单的 Streamlit 应用程序
你可以这样启动你的 Python 程序:
import streamlit as st
import pandas as pd
import plotly.express as px
我将使用 Pandas 存储和操作数据并使用 Plotly 创建图表。
出于演示目的,我使用 Plotly 包中包含的 Gapminder 数据。所以,下一段代码是:
df = pd.DataFrame(px.data.gapminder())
这将创建一个数据框,其中包含有关世界所有国家/地区的信息表,如下所示:
_国家数据-作者图片
表中列出了每个国家以及几十年来的预期寿命、人口和人均 GDP 的数据。还给出了每个国家的大陆(也有其他数据,但这里不感兴趣)。
我们最初要做的是为选定的国家创建人口和人均 GDP 的图。因此,我们需要一个用户可以从中选择的国家名称列表。这很容易通过从数据框中选择国家列并创建唯一名称列表来实现。
clist = df['country'].unique()
运行后,我们在变量 clist 中有一个唯一名称列表。
_国家名单 - 作者图片
下拉菜单是在 clist 的侧边栏中创建的,如下所示:
country = st.sidebar.selectbox("Select a country:",clist)
所有以st. st.sidebar
开头的 Streamlit 函数都会在屏幕左侧创建一个侧边栏,而.selectbox
会使用第一个参数中提供的提示从列表中创建一个下拉列表。
接下来我们绘制图表。
fig = px.line(df[df['country'] == country],
x = "year", y = "gdpPercap", title = country)
在这里,您可以看到我们通过仅选择数据框中与所选国家对应的行来在变量fig
中创建折线图。
整个程序如下所示,正如我之前提到的,它只有十几行代码。
import streamlit as st
import pandas as pd
import plotly.express as px
df = pd.DataFrame(px.data.gapminder())
clist = df['country'].unique()
country = st.sidebar.selectbox("Select a country:",clist)
st.header("GDP per Capita over time")
fig = px.line(df[df['country'] == country],
x = "year", y = "gdpPercap", title = country)
st.plotly_chart(fig)
有几行我没有涉及。st.header("GDP per Capita over time")
创建一个标题,st.plotly_chart(fig)
绘制图表。
当我们运行程序时,我们得到:
一个简单的 Streamlit 应用程序 - 作者的图像
我认为,对于这么小的程序来说,这非常好。
但它会变得更好。
多页面应用
为了说服自己,我可以像使用 Dash 一样轻松地使用 Flask 和 HTML 制作应用程序,我创建了一个简单的多页应用程序,该应用程序对每个页面使用相同的 HTML 模板,但从 Flask 将不同的数据加载到其中.你可以在这里看到这篇文章:
使用 Plotly 和 Flask 进行 Web 可视化。面向datascience.com
Streamlit 的情况就不同了。没有对多页的具体支持,我猜这不是遗漏。 Streamlit 并不意味着创建整个网站。
但有时有点分页很有用,所以我编写了一个新应用程序,它在第一个应用程序的基础上进行了扩展,提供更多信息并运行在两页上。它看起来也更好!
目的是有两页,一页用于国家,另一页用于大陆。在每一页上,您可以选择一个国家或大洲,您将获得两张图表,一张代表 GDP,另一张代表人口。您可以在下面看到大陆页面的样子。
一个多页 Streamlit 应用程序 - 作者的图像
实际上,也许你看不太清楚,所以这里是页面左侧的放大图像。
_来自多页面 Streamlit 应用程序的详细信息 -作者提供的图像
左侧是带有下拉菜单的侧边栏,您可以在其中选择_country_ 或_continent_。页面的主要部分包含图表,并有自己的下拉菜单来选择哪个大陆(欧洲、亚洲等)或哪个国家。
国家页面如下所示。
一个多页 Streamlit 应用程序 - 作者的图像
方法很简单。只需在if... else
语句中使用从侧边栏中的下拉菜单返回的值,并在if
块或else
块中显示相应的数据。代码如下所示:
page = st.sidebar.selectbox('Select page',
['Country data','Continent data'])
if page == 'Country data':
# Display the country content here
else:
# Display the continent content here
我正在使用列来并排显示图表,并且我已将布局设置为宽以给自己更多空间。
除此之外,替换这些注释的代码与我们在第一个示例中看到的几乎相同。
以下是完整清单:
import streamlit as st
import pandas as pd
import plotly.express as px
st.set_page_config(layout = "wide")
df = pd.DataFrame(px.data.gapminder())
st.header("National Statistics")
page = st.sidebar.selectbox('Select page',
['Country data','Continent data'])
if page == 'Country data':
## Countries
clist = df['country'].unique()
country = st.selectbox("Select a country:",clist)
col1, col2 = st.columns(2)
fig = px.line(df[df['country'] == country],
x = "year", y = "gdpPercap",title = "GDP per Capita")
col1.plotly_chart(fig,use_container_width = True)
fig = px.line(df[df['country'] == country],
x = "year", y = "pop",title = "Population Growth")
col2.plotly_chart(fig,use_container_width = True)
else:
## Continents
contlist = df['continent'].unique()
continent = st.selectbox("Select a continent:",contlist)
col1,col2 = st.columns(2)
fig = px.line(df[df['continent'] == continent],
x = "year", y = "gdpPercap",
title = "GDP per Capita",color = 'country')
col1.plotly_chart(fig)
fig = px.line(df[df['continent'] == continent],
x = "year", y = "pop",
title = "Population",color = 'country')
col2.plotly_chart(fig, use_container_width = True)
现在,如果我很聪明,我会意识到我在这个应用程序中有大量非常相似的代码,因此会编写一些函数来减少这种情况。但我暂时保持原样。
优缺点
Streamlit 易于使用并产生非常好的结果,但它仅适用于相当简单的应用程序。具有复杂布局的多页面应用程序并不是它的真正用途,这很公平。
感谢您的阅读,如果您想不时听到我发表的文章,请考虑订阅我的免费时事通讯Technofile或访问我的Github 页面。
您可以在Github上获取本文和其他文章的代码,并在此处查看最终应用程序的演示。
更多推荐
所有评论(0)