Streamlit 的伟大之处在于,它不仅美观,而且简单。

几个月前,我写了一篇关于如何使用 Plotly 和 Flask 编写仪表板的文章——这是使用 Dash 的另一种方法,我对此非常满意。该应用程序由两个文件组成,一个 20 多行的 Python/Flask 应用程序和一个近 30 行的 HTML/Javascript 文件。你可以在这里看到这篇文章:

带有 Plotly 和 Flask 的交互式 Web 仪表板指向datascience.com

然后我决定尝试使用 Streamlit 实现相同的东西:结果是一个大约十几行的 Python 文件。四分之一大小!不仅写起来简单快捷,而且看起来也更好看。

所以,我想我会分享我的经验,首先是使用 Plotly 图表创建一个简单的交互式 Streamlit 应用程序,然后将其开发成一个更复杂(但仍然很简单)的多页应用程序。在此过程中,我研究了如何绘制 Plotly 图表、在 Streamlit 中控制布局以及使用下拉菜单进行导航。

第一个应用程序将是我的 Flask 应用程序的克隆,如下所示:

一个简单的 Streamlit 应用程序 - 作者的图像一个简单的 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 应用程序 - 作者的图像一个简单的 Streamlit 应用程序 - 作者的图像

我认为,对于这么小的程序来说,这非常好。

但它会变得更好。

多页面应用

为了说服自己,我可以像使用 Dash 一样轻松地使用 Flask 和 HTML 制作应用程序,我创建了一个简单的多页应用程序,该应用程序对每个页面使用相同的 HTML 模板,但从 Flask 将不同的数据加载到其中.你可以在这里看到这篇文章:

使用 Plotly 和 Flask 进行 Web 可视化。面向datascience.com

Streamlit 的情况就不同了。没有对多页的具体支持,我猜这不是遗漏。 Streamlit 并不意味着创建整个网站。

但有时有点分页很有用,所以我编写了一个新应用程序,它在第一个应用程序的基础上进行了扩展,提供更多信息并运行在两页上。它看起来也更好!

目的是有两页,一页用于国家,另一页用于大陆。在每一页上,您可以选择一个国家或大洲,您将获得两张图表,一张代表 GDP,另一张代表人口。您可以在下面看到大陆页面的样子。

一个多页 Streamlit 应用程序 - 作者的图像一个多页 Streamlit 应用程序 - 作者的图像

实际上,也许你看不太清楚,所以这里是页面左侧的放大图像。

来自多页 Streamlit 应用程序的详细信息 -作者提供的图像_来自多页面 Streamlit 应用程序的详细信息 -作者提供的图像

左侧是带有下拉菜单的侧边栏,您可以在其中选择_country_ 或_continent_。页面的主要部分包含图表,并有自己的下拉菜单来选择哪个大陆(欧洲、亚洲等)或哪个国家。

国家页面如下所示。

一个多页 Streamlit 应用程序 - 作者的图像一个多页 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上获取本文和其他文章的代码,并在此处查看最终应用程序的演示。

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐