Streamlit 定制化的 Web 应用

06-01 1934阅读

Streamlit 定制化的 Web 应用

目录

  1. Streamlit 简介
    • 1.1 什么是 Streamlit?
    • 1.2 为什么选择 Streamlit?
    • 1.3 核心特性
    • 1.4 目标用户
    • 核心概念
      • 2.1 数据流与脚本执行模型
      • 2.2 “魔法”命令 (Magic Commands)
      • 2.3 控件 (Widgets) 与交互
      • 2.4 状态管理 (Session State)
      • 2.5 缓存 (Caching)
      • 安装教程
        • 3.1 环境要求
        • 3.2 使用 pip 安装
        • 3.3 验证安装
        • 3.4 运行第一个应用
        • 主要组件与常用 API
          • 4.1 文本显示
          • 4.2 数据展示
          • 4.3 图表绘制
          • 4.4 输入控件
          • 4.5 布局与容器
          • 4.6 媒体文件
          • 4.7 状态与控制流
          • 进阶功能与策略
            • 5.1 深入 Session State
            • 5.2 高效使用缓存 (@st.cache_data vs @st.cache_resource)
            • 5.3 优化应用布局
            • 5.4 连接数据源 (数据库, API)
            • 5.5 应用部署 (Streamlit Community Cloud)
            • 5.6 自定义组件 (Brief Mention)
            • 策略示例 (代码驱动)
              • 6.1 示例一:交互式数据探索器
              • 6.2 示例二:参数可调的可视化
              • 6.3 示例三:简单的机器学习模型演示
              • 最佳实践与技巧
              • 总结
              • 学习资源

1. Streamlit 简介

1.1 什么是 Streamlit?

Streamlit 是一个开源的 Python 库,它使得为机器学习和数据科学项目创建和共享美观、定制化的 Web 应用变得极其简单快捷。你无需任何前端知识(HTML, CSS, JavaScript),只需使用 Python 即可构建交互式的数据应用。

1.2 为什么选择 Streamlit?

  • 快速开发: 将数据脚本转化为可共享的 Web 应用通常只需要几行代码。
  • 纯 Python: 无需学习前端框架,专注于 Python 和数据。
  • 交互性: 内置丰富的交互式控件(滑块、按钮、下拉菜单等)。
  • 易于共享: 可以轻松部署到 Streamlit Community Cloud 或其他平台。
  • 代码即应用: 应用的 UI 和逻辑直接由 Python 脚本定义,所见即所得。
  • 活跃社区: 拥有庞大且活跃的社区支持。

    1.3 核心特性

    • 即时反馈: 修改代码并保存后,浏览器中的应用会自动刷新。
    • 数据缓存: 智能缓存机制避免重复计算和加载数据,提升性能。
    • 内置控件: 提供大量开箱即用的 UI 控件。
    • 布局灵活: 支持侧边栏、列、选项卡等布局方式。
    • 主题定制: 支持浅色、深色主题及自定义主题。

      1.4 目标用户

      • 数据科学家: 快速将模型、分析结果可视化并分享给他人。
      • 机器学习工程师: 构建模型演示、数据标注工具等。
      • 数据分析师: 创建交互式报告和仪表板。
      • Python 开发者: 需要快速构建简单 Web 应用的场景。

        2. 核心概念

        2.1 数据流与脚本执行模型

        Streamlit 应用的核心在于其独特的执行模型:每当用户与应用中的控件交互(如点击按钮、拖动滑块)或者源代码被修改时,整个 Python 脚本会从头到尾重新执行一次。

        这听起来可能效率低下,但 Streamlit 通过智能的缓存机制(见 2.5)来优化性能。这种模型的优点是极大地简化了应用开发,开发者只需编写线性的 Python 脚本,Streamlit 负责处理 Web 应用的复杂性。

        2.2 “魔法”命令 (Magic Commands)

        Streamlit 支持“魔法”命令。如果你在脚本中单独写一个变量或一个字面量值(如 DataFrame、字符串、数字),Streamlit 会自动调用 st.write() 将其显示在应用中。

        import streamlit as st
        import pandas as pd
        df = pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})
        "这是一个 Markdown 文本" # Magic command, 等同于 st.write("这是一个 Markdown 文本")
        df # Magic command, 等同于 st.write(df) 或 st.dataframe(df)
        

        2.3 控件 (Widgets) 与交互

        控件是用户与 Streamlit 应用交互的主要方式。每个控件本质上是一个 Python 函数调用,其返回值通常是用户输入的值。

        name = st.text_input("请输入你的名字:")
        if name:
            st.write(f"你好, {name}!")
        age = st.slider("选择你的年龄:", 0, 100, 25) # 最小值, 最大值, 默认值
        st.write(f"你的年龄是: {age}")
        clicked = st.button("点我")
        if clicked:
            st.write("按钮被点击了!")
        

        当用户与控件交互(例如输入文本、移动滑块、点击按钮),Streamlit 会:

        1. 记录控件的新值。
        2. 重新运行整个脚本。
        3. 在重新运行时,控件函数会返回用户设置的新值。

        2.4 状态管理 (Session State)

        由于每次交互都会重新运行脚本,局部变量无法在多次运行之间保持其值。为了解决这个问题,Streamlit 提供了 st.session_state。这是一个类似字典的对象,用于存储需要在脚本重新运行时保留的信息(会话状态)。

        import streamlit as st
        # 初始化 session state 中的计数器(如果它不存在)
        if 'count' not in st.session_state:
            st.session_state.count = 0
        increment = st.button('增加计数')
        if increment:
            st.session_state.count += 1
        st.write('计数器: ', st.session_state.count)
        

        2.5 缓存 (Caching)

        为了避免在每次脚本重新运行时都执行耗时的操作(如加载大型数据集、训练模型、访问 API),Streamlit 提供了缓存装饰器:

        • @st.cache_data: 用于缓存可序列化的数据(如 DataFrame, list, dict)。当函数的输入参数或函数代码改变时,缓存才会失效。
        • @st.cache_resource: 用于缓存不方便或不应该被序列化的全局资源(如数据库连接、机器学习模型)。当函数代码改变时,缓存才会失效(对输入参数不敏感)。
          import streamlit as st
          import pandas as pd
          import time
          @st.cache_data # 缓存数据加载函数
          def load_data(url):
              df = pd.read_csv(url)
              time.sleep(3) # 模拟耗时操作
              return df
          data_url = "https://raw.githubusercontent.com/streamlit/demo-data/master/uber-raw-data-sep14.csv.gz"
          df = load_data(data_url)
          st.dataframe(df.head())
          st.button("再次运行脚本") # 点击按钮会重新运行,但 load_data 不会再次执行耗时操作
          

          3. 安装教程

          3.1 环境要求

          • Python 3.8 - 3.11
          • PIP 包管理器

            建议在虚拟环境中安装 Streamlit,以避免与其他项目的依赖冲突。

            创建和激活虚拟环境 (可选但推荐):

            # Linux/macOS
            python3 -m venv .venv
            source .venv/bin/activate
            # Windows (cmd)
            python -m venv .venv
            .venv\Scripts\activate.bat
            # Windows (PowerShell)
            python -m venv .venv
            .venv\Scripts\Activate.ps1
            

            3.2 使用 pip 安装

            在你的终端或命令行中运行:

            pip install streamlit
            

            3.3 验证安装

            安装完成后,运行以下命令:

            streamlit hello
            

            这会启动一个演示应用,并在你的默认浏览器中打开一个新的标签页。如果能看到 Streamlit 的欢迎页面和演示,说明安装成功。

            3.4 运行第一个应用

            1. 创建一个 Python 文件,例如 my_first_app.py。

              Streamlit 定制化的 Web 应用
              (图片来源网络,侵删)
            2. 在文件中写入以下代码:

              import streamlit as st
              import numpy as np
              import pandas as pd
              st.title('我的第一个 Streamlit 应用')
              st.write("这是一个简单的 Streamlit 应用示例。")
              # 使用魔法命令显示 DataFrame
              df = pd.DataFrame({
                  '第一列': [1, 2, 3, 4],
                  '第二列': [10, 20, 30, 40]
              })
              df
              # 添加一个滑块控件
              x = st.slider('选择一个值', 0, 10)
              st.write('你选择的值是:', x)
              # 绘制一个简单的图表
              st.line_chart(np.random.randn(20, 2))
              
            3. 在终端中,切换到包含 my_first_app.py 的目录,然后运行:

              Streamlit 定制化的 Web 应用
              (图片来源网络,侵删)
              streamlit run my_first_app.py
              
            4. Streamlit 会启动一个本地 Web 服务器,并在浏览器中打开你的应用。

            4. 主要组件与常用 API

            Streamlit 提供了丰富的 API 来构建应用的 UI。

            Streamlit 定制化的 Web 应用
            (图片来源网络,侵删)

            4.1 文本显示

            • st.title(): 应用标题
            • st.header(): 一级标题
            • st.subheader(): 二级标题
            • st.write(): 通用显示函数,可以显示文本、Markdown、数字、DataFrame、图表等。
            • st.markdown(): 渲染 Markdown 格式的文本。
            • st.code(): 显示代码块。
            • st.latex(): 显示 LaTeX 公式。

              4.2 数据展示

              • st.dataframe(): 显示可交互的 DataFrame (支持排序)。
              • st.table(): 显示静态表格。
              • st.json(): 显示 JSON 数据。
              • st.metric(): 显示指标(KPI),可带变化量。

                4.3 图表绘制

                Streamlit 支持多种图表库:

                • 内置图表: st.line_chart(), st.area_chart(), st.bar_chart(), st.scatter_chart() (基于 Vega-Lite)。
                • 第三方库集成:
                  • st.pyplot(): 显示 Matplotlib 图表。
                  • st.plotly_chart(): 显示 Plotly 图表。
                  • st.altair_chart(): 显示 Altair 图表。
                  • st.vega_lite_chart(): 显示 Vega-Lite 图表。
                  • (以及 Bokeh, PyDeck 等)

                    4.4 输入控件

                    这些控件用于收集用户输入,它们的返回值是用户提供的值。

                    • st.button(): 按钮。
                    • st.checkbox(): 复选框。
                    • st.radio(): 单选按钮。
                    • st.selectbox(): 下拉选择框。
                    • st.multiselect(): 多选下拉框。
                    • st.slider(): 滑块。
                    • st.select_slider(): 在一组离散值中选择的滑块。
                    • st.text_input(): 单行文本输入框。
                    • st.text_area(): 多行文本输入框。
                    • st.number_input(): 数字输入框。
                    • st.date_input(): 日期选择器。
                    • st.time_input(): 时间选择器。
                    • st.file_uploader(): 文件上传控件。
                    • st.color_picker(): 颜色选择器。

                      4.5 布局与容器

                      用于组织页面元素:

                      • st.sidebar: 在页面左侧创建一个侧边栏,控件可以放在这里。
                        add_selectbox = st.sidebar.selectbox(
                            "你想联系谁?",
                            ("邮件", "电话", "短信")
                        )
                        
                      • st.columns(): 创建并排的列。
                        col1, col2, col3 = st.columns(3)
                        with col1:
                           st.header("第一列")
                           st.write("内容...")
                        with col2:
                           st.header("第二列")
                           # ...
                        
                      • st.tabs(): 创建选项卡布局。
                        tab1, tab2 = st.tabs(["图表", "数据"])
                        with tab1:
                            st.line_chart(...)
                        with tab2:
                            st.dataframe(...)
                        
                      • st.expander(): 创建可折叠的区域。
                      • st.container(): 创建一个多元素容器,可以用于控制元素插入顺序。
                      • st.empty(): 创建一个占位符,后续可以用内容替换或清空。

                        4.6 媒体文件

                        • st.image(): 显示图片。
                        • st.audio(): 播放音频文件。
                        • st.video(): 播放视频文件。

                          4.7 状态与控制流

                          • st.form(): 创建一个表单,可以批量提交一组输入控件的值。在表单内的控件交互不会触发脚本重新运行,只有点击表单的提交按钮 (st.form_submit_button) 时才会。
                          • st.spinner(): 显示一个加载指示器,用于耗时操作。
                          • st.progress(): 显示一个进度条。
                          • st.error(), st.warning(), st.info(), st.success(): 显示不同类型的消息框。
                          • st.exception(): 显示异常信息。
                          • st.stop(): 停止脚本执行。
                          • st.rerun(): 手动触发脚本重新运行。

                            5. 进阶功能与策略

                            5.1 深入 Session State

                            st.session_state 是构建复杂交互应用的关键。

                            • 初始化: 务必在使用前检查 key 是否存在并进行初始化,通常在脚本开头完成。
                            • 回调函数: 许多控件(如 st.button, st.slider)支持 on_change 参数,可以绑定一个回调函数。当控件值改变时,回调函数会在脚本重新运行 之前 执行,这对于更新 st.session_state 非常有用。
                              import streamlit as st
                              def increment_counter():
                                  st.session_state.count += 1
                              if 'count' not in st.session_state:
                                  st.session_state.count = 0
                              st.button('增加', on_click=increment_counter) # 使用回调
                              st.write('计数器: ', st.session_state.count)
                              

                              5.2 高效使用缓存 (@st.cache_data vs @st.cache_resource)

                              • 选择合适的装饰器:
                                • 加载 DataFrame、处理 JSON/API 结果等返回普通数据的函数,使用 @st.cache_data。
                                • 初始化数据库连接、加载大型机器学习模型等返回复杂对象或需要全局共享资源的函数,使用 @st.cache_resource。
                                • 缓存粒度: 尽量将耗时操作封装在独立的函数中,并对该函数应用缓存。
                                • 注意参数: @st.cache_data 对输入参数敏感。如果参数是可变对象(如列表、字典)且在函数内部被修改,可能会导致意外的缓存行为。考虑传递不可变对象或对象的副本。
                                • 清除缓存: 有时需要手动清除缓存,可以在 Streamlit 应用的右上角菜单中找到 “Clear cache” 选项。

                                  5.3 优化应用布局

                                  • 使用 st.sidebar: 将全局设置、导航或不常变化的控件放在侧边栏,保持主区域清爽。
                                  • 使用 st.columns 或 st.tabs: 合理组织内容,避免页面过长。
                                  • 使用 st.expander: 将详细信息或次要内容隐藏在可展开区域内。
                                  • 使用 st.container: 控制元素的添加顺序,或将一组相关的元素打包。

                                    5.4 连接数据源 (数据库, API)

                                    Streamlit 本身不直接提供数据库或 API 连接器,但可以无缝集成标准的 Python 库:

                                    • 数据库: 使用 SQLAlchemy, psycopg2 (PostgreSQL), mysql-connector-python (MySQL), sqlite3 等库连接数据库。将数据库连接和查询操作封装在函数中,并考虑使用 @st.cache_resource 缓存连接,使用 @st.cache_data 缓存查询结果。
                                    • API: 使用 requests 或 httpx 等库访问外部 API。同样,将 API 调用封装并使用 @st.cache_data 缓存结果,避免频繁请求。
                                      import streamlit as st
                                      import requests
                                      import pandas as pd
                                      @st.cache_data(ttl=600) # 缓存 10 分钟
                                      def get_api_data(api_url):
                                          response = requests.get(api_url)
                                          response.raise_for_status() # 检查请求是否成功
                                          return response.json()
                                      # 示例:获取 GitHub 星标信息
                                      try:
                                          data = get_api_data("https://api.github.com/repos/streamlit/streamlit")
                                          st.write("Streamlit GitHub Repo Stars:", data.get('stargazers_count'))
                                      except requests.exceptions.RequestException as e:
                                          st.error(f"API 请求失败: {e}")
                                      

                                      5.5 应用部署 (Streamlit Community Cloud)

                                      Streamlit Community Cloud 是官方提供的免费部署平台,非常适合共享公共应用。

                                      1. 准备代码: 将你的 Streamlit 应用代码 (.py 文件) 和依赖文件 (requirements.txt) 托管在 GitHub 公开仓库中。
                                      2. 注册/登录: 访问 share.streamlit.io 并使用 GitHub 账号登录。
                                      3. 部署应用: 点击 “New app”,选择你的 GitHub 仓库、分支和主应用文件。
                                      4. 配置 (可选): 可以设置 Python 版本和高级设置。
                                      5. 点击 “Deploy!” Streamlit 会自动拉取代码、安装依赖并运行你的应用。

                                      其他部署选项包括:Heroku, AWS, Google Cloud, Azure, Docker 容器等,这些通常需要更多的配置。

                                      5.6 自定义组件 (Brief Mention)

                                      对于更高级的需求,如果内置控件不满足,可以创建自己的 Streamlit 组件。这需要一些前端知识(React),允许你将任何 Web 技术集成到 Streamlit 应用中。这是一个更深入的主题,可以查阅官方文档了解更多。

                                      6. 策略示例 (代码驱动)

                                      6.1 示例一:交互式数据探索器

                                      这个例子展示了如何上传 CSV 文件,并使用控件进行筛选和可视化。

                                      import streamlit as st
                                      import pandas as pd
                                      import numpy as np
                                      st.title("交互式数据探索器")
                                      uploaded_file = st.file_uploader("上传你的 CSV 文件", type=["csv"])
                                      if uploaded_file is not None:
                                          # 使用缓存加载数据
                                          @st.cache_data
                                          def load_csv(file):
                                              return pd.read_csv(file)
                                          df = load_csv(uploaded_file)
                                          st.header("原始数据")
                                          st.dataframe(df)
                                          st.header("数据筛选与可视化")
                                          # 使用列进行布局
                                          col1, col2 = st.columns(2)
                                          with col1:
                                              # 选择列进行可视化
                                              all_columns = df.columns.tolist()
                                              selected_columns = st.multiselect("选择要显示的列:", all_columns, default=all_columns[:min(5, len(all_columns))])
                                              if selected_columns:
                                                  st.dataframe(df[selected_columns])
                                              else:
                                                   st.warning("请至少选择一列")
                                          with col2:
                                              # 基于数值列进行过滤
                                              numeric_columns = df.select_dtypes(include=np.number).columns.tolist()
                                              if numeric_columns:
                                                  filter_column = st.selectbox("选择用于过滤的数值列:", numeric_columns)
                                                  min_val = float(df[filter_column].min())
                                                  max_val = float(df[filter_column].max())
                                                  value_range = st.slider(
                                                      f"选择 {filter_column} 的范围:",
                                                      min_value=min_val,
                                                      max_value=max_val,
                                                      value=(min_val, max_val) # 默认选择整个范围
                                                  )
                                                  # 应用过滤
                                                  filtered_df = df[(df[filter_column] >= value_range[0]) & (df[filter_column] 
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码