找回密码
 立即注册
首页 业界区 科技 路径选择,调试运行,自定义图表ECharts,分页渲染 ...

路径选择,调试运行,自定义图表ECharts,分页渲染

筒濂 昨天 10:51
Steamlit 并不支持一个可以预览本地文件的路径选择器(并不上传文件)

解决方案:使用 Python 自带的 tkinter 来完成
参考:【Streamlit 选择文件夹的曲折方案】Streamlit选择文件夹-CSDN博客
  1. import streamlit as st from tkinter import filedialog, Tk # Set up tkinter root = Tk() root.withdraw() # Make folder picker dialog appear on top of other windows root.wm_attributes('-topmost', 1) def path_set(label_name: str, segment_name: str, note: str = '', init_path: str = '') -> str: ''' label_name: 标题,用来分割不同的地址获取 segment_name: 标记,作为 session_state 的 key 以及 streamlit 组件的 key 的生成 note: 一些提示,写在地址选择上面 init_path: 初始路径,传入保存在本地的路径或其它 ''' # 会话保证刷新网页后不会丢失 if segment_name not in st.session_state: st.session_state[segment_name] = init_path # 选择路径提示 st.markdown('##### ' + label_name) # 其它文本 st.write(note) dirname_selected = None col1, col2 = st.columns([4, 1]) empty_text = col1.empty() empty_text.text_input( label='1', value=st.session_state[segment_name], label_visibility='collapsed', autocomplete='on', key=segment_name + 'input' + 'a', ) choice = col2.button('浏览文件', key=segment_name + 'button' + 'a') if choice: dirname_selected = filedialog.askdirectory(master=root) if dirname_selected: st.session_state[segment_name] = dirname_selected empty_text.text_input( label='2', value=st.session_state[segment_name], label_visibility='collapsed', autocomplete='on', key=segment_name + 'input' + 'b', ) # st.write(st.session_state[segment_name]) # 测试时候用的,用来观察是否成功记录
复制代码
思路就是用 st.columns 将页面分两栏,然后使用 st.empty 来占位,将传入的 init_path 保存在 st.session_state 的字典中用来保证刷新后不会丢失,先创建一个 st.text_input来显示初始的 init_path ,然后通过 filedialog.askdirectory 获取到文件地址后,更新 st.empty,使得输入来显示选择的地址。
这个东西花了我很长时间,主要是不太理解 Streamlit 的运作模式,又到处找能用的代码
Streamlit运行

Streamlit 的运行比较反常,不是通过 Python 而是通过 Python 环境中的 Streamlit 命令进行的,很多时候运行和调试起来很麻烦(VSCode上),下面是几种运行方式
VSCode 调试

在项目文件夹下的 .vscode 文件夹,里面的 launch.json 文件中加入
  1. { // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Streamlit", "type": "debugpy", "request": "launch", "module": "streamlit.web.cli", "env": { "STREAMLIT_ENABLE_COLAB_BACKEND": "true" }, "args": [ "run", "${file}", "--server.port", "667", "--server.address", "127.0.0.1" ] } ] }
复制代码
这样使用 CodeRunner 中的调试和直接按 F5 调试就可以直接启动了
另附,虽然 Streamlit 有点麻烦,不过正常调试还是可以调试的,打上断点之后启动调试就会卡住,或是随便在代码里加入一个无关紧要的空格(随便改改,不影响代码就行)后,点页面右上角的 Rerun
1.png
就OK(没有的话就在那三个点里)
通过 Python 直接运行

其实就是通过 Python 来执行命令
  1. import streamlit.web.cli as stcli import os, sys if __name__ == "__main__": if getattr(sys, 'frozen', False): current_dir = sys._MEIPASS else: current_dir = os.path.dirname(os.path.abspath(__file__)) file_path = os.path.join(current_dir, "main.py") sys.argv = ["streamlit", "run", file_path, "--server.enableCORS=true", "--server.enableXsrfProtection=false", "--global.developmentMode=false", "--client.toolbarMode=minimal"] sys.exit(stcli.main())
复制代码
注:这种是在 Python 环境中的命令,如果 Python 环境没有激活,也可以使用 Python.exe -m streamlit run  的形式来运行,例如:
2.png

可以把这个写成批处理脚本,例如:
  1. .\runtime\python.exe -m streamlit run .\src\main.py
复制代码
关于图表(主要是柱状图)

Streamlit 提供的 图表 可拓展的能力实在是太低,需要做一些精细化调整时就会出现问题(不过要求不太多的话还是很好使的,也很美观),如:

  • 标签输出不能修改
  • 不能取消柱状图表鼠标滚轮缩放
  • 不能取消某个坐标轴的显示
  • 会乱序
等等,不过毕竟是封装好的简单易用的功能,如果可以忍受瑕疵的话就不要使用第三方的组件(会出现一些奇怪的问题,后面会介绍)所以为了使用更加精细的表格生成,可以通过第三方组件引入 Apache EChart ,其中有两个(在官网上发布的):

  • ECharts:streamlit-echarts
  • Raw ECarts:streamlit-raw-echarts
它们本身功能类似,参考链接里的写法,其中配置项 option 的配置方法参考ECharts配置项手册。
注:由于在 Python 中,option 表现为一个字典,且 Python 内是没有对应的变量,所以要将 key 写为字符串形式,value 同理,除去传入的数据,布尔类型,数字,基本上剩下的都是字符串形式
它们的不同之处在一些更加细节的地方:
区别1:参数可不可以为 JavaScript 函数

它们都包含一个 JScode 函数,可以通过库来导入,但是这个函数在 streamlit-echart 中用处就不大(可能,至少我在尝试使用的时候只能报错),而在 streamlit-raw-echart 中是可以使用的,这个函数可以帮助部分配置项配置 JavaScript函数 ,如:
  1. options = { "tooltip": { "show": True, "trigger": "item", "showContent": True, "triggerOn": "mousemove", "formatter": JsCode(&#39;&#39;&#39;function(params){return params.name+&#39;</p><p>抽数:&#39;+ params.data.value +&#39;</p><p>时间:&#39;+ params.data.time}&#39;&#39;&#39;) }, }
复制代码
其中 "formatter" 就对应了一个函数,用来为悬停提示加入部分数据,这种操作在 streamlit-echart 中就只会报错:
  1. MarshallComponentException: (&#39;Could not convert component args to JSON&#39;, TypeError(&#39;Object of type JsCode is not JSON serializable&#39;))
复制代码
大概意思就是说 JsCode 类不能被 Json 序列化
区别二:参数名字不同

切记注意两个库中函数名同样是 st_echarts 的两个函数,其中的参数名却不一样

  • streamlit-echarts:options
  • streamlit-raw-echarts:option
引入该第三方库所带来的缺点

不能使用tabs分页

由于该库并非是官方自带的,加上一些其它的问题(感觉是 Streamlit 渲染的问题),导致该表格无法使用在分页当中(st.tabs);如果存在多个分页并且每个分页中都有这样的图表,那么它只会渲染出来一个当前被选中页面中的图表,可以在图表未加载出来之前对页面进行切换来加载其它页面的图表,但很不方便。
因此,选择了第三方库就意味着不能使用分页(st.tabs),可以使用多页应用和按钮 st.button来替代
使用按钮来替代分页的代码可以参考:
  1. # 均分一行,使得按钮在同一列 eql = st.columns(7, gap="small") button_list = [] # 循环创建按钮,并将结果保存在一个列表中,跳出分栏当中,防止后续的内容也被分栏 for i in range(7): with eql[i]: button_list.append(st.button("button" + str(i))) for i in range(len(button_list)): if button_list[i]: break # 下面这几行与 Streamlit 和 ECharts 无关,只是在根据按钮来获取对应的数据 gacha_name = gacha_type[i + 1] level_page = level_pages[i] level = levels[i] t = db.table( data_to_analysis_name_trans(gacha_name, level) ) df = pd.DataFrame(t.all()) # 生成 ECharts 图表 options = { "xAxis": { "show": False, }, "yAxis": { "data": list(df[&#39;name&#39;])[::-1] }, "tooltip": { "show": True, "trigger": "item", "showContent": True, "triggerOn": "mousemove" }, "series": [ { "name": "抽数", "type": "bar", "colorBy": "data", "data": list(df["pity_num"])[::-1], "barMinWidth": 20, "barMaxWidth": 20, "barCategoryGap": 20, } ] } st_echarts( options=options, height=str(len(df) * 50 + 150) + "px", )
复制代码
注:我在翻阅 github 问题(st_echarts are not visualized in multitabs · Issue #43 · andfanilo/streamlit-echarts、echarts whit tabs · Issue #54 · andfanilo/streamlit-echarts)的时候看到有位用户在宣传ta的第三方组件库(streamlit-antd-components)中的 tabs ,不过至少我在我的项目中引用该库也并没有解决我的问题,但是这个库还是美观的,只是在使用的时候要注意这个库的文档不够精准,且至少在 tabs 这个组件上,它与 Streamlit 自带的使用逻辑并不一致,如下:
  1. selected_tab = tabs(["tab1", "tab2"]) if selected_tab == "tab1": selected_tab_2 = tabs([&#39;tab11&#39;, &#39;tab12&#39;]) if selected_tab_2 == "tab11": page1() else: page2() elif selected_tab == "tab2": page3()
复制代码
不过这个方法启发我去尝试使用 st.button 来替代 st.tabs ,并且取得了成效。
太多的图表平铺在同一页会出现个别不加载的问题

如标题,这个问题有点抽象,不过可以通过切换页面(重新加载)来试试,多试几次可能就能加载出来,毕竟这个并不是稳定触发的问题,不知道是什么原因导致的,不过也同样可以使用上面([[计算机/编程语言/python/鸣潮抽卡记录软件/关于我在使用Steamlit中碰到的问题及解决方案总结#不能使用tabs分页|不能使用tabs分页]])的按钮方法来缓解这个问题

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册