使用Streamlit和InfluxDB可视化数据

导航到

本文由Fortune Adekogbe撰写。向下滚动查看作者简介和照片。

根据2021年Python开发者调查结果,大多数开发者不积极使用前端工具。这意味着如果您想创建显示机器学习模型和其他您所构建系统的界面,您很可能需要其他开发者的帮助。

这就是开源应用程序框架Streamlit能帮助您的时刻,它作为替代方案,允许您在不使用HTML5、CSS、React和JavaScript等前端相关工具和语言的情况下创建用户界面。您只需要Python和Streamlit API的预配置元素从头开始构建界面。

这比自行构建应用程序并尝试编写有限数量的代码来创建有用的应用程序要容易得多。此外,Python生态系统提供的绝大多数优秀库仍然对您开放。

在本文中,您将了解更多关于Streamlit的信息以及它如何简化应用程序创建过程。此外,您还将学习如何创建和设置InfluxDB数据库,并为Streamlit应用程序查询数据。

什么是Streamlit

如前所述,Streamlit是一个开源框架,用于完全使用Python构建Web应用程序。这使得Python开发者、机器学习工程师、数据分析师和数据科学家能够在没有整个软件开发团队的情况下开发出色的应用程序。

该框架背后的理念是创建应用程序应该像在Jupyter Notebook中工作一样自然,但同时具有强大应用程序开发框架的所有灵活性。

为了使您能够在熟悉的语言和开发环境中工作,Streamlit专注于确保所有必要的脚本都可以在Python中完成。此外,其API提供了一些元素,可以通过将它们声明为变量来简单地实现各种小部件类型。这样,代码就变得有组织和整洁。

Streamlit还有一个缓存系统,充当数据存储,并允许您重用诸如昂贵计算、下载的数据和模型等信息。这降低了延迟并加快了应用程序,因为您的Streamlit应用程序代码在每次用户交互时都会更新并重新运行。

当您对代码进行修改时,Streamlit有一个类似于热重载的功能,允许您立即重新加载您的应用程序。即使在开发阶段,这也避免了延迟,因为Streamlit只会重新运行管道的更新部分。此外,它与GPU配合良好,可以加快深度学习模型的推理速度。

使用存储在InfluxDB中的时间序列数据实现Streamlit

为了展示Streamlit的价值,在本教程中,您将构建一个简单的仪表板来可视化分析天气数据。您将使用InfluxDB作为数据库来完成此任务,因为它专为时间序列数据设计。

您可以在本GitHub仓库的主分支中找到本教程中使用的所有代码片段。

设置InfluxDB

首先,您需要在本地计算机上设置一个开源版本的InfluxDB作为服务器。前往InfluxDB OSS文档中的安装页面开始操作。

InfluxDB-installation-page

有关下载、安装和启动InfluxDB服务器的说明,请点击对应您操作系统的按钮。

完成后,打开浏览器并访问https://127.0.0.1:8086,以确保服务器已启动。如果您使用不同的端口号,请确保在URL中替换它。这将加载InfluxDB用户界面。

要完成InfluxDB的设置,请点击开始使用,然后输入必要的信息并选择继续。完成此操作后,您将被带到主页。

InfluxDB-home-page

将数据写入InfluxDB

设置完成后,您需要将数据写入数据库。为此,创建一个项目目录,并创建一个data/目录。在终端中运行以下命令以下载天气数据

wget -o data/jena_climate_2009_2016.csv.zip https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip

压缩的CSV文件现在应该被解压缩并放入data/目录中。尽管有几种将数据写入InfluxDB的方法,您将使用pandas.DataFrame方法。

在继续之前,前往您的InfluxDB界面,点击左侧菜单中的加载数据选项,然后选择。在右侧点击+ 创建桶按钮,命名桶,并选择创建

Bucket-creation-page

接下来,您需要生成一个API令牌。在左侧菜单中点击API令牌选项。在右侧选择+ 生成API令牌按钮,然后选择所有访问API令牌。描述令牌并点击保存

现在,在项目目录中创建一个虚拟环境,并通过执行以下命令激活它(对于Linux/macOS用户,请遵循这些说明进行相同操作)

python -m venv .venv

.venv\Scripts\activate.bat

接下来,使用pip安装本教程所需的每个库

pip install pandas influxdb-client matplotlib pandas python-dotenv streamlit

然后从InfluxDB复制API令牌并将其放入env文件中

INFLUX_TOKEN={TOKEN FROM INFLUXDB}

完成后,创建一个Python脚本来预处理数据并将其写入InfluxDB

import os

import pandas as pd

import matplotlib.pyplot as plt

from influxdb_client import InfluxDBClient, WriteOptions

from dotenv import load_dotenv

load_dotenv()

df = pd.read_csv("data/jena_climate_2009_2016.csv")

df = df[['Date Time', 'T (degC)']]

df.index = pd.to_datetime(df.pop('Date Time'), format='%d.%m.%Y %H:%M:%S')

df['Measured Fluid'] = ['Air'] * df.shape[0]

plt.plot(df['T (degC)'])

plt.show()

在此,首先导入所有必要的模块。然后使用之前安装的python-dotenv中的load_dotenv()方法加载环境变量。接下来,使用pandas.read_csv()方法通过传递文件路径作为参数读取CSV文件。

数据集中包含温度、压力、湿度和其他各种数量的读数。出于本教程的目的,我们只将与温度读数交互。

从数据框中截取日期和温度列。使用pandas.to_datetime()方法将'Date Time'列转换为DateTime数据类型,使用df.pop()方法从数据框中删除'Date Time'列,并将修改后的列赋给df.index,使其成为数据框的索引。

接下来,在数据帧中添加一列来表示测量的流体,在这种情况下,是空气,并且每一行都会相同。然后,将温度列传递给 plt.plot 以创建图表,并添加 plt.show() 确保它显示出来。你应该看到以下图片。将 plt.show() 注释掉,这样它就不会阻塞代码的执行。

Matplotlib-line-chart

以下代码将数据帧写入 InfluxDB。

ORG = "MY-ORG"

BUCKET = "MY-BUCKET"

TOKEN = os.getenv("INFLUX_TOKEN")

with InfluxDBClient(url="https://127.0.0.1:8086", token=TOKEN, org=ORG) as _client:

with _client.write_api() as _write_client:

_write_client.write(BUCKET, ORG, record=df, data_frame_measurement_name='air_temperature',

data_frame_tag_columns=['Measured Fluid'])

在之前的代码中,您创建变量以存储组织名称和桶名称的字符串。使用 os.getenv() 方法,您定义一个不同的变量来加载 API 令牌。然后,您使用 with 语句通过上下文管理器,使用 InfluxDB 服务器的 URL、令牌和组织作为参数创建一个 InfluxDBClient() 实例。

然后,您创建第二个上下文管理器,使用客户端实例创建一个 client.write_api() 实例。接下来,您调用 write_client.write() 方法,传入桶和组织名称作为参数。您还将数据帧传递给记录参数,将 'air_temperature' 传递给 data_frame_measurement_name 参数,将 ['Measured Fluid'] 传递给 data_frame_tag_columns 参数。最后,运行此脚本来将数据写入 InfluxDB。

创建 Streamlit 应用程序

以下步骤涉及查询 InfluxDB 中的数据并将其提供给 Streamlit 应用程序。首先,创建一个新的 Python 脚本名为 app.py 并导入必要的模块。

import os

from influxdb_client import InfluxDBClient

import streamlit as st

from dotenv import load_dotenv

load_dotenv()

ORG = "MY-ORG"

BUCKET = "MY-BUCKET"

TOKEN = os.getenv("INFLUX_TOKEN")

@st.cache

def get_weather_data(time_range=20):

client = InfluxDBClient(url="https://127.0.0.1:8086", token=TOKEN, org=ORG)

query_api = client.query_api()

result_df = query_api.query_data_frame(f'from(bucket:"{BUCKET}") '

f'|> range(start: -{time_range}y) '

'|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value") '

'|> keep(columns: ["_time","Measured Fluid", "T (degC)"])')

result_df['month'] = result_df['_time'].dt.month

client.close()

return result_df

在上面的代码示例中,在导入模块后,您加载环境变量并创建变量以存储组织、桶和令牌。

然后,您定义一个名为 get_weather_data() 的函数来从 InfluxDB 读取温度数据。应该将 @st.cache 装饰器添加到该方法中,以确保查询被缓存且不会在每个用户交互时重新运行。然后,您在函数中创建一个 InfluxDBClient 实例以创建查询 API 实例。

使用 query_api.query_data_frame() 方法并使用查询作为参数,确保结果作为数据帧返回。此查询是使用 InfluxData 的 Flux 脚本语言编写的字符串。通过逐行观察它,您可以看到桶、查询时间范围(以年为单位)、枢纽(确定输出行依赖于哪些列)和要返回的列都已被定义。在此之后,通过在 DateTime 列上调用 .dt.month 方法创建月份属性。

然后调用 client.close() 方法关闭客户端并返回数据帧。

接下来定义 Streamlit 应用程序的组件。折线图、面积图和柱状图是必须创建的三种图表类型。

chart_df = get_weather_data()

chart_df.rename(columns={"_time": "Date-Time", "T (degC)": "Temperature (°C)"},

inplace=True)

st.title("Air Temperature (°C) vs. Time")

st.write("## Line Chart")

st.line_chart(chart_df, x="Date-Time", y="Temperature (°C)")

在此代码中,调用 get_weather_data 方法进行查询并返回数据帧。接下来,向数据帧添加更多描述性列名。然后,使用 st.write() 方法指定绘图名称,并创建一个折线图来显示数据。通过将数据帧以及 x 轴和 y 轴的列名作为参数传递给 st.line_chart() 方法来实现这一点。

在终端中运行命令 streamlit run app.py 以查看应用程序。这将启动一个与这里显示相似的浏览器选项卡。

Streamlit-line-chart

如您所见,与之前使用 matplotlib 创建的图表不同,Streamlit 图表是交互式的。通过将光标移至图表上,您可以查看每个数据点的更多信息。此外,您可以放大以查看更具体的时间段。

然后制作了第二个和第三个图表,如图所示。

st.write("## Area Chart")

st.area_chart(chart_df, x="Date-Time", y="Temperature (°C)")

chart_month = chart_df.groupby('month')['Temperature (°C)'].mean()

st.write("## Bar Chart\nThis shows the average temperature in each month")

st.bar_chart({'Month number': chart_month.index,

'Average Temperature (°C)': chart_month.values},

x="Month number",

y="Average Temperature (°C)")

接着添加了第二个图表的标题,并使用 st.area_chart() 以类似的方式创建了一个区域图表。

使用 dataframe.groupby() 方法按月份分组数据,以确定平均温度以创建第三个图表。

最后,添加了第三个图表的标题,然后使用 st.bar_chart() 方法创建图表。数据被解析为包含每个月份编号和每个月的平均温度的字典。

要查看应用程序,请在浏览器中导航,并点击右上角的 重新运行 按钮。以下图表将被添加到您的仪表板上

Streamlit-area-and-bar-plots

与之前一样,这些图表也是交互式的,并且在部署后允许您以交互方式与数据互动并与他人共享。您可以在本 GitHub 仓库 的主分支中找到这里使用的所有代码片段。

结论

在本篇文章中,您了解了 Streamlit,它的好处以及它的功能。您还可以设置、写入和从 InfluxDB 数据库中读取数据。此外,您可以使用 Streamlit 构建仪表板来可视化数据。

InfluxDB 是由 InfluxData 开发的,用于简化实时应用程序的创建和处理时间序列数据。您可以使用 InfluxDB 创建系统来跟踪和分析来自您的网络或传感器的实时数据。现在 注册 并开始使用 InfluxDB。

其他资源

如果您对学习更多关于数据可视化或处理时间序列数据感兴趣,请查看以下资源

关于作者

Fortune-Adekogbe

Fortune 是 Josplay 的 Python 开发人员,擅长处理数据和构建智能系统。他还是一名工艺工程师和技术作家。