plotly/dash
と比較されることが多いjavascript
不要、スクリプトライクな記述matplotlib
, plotly
, altair
, ...pip install streamlit
%%writefile app.py
import streamlit as st
st.write("# Hello, Streamlit!")
Overwriting app.py
!streamlit run app.py
You can now view your Streamlit app in your browser. Network URL: http://172.17.0.2:8501 External URL: http://49.251.189.62:8501 ^C Stopping...
streamlit
コマンドを実行Rerun
ボタンを自動表示%%writefile app.py
import streamlit as st
st.write("# Hello, Streamlit!")
st.write("# Where is Rerun button?")
Overwriting app.py
%%writefile app.py
import streamlit as st
st.write("# Hello, Streamlit!")
raise ValueError
Overwriting app.py
st.write
¶%%writefile app.py
import numpy as np
import pandas as pd
import streamlit as st
st.write([1, 2, 3])
st.write({"hello": "world!"})
st.write(np.arange(10).reshape(1,10))
st.write(pd.DataFrame(np.random.randn(10, 4), columns=["1", "2", "3", "4"]))
Overwriting app.py
master
heroku
espnet2
Steramlit
のバージョンは0.66.0streamlit run https://github.com/user/repos.git/master/app.py
scipy.signal
を使用Streamlit
によるアプリ構築をライブコーディング的に実施selectbox
で表示st.sidebar.xxx
st.xxx
と本体に配置できるウィジェットは何でも配置可能st.selectbox
¶st.selectbox(ラベル名, 選択肢のリスト, デフォルト項目のインデックス)
%%writefile app.py
import streamlit as st
windows = ["boxcar", "triang", "blackman", "hamming", "hann", "bartlett", "flattop",
"parzen", "bohman", "blackmanharris", "nuttall", "barthann"]
Overwriting app.py
%%writefile -a app.py
でapp.py
に追記%%writefile -a app.py
win_name = st.sidebar.selectbox("window", windows, 4)
st.write(win_name)
Appending to app.py
st.selectbox
で2の累乗の値を取得%%writefile -a app.py
two_powers = [2**i for i in range(16)]
Nx = st.sidebar.selectbox("Window Length", two_powers, 8)
nfft = st.sidebar.selectbox("FFT Length", two_powers, 10)
st.write(win_name, Nx, nfft)
Appending to app.py
scipy.signal.get_window
scipy.fft.fft
で周波数分析%%writefile -a app.py
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as sg
import scipy.fft as fft
Appending to app.py
%%writefile -a app.py
eps = 1.e-12
win = sg.get_window(win_name, Nx)
W = 20.0 * np.log10(np.abs(fft.fft(win, nfft)) + eps)
W = fft.fftshift(W)
Appending to app.py
matplotlib
を用いて描画%%writefile -a app.py
fig, axes = plt.subplots(2, 1)
axes[0].plot(win)
axes[1].plot(W)
st.pyplot(fig)
Appending to app.py
st.pyplot
¶matplotlib
のfigureを描画st.pyplot(fig)
streamlit
の描画ライブラリ¶st.line_chart
, st.area_chart
, st.bar_chart
st.altair_chart
のsyntax sugarvega
, plotly
, bokeh
なども使用可能%%writefile -a app.py
st.line_chart(win)
st.line_chart(W)
Appending to app.py
st.line_chart
の見た目!cat app.py | pygmentize
import streamlit as st windows = ["boxcar", "triang", "blackman", "hamming", "hann", "bartlett", "flattop", "parzen", "bohman", "blackmanharris", "nuttall", "barthann"] win_name = st.sidebar.selectbox("window", windows, 4) st.write(win_name) two_powers = [2**i for i in range(16)] Nx = st.sidebar.selectbox("Window Length", two_powers, 8) nfft = st.sidebar.selectbox("FFT Length", two_powers, 10) st.write(win_name, Nx, nfft) import matplotlib.pyplot as plt import numpy as np import scipy.signal as sg import scipy.fft as fft eps = 1.e-12 win = sg.get_window(win_name, Nx) W = 20.0 * np.log10(np.abs(fft.fft(win, nfft)) + eps) W = fft.fftshift(W) fig, axes = plt.subplots(2, 1) axes[0].plot(win) axes[1].plot(W) st.pyplot(fig) st.line_chart(win) st.line_chart(W)
st.multiselect(ラベル名, 選択肢のリスト, デフォルト項目の要素のリスト)
%%writefile app.py
import streamlit as st
windows = ["boxcar", "triang", "blackman", "hamming", "hann", "bartlett", "flattop",
"parzen", "bohman", "blackmanharris", "nuttall", "barthann"]
Overwriting app.py
%%writefile -a app.py
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as sg
import scipy.fft as fft
Appending to app.py
st.multiselect
を使用%%writefile -a app.py
# ここから先が異なる
win_names = st.sidebar.multiselect("window", windows, [windows[4]])
st.write(win_names)
Appending to app.py
win_names
をst.write
する以外は同じ%%writefile -a app.py
two_powers = [2**i for i in range(16)]
Nx = st.sidebar.selectbox("Window Length", two_powers, 8)
nfft = st.sidebar.selectbox("FFT Length", two_powers, 10)
st.write(win_names, Nx, nfft)
Appending to app.py
win_names
をループで処理%%writefile -a app.py
eps = 1.e-12
for win_name in win_names: # ループとして処理
win = sg.get_window(win_name, Nx)
W = 20.0 * np.log10(np.abs(fft.fft(win, nfft)) + eps)
W = fft.fftshift(W)
Appending to app.py
%%writefile -a app.py
# ループの続き
st.write(win_name)
st.line_chart(win)
st.line_chart(W)
Appending to app.py
st.line_chart
に渡す%%writefile app.py
import streamlit as st
windows = ["boxcar", "triang", "blackman", "hamming", "hann", "bartlett", "flattop",
"parzen", "bohman", "blackmanharris", "nuttall", "barthann"]
Overwriting app.py
%%writefile -a app.py
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as sg
import scipy.fft as fft
import pandas as pd # 追加
Appending to app.py
%%writefile -a app.py
win_names = st.sidebar.multiselect("window", windows, [windows[4]])
st.write(win_names)
Appending to app.py
%%writefile -a app.py
two_powers = [2**i for i in range(16)]
Nx = st.sidebar.selectbox("Window Length", two_powers, 8)
nfft = st.sidebar.selectbox("FFT Length", two_powers, 10)
st.write(win_names, Nx, nfft)
Appending to app.py
%%writefile -a app.py
eps = 1.e-12
win_ary = []; W_ary = []
for win_name in win_names: # ループとして処理
win = sg.get_window(win_name, Nx)
W = 20.0 * np.log10(np.abs(fft.fft(win, nfft)) + eps)
W = fft.fftshift(W)
win_ary.append(win)
W_ary.append(W)
Appending to app.py
%%writefile -a app.py
fs = 16000.0
t = np.arange(Nx)
f = (fs / nfft) * np.arange(-nfft/2, nfft/2)
df_win = pd.DataFrame(np.array(win_ary).T, index=t, columns=win_names)
df_W = pd.DataFrame(np.array(W_ary).T, index=f, columns=win_names)
Appending to app.py
%%writefile -a app.py
st.line_chart(df_win)
st.line_chart(df_W)
Appending to app.py
st.selectbox
, st.multiselect
を紹介st.pyplot
, st.line_chart
の使い方を紹介scipy.signal
のデジタルフィルタ設計関数を用いたダッシュボードを作成scipy.signal.firwin
のみ対応st.number_input
st.checkbox
st.file_uploader
st.audio
st.number_input(ラベル名, min_value, max_value, value)
%%writefile app.py
import streamlit as st
fs = st.sidebar.number_input("Sampling Frequency", min_value=1,
max_value=192000, value=16000)
cutoff_hz = st.sidebar.number_input("cutoff [Hz]", min_value=0.0,
max_value=fs/2.0, value=100.0)
Overwriting app.py
st.checkbox(ラベル名, デフォルト真偽値)
%%writefile -a app.py
show_time_coeff = st.checkbox("time coefficient", value=True)
if show_time_coeff:
pass # do something
Appending to app.py
st.file_uploader(ラベル名, type)
BytesIO
のサブクラス(UploadedFile
)%%writefile -a app.py
import soundfile as sf
wav_file = st.sidebar.file_uploader("input wave file", type="wav")
if wav_file is not None:
sig, wav_fs = sf.read(wav_file) # file-likeなので渡せる
st.line_chart(sig)
Appending to app.py
st.audio(data)
%%writefile -a app.py
if wav_file is not None:
st.audio(wav_file)
Appending to app.py
chromeでの見た目
st.file_uploader(ラベル名, type, encoding=None, accept_multiple_files=True)
0.68.0
で導入%%writefile -a app.py
wav_files = st.sidebar.file_uploader("input wave files", encoding=None,
type="wav", accept_multiple_files=True)
if wav_files is not None:
for wav_fname in wav_files:
sig, wav_fs = sf.read(wav_fname)
st.line_chart(sig)
Appending to app.py
st.markdown
で表示%%writefile -a app.py
import os
import base64
def get_binary_file_downloader_html(bin_file, file_label='File', extension=""):
with open(bin_file, 'rb') as f:
data = f.read()
bin_str = base64.b64encode(data).decode()
href = f'<a href="data:application/octet-stream;base64,{bin_str}" download="{os.path.basename(bin_file)}{extension}">Download {file_label}</a>'
return href
Appending to app.py
%%writefile -a app.py
import tempfile
if wav_file is not None:
sig, wav_fs = sf.read(wav_file)
hsig = 0.5 * sig
# 名前付き一時ファイルに保存
fp = tempfile.NamedTemporaryFile()
sf.write(fp.name, hsig, wav_fs, format="wav")
st.audio(fp.name)
# ダウンロードリンクを表示
href = get_binary_file_downloader_html(fp.name, "filtered wave file", ".wav")
st.markdown(href, unsafe_allow_html=True)
Appending to app.py
pyroomacoustics
を用いたシミュレータ¶pyroomacoustics
のroomオブジェクト、音源、マイクをGUIで配置Streamlit
のバージョン0.68.0
ではシミュレーションでエラーが発生Shoebox
のみ対応st.slider
st.button
st.slider(ラベル名, min_value, max_value, value)
rx = st.sidebar.slider("x", min_value=0.0, max_value=100.0)
st.radio
で代用可能ret = st.sidebar.radio("app", ["window viewer", "filter designer", "room designer"])
print(ret)
if ret == "window viewer":
window_viewer.main()
elif ret == "filter designer":
filter_designer.main()
elif ret == "room designer":
room_designer.main()
espnet2
table.csv
記載のnameを打ち込むとモデルをダウンロードgit push heroku local_branch:main
Procfile
Aptfile
requirements.txt
runtime.txt
Procfile
¶web: streamlit run --server.enableCORS false --server.port $PORT streamlit_dsp/app.py
runtime.txt
¶Python 3.8.6
Aptfile
¶apt install
する対象を記述soundfile
ライブラリがlibsndfile
に依存heroku buildpacks:add heroku-community/apt
libsndfile-dev
requirements.txt
¶pyproject.toml
からpush時に動的にrequirements.txt
を生成poetry export -f requirements.txt --output requirements.txt
$ heroku buildpacks:clear
$ heroku buildpacks:add heroku-community/apt
$ heroku buildpacks:add heroku/python
$ heroku create
$ git push heroku heroku:main
$ heroku open
ast
でコードを書き換えastor
ライブラリでコードを生成SessionState.py
を使う例contextlib
でredirectは可能だが、非同期実行ができないStreamlit
について紹介