『玩转Streamlit』--集成Matplotlib

Steamlit虽然也自带了一些绘图组件(比如折线图,柱状图和散点图等等),但是都比较简单,

Python传统的可视化库比起来,功能上差了很多。

本篇介绍如何在Streamlit App中使用Matplotlib库来绘图。

1. st.pyplot函数

st.pyplot函数专门用于在Steamlit应用中显示 Matplotlib 绘制的图形。

这个函数能够直接将Matplotlib Figure对象直接渲染到页面的指定位置上。

st.pyplot的参数不多,主要有:

名称 类型 说明
fig Figure对象 要渲染的 Matplotlib Figure 对象
clear_figure bool 控制图形渲染后是否清除
use_container_width bool 决定是否使用父容器的宽度覆盖图形的原始宽度

最重要的就是fig参数,它是通过 Matplotlib 的常规绘图方式创建图形对象。

也就是说,我们绘制图形时,完全不用考虑Streamlit,正常使用Matplotlib来绘图,

绘制之后直接将Matplotlibfig对象传给st.pyplot函数即可。

2. Matplotlib兼容性问题

在使用 MatplotlibStreamlit 结合时,可能会遇到一些兼容性问题。

Matplotlib 支持多种 Backend,如果在使用过程中出现错误,可以尝试将Backend设置为TkAgg

具体的设置方法如下:

  1. 打开~/.matplotlib/matplotlibrc文件,如果不存在就创建一个
  2. 在上面的文件中添加一行:backend: TkAgg

如果是windows系统,上面的文件路径改为:C:\Users\%username%\.matplotlib\matplotlibrc

此外,Matplotlib 在多线程环境下可能会出现问题,因为它本身对线程的支持并不完善。

当部署和共享应用程序时,由于可能存在并发用户,这个问题可能会更加突出。

为了解决这个问题,建议使用RendererAgg.lock来包裹 Matplotlib 相关代码,如下所示:

python 复制代码
from matplotlib.backends.backend_agg import RendererAgg
_lock = RendererAgg.lock

with _lock:
    fig.title('sample figure')
    fig.plot([1,20,3,50])
    st.pyplot(fig)

3. 使用示例

下面通过两个根据实际情况简化的示例来演示两者结合的效果。

3.1. 模拟数据分析项目

这个示例中,我们使用 np.random 函数生成了包含三列不同类型随机数据的 DataFrame

在数据分析与可视化部分,根据选择的列进行不同类型的绘图操作,

  • 当选择 Column1Column2 时绘制柱状图或直方图
  • 当选择 Column3 时可选择绘制 Column1Column2 的散点图

本示例主要展示了 StreamlitMatplotlib 结合在数据探索和分析可视化方面的便利性与交互性。

python 复制代码
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

import matplotlib

# 为了显示中文
matplotlib.rcParams["font.sans-serif"] = ["Microsoft YaHei Mono"]
matplotlib.rcParams["axes.unicode_minus"] = False


# 生成随机数据
@st.cache_data
def generate_data():
    # 生成 100 行 3 列的随机数据
    data = {
        "Column1": np.random.randint(1, 100, 100),
        "Column2": np.random.normal(50, 10, 100),
        "Column3": np.random.choice(["A", "B", "C"], 100),
    }
    return pd.DataFrame(data)


data = generate_data()

# 数据探索部分
st.subheader("数据探索")
st.write(data.head())

# 数据分析与可视化
st.subheader("数据分析与可视化")
# 选择分析的列
selected_column = st.selectbox("选择要分析的列", data.columns)

# 使用 Matplotlib 绘制柱状图
if selected_column in ["Column1", "Column2"]:
    fig, ax = plt.subplots()
    if selected_column == "Column1":
        sns.countplot(data=data, x=selected_column, ax=ax)
    else:
        sns.histplot(data=data, x=selected_column, kde=True, ax=ax)
    ax.set_title(f"{selected_column} 分布情况")
    ax.set_xlabel(selected_column)
    ax.set_ylabel("数量")
    st.pyplot(fig)

# 绘制散点图(以 Column1 和 Column2 为例)
elif selected_column == "Column3":
    if st.checkbox("显示散点图"):
        fig2, ax2 = plt.subplots()
        ax2.scatter(data["Column1"], data["Column2"])
        ax2.set_title("Column1 与 Column2 的关系")
        ax2.set_xlabel("Column1")
        ax2.set_ylabel("Column2")
        st.pyplot(fig2)

运行效果:

3.2. 模拟数据监控与报告

在这个数据监控与报告应用示例中,通过get_live_data 函数模拟获取实时数据(实际应用中可替换为真实的数据获取逻辑)。

然后通过一个循环,不断获取新数据并合并到总的数据集中,再使用 Matplotlib 绘制折线图展示数据随时间的变化趋势。

这样就构建了一个简单的实时数据监控应用,在实际业务场景中,例如监控服务器性能指标、生产线上的关键数据等,可以让相关人员实时直观地了解数据的变化情况,及时发现异常并做出决策。

python 复制代码
import streamlit as st
import matplotlib.pyplot as plt
import time
import random
import pandas as pd

import matplotlib

# 为了显示中文
matplotlib.rcParams["font.sans-serif"] = ["Microsoft YaHei Mono"]
matplotlib.rcParams["axes.unicode_minus"] = False


# 模拟获取实时数据的函数
def get_live_data():
    # 这里可以替换为真实的获取数据逻辑,比如从数据库或 API 获取
    new_data = pd.DataFrame(
        {
            "time": [time.strftime("%H:%M:%S")],
            "value": [random.randint(-10, 10)],
        }
    )
    return new_data


# 初始化数据
data = pd.DataFrame(columns=["time", "value"])

# 实时数据监控应用标题
st.title("实时数据监控")

# 创建一个占位符用于更新图表
chart_placeholder = st.empty()

while True:
    # 获取新数据
    new_data = get_live_data()
    # 合并新数据到总数据
    data = pd.concat([data, new_data], ignore_index=True)

    # 使用 Matplotlib 绘制折线图
    fig, ax = plt.subplots()
    ax.plot(data["time"], data["value"])
    ax.set_title("实时数据趋势")
    ax.set_xlabel("时间")
    ax.set_ylabel("数值")
    ax.set_xticklabels(data["time"], rotation=45)

    # 在 Streamlit 中更新图表
    chart_placeholder.pyplot(fig)

    # 每隔一段时间更新数据(这里设置为 2 秒)
    time.sleep(2)

运行效果:

4. 总结

StreamlitMatplotlib 结合的关键点在于,Streamlit 提供便捷的应用构建框架,Matplotlib 专注强大的绘图功能,二者通过 st.pyplot 函数紧密相连。

在数据处理流程上,可先在 Matplotlib 中依据数据特性灵活创建各类图形对象,再借助 Streamlit 整合进应用。

它们结合的优势也非常明显,首先,在可视化效率方面,能快速将 Matplotlib 绘制的图形嵌入 Streamlit 应用,减少开发时间与代码量。

其次,在交互性上,Streamlit 的丰富交互组件可与 Matplotlib 图形联动,如通过按钮、滑块等控制图形展示内容或范围,让用户更方便的进行数据探索。

相关推荐
wang_yb21 小时前
manim边做边学--淡入淡出变换
databook·manim
wang_yb2 天前
Django和FastAPI的比较
python·databook
wang_yb3 天前
manim边做边学--交替变换
databook·manim
wang_yb7 天前
manim边做边学--缩放变换
databook·manim
wang_yb7 天前
Peewee:Python 简洁强大的 ORM 框架
python·databook
wang_yb9 天前
manim边做边学--动画联动
databook·manim
wang_yb13 天前
manim边做边学--动画更新
databook·manim
wang_yb16 天前
manim边做边学--动画组合
databook·manim
wang_yb17 天前
探索Python @dataclass的内部原理
python·databook
wang_yb21 天前
manim边做边学--动画轨迹
databook·manim