详解一个Python库,用于构建精美数据可视化web app,练习做个垃圾分类app
共 7665字,需浏览 16分钟
·
2021-12-25 22:34
回复“书籍”即可获赠Python从入门到进阶共10本电子书
1
文本组件
import streamlit as st
# markdown
st.markdown('Streamlit is **_really_ cool**.')
# 设置网页标题
st.title('This is a title')
# 展示一级标题
st.header('This is a header')
# 展示二级标题
st.subheader('This is a subheader')
# 展示代码,有高亮效果
code = '''def hello():
print("Hello, Streamlit!")'''
st.code(code, language='python')
# 纯文本
st.text('This is some text.')
# LaTeX 公式
st.latex(r'''
a + ar + a r^2 + a r^3 + \cdots + a r^{n-1} =
\sum_{k=0}^{n-1} ar^k =
a \left(\frac{1-r^{n}}{1-r}\right)
''')
streamlit run garbage_classifier.py
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://192.168.10.141:8501
2
数据组件
import streamlit as st
import pandas as pd
import numpy as np
df = pd.DataFrame(
np.random.randn(50, 5),
columns=('col %d' % i for i in range(5)))
# 交互式表格
st.dataframe(df)
# 静态表格
st.table(df)
st.metric(label="Temperature", value="70 °F", delta="1.2 °F")
st.json({
'foo': 'bar',
'stuff': [
'stuff 1',
'stuff 2',
],
})
3
图表组件
chart_data = pd.DataFrame(
np.random.randn(20, 3),
columns=['a', 'b', 'c'])
st.line_chart(chart_data)
import matplotlib.pyplot as plt
arr = np.random.normal(1, 1, size=100)
fig, ax = plt.subplots()
ax.hist(arr, bins=20)
st.pyplot(fig)
4
输入组件
button:按钮
download_button:文件下载
file_uploader:文件上传
checkbox:复选框
radio:单选框
selectbox:下拉单选框
multiselect:下拉多选框
slider:滑动条
select_slider:选择条
text_input:文本输入框
text_area:文本展示框
number_input:数字输入框,支持加减按钮
date_input:日期选择框
time_input:时间选择框
color_picker:颜色选择器
它们包含一些公共的参数:
label:组件上展示的内容(如:按钮名称) key:当前页面唯一标识一个组件 help:鼠标放在组件上展示说明信息 on_click / on_change:组件发生交互(如:输入、点击)后的回调函数 args:回调函数的参数 kwargs:回调函数的参数
下面以 selectbox 来演示输入组件的用法
option = st.selectbox(
'下拉框',
('选项一', '选项二', '选项三'))
st.write('选择了:', option)
selectbox 展示三个选项,并输出当前选中的项(默认选中第一个)。当我们在页面下拉选择其他选项后,整个页面代码会重新执行,但组件的选择状态 会保留在 option 中,因此,调用 st.write 后会输出选择后的选项。
st.write 也是一个输出组件,可以输出字符串、DataFrame、普通对象等各种类型数据。
其他组件的使用与之类似,组件效果图如下:
5
多媒体组件
Streamlit 定义了 image、audio 和 video 用于展示图片、音频和视频。
可以展示本地多媒体,也通过 url 展示网络多媒体。
用法跟前面的组件是一样的,后面的垃圾分类 APP 我们会用到 image 组件。
6
状态组件
状态组件用来向用户展示当前程序的运行状态,包括:
progress:进度条,如游戏加载进度
spinner:等待提示
balloons:页面底部飘气球,表示祝贺
error:显示错误信息
warning:显示报警信息
info:显示常规信息
success:显示成功信息
exception:显示异常信息(代码错误栈)
效果如下:
7
其他内容
到这里,Streamlit 的组件基本上就全介绍完了,组件也是 Streamlit 的主要内容。
这小节介绍一下其他比较重要的内容,包括页面布局、控制流和缓存。
页面布局。之前我们写的 Streamlit 都是按照代码执行顺序从上至下展示组件,Streamlit 提供了 5 种布局:
sidebar:侧边栏,如:文章开头那张图,页面左侧模型参数选择
columns:列容器,处在同一个 columns 内组件,按照从左至右顺序展示
expander:隐藏信息,点击后可展开展示详细内容,如:展示更多
container:包含多组件的容器
empty:包含单组件的容器
控制流。控制 Streamlit 应用的执行,包括
stop:可以让 Streamlit 应用停止而不向下执行,如:验证码通过后,再向下运行展示后续内容。
form:表单,Streamlit 在某个组件有交互后就会重新执行页面程序,而有时候需要等一组组件都完成交互后再刷新(如:登录填用户名和密码),这时候就需要将这些组件添加到 form 中
form_submit_button:在 form 中使用,提交表单。
缓存。这个比较关键,尤其是做机器学习的同学。刚刚说了, Streamlit 组件交互后页面代码会重新执行,如果程序中包含一些复杂的数据处理逻辑(如:读取外部数据、训练模型),就会导致每次交互都要重复执行相同数据处理逻辑,进而导致页面加载时间过长,影响体验。
加入缓存便可以将第一次处理的结果存到内存,当程序重新执行会从内存读,而不需要重新处理。
使用方法也简单,在需要缓存的函数加上 @st.cache 装饰器即可。前两天我们讲过 Python 装饰器。
DATE_COLUMN = 'date/time'
DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
'streamlit-demo-data/uber-raw-data-sep14.csv.gz')
@st.cache
def load_data(nrows):
data = pd.read_csv(DATA_URL, nrows=nrows)
lowercase = lambda x: str(x).lower()
data.rename(lowercase, axis='columns', inplace=True)
data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
return data
8
垃圾分类
最后讲解垃圾分类APP的代码,前面介绍几大类组件在该 APP 都有涉及。
垃圾分类模型我用的是天行 API ,大家可以去 https://www.tianapi.com/ 注册账号,获取 appkey,开通“图像垃圾分类” 接口即可。
import base64
import requests
import streamlit as st
import pandas as pd
import numpy as np
add_selectbox = st.sidebar.selectbox(
"图片来源",
("本地上传", "URL")
)
uploaded_file = None
img_url = None
if add_selectbox == '本地上传':
uploaded_file = st.sidebar.file_uploader(label='上传图片')
else:
img_url = st.sidebar.text_input('图片url')
cls_mode = {'严格模式': 0, '模糊模式': 1}
mode_name = st.sidebar.radio('分类模式', cls_mode)
mode = cls_mode[mode_name]
# 请求结果
img_base64 = None
if uploaded_file:
st.image(uploaded_file, caption='本地图片')
base64_data = base64.b64encode(uploaded_file.getvalue())
img_base64 = base64_data.decode()
if img_url:
st.image(img_url, caption='网络图片')
if img_base64 or img_url:
cls_res = get_img_cls_res(img_base64, img_url, mode)
lajitype_to_name = {0: '可回收物', 1: '有害垃圾', 2: '厨余垃圾', 3: '其他垃圾', 4: '无法识别'}
if cls_res.status_code == 200:
cls_df = pd.DataFrame(cls_res.json()['newslist'])
cls_df['分类'] = cls_df.index.astype(str) + '-' + cls_df['name'] + '-' + cls_df['lajitype'].apply(lambda x: lajitype_to_name[x])
cls_df['置信度'] = cls_df['trust']
cls_df.set_index(["分类"], inplace=True)
print(cls_df)
st.bar_chart(cls_df[['置信度']])
else:
st.write(cls_res)
def get_img_cls_res(img_base64, img_url, mode):
url = 'https://api.tianapi.com/txapi/imglajifenlei/index'
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
body = {
'key': 'APPKEY',
'mode': mode
}
if img_base64:
body["img"] = img_base64
if img_url:
body['imgurl'] = img_url
response = requests.post(url, headers=headers, data=body)
return response
小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。
小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。
------------------- End -------------------
往期精彩文章推荐:
欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持
想加入Python学习群请在后台回复【入群】
万水千山总是情,点个【在看】行不行
/今日留言主题/
随便说一两句吧~~