<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Streamlit on IT 空間</title><link>https://blog.jiatool.com/tags/Streamlit/</link><description>Recent content in Streamlit on IT 空間</description><generator>Hugo -- gohugo.io</generator><language>zh</language><managingEditor>jia@jiatool.com (Jia)</managingEditor><webMaster>jia@jiatool.com (Jia)</webMaster><copyright>&amp;copy;{year}, Jia All Rights Reserved</copyright><lastBuildDate>Sat, 09 Nov 2024 20:40:00 +0800</lastBuildDate><atom:link href="https://blog.jiatool.com/tags/Streamlit/index.xml" rel="self" type="application/rss+xml"/><item><title>Streamlit 使用 Nginx 佈署在網址其他路徑</title><link>https://blog.jiatool.com/posts/streamlit_nginx/</link><pubDate>Sat, 09 Nov 2024 20:40:00 +0800</pubDate><author>jia@jiatool.com (Jia)</author><atom:modified>Sat, 09 Nov 2024 20:40:00 +0800</atom:modified><guid>https://blog.jiatool.com/posts/streamlit_nginx/</guid><description>前言 當使用 Streamlit 做出一個 web app 之後，除了佈署到 Streamlit Community Cloud，我們也可以自己佈署 (例如使用 Docker、Kubernetes)。 * 之前寫的文章：(</description><content:encoded>&lt;h2 id="前言">前言&lt;/h2>
&lt;p>當使用 &lt;a href="https://streamlit.io/" target="_blank" rel="noopener">
Streamlit
&lt;/a> 做出一個 web app 之後，除了佈署到 Streamlit Community Cloud，我們也可以自己佈署 (例如使用 Docker、Kubernetes)。&lt;/p>
&lt;p>* 之前寫的文章：&lt;a href="https://blog.jiatool.com/posts/streamlit_2023" target="_blank" rel="noopener">
(2023年新版) 使用 Streamlit 簡單又快速建立 Dashboard 網頁
&lt;/a>&lt;/p>
&lt;br/>
&lt;p>最近剛好有這需求，但我不是要起在根路徑(&lt;code>/&lt;/code>)，而是要指定其他路徑(例如 &lt;code>/myapp&lt;/code>)，這部分會透過 Nginx 去設定。&lt;/p>
&lt;p>不過找了幾篇網路文章，卻還是設定不起來，所以把最終成功的設定分享出來，讓大家少踩一些坑。&lt;/p>
&lt;br/>
&lt;!--adsense-->
&lt;br/>
&lt;h2 id="設定細節">設定細節&lt;/h2>
&lt;p>我需要設定，當其他電腦連到這台主機的某個路徑 (例如 &lt;code>https://mysite.com/myapp&lt;/code>)，它可以轉到 Streamlit app 的 port (例如 &lt;code>http://localhost:8000&lt;/code>)。&lt;/p>
&lt;br/>
&lt;h3 id="環境">環境&lt;/h3>
&lt;p>我是在 Windows 11 裡的 WSL (Linux 系統) 起 Docker 環境，裡面跑 Streamlit app。&lt;/p>
&lt;p>並在 Windows 底下起 Nginx server (v1.24.0)，讓公司內其他電腦可以連到這台的 localhost。&lt;/p>
&lt;br/>
&lt;h3 id="nginx-設定">Nginx 設定&lt;/h3>
&lt;p>因為 Streamlit 有用到 WebSocket，所以還需要多加幾行相關設定。&lt;/p>
&lt;blockquote>
&lt;p>WebSocket 是一種網路傳輸協定，用來在 Server 和 Client 之間建立「持續的雙向通訊」通道，是持續的連線，Server 可以主動向 Client 發送資料，而不需要等待 Client 發出請求。&lt;br />
這使得 WebSocket 特別適合用於即時應用場景，比如即時聊天、線上遊戲等。&lt;/p>
&lt;/blockquote>
&lt;br/>
&lt;p>設定 &lt;code>nginx.conf&lt;/code> 檔案，這個檔案可以到 &lt;code>nginx 安裝路徑&lt;/code>、&lt;code>/usr/local/nginx/conf&lt;/code>、&lt;code>/etc/nginx&lt;/code>、&lt;code>/usr/local/etc/nginx&lt;/code> 找找。&lt;/p>
&lt;pre>&lt;code>http {
...
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen 443 ssl;
ssl_certificate &amp;quot;(省略)/conf/certs/demo.pem&amp;quot;;
ssl_certificate_key &amp;quot;(省略)/conf/certs/demo.key&amp;quot;;
# Streamlit app
location /myapp {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>&lt;code># Streamlit app&lt;/code> 的部分我還有看到另外一種設定，但在此案例應該沒差(?)：&lt;/p>
&lt;pre>&lt;code> location /myapp/_stcore/stream {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /myapp {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
&lt;/code>&lt;/pre>&lt;br/>
&lt;h3 id="streamlit-指令">Streamlit 指令&lt;/h3>
&lt;p>這邊是一大重點，因為找到的文章很多都是在說 Nginx 設定，而沒有提到 &lt;code>streamlit run&lt;/code> 也要帶相關參數：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-shell" data-lang="shell">streamlit run streamlit.py --server.port &lt;span class="m">8000&lt;/span> --server.enableCORS &lt;span class="nb">false&lt;/span> --server.enableXsrfProtection &lt;span class="nb">false&lt;/span> --server.baseUrlPath &lt;span class="s2">&amp;#34;myapp&amp;#34;&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;br/>
&lt;p>題外話，可以關閉將使用情況統計資料傳送給 Streamlit：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-shell" data-lang="shell">--browser.gatherUsageStats &lt;span class="nb">false&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;!--adsense-->
&lt;br/>
&lt;h2 id="結語">結語&lt;/h2>
&lt;p>雖然我不知道這樣設定是不是最好的，但至少對我有效 (🤣&lt;/p>
&lt;br/>
&lt;p>我把找到的幾篇文章都貼在下方參考連結，如果以上的方法還是幫不了你，可以去參考連結翻翻試試。&lt;/p>
&lt;br/>
&lt;br/>
&lt;hr />
&lt;p>參考：&lt;br />
&lt;a href="https://docs.streamlit.io/develop/api-reference/configuration/config.toml" target="_blank" rel="noopener">
config.toml | Streamlit API reference
&lt;/a>&lt;br />
&lt;a href="https://discuss.streamlit.io/t/how-to-use-streamlit-with-nginx/378" target="_blank" rel="noopener">
How to use Streamlit with Nginx? | Streamlit Discuss
&lt;/a>&lt;br />
&lt;a href="https://discuss.streamlit.io/t/deploy-streamlit-with-nginx-with-ssl/61770" target="_blank" rel="noopener">
Deploy Streamlit with NGINX with SSL | Streamlit Discuss
&lt;/a>&lt;br />
&lt;a href="https://discuss.streamlit.io/t/deploy-streamlit-with-nginx-docker/52907" target="_blank" rel="noopener">
Deploy streamlit with nginx + docker | Streamlit Discuss
&lt;/a>&lt;br />
&lt;a href="https://discuss.streamlit.io/t/run-streamlit-app-on-specific-url-path/32147" target="_blank" rel="noopener">
Run streamlit app on specific URL path | Streamlit Discuss
&lt;/a>&lt;/p>
&lt;br/>
&lt;blockquote>
&lt;p>平靜的海面造就不出優秀的水手。&lt;/p>
&lt;/blockquote></content:encoded><dc:creator>Jia</dc:creator><media:content url="https://blog.jiatool.comimages/cover/streamlit_nginx.jpg" medium="image"><media:title type="html">featured image</media:title></media:content><media:content url="https://blog.jiatool.comimages/posts/streamlit_nginx_meta.jpg" medium="image"><media:title type="html">meta image</media:title></media:content><category>Streamlit</category><category>Nginx</category><category>套件</category><category>分享</category><category>Python套件</category></item><item><title>(2023年新版) 使用 Streamlit 簡單又快速建立 Dashboard 網頁</title><link>https://blog.jiatool.com/posts/streamlit_2023/</link><pubDate>Sun, 17 Sep 2023 21:35:00 +0800</pubDate><author>jia@jiatool.com (Jia)</author><atom:modified>Sun, 17 Sep 2023 21:35:00 +0800</atom:modified><guid>https://blog.jiatool.com/posts/streamlit_2023/</guid><description>前言 之前寫這篇 Streamlit 的教學文章 已經過去兩年多了，陸續官方還增加了許多功能與優化，而且從我部落格後台的數據來看，發現那篇文章還蠻多人觀看。因此決定</description><content:encoded>&lt;h2 id="前言">前言&lt;/h2>
&lt;p>之前寫&lt;a href="https://blog.jiatool.com/posts/streamlit" target="_blank" rel="noopener">
這篇 Streamlit 的教學文章
&lt;/a>已經過去兩年多了，陸續官方還增加了許多功能與優化，而且從我部落格後台的數據來看，發現那篇文章還蠻多人觀看。因此決定再寫篇更新的內容，並多補充一些細節。&lt;/p>
&lt;p>此篇文章使用的 Streamlit 是 v1.26.0 版本。&lt;/p>
&lt;br/>
&lt;p>Streamlit 幫助我們快速製作 Web 應用程式，而且不需要任何前端技能，全部都採用 Python 語法完成。讓你輕鬆分享網路爬蟲、數據科學和機器學習的資料，是一個非常方便的套件。&lt;/p>
&lt;p>* 文章最後會附上完整的範例程式碼，請一定看到最後~&lt;/p>
&lt;br/>
&lt;h2 id="demo">Demo&lt;/h2>
&lt;p>這是最後將程式碼放到 GitHub，並使用 Streamlit Cloud 部署的成果。&lt;/p>
&lt;div class="alert alert-info" role="alert" data-dir="ltr">Streamlit 成果範例：&lt;a href="https://jiatool-demo.streamlit.app/">streamlit_2023_demo&lt;/a>&lt;/div>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/demo.jpg" alt="Streamlit Demo 範例" data-caption="Streamlit Demo 範例" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
Streamlit Demo 範例
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;!--adsense-->
&lt;h2 id="安裝與執行">安裝與執行&lt;/h2>
&lt;ul>
&lt;li>Streamlit [&lt;a href="https://streamlit.io/" target="_blank" rel="noopener">
官方網站
&lt;/a>] [&lt;a href="https://docs.streamlit.io/" target="_blank" rel="noopener">
官方文檔
&lt;/a>]&lt;/li>
&lt;/ul>
&lt;p>安裝&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">pip install streamlit
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>撰寫本篇文章時最新版為：v1.26.0&lt;/p>
&lt;p>執行&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">streamlit run &amp;lt;py程式檔案路徑&amp;gt;
&lt;span class="c1"># 以我下方文章範例的話，就是：&lt;/span>
streamlit run streamlit_app.py
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>如果想指定 Streamlit 的 port 埠號，只要在後方加上&lt;code>--server.port&lt;/code> 參數：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">streamlit run &amp;lt;py程式檔案路徑&amp;gt; --server.port &lt;span class="m">8888&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>需要終止該應用程式只需在終端中按 &lt;strong>Ctrl + c&lt;/strong>。&lt;/p>
&lt;br/>
&lt;h2 id="創建-streamlit-應用程式">創建 Streamlit 應用程式&lt;/h2>
&lt;p>除了跟著我以下的文章流程學習，也可以參考 &lt;a href="https://docs.streamlit.io/library/get-started" target="_blank" rel="noopener">
官方文檔 Get started
&lt;/a> 的流程操作。&lt;/p>
&lt;h3 id="新增-py-程式碼">新增 py 程式碼&lt;/h3>
&lt;p>新創建一個 Python 檔案 &lt;code>streamlit_app.py&lt;/code>，以下教學都只會編輯這個檔案。&lt;/p>
&lt;p>打開它，在一開始導入 Streamlit 與範例需要的其他套件：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="kn">import&lt;/span> &lt;span class="nn">time&lt;/span>
&lt;span class="kn">import&lt;/span> &lt;span class="nn">streamlit&lt;/span> &lt;span class="kn">as&lt;/span> &lt;span class="nn">st&lt;/span>
&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="kn">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="kn">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;p>打開 &amp;quot;命令提示字元&amp;quot; 或 &amp;quot;終端機&amp;quot;，開始執行程式：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">streamlit run streamlit_app.py
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>* 第一次執行時，它可能會問你 Email，這可以不用理它，直接按 Enter 即可。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/streamlit_run_email.png" alt="執行 Streamlit 程式，第一次會遇到 Email" data-caption="執行 Streamlit 程式，第一次會遇到 Email" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
執行 Streamlit 程式，第一次會遇到 Email
&lt;/figcaption>
&lt;/figure>
&lt;p>它應該會顯示如下資訊，並自動開啟一個瀏覽器網頁。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/run_streamlit.png" alt="執行 Streamlit 程式" data-caption="執行 Streamlit 程式" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
執行 Streamlit 程式
&lt;/figcaption>
&lt;/figure>
&lt;p>然後網頁裡面顯示&amp;hellip; 一片空白？！&lt;br />
沒錯！我們又還沒有添加元件進去，怎麼會有東西呢~ 😆&lt;/p>
&lt;br/>
&lt;h3 id="添加文字和數據">添加文字和數據&lt;/h3>
&lt;p>先幫我們的應用程式上個標題，加入以下程式碼：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">title&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;我的第一個應用程式&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>存檔，回到瀏覽器的網頁上。&lt;/p>
&lt;p>可以重整網頁，或點擊右上角菜單內 &amp;quot;Rerun&amp;quot; 的按鈕，&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/rerun.jpg" alt="Rerun 重整網頁" data-caption="Rerun 重整網頁" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='350px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:350px;height:;"/>
&lt;figcaption style="text-align: center;">
Rerun 重整網頁
&lt;/figcaption>
&lt;/figure>
&lt;p>網頁上就會顯示一個標題文字了：&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/first_title.jpg" alt="試著加入標題吧" data-caption="試著加入標題吧" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
試著加入標題吧
&lt;/figcaption>
&lt;/figure>
&lt;p>如何？簡單吧，那我們再繼續接著下去~&lt;/p>
&lt;br/>
&lt;h3 id="使用-stwrite-和-magic-commands">使用 &lt;code>st.write&lt;/code> 和 Magic Commands&lt;/h3>
&lt;p>在 Streamlit 內有個神奇的指令，他們把它叫 &lt;a href="https://docs.streamlit.io/library/api-reference/write-magic" target="_blank" rel="noopener">
&lt;code>st.write&lt;/code> 和 Magic Commands
&lt;/a>，不管給它 &amp;quot;字串&amp;quot;、&amp;quot;Markdown&amp;quot;、&amp;quot;數據資料&amp;quot; 還是 &amp;quot;圖表&amp;quot;，Streamlit 都會自動辨別並以合適的方式顯示出來。&lt;/p>
&lt;p>在程式碼中只要把想顯示的東西放進 &lt;code>st.write&lt;/code>，甚至單一行只有變數或字串，根本不需要使用 &lt;code>st.write&lt;/code>，它都會自動套用並顯示。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;嘗試創建**表格**：&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">({&lt;/span>
&lt;span class="s1">&amp;#39;first column&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">],&lt;/span>
&lt;span class="s1">&amp;#39;second column&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">20&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">30&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">40&lt;/span>&lt;span class="p">]&lt;/span>
&lt;span class="p">})&lt;/span>
&lt;span class="n">df&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/magic_commands.jpg" alt="呈現 Markdown 與 表格" data-caption="呈現 Markdown 與 表格" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
呈現 Markdown 與 表格
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;p>但是官方有提到有以下三個原因，如果可以的話還是使用更具體的方法比較好：&lt;/p>
&lt;ol>
&lt;li>&lt;code>Magic&lt;/code> 和 &lt;code>st.write()&lt;/code> 會檢查您傳入的數據類型，然後決定如何最好地呈現，但有時你可能想以另一種方式呈現它。&lt;/li>
&lt;li>其他方法返回一個可以使用和修改的對象，可以通過向其添加數據或替換它。&lt;/li>
&lt;li>如果使用更具體的 Streamlit 方法，您可以傳遞其他參數來自定義其行為。&lt;/li>
&lt;/ol>
&lt;br/>
&lt;h3 id="繪製圖表和地圖-chart">繪製圖表和地圖 Chart&lt;/h3>
&lt;h5 id="折線圖-stline_chart">折線圖 &lt;code>st.line_chart()&lt;/code>&lt;/h5>
&lt;p>使用 Numpy 生成一個隨機樣本，然後將其繪製成折線圖。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">chart_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">20&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">),&lt;/span>
&lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;a&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;b&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;c&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">line_chart&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chart_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>而且它本身有下載、全螢幕觀看等功能。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/line_chart.jpg" alt="繪製折線圖" data-caption="繪製折線圖" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
繪製折線圖
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h5 id="地圖-stmap">地圖 &lt;code>st.map()&lt;/code>&lt;/h5>
&lt;p>使用 Numpy 生成一個隨機樣本，繪製到地圖上。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">map_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mf">22.6&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">120.4&lt;/span>&lt;span class="p">],&lt;/span>
&lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;lat&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;lon&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">map_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/map.jpg" alt="繪製地圖" data-caption="繪製地圖" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
繪製地圖
&lt;/figcaption>
&lt;/figure>
&lt;p>更多圖表元件請參考：&lt;a href="https://docs.streamlit.io/library/api-reference/charts" target="_blank" rel="noopener">
官方文件 Chart elements
&lt;/a>&lt;/p>
&lt;br/>
&lt;h3 id="輸入類元件">輸入類元件&lt;/h3>
&lt;p>除了上述標題、圖表，還有其他小工具，像是按鈕、選擇框、複選框、滑塊等等。&lt;/p>
&lt;br/>
&lt;h5 id="按鈕-stbutton">按鈕 &lt;code>st.button()&lt;/code>&lt;/h5>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="k">if&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">button&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;不要按!&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;不是叫你不要按了嗎！&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/button.png" alt="按鈕元件" data-caption="按鈕元件" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='400px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:400px;height:;"/>
&lt;figcaption style="text-align: center;">
按鈕元件
&lt;/figcaption>
&lt;/figure>
&lt;p>但你可能會注意到，每次點擊按鈕時，上方的折線圖也會產生變化。&lt;br />
這是因為 Streamlit 只要元件有輸入值的改變，整個程式(網頁)就會重新運行，因此折線圖裡的 random 才會出來不同資料。&lt;/p>
&lt;br/>
&lt;h5 id="複選框-stcheckbox">複選框 &lt;code>st.checkbox()&lt;/code>&lt;/h5>
&lt;p>使用複選框來顯示/隱藏數據，例如將剛剛繪製地圖的程式改成：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="k">if&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">checkbox&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;顯示地圖圖表&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">map_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mf">22.6&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">120.4&lt;/span>&lt;span class="p">],&lt;/span>
&lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;lat&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;lon&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">map_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;h5 id="選擇框-stselectbox">選擇框 &lt;code>st.selectbox()&lt;/code>&lt;/h5>
&lt;p>使用選擇框提供使用者選擇：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">option&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">selectbox&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="s1">&amp;#39;你喜歡哪種動物？&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;狗&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;貓&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;鸚鵡&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;天竺鼠&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="s1">&amp;#39;你的答案：{option}&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/checkbox_selectbox.jpg" alt="複選框 與 選擇框" data-caption="複選框 與 選擇框" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
複選框 與 選擇框
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h3 id="調整佈局-layout">調整佈局 Layout&lt;/h3>
&lt;p>除了剛剛示範的一行一個元件，Streamlit 有提供幾種佈局容器元件供使用、排版。&lt;/p>
&lt;br/>
&lt;h5 id="側邊欄-stsidebar">側邊欄 &lt;code>st.sidebar&lt;/code>&lt;/h5>
&lt;p>例如我們能將元件移到側邊欄中，這邊範例將剛剛的選擇框移入側邊欄：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">option&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sidebar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">selectbox&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="s1">&amp;#39;你喜歡哪種動物？&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;狗&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;貓&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;鸚鵡&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;天竺鼠&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sidebar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="s1">&amp;#39;你的答案：{option}&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/sidebar.jpg" alt="將元件移到側邊欄" data-caption="將元件移到側邊欄" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='750px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:750px;height:;"/>
&lt;figcaption style="text-align: center;">
將元件移到側邊欄
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h5 id="列容器-stcolumns">列容器 &lt;code>st.columns()&lt;/code>&lt;/h5>
&lt;p>也有左右兩邊的方式來排列的容器：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">left_column&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">right_column&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">columns&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">left_column&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;這是左邊欄位。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">right_column&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;這是右邊欄位。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;h5 id="展開容器-stexpander">展開容器 &lt;code>st.expander()&lt;/code>&lt;/h5>
&lt;p>也可以通過能展開的容器，來隱藏大量內容來節省空間：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">expander&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">expander&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;點擊來展開...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">expander&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;如果你要顯示很多文字，但又不想佔大半空間，可以使用這種方式。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/expander.png" alt="將內容摺疊起來，節省空間" data-caption="將內容摺疊起來，節省空間" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
將內容摺疊起來，節省空間
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h5 id="分頁容器-sttabs">分頁容器 &lt;code>st.tabs()&lt;/code>&lt;/h5>
&lt;p>或者切出不同分頁，來放置不同種類的資料：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">tab1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">tab2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">tabs&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="s2">&amp;#34;Cat 介紹&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Dog 介紹&amp;#34;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="k">with&lt;/span> &lt;span class="n">tab1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">header&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;A cat&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">image&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;https://static.streamlit.io/examples/cat.jpg&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">200&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">with&lt;/span> &lt;span class="n">tab2&lt;/span>&lt;span class="p">:&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">header&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;A dog&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">image&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;https://static.streamlit.io/examples/dog.jpg&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">200&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/tabs.jpg" alt="不同分頁，放置不同種類的資料" data-caption="不同分頁，放置不同種類的資料" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
不同分頁，放置不同種類的資料
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;p>其他更多佈局和容器請參考：&lt;a href="https://docs.streamlit.io/library/api-reference/layout" target="_blank" rel="noopener">
官方文件 Layouts and Containers
&lt;/a>&lt;/p>
&lt;br/>
&lt;h3 id="狀態元件-status">狀態元件 Status&lt;/h3>
&lt;h5 id="進度條-stprogress">進度條 &lt;code>st.progress()&lt;/code>&lt;/h5>
&lt;p>使用 &lt;code>time.sleep()&lt;/code> 來模擬進度條的等待：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">bar&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">progress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">bar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">progress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="s1">&amp;#39;目前進度 {i+1} %&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">0.05&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">bar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">progress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;載入完成！&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>而且網頁右上角還會顯示&amp;quot;RUNNING&amp;hellip;&amp;quot;，並有多個運動圖示跳動，讓使用者知道目前網頁中還有東西正在運行。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/progress.jpg" alt="進度條載入時，網頁右上角 RUNNING... 字樣" data-caption="進度條載入時，網頁右上角 RUNNING... 字樣" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
進度條載入時，網頁右上角 RUNNING... 字樣
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h5 id="消息通知-sttoast">消息通知 &lt;code>st.toast()&lt;/code>&lt;/h5>
&lt;p>當有時候我們會需要跳出一個消息通知使用者，但並不想太干擾使用者，這時候就可以使用 &lt;code>st.toast()&lt;/code>：&lt;/p>
&lt;p>* 也可以為文字加上顏色，和加上 icon。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="k">if&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">button&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;儲存&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;primary&amp;#34;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">toast&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;:rainbow[你編輯的內容已經保存]&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">icon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;💾&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="c1"># 或是簡單點，只顯示文字&lt;/span>
&lt;span class="c1"># st.toast(&amp;#39;你編輯的內容已經保存&amp;#39;)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;h5 id="box-訊息-stsuccessstinfostwarningsterror">box 訊息 &lt;code>st.success()&lt;/code>、&lt;code>st.info()&lt;/code>、&lt;code>st.warning()&lt;/code>、&lt;code>st.error()&lt;/code>&lt;/h5>
&lt;p>或者想要在頁面上顯示較醒目的錯誤訊息：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">success&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Success!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Info!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">warning&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Warning!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Error!&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">icon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;🚨&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/toast_and_box.jpg" alt="box 訊息 和右下角的 toast 消息" data-caption="box 訊息 和右下角的 toast 消息" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='800px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:800px;height:;"/>
&lt;figcaption style="text-align: center;">
box 訊息 和右下角的 toast 消息
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h5 id="特效-stballoons-與-stsnow">特效 &lt;code>st.balloons()&lt;/code> 與 &lt;code>st.snow()&lt;/code>&lt;/h5>
&lt;p>還有看似無用，但真的好像無用(?)的特效，慶祝氣球 &lt;code>st.balloons()&lt;/code> 與慶祝降雪 &lt;code>st.snow()&lt;/code>：&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/balloons.jpg" alt="慶祝氣球特效" data-caption="慶祝氣球特效" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
慶祝氣球特效
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h3 id="聊天元件-chat">聊天元件 Chat&lt;/h3>
&lt;h5 id="聊天元件-stchat_message-與-stchat_input">聊天元件 &lt;code>st.chat_message()&lt;/code> 與 &lt;code>st.chat_input()&lt;/code>&lt;/h5>
&lt;p>最近因為 ChatGPT 之類的 LLM 熱門而新增的 &amp;quot;聊天元件&amp;quot; &lt;code>st.chat_message()&lt;/code>、&lt;code>st.chat_input()&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="k">with&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat_message&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;user&amp;#34;&lt;/span>&lt;span class="p">):&lt;/span> &lt;span class="c1"># 或者寫 &amp;#34;human&amp;#34;&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Hi 👋，請問你是誰？&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="c1"># 另一種寫法&lt;/span>
&lt;span class="n">message&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat_message&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;assistant&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># 或者寫 &amp;#34;ai&amp;#34;&lt;/span>
&lt;span class="c1"># message = st.chat_message(&amp;#34;assistant&amp;#34;, avatar=&amp;#34;🦖&amp;#34;) # 自訂頭像&lt;/span>
&lt;span class="n">message&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;你好！我是 ChatBot 🤖，可以回答各種問題，提供資訊。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">message&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;有什麼我可以幫助你的嗎？&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat_input&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Say something...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/chat_message.jpg" alt="因應最近 LLM 熱門而新增的聊天元件" data-caption="因應最近 LLM 熱門而新增的聊天元件" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
因應最近 LLM 熱門而新增的聊天元件
&lt;/figcaption>
&lt;/figure>
&lt;p>官方還特別寫兩篇教你如何搭建一個對話式的應用程式，甚至示範如何串接 OpenAI 的 GPT 模型，或透過 LangChain 串接：&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps" target="_blank" rel="noopener">
Build conversational apps
&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.streamlit.io/knowledge-base/tutorials/llm-quickstart" target="_blank" rel="noopener">
LLM quickstart
&lt;/a>&lt;/li>
&lt;/ul>
&lt;br/>
&lt;h3 id="表單元件">表單元件&lt;/h3>
&lt;h5 id="表單-stform">表單 &lt;code>st.form()&lt;/code>&lt;/h5>
&lt;p>經過上面的嘗試，我們都發現在 Streamlit 中，操作每個元件都會導致整個應用程式重新運行。&lt;/p>
&lt;p>但是，有時我們可能希望像表單那樣，全部填寫好後再一次觸發(提交)，這時候就可以使用 &lt;code>st.form()&lt;/code> 表單元件：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="k">with&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">form&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;my_form&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">form_name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text_input&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">label&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;姓名&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">placeholder&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;請輸入姓名&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">form_gender&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">selectbox&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;性別&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;男&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;女&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;其他&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">form_birthday&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">date_input&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;生日&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">submit_button&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">form_submit_button&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">label&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;Submit&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">if&lt;/span> &lt;span class="n">submit_button&lt;/span>&lt;span class="p">:&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="s1">&amp;#39;hello {form_name}, 性別:{form_gender}, 生日:{form_birthday}&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/form.png" alt="使用表單元件，一次一起提交" data-caption="使用表單元件，一次一起提交" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
使用表單元件，一次一起提交
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h3 id="使用快取-caching">使用快取 Caching&lt;/h3>
&lt;p>如同前面所述，只要元件輸入值有改變，整個程式(網頁)就會重新運行，但假如有較耗費時間、資源的運算，會造成使用者每調一個參數，就浪費時間在等待，或者產生的物件被重置。&lt;/p>
&lt;p>因此 Streamlit 內提供兩種快取(Caching)機制，將之前運算過的結果快取起來，如果下次遇到一樣的輸入值，就能直接使用之前的結果，節省時間，也有助於在重新運行時持久保存物件。&lt;/p>
&lt;p>這兩種快取機制以裝飾器(Decorator)寫法使用，用途區分如下：&lt;/p>
&lt;ol>
&lt;li>&lt;code>@st.cache_data&lt;/code>：計算後的結果、從 CSV 加載 DataFrame、查詢 API&amp;hellip;，大多情況都可以使用 &lt;code>@st.cache_data&lt;/code>。&lt;/li>
&lt;li>&lt;code>@st.cache_resource&lt;/code>：全域資源，例如 ML 模型或資料庫連接。&lt;/li>
&lt;/ol>
&lt;figure >
&lt;img data-src="https://docs.streamlit.io/images/caching-high-level-diagram.png" alt="Streamlit 提供兩種緩存(Caching)機制" data-caption="Streamlit 提供兩種緩存(Caching)機制" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='550px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:550px;height:;"/>
&lt;figcaption style="text-align: center;">
Streamlit 提供兩種緩存(Caching)機制
&lt;/figcaption>
&lt;/figure>
&lt;p>對於會變動的資料來源，建議可以設定 ttl (time to live)，例如設定 &lt;code>ttl=300&lt;/code>，則快取會在 3600 秒 (1小時) 後失效，並在重新運行函數時，再次執行、緩存快取。&lt;/p>
&lt;p>對於資料量太大造成記憶體可能不足問題，則可以設定 &lt;code>max_entries=1000&lt;/code> 來限制最大資料筆數。&lt;/p>
&lt;p>* 更多說明請參考官方文件：&lt;a href="https://docs.streamlit.io/library/advanced-features/caching" target="_blank" rel="noopener">
Caching
&lt;/a>&lt;/p>
&lt;br/>
&lt;p>要使用 &lt;code>@st.cache_data&lt;/code> 裝飾器，就需要將運算部分的程式碼包成函式(def)。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="nd">@st.cache_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ttl&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">3600&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">show_spinner&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;正在加載資料...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># 👈 Add the caching decorator&lt;/span>
&lt;span class="k">def&lt;/span> &lt;span class="nf">load_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">read_csv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">return&lt;/span> &lt;span class="n">df&lt;/span>
&lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">load_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;https://raw.githubusercontent.com/plotly/datasets/master/26k-consumer-complaints.csv&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dataframe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>第一次載入時會跑比較久(上面範例是讓它到網路上下載 csv 資料後顯示)，之後再重整網頁時，因為有快取的關係，它應該一瞬間就顯示出來了。&lt;/p>
&lt;br/>
&lt;p>如果想要清除快取再測試，可以從右上角的選單選擇 &amp;quot;Clear caches&amp;quot;：&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/clear_caches.jpg" alt="右上角選單 &amp;#34;Clear caches&amp;#34; 可以清除快取" data-caption="右上角選單 &amp;#34;Clear caches&amp;#34; 可以清除快取" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
右上角選單 &amp;#34;Clear caches&amp;#34; 可以清除快取
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h3 id="網頁配置設定">網頁配置設定&lt;/h3>
&lt;div class="alert alert-warning" role="alert" data-dir="ltr">網頁配置程式碼要寫在所有 Streamlit 命令之前，而且只能設定一次。&lt;/div>
&lt;p>此函式有五個參數：&lt;/p>
&lt;ul>
&lt;li>page_title：網頁標題，顯示在瀏覽器分頁的標籤上，預設是程式碼的檔名。&lt;/li>
&lt;li>page_icon：網頁圖標，顯示在網頁標題前，可以使用 &lt;code>st.image&lt;/code> 或 Emoji，或者使用&amp;quot;random&amp;quot;讓它隨機產生XD。&lt;/li>
&lt;li>layout：網頁中佈局寬度，預設是&amp;quot;centered&amp;quot;，還可以使用&amp;quot;wide&amp;quot;。&lt;/li>
&lt;li>initial_sidebar_state：側邊欄顯示狀態，&amp;quot;expanded&amp;quot;打開或&amp;quot;collapsed&amp;quot;隱藏，預設是&amp;quot;auto&amp;quot;，代表在手機尺寸的設備上是隱藏，否則是打開顯示。&lt;/li>
&lt;li>menu_items：右上角的菜單設定，共有以下三項可以設定：
&lt;ul>
&lt;li>&amp;ldquo;Get help&amp;rdquo;：設定 URL，如果沒有，則會隱藏此菜單選項。&lt;/li>
&lt;li>&amp;ldquo;Report a Bug&amp;rdquo;：設定 URL，如果沒有，則會隱藏此菜單選項。&lt;/li>
&lt;li>&amp;ldquo;About&amp;rdquo;：顯示在 &amp;quot;關於&amp;quot; 彈跳視窗中的 Markdown 字串，如果沒有，則僅顯示 Streamlit 預設的內容。&lt;/li>
&lt;li>URL 也可以設定為電子郵件地址，像是 &lt;code>mailto:john@example.com&lt;/code>。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>官方文件：&lt;a href="https://docs.streamlit.io/library/api-reference/utilities/st.set_page_config" target="_blank" rel="noopener">
st.set_page_config
&lt;/a>&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/web_page.png" alt="自訂網頁標題與 icon" data-caption="自訂網頁標題與 icon" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
自訂網頁標題與 icon
&lt;/figcaption>
&lt;/figure>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">set_page_config&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">page_title&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;自定義網頁標題&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">page_icon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;random&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">layout&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;centered&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">initial_sidebar_state&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;expanded&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">menu_items&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>
&lt;span class="s1">&amp;#39;Get Help&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;https://blog.jiatool.com/about/&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="s1">&amp;#39;About&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;# 這是什麼網頁？ &lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">**[IT空間](https://blog.jiatool.com/)** 示範 streamlit 之用網頁&amp;#34;&lt;/span>
&lt;span class="p">}&lt;/span>
&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;p>在網頁右上方選單，除了之前提過的 Rerun 和清除快取，還有網頁設定與螢幕錄影功能，將你的操作流程直接錄影起來，展示給其他人。&lt;/p>
&lt;p>而選單內的&amp;quot;設定&amp;quot;有幾個選項：&lt;/p>
&lt;ul>
&lt;li>Run on save：程式存檔後網頁自動重跑，不需要再手動點 Rerun&lt;/li>
&lt;li>Wide mode：佈局寬度調寬&lt;/li>
&lt;li>Theme：選擇或自訂佈景主題&lt;/li>
&lt;/ul>
&lt;p>* 自定義主題可參考&lt;a href="https://docs.streamlit.io/library/advanced-features/theming" target="_blank" rel="noopener">
官方介紹說明
&lt;/a>。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/settings.jpg" alt="右上角選單 &amp;#34;Settings&amp;#34; 網頁設定" data-caption="右上角選單 &amp;#34;Settings&amp;#34; 網頁設定" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
右上角選單 &amp;#34;Settings&amp;#34; 網頁設定
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h3 id="更多的元件工具">更多的元件、工具&lt;/h3>
&lt;p>Streamlit 還有提供更多的元件，和或者其他用途的工具：&lt;/p>
&lt;ul>
&lt;li>連接 &amp;quot;Database 資料庫&amp;quot; 或 &amp;quot;Web API&amp;quot; 取得資料：&lt;a href="https://docs.streamlit.io/library/advanced-features/connecting-to-data" target="_blank" rel="noopener">
Connecting to data
&lt;/a>&lt;/li>
&lt;li>設定主題顏色的配置：&lt;a href="https://docs.streamlit.io/library/advanced-features/theming" target="_blank" rel="noopener">
Theming
&lt;/a>&lt;/li>
&lt;li>做成多頁的應用：&lt;a href="https://docs.streamlit.io/library/get-started/multipage-apps" target="_blank" rel="noopener">
Multipage apps
&lt;/a>&lt;/li>
&lt;li>設定和取得瀏覽器網址列的查詢參數：&lt;a href="https://docs.streamlit.io/library/api-reference/utilities/st.experimental_set_query_params" target="_blank" rel="noopener">
st.experimental_set_query_params()
&lt;/a>、&lt;a href="https://docs.streamlit.io/library/api-reference/utilities/st.experimental_get_query_params" target="_blank" rel="noopener">
st.experimental_get_query_params()
&lt;/a>&lt;/li>
&lt;li>託管靜態文件服務：&lt;a href="https://docs.streamlit.io/library/advanced-features/static-file-serving" target="_blank" rel="noopener">
Static file serving
&lt;/a>&lt;/li>
&lt;li>更多更多元件：&lt;a href="https://docs.streamlit.io/library/api-reference" target="_blank" rel="noopener">
API reference
&lt;/a>&lt;/li>
&lt;/ul>
&lt;br/>
&lt;p>官方有將 streamlit 可以下的指令、各式元件的寫法濃縮整理成一頁，方便快速查閱：&lt;a href="https://cheat-sheet.streamlit.app/">https://cheat-sheet.streamlit.app/&lt;/a>&lt;/p>
&lt;br/>
&lt;h2 id="部署應用程式">部署應用程式&lt;/h2>
&lt;p>除了將程式在自己的電腦執行，或架在伺服器之外，官方有提供「&lt;a href="https://streamlit.io/cloud" target="_blank" rel="noopener">
Streamlit Community Cloud
&lt;/a>」，可以在上面部署、管理、共享你的 Streamlit 應用程式。你只要將專案上傳自己的 GitHub 存儲庫(公開或私有都可以)，再到 Streamlit Community Cloud 設定連接即可，算是蠻方便的。&lt;/p>
&lt;p>* 關於 Streamlit Community Cloud 官方說明可在這邊查看：&lt;a href="https://docs.streamlit.io/streamlit-community-cloud" target="_blank" rel="noopener">
Welcome to Streamlit Community Cloud
&lt;/a>&lt;/p>
&lt;br/>
&lt;p>完整部署介紹請參考&lt;a href="https://docs.streamlit.io/streamlit-community-cloud/deploy-your-app" target="_blank" rel="noopener">
官方說明
&lt;/a>，只需要四個步驟：&lt;/p>
&lt;ol>
&lt;li>先確認你的資料夾內有程式執行需要的&lt;a href="https://docs.streamlit.io/streamlit-community-cloud/deploy-your-app/app-dependencies" target="_blank" rel="noopener">
依賴套件文件
&lt;/a>：
&lt;ul>
&lt;li>Python 依賴文件 [必要]：&lt;code>requirements.txt&lt;/code>、&lt;code>Pipfile&lt;/code>、&lt;code>environment.yml&lt;/code>、&lt;code>pyproject.toml&lt;/code> 這幾種擇一，指定程式需要哪些 Python 套件。&lt;/li>
&lt;li>apt-get 依賴 [非必要]：需要哪些 apt-get 的依賴套件。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>將專案推到自己的 GitHub (公開或私有都可以)。&lt;/li>
&lt;li>前往 &lt;a href="https://share.streamlit.io/" target="_blank" rel="noopener">
share.streamlit.io
&lt;/a> 工作區，連接你剛剛上傳的 GitHub 存儲庫。&lt;/li>
&lt;li>部署完成！！&lt;/li>
&lt;/ol>
&lt;br/>
&lt;p>推上 GitHub 的專案資料夾內大致會長這樣：&lt;/p>
&lt;pre>&lt;code>your-repository/
├── streamlit_app.py
└── requirements.txt
&lt;/code>&lt;/pre>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/github_repository.jpg" alt="推上 GitHub Repository" data-caption="推上 GitHub Repository" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='850px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:850px;height:;"/>
&lt;figcaption style="text-align: center;">
推上 GitHub Repository
&lt;/figcaption>
&lt;/figure>
&lt;p>前往 &lt;a href="https://share.streamlit.io/" target="_blank" rel="noopener">
share.streamlit.io
&lt;/a> 工作區，連接你剛剛上傳的 GitHub 存儲庫。&lt;/p>
&lt;p>點擊右上角 &amp;quot;New app&amp;quot;&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/new_app.jpg" alt="右上角 &amp;#34;New app&amp;#34;" data-caption="右上角 &amp;#34;New app&amp;#34;" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
右上角 &amp;#34;New app&amp;#34;
&lt;/figcaption>
&lt;/figure>
&lt;p>第一次需要給 Streamlit 擁有讀取 GitHub Repository 的權限：&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/github_permission.jpg" alt="第一次需要給 Streamlit 讀取 GitHub 權限" data-caption="第一次需要給 Streamlit 讀取 GitHub 權限" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
第一次需要給 Streamlit 讀取 GitHub 權限
&lt;/figcaption>
&lt;/figure>
&lt;p>下一步，指定 GitHub Repository、分支、程式檔案名稱，以及是否要自訂網址名稱(你可以為你的應用程式自訂一個獨一無二的名稱)：&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/deploy_setting.jpg" alt="部署設定" data-caption="部署設定" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
部署設定
&lt;/figcaption>
&lt;/figure>
&lt;p>下方還可以打開 &amp;quot;Advanced settings&amp;hellip;&amp;quot;，這邊可以更改 Python 版本、設定環境變數。&lt;br />
我們這個範例不需要編輯這邊。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/advanced_settings.jpg" alt="部署進階設定" data-caption="部署進階設定" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
部署進階設定
&lt;/figcaption>
&lt;/figure>
&lt;p>點擊 &amp;quot;Deploy!&amp;quot;，等個一、兩分鐘安裝。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/deploying.jpg" alt="部署中..." data-caption="部署中..." src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='800px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:800px;height:;"/>
&lt;figcaption style="text-align: center;">
部署中...
&lt;/figcaption>
&lt;/figure>
&lt;p>部署完成，網址列上顯示的就是你這個應用程式的專屬網址，把它分享給其他人炫耀你努力的成果吧~🎉&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/deploy_completed.jpg" alt="部署完成" data-caption="部署完成" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
部署完成
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;br/>
&lt;p>前往 &lt;a href="https://share.streamlit.io/" target="_blank" rel="noopener">
share.streamlit.io
&lt;/a> 工作區，可以查看你全部的 Streamlit 應用程式，它還提供統計來訪人數的功能。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/your_apps.jpg" alt="share.streamlit.io 工作區" data-caption="share.streamlit.io 工作區" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='850px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:850px;height:;"/>
&lt;figcaption style="text-align: center;">
share.streamlit.io 工作區
&lt;/figcaption>
&lt;/figure>
&lt;p>來看看我 2021 年發布的 &lt;a href="https://it-jia-streamlit-demo-streamlit-app-t4el3t.streamlit.app/" target="_blank" rel="noopener">
Demo
&lt;/a> 範例，共有 1,522 名讀者來訪~ (而且是計算不重複的)&lt;br />
* 這個統計功能是從 2022 年 4 月才開始，所以實際上會再更多。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit_2023/analytics.jpg" alt="統計來訪人數" data-caption="統計來訪人數" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
統計來訪人數
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h2 id="完整範例程式碼">完整範例程式碼&lt;/h2>
&lt;p>附上完整範例程式碼：&lt;a href="https://github.com/it-jia/streamlit_2023_demo/blob/main/streamlit_app.py" target="_blank" rel="noopener">
streamlit_app.py
&lt;/a>&lt;/p>
&lt;p>此範例程式碼部署在 Streamlit Cloud (share.streamlit.io) 的 Demo：&lt;/p>
&lt;div class="alert alert-info" role="alert" data-dir="ltr">Streamlit 成果範例：&lt;a href="https://jiatool-demo.streamlit.app/">streamlit_2023_demo&lt;/a>&lt;/div>
&lt;br/>
&lt;!--adsense-->
&lt;h2 id="結語">結語&lt;/h2>
&lt;p>從之前第一次嘗試 Streamlit 到現在過了兩年多，它又陸續新增了不少功能，看起來還有積極再發展。&lt;/p>
&lt;p>經過上方教學實際操作後，會發覺這個套件真的可以很簡單、快速的建立一個顯示資料用的儀表板(Dashboard)，因此特別寫這篇文章來分享給大家~&lt;/p>
&lt;br/>
&lt;br/>
&lt;hr />
&lt;p>參考：&lt;br />
&lt;a href="https://streamlit.io/" target="_blank" rel="noopener">
Streamlit 官方網站
&lt;/a>&lt;br />
&lt;a href="https://docs.streamlit.io/" target="_blank" rel="noopener">
Streamlit 官方文檔
&lt;/a>&lt;/p>
&lt;br/>
&lt;blockquote>
&lt;p>每一個你討厭的現在，&lt;br />
都有一個不夠努力的曾經。&lt;/p>
&lt;p align="right">—— 幾米 (台灣繪本作家)&lt;/p>
&lt;/blockquote></content:encoded><dc:creator>Jia</dc:creator><media:content url="https://blog.jiatool.comimages/cover/streamlit_2023.jpg" medium="image"><media:title type="html">featured image</media:title></media:content><media:content url="https://blog.jiatool.comimages/posts/streamlit_2023_meta.jpg" medium="image"><media:title type="html">meta image</media:title></media:content><category>Python</category><category>Streamlit</category><category>Dashboard</category><category>套件</category><category>分享</category><category>Python套件</category></item><item><title>Streamlit 超快速又輕鬆建立網頁 Dashboard</title><link>https://blog.jiatool.com/posts/streamlit/</link><pubDate>Sun, 23 May 2021 20:50:00 +0800</pubDate><author>jia@jiatool.com (Jia)</author><atom:modified>Wed, 06 Oct 2021 09:40:00 +0800</atom:modified><guid>https://blog.jiatool.com/posts/streamlit/</guid><description>前言 後來時隔兩年，我有整理更新的版本，請改去這邊： (2023年新版) 使用 Streamlit 快速又輕鬆建立 Dashboard 網頁 Streamlit 是個可快速製作出 Web 網頁應用程式的套件，而且不</description><content:encoded>&lt;h2 id="前言">前言&lt;/h2>
&lt;p>後來時隔兩年，我有整理更新的版本，請改去這邊：&lt;br />
&lt;a href="https://blog.jiatool.com/posts/streamlit_2023" target="_blank" rel="noopener">
(2023年新版) 使用 Streamlit 快速又輕鬆建立 Dashboard 網頁
&lt;/a>&lt;/p>
&lt;br/>
&lt;br/>
&lt;p>Streamlit 是個可快速製作出 Web 網頁應用程式的套件，而且不需要任何前端技術，全部都採用 Python 語法，讓你將網路爬蟲、數據科學、機器學習資料簡單地呈現出來分享，是一個很方便的套件。&lt;/p>
&lt;h2 id="demo">Demo&lt;/h2>
&lt;p>這是最後將程式碼放到 GitHub，並使用 Streamlit 部署的成果。&lt;/p>
&lt;div class="alert alert-info" role="alert" data-dir="ltr">Streamlit 成果範例：&lt;a href="https://share.streamlit.io/it-jia/streamlit_demo/streamlit_app.py">streamlit_demo&lt;/a>&lt;/div>
&lt;br/>
&lt;!--adsense-->
&lt;h2 id="安裝與執行">安裝與執行&lt;/h2>
&lt;ul>
&lt;li>Streamlit [&lt;a href="https://streamlit.io/" target="_blank" rel="noopener">
官方網站
&lt;/a>] [&lt;a href="https://docs.streamlit.io/en/stable/" target="_blank" rel="noopener">
官方文檔
&lt;/a>]&lt;/li>
&lt;/ul>
&lt;p>安裝&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">pip install streamlit
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>執行&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">streamlit run &amp;lt;py程式檔案路徑&amp;gt;
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>如果想指定 Streamlit 的 port 埠號，只要在後方加上&lt;code>--server.port&lt;/code> 參數：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">streamlit run &amp;lt;py程式檔案路徑&amp;gt; --server.port &lt;span class="m">8888&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>需要終止該應用程式只需在終端中按 &lt;strong>Ctrl + c&lt;/strong>。&lt;/p>
&lt;h2 id="範例教學">範例教學&lt;/h2>
&lt;p>底下流程是參考&lt;a href="https://docs.streamlit.io/en/stable/" target="_blank" rel="noopener">
官方文檔
&lt;/a>的流程操作。&lt;/p>
&lt;h3 id="創建一個-streamlit-應用程式">創建一個 Streamlit 應用程式&lt;/h3>
&lt;p>新創建一個 Python 檔案 &lt;code>streamlit_app.py&lt;/code>，以下教學都只會編輯這個檔案。&lt;/p>
&lt;p>打開它，在一開始導入 Streamlit 與其他套件：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="kn">import&lt;/span> &lt;span class="nn">time&lt;/span>
&lt;span class="kn">import&lt;/span> &lt;span class="nn">streamlit&lt;/span> &lt;span class="kn">as&lt;/span> &lt;span class="nn">st&lt;/span>
&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="kn">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="kn">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>打開&amp;quot;命令提示字元&amp;quot;或&amp;quot;終端機&amp;quot;，開始執行程式：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Shell" data-lang="Shell">streamlit run streamlit_app.py
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>它應該會顯示如下資訊，並自動開啟一個瀏覽器網頁。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/run_streamlit.png" alt="執行 Streamlit 程式" data-caption="執行 Streamlit 程式" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
執行 Streamlit 程式
&lt;/figcaption>
&lt;/figure>
&lt;p>然後網頁裡面顯示&amp;hellip; 一片空白？！&lt;br />
沒錯！我們又還沒有添加元件進去，怎麼會有東西呢~ 😆&lt;/p>
&lt;h3 id="添加文字和數據">添加文字和數據&lt;/h3>
&lt;p>先幫我們的應用程式加上個標題，加入以下程式碼：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">title&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;我的第一個應用程式&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>存檔，回到瀏覽器的網頁上。&lt;br />
可以重整網頁，或點擊右上角&amp;quot;Rerun&amp;quot;的按鈕，&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/rerun.png" alt="網頁重跑" data-caption="網頁重跑" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
網頁重跑
&lt;/figcaption>
&lt;/figure>
&lt;p>網頁上就會顯示一個標題文字了：&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/first_title.png" alt="加入標題" data-caption="加入標題" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
加入標題
&lt;/figcaption>
&lt;/figure>
&lt;p>如何？簡單吧，那我們再繼續接著下去~&lt;/p>
&lt;h3 id="使用-magic-commands">使用 Magic Commands&lt;/h3>
&lt;p>在 Streamlit 內有個神奇的指令，他們把它叫 &lt;a href="https://docs.streamlit.io/en/stable/api.html#magic-commands" target="_blank" rel="noopener">
Magic commands
&lt;/a>，不管你給它&amp;quot;字串&amp;quot;、&amp;quot;Markdown&amp;quot;、&amp;quot;數據資料&amp;quot;、&amp;quot;Matplotlib figures&amp;quot;、&amp;quot;Altair charts&amp;quot;，Streamlit 都會辨別並以合適的方式顯示出來。&lt;/p>
&lt;p>甚至在程式碼中單一行只有變數或字串，根本不需要使用 st.write()，它都會自動套用並顯示。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;嘗試創建**表格**：&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">({&lt;/span>
&lt;span class="s1">&amp;#39;first column&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">],&lt;/span>
&lt;span class="s1">&amp;#39;second column&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">20&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">30&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">40&lt;/span>&lt;span class="p">]&lt;/span>
&lt;span class="p">})&lt;/span>
&lt;span class="n">df&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/magic_commands.jpg" alt="Markdown 與 表格" data-caption="Markdown 與 表格" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
Markdown 與 表格
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="繪製圖表和地圖">繪製圖表和地圖&lt;/h3>
&lt;p>&lt;strong>繪製折線圖&lt;/strong>&lt;br />
使用 Numpy 生成一個隨機樣本，然後將其繪製成圖表。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">chart_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">20&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">),&lt;/span>
&lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;a&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;b&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;c&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">line_chart&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chart_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>而且它本身有下載、全螢幕觀看等功能。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/line_chart.jpg" alt="繪製折線圖" data-caption="繪製折線圖" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
繪製折線圖
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;p>&lt;strong>繪製地圖&lt;/strong>&lt;br />
使用 Numpy 生成一個隨機樣本，繪製到地圖上。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">map_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mf">22.7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">120.3&lt;/span>&lt;span class="p">],&lt;/span>
&lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;lat&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;lon&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">map_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/map.jpg" alt="繪製地圖" data-caption="繪製地圖" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
繪製地圖
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="加入小工具">加入小工具&lt;/h3>
&lt;p>除了上述標題、圖表，還有其他小工具，像是複選框、選擇框、按鈕、滑塊等等。&lt;/p>
&lt;p>使用複選框來顯示/隱藏數據，例如在剛剛繪製地圖的程式上方加入：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="k">if&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">checkbox&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;顯示地圖圖表&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">map_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">random&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">randn&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mf">22.7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">120.3&lt;/span>&lt;span class="p">],&lt;/span>
&lt;span class="n">columns&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;lat&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;lon&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">map_data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>但你可能會注意到，每次點擊複選框時，上方的折線圖也會產生變化。&lt;br />
這是因為 Streamlit 只要元件有輸入值的改變，整個程式(網頁)就會重新運行，因此折線圖裡的 random 才會出來不同資料。&lt;/p>
&lt;br/>
&lt;p>使用選擇框進行選擇：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">option&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">selectbox&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="s1">&amp;#39;你喜歡哪種動物？&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;狗&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;貓&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;鸚鵡&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;天竺鼠&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="s1">&amp;#39;你的答案：&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">option&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/checkbox_selectbox.png" alt="複選框 與 選擇框" data-caption="複選框 與 選擇框" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
複選框 與 選擇框
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="調整佈局">調整佈局&lt;/h3>
&lt;p>我們也能將元件移到側邊欄中，這邊範例將上方選擇框移入側邊欄：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">option&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sidebar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">selectbox&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="s1">&amp;#39;你喜歡哪種動物？&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;狗&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;貓&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;鸚鵡&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;天竺鼠&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;span class="s1">&amp;#39;你的答案：&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">option&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/sidebar.jpg" alt="將元件移到側邊欄" data-caption="將元件移到側邊欄" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='750px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:750px;height:;"/>
&lt;figcaption style="text-align: center;">
將元件移到側邊欄
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;p>也有左右兩邊的方式來排列：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">left_column&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">right_column&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">beta_columns&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">left_column&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;這是左邊欄位。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">right_column&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;這是右邊欄位。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;br/>
&lt;p>或通過 st.beta_expander 來隱藏大量內容來節省空間。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">expander&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">beta_expander&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;點擊來展開...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">expander&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;如果你要顯示很多文字，但又不想佔大半空間，可以使用這種方式。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/expander.png" alt="將內容摺疊起來" data-caption="將內容摺疊起來" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
將內容摺疊起來
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="加入進度條">加入進度條&lt;/h3>
&lt;p>這邊使用 &lt;code>time.sleep()&lt;/code> 來模擬進度：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="c1"># 增加一個空白元件，等等要放文字&lt;/span>
&lt;span class="n">latest_iteration&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">empty&lt;/span>&lt;span class="p">()&lt;/span>
&lt;span class="n">bar&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">progress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">latest_iteration&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="s1">&amp;#39;目前進度 {i+1} %&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">bar&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">progress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">0.1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>而且網頁右上角還會顯示&amp;quot;RUNNING&amp;hellip;&amp;quot;，並有多個運動圖示跳動，讓使用者知道目前網頁中還有東西正在運行。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/running.png" alt="網頁 RUNNING... 字樣" data-caption="網頁 RUNNING... 字樣" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='400px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:400px;height:;"/>
&lt;figcaption style="text-align: center;">
網頁 RUNNING... 字樣
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="使用快取">使用快取&lt;/h3>
&lt;p>如同前面所述，只要元件輸入值有改變，整個程式(網頁)就會重新運行，但假如有較耗費時間、資源的運算，會造成使用者每調一個參數，就浪費時間在等。&lt;/p>
&lt;p>因此 Streamlit 內提供一個緩存機制，可以使用 &lt;code>@st.cache&lt;/code> 裝飾器，將之前運算過的結果快取起來，如果下次遇到一樣的輸入值，就能直接使用之前的結果，節省時間。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.streamlit.io/en/stable/caching.html" target="_blank" rel="noopener">
官方說明 Improve app performance
&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>要使用 &lt;code>@st.cache&lt;/code> 裝飾器，就需要將運算部分的程式碼包成函式(def)。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="nd">@st.cache&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">suppress_st_warning&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="bp">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">def&lt;/span> &lt;span class="nf">expensive_computation&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">):&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="s2">&amp;#34;沒有快取：expensive_computation({a})&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">time&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">slider&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;選擇一個數字&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">expensive_computation&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span>
&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;結果：&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/cache.png" alt="cache 快取" data-caption="cache 快取" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
cache 快取
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="網頁配置設定">網頁配置設定&lt;/h3>
&lt;p>要寫在程式內所有 Streamlit 命令之前，而且只能設定一次。&lt;/p>
&lt;p>此函式有四個參數：&lt;/p>
&lt;ul>
&lt;li>page_title：網頁標題，顯示在瀏覽器分頁的標籤上，預設是程式碼的檔名。&lt;/li>
&lt;li>page_icon：網頁圖標，顯示在網頁標題前，可以使用 &lt;code>st.image&lt;/code> 或 Emoji，或者使用&amp;quot;random&amp;quot;讓它隨機產生XD。&lt;/li>
&lt;li>layout：網頁中佈局寬度，預設是&amp;quot;centered&amp;quot;，還可以使用&amp;quot;wide&amp;quot;。&lt;/li>
&lt;li>initial_sidebar_state：側邊欄顯示狀態，&amp;quot;expanded&amp;quot;打開或&amp;quot;collapsed&amp;quot;隱藏，預設是&amp;quot;auto&amp;quot;，代表在手機尺寸的設備上是隱藏，否則是打開顯示。&lt;/li>
&lt;/ul>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/web_page.png" alt="網頁標題與 icon" data-caption="網頁標題與 icon" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='600px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:600px;height:;"/>
&lt;figcaption style="text-align: center;">
網頁標題與 icon
&lt;/figcaption>
&lt;/figure>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre class="chroma">&lt;code class="language-Python" data-lang="Python">&lt;span class="n">st&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">set_page_config&lt;/span>&lt;span class="p">(&lt;/span>
&lt;span class="n">page_title&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;自定義網頁標題&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">page_icon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;random&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">layout&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;centered&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="n">initial_sidebar_state&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;collapsed&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;span class="p">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="網頁選單設定">網頁選單設定&lt;/h3>
&lt;p>在網頁右上方有個選單，包含之前提過的 Rerun，以及清除快取、連結到官方文件論壇，甚至還有螢幕錄影功能，將你的操作流程直接錄影起來，展示給其他人。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/menu.jpg" alt="網頁選單" data-caption="網頁選單" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='400px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:400px;height:;"/>
&lt;figcaption style="text-align: center;">
網頁選單
&lt;/figcaption>
&lt;/figure>
&lt;p>而選單內的&amp;quot;設定&amp;quot;有幾個選項：&lt;/p>
&lt;ul>
&lt;li>Run on save：程式存檔後網頁自動重跑，不需要再手動點 Rerun&lt;/li>
&lt;li>Wide mode：佈局寬度調寬&lt;/li>
&lt;li>Theme：佈景主題&lt;/li>
&lt;/ul>
&lt;p>* 自定義主題可參考&lt;a href="https://blog.streamlit.io/introducing-theming/" target="_blank" rel="noopener">
官方介紹說明
&lt;/a>。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/streamlit/settings.jpg" alt="網頁設定" data-caption="網頁設定" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
網頁設定
&lt;/figcaption>
&lt;/figure>
&lt;h3 id="部署應用程式">部署應用程式&lt;/h3>
&lt;p>官方提供一種方式部署，只需要將你的 Streamlit 應用程式放在 GitHub 上，即可登入 share.streamlit.io 去部署運行起來。&lt;/p>
&lt;p>完整部署介紹請參考&lt;a href="https://docs.streamlit.io/en/stable/deploy_streamlit_app.html" target="_blank" rel="noopener">
官方說明
&lt;/a>：&lt;/p>
&lt;ol>
&lt;li>先確認你的資料夾內有 &lt;a href="https://docs.streamlit.io/en/stable/deploy_streamlit_app.html#python-dependencies" target="_blank" rel="noopener">
Python 依賴文件
&lt;/a>，例如 &lt;code>requirements.txt&lt;/code>、&lt;code>Pipfile&lt;/code>、&lt;code>pyproject.toml&lt;/code>、&lt;code>environment.yml&lt;/code> 這幾種，或者還有 &lt;a href="https://docs.streamlit.io/en/stable/deploy_streamlit_app.html#apt-get-dependencies" target="_blank" rel="noopener">
apt-get 依賴
&lt;/a>。&lt;/li>
&lt;li>將你的 Streamlit 應用程式推到自己的 GitHub 公開 Repository。&lt;/li>
&lt;li>前往&lt;a href="https://streamlit.io/" target="_blank" rel="noopener">
官網
&lt;/a>註冊登入，並到 &lt;a href="https://streamlit.io/sharing-sign-up" target="_blank" rel="noopener">
Get an invite to Streamlit sharing
&lt;/a> 設定。&lt;/li>
&lt;li>打開網址、查看結果~&lt;/li>
&lt;/ol>
&lt;p>註冊 Streamlit sharing 後要等到邀請的 Email 回信，我的經驗是等了一天。&lt;/p>
&lt;br/>
&lt;p>&lt;strong>應用程式網址格式&lt;/strong>&lt;/p>
&lt;p>你的網址格式為：&lt;br />
&lt;code>https://share.streamlit.io/[user name]/[repo name]/[branch name]/[app path]&lt;/code>&lt;br />
例如我上面的範例是：&lt;br />
&lt;code>https://share.streamlit.io/it-jia/streamlit_demo/master/streamlit_app.py&lt;/code>&lt;/p>
&lt;p>而如果你 Git 分支是 &lt;code>master&lt;/code>，或應用程式檔案名稱為 &lt;code>streamlit_app.py&lt;/code>，甚至可以簡化成：&lt;br />
&lt;code>https://share.streamlit.io/[user name]/[repo name]&lt;/code>&lt;br />
我的範例簡化成：&lt;br />
&lt;code>https://share.streamlit.io/it-jia/streamlit_demo&lt;/code>&lt;/p>
&lt;br/>
&lt;!--adsense-->
&lt;h2 id="完整範例程式碼">完整範例程式碼&lt;/h2>
&lt;p>附上完整範例程式碼：&lt;a href="https://github.com/it-jia/streamlit_demo/blob/master/streamlit_app.py" target="_blank" rel="noopener">
streamlit_app.py
&lt;/a>&lt;/p>
&lt;p>此範例程式碼部署在 share.streamlit.io 的 Demo：&lt;/p>
&lt;div class="alert alert-info" role="alert" data-dir="ltr">Streamlit 成果範例：&lt;a href="https://share.streamlit.io/it-jia/streamlit_demo/streamlit_app.py">streamlit_demo&lt;/a>&lt;/div>
&lt;h2 id="結語">結語&lt;/h2>
&lt;p>實際安裝使用後，發現這個套件真的可以很容易、快速的建立一個顯示資料用的儀表板(Dashboard)，因此寫這篇文章來分享給大家~&lt;/p>
&lt;p>官方有將 API 濃縮成一頁，方便快速尋找：&lt;br />
&lt;a href="https://share.streamlit.io/daniellewisdl/streamlit-cheat-sheet/app.py">https://share.streamlit.io/daniellewisdl/streamlit-cheat-sheet/app.py&lt;/a>&lt;/p>
&lt;br/>
&lt;br/>
&lt;hr />
&lt;p>參考：&lt;br />
&lt;a href="https://streamlit.io/" target="_blank" rel="noopener">
Streamlit 官方網站
&lt;/a>&lt;br />
&lt;a href="https://docs.streamlit.io/en/stable/" target="_blank" rel="noopener">
Streamlit 官方文檔
&lt;/a>&lt;br />
&lt;a href="https://neutron0916.medium.com/c433e1da1559" target="_blank" rel="noopener">
Streamlit極簡易的Dashboard開發 - Neutron
&lt;/a>&lt;br />
&lt;a href="https://officeguide.cc/python-streamlit-build-web-data-analysis-app-tutorial-examples/" target="_blank" rel="noopener">
Python 以 Streamlit 建立網頁資料分析應用程式教學與範例 - Office指南
&lt;/a>&lt;/p>
&lt;br/>
&lt;blockquote>
&lt;p>選擇，比努力更重要。&lt;/p>
&lt;/blockquote></content:encoded><dc:creator>Jia</dc:creator><media:content url="https://blog.jiatool.comimages/cover/streamlit.jpg" medium="image"><media:title type="html">featured image</media:title></media:content><media:content url="https://blog.jiatool.comimages/posts/streamlit_meta.jpg" medium="image"><media:title type="html">meta image</media:title></media:content><category>Python</category><category>Streamlit</category><category>Dashboard</category><category>套件</category><category>分享</category><category>Python套件</category></item></channel></rss>