【小笔记】streamlit使用笔记
目录
1.streamlit是什么,为什么要用它?
一句话,这个东西是一个python的可视化库,当你想要给你的程序添加个web界面,而又不会或不想用前端技术时,你就可以考虑用它。
类似的可视化库还有下面这几个,对比如下:
参考:
Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
2.安装及版本要求:
安装:
pip install streamlit
以下辅助库也可以安装:
pip install pyecharts
pip install streamlit_echarts
特别注意:streamlit最新版要求python >= 3.8
3.入门:一个问答demo
教程参考:小白也能轻松搞定:用几行代码实现强大的问答机器人!
创建:
demo.py
import streamlit as st
def display_existing_messages():
if "messages" not in st.session_state:
st.session_state["messages"] = []
for message in st.session_state["messages"]:
with st.chat_message(message["role"]):
st.markdown(message["content"])
def add_user_message_to_session(prompt):
if prompt:
st.session_state["messages"].append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
#
def generate_assistant_response(query):
# add_user_message_to_session 显示消息的时候做了处理,所以这里不需要再次添加最新提问
print('history-->')
history = st.session_state["messages"]
print(history)
with st.chat_message("assistant"):
message_placeholder = st.empty()
full_response = ""
for response in client.chat.completions.create(
model=model,
temperature=0,
messages=history,
stream=True,
):
try:
full_response += response.choices[0].delta.content
except Exception as e:
print("")
message_placeholder.markdown(full_response + "▌")
message_placeholder.markdown(full_response)
st.session_state["messages"].append(
{"role": "assistant", "content": full_response}
)
return full_response
def hide_streamlit_header_footer():
hide_st_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
#root > div:nth-child(1) > div > div > div > div > section > div {padding-top: 0rem;}
</style>
"""
st.markdown(hide_st_style, unsafe_allow_html=True)
def main():
st.title("问答机器人")
st.write(
"我的第一个专属机器人,它可以回答你的问题,也可以和你聊天。"
)
hide_streamlit_header_footer()
display_existing_messages()
query = st.chat_input("你可以问我任何你想问的问题")
if query:
print(query)
add_user_message_to_session(query)
# response = generate_assistant_response(query)
# print(response)
if __name__ == "__main__":
main()
启动:
streamlit run demo.py
其它问答系统界面参考示例:
1.【Langchain+Streamlit】打造一个旅游问答AI
2.当科技遇上神奇:用Streamlit打造定制AI问答界面
官方的chatGLM3-6B问答界面也是基于streamlit创建的。说明streamlit还是很好用的。
4.streamlit基础组件及教程
1.基础组件使用教程
1.实用篇 | 一文快速构建人工智能前端展示streamlit应用
2.python库streamlit学习笔记
3.streamlit中文开发手册(详细版)
4.Streamlit开发手册
2.布局教程
1.streamlit框架,各种图表绘制,布局以及生产综合案例剖析
2.Streamlit 布局篇(容器布局)
6.streamlit结合echarts💡
7.streamlit绘制知识图谱💡
方式一:基于graphviz
http://cw.hubwiz.com/card/c/streamlit-manual/1/6/18/
>>> st.graphviz_chart('''
digraph {
run -> intr
intr -> runbl
runbl -> run
run -> kernel
kernel -> zombie
kernel -> sleep
kernel -> runmem
sleep -> swap
swap -> runswap
runswap -> new
runswap -> runmem
new -> runmem
sleep -> runmem
}
''')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7oFvIdfW-1720705304224)(https://i-blog.csdnimg.cn/direct/2795265ce9e845109f078432dcdf6e8f.png)]
简单直接!
方式二:基于streamlit-agraph
非常好用的一个工具,堪称神器!
【知识图谱的可视化】streamlit读取三元组生成有向图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HWZQGEd7-1720705304226)(https://i-blog.csdnimg.cn/direct/c0d31730de1f4144bbfd3420df9d1f03.png)]
绘制的图还可以拖动和交互,非静态,很nice。
还可以绘制这个带图片的知识图谱?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBN83PFd-1720705304227)(https://i-blog.csdnimg.cn/direct/2c20a315e2d3445f93313d7ff92681a3.png)]
streamlit相关报错及solution
Q1:AttributeError: module ‘streamlit.components’ has no attribute ‘v1’
出错代码:
import streamlit as st
# ... 其他代码 ...
with st.container():
st.write("### B部分: 知识图谱")
knowledge_graph = create_knowledge_graph()
graph_html = knowledge_graph.render_embed()
st.components.v1.html(graph_html, width=1000, height=500)
解决办法:
streamlit版本可能较新,已经不再使用v1的命名空间了。从 Streamlit 1.13 开始,所有的组件函数(如html)可以直接从streamlit模块调用,而不需要使用v1前缀。
因此,你可以直接使用st.html代替st.components.v1.html。以下是修改后的代码段落:
import streamlit as st
# ... 其他代码 ...
def main():
knowledge_graph = create_knowledge_graph()
graph_html = knowledge_graph.render_embed()
st.html(graph_html)
if __name__ == "__main__":
main()
Q2:AttributeError: module ‘streamlit’ has no attribute ‘beta_columns’
代码:
col1, col2, col3, col4, col5 = st.beta_columns([0.2, 1, 0.1, 1, 0.2])
解决:
replace st.beta_columns with st.columns.
col1, col2, col3, col4, col5 = st.columns([0.2, 1, 0.1, 1, 0.2])
Streamlit组件理解
button
创建一个按键和一个文本显示,文本默认显示"456",当点击按键后,文本显示“123”
import streamlit as st
# 初始化session state
if 'text_display' not in st.session_state:
st.session_state.text_display = '456'
# 显示文本
st.write(st.session_state.text_display)
# 创建按钮
if st.button('Click Me'):
# 更新文本显示
st.session_state.text_display = '123'
上述这种方式,按键需要点击两次慧慧更新文本(每次点击都会运行一遍streamlit的程序)
改进:
streamlit美化小技巧
部分内容来自:https://zhuanlan.zhihu.com/p/704882136
1.设置为宽屏
默认为竖屏显示方式,,添加如下代码修改为宽屏
import streamlit as st
st.set_page_config(layout="wide")#设置屏幕展开方式,宽屏模式布局更好
2.布局思路
import streamlit as st
st.set_page_config(layout="wide")#设置屏幕展开方式,宽屏模式布局更好
col1, col2, col3, col4, col5=st.columns([0.2, 1, 0.2, 1, 0.2])
with col1:
st.empty()
with col2:
这里放第1、第2个图表代码
with col3:
st.empty()
with col4:
这里放第3、第4个图表代码
with col5:
st.empty()
st.empty()用于留白区域,
col1, col2, col3, col4, col5=st.beta_columns([0.2, 1, 0.2, 1, 0.2])
这5个参数决定了每一列的宽度值,可以看出留白列的比例小,图表区域的列的比例大
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dW7fK5Ta-1720705304228)(https://i-blog.csdnimg.cn/direct/4ff33b32984e4500bc2140a0b31b872b.png)]
3、去掉右上角上个点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMnxqs4X-1720705304228)(https://i-blog.csdnimg.cn/direct/b250150dbfd943329924a05ae0462323.png)]
参考:https://discuss.streamlit.io/t/removing-the-deploy-button/53621/2
st.markdown("""
<style>
.reportview-container {
margin-top: -2em;
}
#MainMenu {visibility: hidden;}
.stDeployButton {display:none;}
footer {visibility: hidden;}
#stDecoration {display:none;}
</style>
""", unsafe_allow_html=True)
4.button按键颜色自定义
参考:
https://discuss.streamlit.io/t/how-to-change-the-backgorund-color-of-button-widget/12103/24?page=2
import streamlit as st
m = st.markdown("""
<style>
div.stButton > button:first-child {
background-color: #0099ff;
color:#ffffff;
}
div.stButton > button:hover {
background-color: #00ff00;
color:#ff0000;
}
</style>""", unsafe_allow_html=True)
b = st.button("点我开始运行程序")
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jqKQs9Zt-1720705304229)(https://i-blog.csdnimg.cn/direct/4b92943313fd403bba460be628f10435.png)]
5.输入框和按键底部对齐
当页面中只有这两个组件时,好解决:
# 在页面加载时应用 CSS 样式,是按键和文本输入款底部对齐
def apply_css():
st.markdown(
"""
<style>
.stApp [data-testid="stVerticalBlock"] > div {
display: flex;
align-items: flex-end;
}
</style>
""",
unsafe_allow_html=True,
)
apply_css()
当有多个组件时,难搞。上面的css会对其它空间产生影响。
6.减少顶部间距
添加 CSS 样式
import streamlit as st
hide_streamlit_style = “”"
“”"
st.html(hide_streamlit_style)
st.write(
‘’’
Streamlit 是一个开源 Python 框架,供数据科学家和 AI/ML 工程师使用,只需几行代码即可交付动态数据应用程序。
在几分钟内构建和部署功能强大的数据应用。
让我们开始吧!
‘’’
)
st.image(‘https://docs.streamlit.io/images/app_model.png’)
st.write(
‘’’
现在您对所有单独的部分都有了更多的了解,让我们结束循环,回顾一下它是如何协同工作的:
- Streamlight应用程序是从上到下运行的Python脚本。
- 每次用户打开指向您的应用程序的浏览器选项卡时,都会执行脚本并启动新的会话。
- 当脚本执行时,Streamlight会在浏览器中实时绘制其输出。
- 每次用户与小部件交互时,您的脚本都会重新执行,Streamlight会在浏览器中重新绘制其输出。
- 该小部件的输出值与重新运行期间的新值相匹配。
- 脚本使用Streamlit缓存来避免重新计算昂贵的函数,因此更新速度非常快。
- 会话状态使您可以在需要一个简单的小部件以外的内容时,保存在重新运行之间持续存在的信息。
- Streamlight应用程序可以包含多个页面,这些页面在页面文件夹中的单独.py文件中定义。
‘’’
)
import streamlit as st
# 添加自定义CSS来减少顶部间距
st.markdown(
"""
<style>
.block-container {
padding-top: 1rem; /* 减少顶部间距 */
padding-bottom: 0rem; /* 也可以减少底部间距 */
}
</style>
""",
unsafe_allow_html=True
)
# 接下来是你的应用内容
st.title('我的Streamlit应用')
st.write('这是一个示例应用,顶部间距已经减少。')
7.侧边栏优化
参考:https://zhuanlan.zhihu.com/p/704882136
添加 CSS 样式
import streamlit as st
hide_streamlit_style = """
<style>
[data-testid="stSidebarNavItems"] {
padding-top: 2rem;
} /*顶部内边距*/
[data-testid="stSidebarUserContent"] {
padding: 1rem 1.5rem 3rem;
} /*侧边栏顶部、左侧&右侧、底部内边距*/
</style>
"""
st.html(hide_streamlit_style)
with st.sidebar:
st.write(
'''
Streamlit 是一个开源 Python 框架,供数据科学家和 AI/ML 工程师使用,只需几行代码即可交付动态数据应用程序。
在几分钟内构建和部署功能强大的数据应用。
让我们开始吧!
'''
)
st.image('https://docs.streamlit.io/images/app_model.png')
st.write(
'''
现在您对所有单独的部分都有了更多的了解,让我们结束循环,回顾一下它是如何协同工作的:
- Streamlight应用程序是从上到下运行的Python脚本。
- 每次用户打开指向您的应用程序的浏览器选项卡时,都会执行脚本并启动新的会话。
- 当脚本执行时,Streamlight会在浏览器中实时绘制其输出。
- 每次用户与小部件交互时,您的脚本都会重新执行,Streamlight会在浏览器中重新绘制其输出。
- 该小部件的输出值与重新运行期间的新值相匹配。
- 脚本使用Streamlit缓存来避免重新计算昂贵的函数,因此更新速度非常快。
- 会话状态使您可以在需要一个简单的小部件以外的内容时,保存在重新运行之间持续存在的信息。
- Streamlight应用程序可以包含多个页面,这些页面在页面文件夹中的单独.py文件中定义。
'''
)
st.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
8.st.dataframe 禁用下载按钮
有的时候我们不想让用户下载数据,可以禁用 streamlit 自带的下载提示按钮
添加 CSS 样式
import streamlit as st
import pandas as pd
import numpy as np
**8. 隐藏st.dataframe()下载按钮的方法**
st.html(
"""
<style>
[data-testid="stElementToolbar"] {
display: none;
}
</style>
"""
)
df = pd.DataFrame(np.random.randn(50, 20), columns=("col %d" % i for i in range(20)))
st.dataframe(df)
9.gap 间隙管理
有的时候我们觉得组件之间的间隙过大,可以尝试调整间隙
添加 CSS 样式
import streamlit as st
import pandas as pd
import numpy as np
**9.调整组件间隙**
st.html(
"""
<style>
[data-testid="stVerticalBlock"] {
gap: 0.5rem;
}
</style>
"""
)
df = pd.DataFrame(np.random.randn(3, 20), columns=("col %d" % i for i in range(20)))
st.dataframe(df)
st.image('https://docs.streamlit.io/images/app_model.png')
st.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
st.html(
"""
<style>
[data-testid="column"]:nth-child(1) div>[data-testid="baseLinkButton-primary"]>[data-testid="stMarkdownContainer"]>p {
font-size: 32px;
}
}
</style>
"""
)
col01, col02 = st.columns([1, 1])
col01.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
col02.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
10文本大小管理
有的时候我们觉得组件文本大小不适,可以尝试调整文本大小
添加 CSS 样式(全部)
import streamlit as st
# 调整组件间隙
st.html(
"""
<style>
[data-testid="baseLinkButton-primary"]>[data-testid="stMarkdownContainer"]>p {
font-size: 32px;
}
}
</style>
"""
)
col01, col02 = st.columns([1, 1])
col01.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
col02.button(label='Streamlit run', type='primary')
添加 CSS 样式(CSS选择器精准定位)
import streamlit as st
# 调整组件间隙
st.html(
"""
<style>
[data-testid="column"]:nth-child(1) div>[data-testid="baseLinkButton-primary"]>[data-testid="stMarkdownContainer"]>p {
font-size: 32px;
}
}
</style>
"""
)
col01, col02 = st.columns([1, 1])
col01.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
col02.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
11.背景样式管理
有的时候我们想要创建一个特殊的应用场景应用,可以尝试调整页面背景
st.html(
"""
<style>
.stApp {
background-image: url("https://cdn.pixabay.com/photo/2024/04/12/19/50/earthday-8692504_1280.png");
background-size: cover;
}
[data-testid="stVerticalBlockBorderWrapper"] {
background-color: rgba(255, 255, 255, 0.75);
padding: 0.5rem;
}
[data-testid="stVerticalBlockBorderWrapper"]>div {
background-color: rgba(255, 255, 255, 1);
}
</style>
"""
)
with st.container(height=720, border=False):
st.image('https://docs.streamlit.io/images/app_model.png')
st.write(
'''
现在您对所有单独的部分都有了更多的了解,让我们结束循环,回顾一下它是如何协同工作的:
- Streamlight应用程序是从上到下运行的Python脚本。
- 每次用户打开指向您的应用程序的浏览器选项卡时,都会执行脚本并启动新的会话。
- 当脚本执行时,Streamlight会在浏览器中实时绘制其输出。
- 每次用户与小部件交互时,您的脚本都会重新执行,Streamlight会在浏览器中重新绘制其输出。
- 该小部件的输出值与重新运行期间的新值相匹配。
'''
)
st.link_button(label='Streamlit run', url='https://docs.streamlit.io/', type='primary')
侧边栏的按键进行右对齐/居中对齐
hide_streamlit_style = """
<style>
[data-testid="stSidebar"] button {
display: block;
margin-left: auto;
margin-right: 0;
} /* 将侧边栏中的按钮右对齐 */
</style>
"""
hide_streamlit_style = """
<style>
[data-testid="stSidebar"] button {
display: block;
margin-left: auto;
margin-right: auto;
} /* 将侧边栏中的按钮居中对齐 */
</style>
"""
滑动条去除label显示和区域
hide_streamlit_style = """
<style>
[data-testid="stWidgetLabel"] {
display: none;
} /* 隐藏滑块的title */
</style>
"""
st.html(hide_streamlit_style)
# 方式二:使用 select_slider 实现五星级评分
def on_rating_change(idx, selected_item):
rating = st.session_state[f"rating_{idx + 1}"]
options = ["很不喜欢", "比较不喜欢", "一般", "比较喜欢", "很喜欢"]
selected_index = options.index(rating)
selected_label = options[selected_index]
# print(f"Rating changed to {rating}")
# print(f"Selected label: {selected_label}")
st.session_state.selected_score = f"您对【{selected_item}】表示了【{selected_label}】!"
rating = st.select_slider(
label=item['name'],
options=["很不喜欢", "比较不喜欢", "一般", "比较喜欢", "很喜欢"],
value="一般",
key=f"rating_{idx + 1}",
on_change=on_rating_change,
args=(idx,item['name']) # 传递索引参数
)
# 在页面顶部显示消息提示
if 'selected_score' in st.session_state and st.session_state.selected_score:
with info_container.container():
st.info(st.session_state.selected_score)
隐藏右上角deploy标志:
import streamlit as st
# 隐藏 Streamlit Cloud 的 "Deploy" 标志
hide_streamlit_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
</style>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
# 你的应用代码
st.title('你的应用标题')
streamlit生态工具
streamlit像Flask一样,周边诞生了很多好用的配套库,一个牛逼的软件一定会产生生态。
- streamlit-echarts:可以绘制很多好看的,可以交互的图表(比matplotlib好看)
- streamlit-agraph:可以绘制动态的知识图谱,黑帅!