[{"data":1,"prerenderedAt":1444},["ShallowReactive",2],{"content-\u002Fcontents\u002Fstramlit":3,"surroundPost-\u002Fcontents\u002Fstramlit":1435},{"id":4,"title":5,"body":6,"createdAt":1422,"description":1423,"draft":1424,"extension":1425,"meta":1426,"navigation":113,"path":1427,"seo":1428,"stem":1429,"tags":1430,"thumbnail":1433,"updatedAt":1422,"__hash__":1434},"contents\u002Fcontents\u002Fstramlit.md","Streamlit 入門: 表示、インプット、複数ページの構成方法",{"type":7,"value":8,"toc":1409},"minimark",[9,14,18,26,29,54,67,70,80,83,87,90,177,183,188,204,207,210,216,286,290,294,297,300,304,468,471,474,477,575,578,582,586,592,595,598,709,712,721,725,728,899,902,906,910,914,923,927,930,1368,1371,1375,1379,1388,1391,1396,1399,1402,1405],[10,11,13],"h2",{"id":12},"どんなもの","どんなもの？",[15,16,17],"p",{},"Python で簡単な UI が作成可能なライブラリです。",[15,19,20,21,25],{},"フロントエンドも Python で簡単に構築したい方におすすめです。特に後述する",[22,23,24],"code",{},"write","メソッドを使用した記述方法がめちゃめちゃ便利です。",[15,27,28],{},"インストールは以下で可能です。",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-bash shiki shiki-themes github-dark","pip install streamlit\n","bash","",[22,37,38],{"__ignoreMap":35},[39,40,43,47,51],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"svObZ","pip",[39,48,50],{"class":49},"sU2Wk"," install",[39,52,53],{"class":49}," streamlit\n",[55,56,57],"ul",{},[58,59,60],"li",{},[61,62,66],"a",{"href":63,"rel":64},"https:\u002F\u002Fdocs.streamlit.io\u002Flibrary\u002Fget-started\u002Finstallation",[65],"nofollow","installation",[10,68,69],{"id":69},"基本的な使い方",[15,71,72,75,76,79],{},[22,73,74],{},"streamlit","の記法で書かれた Python ファイルを",[22,77,78],{},"streamlit run \u003C.pyファイル>","で実行するとブラウザに画面が表示されます。",[15,81,82],{},"詳しい使い方は後述します。",[84,85,86],"h3",{"id":86},"データフレームの表示",[15,88,89],{},"先日使用した自然言語処理系のファイルを入力とします\n単純に表示するなら以下のように実行可能。",[30,91,95],{"className":92,"code":93,"language":94,"meta":35,"style":35},"language-py shiki shiki-themes github-dark","import pandas as pd\nimport streamlit as st\n\nSOURCE_DATA_PATH = \".\u002Fdata\u002Ftest.csv\"\n\n\n@st.cache\ndef get_data() -> pd.DataFrame:\n    df = pd.read_csv(SOURCE_DATA_PATH)\n    return df\n\n\ndf = get_data()\nst.dataframe(data=df)\n","py",[22,96,97,102,108,115,121,126,131,137,143,149,155,160,165,171],{"__ignoreMap":35},[39,98,99],{"class":41,"line":42},[39,100,101],{},"import pandas as pd\n",[39,103,105],{"class":41,"line":104},2,[39,106,107],{},"import streamlit as st\n",[39,109,111],{"class":41,"line":110},3,[39,112,114],{"emptyLinePlaceholder":113},true,"\n",[39,116,118],{"class":41,"line":117},4,[39,119,120],{},"SOURCE_DATA_PATH = \".\u002Fdata\u002Ftest.csv\"\n",[39,122,124],{"class":41,"line":123},5,[39,125,114],{"emptyLinePlaceholder":113},[39,127,129],{"class":41,"line":128},6,[39,130,114],{"emptyLinePlaceholder":113},[39,132,134],{"class":41,"line":133},7,[39,135,136],{},"@st.cache\n",[39,138,140],{"class":41,"line":139},8,[39,141,142],{},"def get_data() -> pd.DataFrame:\n",[39,144,146],{"class":41,"line":145},9,[39,147,148],{},"    df = pd.read_csv(SOURCE_DATA_PATH)\n",[39,150,152],{"class":41,"line":151},10,[39,153,154],{},"    return df\n",[39,156,158],{"class":41,"line":157},11,[39,159,114],{"emptyLinePlaceholder":113},[39,161,163],{"class":41,"line":162},12,[39,164,114],{"emptyLinePlaceholder":113},[39,166,168],{"class":41,"line":167},13,[39,169,170],{},"df = get_data()\n",[39,172,174],{"class":41,"line":173},14,[39,175,176],{},"st.dataframe(data=df)\n",[15,178,179,182],{},[22,180,181],{},"@st.cache","はそのままの意味で関数の出力をキャッシュしてくれます。",[184,185],"img",{"alt":186,"img-src":187},"dataframe","\u002Fimg\u002Fstreamlit\u002Fdataframe.png",[55,189,190,197],{},[58,191,192],{},[61,193,196],{"href":194,"rel":195},"https:\u002F\u002Fdocs.streamlit.io\u002Flibrary\u002Fapi-reference\u002Fperformance\u002Fst.cache",[65],"st.cache",[58,198,199],{},[61,200,203],{"href":201,"rel":202},"https:\u002F\u002Fdocs.streamlit.io\u002Flibrary\u002Fapi-reference\u002Fdata\u002Fst.dataframe",[65],"st.dataframe",[84,205,206],{"id":206},"グラフ表示",[15,208,209],{},"サンプルを表示してみました。",[15,211,212,215],{},[22,213,214],{},"st.pyplot","で matplotlib で作成した図を表示できるようです。",[30,217,219],{"className":92,"code":218,"language":94,"meta":35,"style":35},"import matplotlib.pyplot as plt\nimport numpy as np\nimport streamlit as st\nfrom matplotlib.figure import Figure\n\n\ndef create_test_hist() -> Figure:\n    arr = np.random.normal(1, 1, size=100)\n    fig, ax = plt.subplots()\n    ax.hist(arr, bins=20)\n    return fig\n\n\nst.pyplot(create_test_hist())\n",[22,220,221,226,231,235,240,244,248,253,258,263,268,273,277,281],{"__ignoreMap":35},[39,222,223],{"class":41,"line":42},[39,224,225],{},"import matplotlib.pyplot as plt\n",[39,227,228],{"class":41,"line":104},[39,229,230],{},"import numpy as np\n",[39,232,233],{"class":41,"line":110},[39,234,107],{},[39,236,237],{"class":41,"line":117},[39,238,239],{},"from matplotlib.figure import Figure\n",[39,241,242],{"class":41,"line":123},[39,243,114],{"emptyLinePlaceholder":113},[39,245,246],{"class":41,"line":128},[39,247,114],{"emptyLinePlaceholder":113},[39,249,250],{"class":41,"line":133},[39,251,252],{},"def create_test_hist() -> Figure:\n",[39,254,255],{"class":41,"line":139},[39,256,257],{},"    arr = np.random.normal(1, 1, size=100)\n",[39,259,260],{"class":41,"line":145},[39,261,262],{},"    fig, ax = plt.subplots()\n",[39,264,265],{"class":41,"line":151},[39,266,267],{},"    ax.hist(arr, bins=20)\n",[39,269,270],{"class":41,"line":157},[39,271,272],{},"    return fig\n",[39,274,275],{"class":41,"line":162},[39,276,114],{"emptyLinePlaceholder":113},[39,278,279],{"class":41,"line":167},[39,280,114],{"emptyLinePlaceholder":113},[39,282,283],{"class":41,"line":173},[39,284,285],{},"st.pyplot(create_test_hist())\n",[184,287],{"alt":288,"img-src":289},"graph","\u002Fimg\u002Fstreamlit\u002Fgraph.png",[10,291,293],{"id":292},"セレクトボックスチェックボックスボタンなどインプット系","セレクトボックス、チェックボックス、ボタンなどインプット系",[15,295,296],{},"よく利用されそうなインプット系をまとめてみました。\nmarkdown も使える方法があるのできれいに表示を整えられます。",[15,298,299],{},"こちらが作成した画面とコードです。",[184,301],{"alt":302,"img-src":303},"screen","\u002Fimg\u002Fstreamlit\u002Fscreen.png",[30,305,307],{"className":92,"code":306,"language":94,"meta":35,"style":35},"import datetime\n\nimport streamlit as st\n\nselect_option = st.selectbox(\"セレクトボックス\", (\"選択肢1\", \"選択肢2\", \"選択肢3\"))\nst.write(\"You selected:\", select_option)\nst.markdown(\"---\")\n\nmultiselect_ptions = st.multiselect(\n    \"複数選択\", [\"Green\", \"Yellow\", \"Red\", \"Blue\"], [\"Yellow\", \"Red\"]  # default値\n)\nst.write(\"You selected:\", multiselect_ptions)\nst.markdown(\"---\")\n\nage = st.slider(\"年齢選択\", 0, 130, 25)\nst.write(\"年齢：\", age, \"歳\")\nst.markdown(\"---\")\n\ntitle = st.text_input(\"テキスト入力\", \"テキストを入力\")\nst.write(\"入力文字列：\", title)\nst.markdown(\"---\")\n\nd = st.date_input(\"When's your birthday\", datetime.date(2019, 7, 6))\nst.write(\"選択肢た日付:\", d)\nst.markdown(\"---\")\n\n\nif st.button(\"ボタン\"):\n    st.write(\"ボタン押下後\")\nelse:\n    st.write(\"ボタン押下前\")\n\n",[22,308,309,314,318,322,326,331,336,341,345,350,355,360,365,369,373,379,385,390,395,401,407,412,417,423,429,434,439,444,450,456,462],{"__ignoreMap":35},[39,310,311],{"class":41,"line":42},[39,312,313],{},"import datetime\n",[39,315,316],{"class":41,"line":104},[39,317,114],{"emptyLinePlaceholder":113},[39,319,320],{"class":41,"line":110},[39,321,107],{},[39,323,324],{"class":41,"line":117},[39,325,114],{"emptyLinePlaceholder":113},[39,327,328],{"class":41,"line":123},[39,329,330],{},"select_option = st.selectbox(\"セレクトボックス\", (\"選択肢1\", \"選択肢2\", \"選択肢3\"))\n",[39,332,333],{"class":41,"line":128},[39,334,335],{},"st.write(\"You selected:\", select_option)\n",[39,337,338],{"class":41,"line":133},[39,339,340],{},"st.markdown(\"---\")\n",[39,342,343],{"class":41,"line":139},[39,344,114],{"emptyLinePlaceholder":113},[39,346,347],{"class":41,"line":145},[39,348,349],{},"multiselect_ptions = st.multiselect(\n",[39,351,352],{"class":41,"line":151},[39,353,354],{},"    \"複数選択\", [\"Green\", \"Yellow\", \"Red\", \"Blue\"], [\"Yellow\", \"Red\"]  # default値\n",[39,356,357],{"class":41,"line":157},[39,358,359],{},")\n",[39,361,362],{"class":41,"line":162},[39,363,364],{},"st.write(\"You selected:\", multiselect_ptions)\n",[39,366,367],{"class":41,"line":167},[39,368,340],{},[39,370,371],{"class":41,"line":173},[39,372,114],{"emptyLinePlaceholder":113},[39,374,376],{"class":41,"line":375},15,[39,377,378],{},"age = st.slider(\"年齢選択\", 0, 130, 25)\n",[39,380,382],{"class":41,"line":381},16,[39,383,384],{},"st.write(\"年齢：\", age, \"歳\")\n",[39,386,388],{"class":41,"line":387},17,[39,389,340],{},[39,391,393],{"class":41,"line":392},18,[39,394,114],{"emptyLinePlaceholder":113},[39,396,398],{"class":41,"line":397},19,[39,399,400],{},"title = st.text_input(\"テキスト入力\", \"テキストを入力\")\n",[39,402,404],{"class":41,"line":403},20,[39,405,406],{},"st.write(\"入力文字列：\", title)\n",[39,408,410],{"class":41,"line":409},21,[39,411,340],{},[39,413,415],{"class":41,"line":414},22,[39,416,114],{"emptyLinePlaceholder":113},[39,418,420],{"class":41,"line":419},23,[39,421,422],{},"d = st.date_input(\"When's your birthday\", datetime.date(2019, 7, 6))\n",[39,424,426],{"class":41,"line":425},24,[39,427,428],{},"st.write(\"選択肢た日付:\", d)\n",[39,430,432],{"class":41,"line":431},25,[39,433,340],{},[39,435,437],{"class":41,"line":436},26,[39,438,114],{"emptyLinePlaceholder":113},[39,440,442],{"class":41,"line":441},27,[39,443,114],{"emptyLinePlaceholder":113},[39,445,447],{"class":41,"line":446},28,[39,448,449],{},"if st.button(\"ボタン\"):\n",[39,451,453],{"class":41,"line":452},29,[39,454,455],{},"    st.write(\"ボタン押下後\")\n",[39,457,459],{"class":41,"line":458},30,[39,460,461],{},"else:\n",[39,463,465],{"class":41,"line":464},31,[39,466,467],{},"    st.write(\"ボタン押下前\")\n",[10,469,470],{"id":470},"イベント処理を書いてみる",[15,472,473],{},"単純にボタン押下で処理が実行されるようにしてみます。",[15,475,476],{},"button はクリックされると bool 値を返すのでそれにしたがって表示が行われるようにします。",[30,478,480],{"className":92,"code":479,"language":94,"meta":35,"style":35},"import pandas as pd\nimport streamlit as st\n\nSOURCE_DATA_PATH = \".\u002Fdata\u002Ftest.csv\"\n\n\n@st.cache\ndef get_data() -> pd.DataFrame:\n    df = pd.read_csv(SOURCE_DATA_PATH)\n    return df\n\n\ndf = get_data()\nst.dataframe(data=df)\n\nidx = st.text_input(\"enter index\", \"0\")\n\n# 指定した行の内容表示\nif st.button(\"ボタン\"):\n    if idx == \"\":\n        raise ValueError(\"Value is Empty. Enter int value\")\n    st.dataframe(data=df.iloc[int(idx)])\n",[22,481,482,486,490,494,498,502,506,510,514,518,522,526,530,534,538,542,547,551,556,560,565,570],{"__ignoreMap":35},[39,483,484],{"class":41,"line":42},[39,485,101],{},[39,487,488],{"class":41,"line":104},[39,489,107],{},[39,491,492],{"class":41,"line":110},[39,493,114],{"emptyLinePlaceholder":113},[39,495,496],{"class":41,"line":117},[39,497,120],{},[39,499,500],{"class":41,"line":123},[39,501,114],{"emptyLinePlaceholder":113},[39,503,504],{"class":41,"line":128},[39,505,114],{"emptyLinePlaceholder":113},[39,507,508],{"class":41,"line":133},[39,509,136],{},[39,511,512],{"class":41,"line":139},[39,513,142],{},[39,515,516],{"class":41,"line":145},[39,517,148],{},[39,519,520],{"class":41,"line":151},[39,521,154],{},[39,523,524],{"class":41,"line":157},[39,525,114],{"emptyLinePlaceholder":113},[39,527,528],{"class":41,"line":162},[39,529,114],{"emptyLinePlaceholder":113},[39,531,532],{"class":41,"line":167},[39,533,170],{},[39,535,536],{"class":41,"line":173},[39,537,176],{},[39,539,540],{"class":41,"line":375},[39,541,114],{"emptyLinePlaceholder":113},[39,543,544],{"class":41,"line":381},[39,545,546],{},"idx = st.text_input(\"enter index\", \"0\")\n",[39,548,549],{"class":41,"line":387},[39,550,114],{"emptyLinePlaceholder":113},[39,552,553],{"class":41,"line":392},[39,554,555],{},"# 指定した行の内容表示\n",[39,557,558],{"class":41,"line":397},[39,559,449],{},[39,561,562],{"class":41,"line":403},[39,563,564],{},"    if idx == \"\":\n",[39,566,567],{"class":41,"line":409},[39,568,569],{},"        raise ValueError(\"Value is Empty. Enter int value\")\n",[39,571,572],{"class":41,"line":414},[39,573,574],{},"    st.dataframe(data=df.iloc[int(idx)])\n",[15,576,577],{},"結果はこんな感じ",[184,579],{"alt":580,"img-src":581},"event","\u002Fimg\u002Fstreamlit\u002Fevent.png",[10,583,585],{"id":584},"なんでも表示できる-write","なんでも表示できる write",[15,587,588,589,591],{},"これまでも登場してますが、",[22,590,24],{},"メソッドはなんでも表示できます。",[15,593,594],{},"しかも表示したい順に引数に入れておげるとその通りに表示されます。",[15,596,597],{},"例えば以下のようなことができます。",[30,599,601],{"className":92,"code":600,"language":94,"meta":35,"style":35},"import matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport streamlit as st\nfrom matplotlib.figure import Figure\n\n\ndef create_test_hist() -> Figure:\n    arr = np.random.normal(1, 1, size=100)\n    fig, ax = plt.subplots(figsize=[4, 2])\n    ax.hist(arr, bins=20)\n    return fig\n\n\nidx = 10\ndf = pd.DataFrame({\"a\": [0, 1], \"b\": [2, 3]})\nst.write(\n    \"## writeはなんでもいける\",\n    df,\n    \"Hello World\",\n    idx,\n    {\"hoge\": \"fuga\", \"aaa\": \"bbb\"},\n    create_test_hist(),\n)\n",[22,602,603,607,611,615,619,623,627,631,635,639,644,648,652,656,660,665,670,675,680,685,690,695,700,705],{"__ignoreMap":35},[39,604,605],{"class":41,"line":42},[39,606,225],{},[39,608,609],{"class":41,"line":104},[39,610,230],{},[39,612,613],{"class":41,"line":110},[39,614,101],{},[39,616,617],{"class":41,"line":117},[39,618,107],{},[39,620,621],{"class":41,"line":123},[39,622,239],{},[39,624,625],{"class":41,"line":128},[39,626,114],{"emptyLinePlaceholder":113},[39,628,629],{"class":41,"line":133},[39,630,114],{"emptyLinePlaceholder":113},[39,632,633],{"class":41,"line":139},[39,634,252],{},[39,636,637],{"class":41,"line":145},[39,638,257],{},[39,640,641],{"class":41,"line":151},[39,642,643],{},"    fig, ax = plt.subplots(figsize=[4, 2])\n",[39,645,646],{"class":41,"line":157},[39,647,267],{},[39,649,650],{"class":41,"line":162},[39,651,272],{},[39,653,654],{"class":41,"line":167},[39,655,114],{"emptyLinePlaceholder":113},[39,657,658],{"class":41,"line":173},[39,659,114],{"emptyLinePlaceholder":113},[39,661,662],{"class":41,"line":375},[39,663,664],{},"idx = 10\n",[39,666,667],{"class":41,"line":381},[39,668,669],{},"df = pd.DataFrame({\"a\": [0, 1], \"b\": [2, 3]})\n",[39,671,672],{"class":41,"line":387},[39,673,674],{},"st.write(\n",[39,676,677],{"class":41,"line":392},[39,678,679],{},"    \"## writeはなんでもいける\",\n",[39,681,682],{"class":41,"line":397},[39,683,684],{},"    df,\n",[39,686,687],{"class":41,"line":403},[39,688,689],{},"    \"Hello World\",\n",[39,691,692],{"class":41,"line":409},[39,693,694],{},"    idx,\n",[39,696,697],{"class":41,"line":414},[39,698,699],{},"    {\"hoge\": \"fuga\", \"aaa\": \"bbb\"},\n",[39,701,702],{"class":41,"line":419},[39,703,704],{},"    create_test_hist(),\n",[39,706,707],{"class":41,"line":425},[39,708,359],{},[184,710],{"alt":24,"img-src":711},"\u002Fimg\u002Fstreamlit\u002Fwrite.png",[55,713,714],{},[58,715,716],{},[61,717,720],{"href":718,"rel":719},"https:\u002F\u002Fdocs.streamlit.io\u002Flibrary\u002Fapi-reference\u002Fwrite-magic\u002Fst.write",[65],"st.write",[10,722,724],{"id":723},"サイドバータブ表示展開などのレイアウト","サイドバー、タブ表示、展開などのレイアウト",[15,726,727],{},"サイドバーやタブを使うとより綺麗なページにできます。",[30,729,731],{"className":92,"code":730,"language":94,"meta":35,"style":35},"import matplotlib.pyplot as plt\nimport numpy as np\nimport streamlit as st\nfrom matplotlib.figure import Figure\n\n\ndef create_test_hist() -> Figure:\n    arr = np.random.normal(1, 1, size=100)\n    fig, ax = plt.subplots(figsize=[4, 2])\n    ax.hist(arr, bins=20)\n    return fig\n\n# ページ情報、基本的なレイアウト\nst.set_page_config(\n    page_title=\"test streamlit\",\n    page_icon=\"🧊\",\n    layout=\"wide\",\n    initial_sidebar_state=\"expanded\",\n)\n\n# サイドバー\nselect_option = st.sidebar.selectbox(\n    \"セレクトボックス\", (\"Email\", \"Home phone\", \"Mobile phone\")\n)\n\n\n# タブ\ntab1, tab2, tab3 = st.tabs([\"data1\", \"data2\", \"data3\"])\n\nwith tab1:\n    st.write(\"expanderで要素を展開する\")\n    with st.expander(\"testグラフ\"):\n        st.write(\"テスト用のグラフ\", create_test_hist())\n\nwith tab2:\n    st.write(\"サイドバーで選択した値: \", select_option)\n\n",[22,732,733,737,741,745,749,753,757,761,765,769,773,777,781,786,791,796,801,806,811,815,819,824,829,834,838,842,846,851,856,860,865,870,876,882,887,893],{"__ignoreMap":35},[39,734,735],{"class":41,"line":42},[39,736,225],{},[39,738,739],{"class":41,"line":104},[39,740,230],{},[39,742,743],{"class":41,"line":110},[39,744,107],{},[39,746,747],{"class":41,"line":117},[39,748,239],{},[39,750,751],{"class":41,"line":123},[39,752,114],{"emptyLinePlaceholder":113},[39,754,755],{"class":41,"line":128},[39,756,114],{"emptyLinePlaceholder":113},[39,758,759],{"class":41,"line":133},[39,760,252],{},[39,762,763],{"class":41,"line":139},[39,764,257],{},[39,766,767],{"class":41,"line":145},[39,768,643],{},[39,770,771],{"class":41,"line":151},[39,772,267],{},[39,774,775],{"class":41,"line":157},[39,776,272],{},[39,778,779],{"class":41,"line":162},[39,780,114],{"emptyLinePlaceholder":113},[39,782,783],{"class":41,"line":167},[39,784,785],{},"# ページ情報、基本的なレイアウト\n",[39,787,788],{"class":41,"line":173},[39,789,790],{},"st.set_page_config(\n",[39,792,793],{"class":41,"line":375},[39,794,795],{},"    page_title=\"test streamlit\",\n",[39,797,798],{"class":41,"line":381},[39,799,800],{},"    page_icon=\"🧊\",\n",[39,802,803],{"class":41,"line":387},[39,804,805],{},"    layout=\"wide\",\n",[39,807,808],{"class":41,"line":392},[39,809,810],{},"    initial_sidebar_state=\"expanded\",\n",[39,812,813],{"class":41,"line":397},[39,814,359],{},[39,816,817],{"class":41,"line":403},[39,818,114],{"emptyLinePlaceholder":113},[39,820,821],{"class":41,"line":409},[39,822,823],{},"# サイドバー\n",[39,825,826],{"class":41,"line":414},[39,827,828],{},"select_option = st.sidebar.selectbox(\n",[39,830,831],{"class":41,"line":419},[39,832,833],{},"    \"セレクトボックス\", (\"Email\", \"Home phone\", \"Mobile phone\")\n",[39,835,836],{"class":41,"line":425},[39,837,359],{},[39,839,840],{"class":41,"line":431},[39,841,114],{"emptyLinePlaceholder":113},[39,843,844],{"class":41,"line":436},[39,845,114],{"emptyLinePlaceholder":113},[39,847,848],{"class":41,"line":441},[39,849,850],{},"# タブ\n",[39,852,853],{"class":41,"line":446},[39,854,855],{},"tab1, tab2, tab3 = st.tabs([\"data1\", \"data2\", \"data3\"])\n",[39,857,858],{"class":41,"line":452},[39,859,114],{"emptyLinePlaceholder":113},[39,861,862],{"class":41,"line":458},[39,863,864],{},"with tab1:\n",[39,866,867],{"class":41,"line":464},[39,868,869],{},"    st.write(\"expanderで要素を展開する\")\n",[39,871,873],{"class":41,"line":872},32,[39,874,875],{},"    with st.expander(\"testグラフ\"):\n",[39,877,879],{"class":41,"line":878},33,[39,880,881],{},"        st.write(\"テスト用のグラフ\", create_test_hist())\n",[39,883,885],{"class":41,"line":884},34,[39,886,114],{"emptyLinePlaceholder":113},[39,888,890],{"class":41,"line":889},35,[39,891,892],{},"with tab2:\n",[39,894,896],{"class":41,"line":895},36,[39,897,898],{},"    st.write(\"サイドバーで選択した値: \", select_option)\n",[15,900,901],{},"作成後のページはこのようになります。タブやサイドバーを設けることがかなりカスタマイズ性が向上します。",[184,903],{"alt":904,"img-src":905},"layout1","\u002Fimg\u002Fstreamlit\u002Flayout1.png",[184,907],{"alt":908,"img-src":909},"layout3","\u002Fimg\u002Fstreamlit\u002Flayout3.png",[184,911],{"alt":912,"img-src":913},"layout2","\u002Fimg\u002Fstreamlit\u002Flayout2.png",[55,915,916],{},[58,917,918],{},[61,919,922],{"href":920,"rel":921},"https:\u002F\u002Fdocs.streamlit.io\u002Flibrary\u002Fapi-reference\u002Flayout",[65],"Layouts and Containers",[10,924,926],{"id":925},"複数ページタブ表示などのレイアウトの方法","複数ページ、タブ表示などのレイアウトの方法",[15,928,929],{},"最後にこれまで作成したものを複数ページのように構成してみます。streamlit で複数ページのように構成するには、サイドバーのセレクトボックスで表示を切り替えるようにします。",[30,931,933],{"className":92,"code":932,"language":94,"meta":35,"style":35},"import datetime\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport streamlit as st\nfrom matplotlib.figure import Figure\n\n\ndef create_test_hist() -> Figure:\n    arr = np.random.normal(1, 1, size=100)\n    fig, ax = plt.subplots(figsize=[4, 2])\n    ax.hist(arr, bins=20)\n    return fig\n\n\nst.set_page_config(\n    page_title=\"test streamlit\",\n    page_icon=\"🧊\",\n    layout=\"wide\",\n    initial_sidebar_state=\"expanded\",\n)\n\n\ndef intro() -> None:\n    import streamlit as st\n\n    st.write(\"# demo\")\n\n\ndef input_test() -> None:\n    import streamlit as st\n\n    select_option = st.selectbox(\"セレクトボックス\", (\"選択肢1\", \"選択肢2\", \"選択肢3\"))\n    st.write(\"You selected:\", select_option)\n    st.markdown(\"---\")\n\n    multiselect_ptions = st.multiselect(\n        \"複数選択\", [\"Green\", \"Yellow\", \"Red\", \"Blue\"], [\"Yellow\", \"Red\"]  # default値\n    )\n    st.write(\"You selected:\", multiselect_ptions)\n    st.markdown(\"---\")\n\n    age = st.slider(\"年齢選択\", 0, 130, 25)\n    st.write(\"年齢：\", age, \"歳\")\n    st.markdown(\"---\")\n\n    title = st.text_input(\"テキスト入力\", \"テキストを入力\")\n    st.write(\"入力文字列：\", title)\n    st.markdown(\"---\")\n\n    d = st.date_input(\"When's your birthday\", datetime.date(2019, 7, 6))\n    st.write(\"選択肢た日付:\", d)\n    st.markdown(\"---\")\n\n    if st.button(\"ボタン\"):\n        st.write(\"ボタン押下後\")\n    else:\n        st.write(\"ボタン押下前\")\n\n\ndef layouts_demo() -> None:\n    import streamlit as st\n\n    # タブ\n    tab1, tab2, tab3 = st.tabs([\"data1\", \"data2\", \"data3\"])\n\n    with tab1:\n        st.write(\"expanderで要素を展開する\")\n        with st.expander(\"testグラフ\"):\n            st.write(\"テスト用のグラフ\", create_test_hist())\n\n    with tab2:\n        st.write(\"サイドバーで選択した値: \", \"なし\")\n\n    with tab3:\n        st.write(\"## なし\")\n\n\npage_names_to_funcs = {\n    \"—\": intro,\n    \"input Demo\": input_test,\n    \"layout Demo\": layouts_demo,\n}\n\ndemo_name = st.sidebar.selectbox(\"Choose a demo\", page_names_to_funcs.keys())\npage_names_to_funcs[demo_name]()\n\n",[22,934,935,939,943,947,951,955,959,963,967,971,975,979,983,987,991,995,999,1003,1007,1011,1015,1019,1023,1027,1032,1037,1041,1046,1050,1054,1059,1063,1067,1072,1077,1082,1086,1092,1098,1104,1110,1115,1120,1126,1132,1137,1142,1148,1154,1159,1164,1170,1176,1181,1186,1192,1198,1204,1210,1215,1220,1226,1231,1236,1242,1248,1253,1259,1265,1271,1277,1282,1288,1294,1299,1305,1311,1316,1321,1327,1333,1339,1345,1351,1356,1362],{"__ignoreMap":35},[39,936,937],{"class":41,"line":42},[39,938,313],{},[39,940,941],{"class":41,"line":104},[39,942,114],{"emptyLinePlaceholder":113},[39,944,945],{"class":41,"line":110},[39,946,225],{},[39,948,949],{"class":41,"line":117},[39,950,230],{},[39,952,953],{"class":41,"line":123},[39,954,107],{},[39,956,957],{"class":41,"line":128},[39,958,239],{},[39,960,961],{"class":41,"line":133},[39,962,114],{"emptyLinePlaceholder":113},[39,964,965],{"class":41,"line":139},[39,966,114],{"emptyLinePlaceholder":113},[39,968,969],{"class":41,"line":145},[39,970,252],{},[39,972,973],{"class":41,"line":151},[39,974,257],{},[39,976,977],{"class":41,"line":157},[39,978,643],{},[39,980,981],{"class":41,"line":162},[39,982,267],{},[39,984,985],{"class":41,"line":167},[39,986,272],{},[39,988,989],{"class":41,"line":173},[39,990,114],{"emptyLinePlaceholder":113},[39,992,993],{"class":41,"line":375},[39,994,114],{"emptyLinePlaceholder":113},[39,996,997],{"class":41,"line":381},[39,998,790],{},[39,1000,1001],{"class":41,"line":387},[39,1002,795],{},[39,1004,1005],{"class":41,"line":392},[39,1006,800],{},[39,1008,1009],{"class":41,"line":397},[39,1010,805],{},[39,1012,1013],{"class":41,"line":403},[39,1014,810],{},[39,1016,1017],{"class":41,"line":409},[39,1018,359],{},[39,1020,1021],{"class":41,"line":414},[39,1022,114],{"emptyLinePlaceholder":113},[39,1024,1025],{"class":41,"line":419},[39,1026,114],{"emptyLinePlaceholder":113},[39,1028,1029],{"class":41,"line":425},[39,1030,1031],{},"def intro() -> None:\n",[39,1033,1034],{"class":41,"line":431},[39,1035,1036],{},"    import streamlit as st\n",[39,1038,1039],{"class":41,"line":436},[39,1040,114],{"emptyLinePlaceholder":113},[39,1042,1043],{"class":41,"line":441},[39,1044,1045],{},"    st.write(\"# demo\")\n",[39,1047,1048],{"class":41,"line":446},[39,1049,114],{"emptyLinePlaceholder":113},[39,1051,1052],{"class":41,"line":452},[39,1053,114],{"emptyLinePlaceholder":113},[39,1055,1056],{"class":41,"line":458},[39,1057,1058],{},"def input_test() -> None:\n",[39,1060,1061],{"class":41,"line":464},[39,1062,1036],{},[39,1064,1065],{"class":41,"line":872},[39,1066,114],{"emptyLinePlaceholder":113},[39,1068,1069],{"class":41,"line":878},[39,1070,1071],{},"    select_option = st.selectbox(\"セレクトボックス\", (\"選択肢1\", \"選択肢2\", \"選択肢3\"))\n",[39,1073,1074],{"class":41,"line":884},[39,1075,1076],{},"    st.write(\"You selected:\", select_option)\n",[39,1078,1079],{"class":41,"line":889},[39,1080,1081],{},"    st.markdown(\"---\")\n",[39,1083,1084],{"class":41,"line":895},[39,1085,114],{"emptyLinePlaceholder":113},[39,1087,1089],{"class":41,"line":1088},37,[39,1090,1091],{},"    multiselect_ptions = st.multiselect(\n",[39,1093,1095],{"class":41,"line":1094},38,[39,1096,1097],{},"        \"複数選択\", [\"Green\", \"Yellow\", \"Red\", \"Blue\"], [\"Yellow\", \"Red\"]  # default値\n",[39,1099,1101],{"class":41,"line":1100},39,[39,1102,1103],{},"    )\n",[39,1105,1107],{"class":41,"line":1106},40,[39,1108,1109],{},"    st.write(\"You selected:\", multiselect_ptions)\n",[39,1111,1113],{"class":41,"line":1112},41,[39,1114,1081],{},[39,1116,1118],{"class":41,"line":1117},42,[39,1119,114],{"emptyLinePlaceholder":113},[39,1121,1123],{"class":41,"line":1122},43,[39,1124,1125],{},"    age = st.slider(\"年齢選択\", 0, 130, 25)\n",[39,1127,1129],{"class":41,"line":1128},44,[39,1130,1131],{},"    st.write(\"年齢：\", age, \"歳\")\n",[39,1133,1135],{"class":41,"line":1134},45,[39,1136,1081],{},[39,1138,1140],{"class":41,"line":1139},46,[39,1141,114],{"emptyLinePlaceholder":113},[39,1143,1145],{"class":41,"line":1144},47,[39,1146,1147],{},"    title = st.text_input(\"テキスト入力\", \"テキストを入力\")\n",[39,1149,1151],{"class":41,"line":1150},48,[39,1152,1153],{},"    st.write(\"入力文字列：\", title)\n",[39,1155,1157],{"class":41,"line":1156},49,[39,1158,1081],{},[39,1160,1162],{"class":41,"line":1161},50,[39,1163,114],{"emptyLinePlaceholder":113},[39,1165,1167],{"class":41,"line":1166},51,[39,1168,1169],{},"    d = st.date_input(\"When's your birthday\", datetime.date(2019, 7, 6))\n",[39,1171,1173],{"class":41,"line":1172},52,[39,1174,1175],{},"    st.write(\"選択肢た日付:\", d)\n",[39,1177,1179],{"class":41,"line":1178},53,[39,1180,1081],{},[39,1182,1184],{"class":41,"line":1183},54,[39,1185,114],{"emptyLinePlaceholder":113},[39,1187,1189],{"class":41,"line":1188},55,[39,1190,1191],{},"    if st.button(\"ボタン\"):\n",[39,1193,1195],{"class":41,"line":1194},56,[39,1196,1197],{},"        st.write(\"ボタン押下後\")\n",[39,1199,1201],{"class":41,"line":1200},57,[39,1202,1203],{},"    else:\n",[39,1205,1207],{"class":41,"line":1206},58,[39,1208,1209],{},"        st.write(\"ボタン押下前\")\n",[39,1211,1213],{"class":41,"line":1212},59,[39,1214,114],{"emptyLinePlaceholder":113},[39,1216,1218],{"class":41,"line":1217},60,[39,1219,114],{"emptyLinePlaceholder":113},[39,1221,1223],{"class":41,"line":1222},61,[39,1224,1225],{},"def layouts_demo() -> None:\n",[39,1227,1229],{"class":41,"line":1228},62,[39,1230,1036],{},[39,1232,1234],{"class":41,"line":1233},63,[39,1235,114],{"emptyLinePlaceholder":113},[39,1237,1239],{"class":41,"line":1238},64,[39,1240,1241],{},"    # タブ\n",[39,1243,1245],{"class":41,"line":1244},65,[39,1246,1247],{},"    tab1, tab2, tab3 = st.tabs([\"data1\", \"data2\", \"data3\"])\n",[39,1249,1251],{"class":41,"line":1250},66,[39,1252,114],{"emptyLinePlaceholder":113},[39,1254,1256],{"class":41,"line":1255},67,[39,1257,1258],{},"    with tab1:\n",[39,1260,1262],{"class":41,"line":1261},68,[39,1263,1264],{},"        st.write(\"expanderで要素を展開する\")\n",[39,1266,1268],{"class":41,"line":1267},69,[39,1269,1270],{},"        with st.expander(\"testグラフ\"):\n",[39,1272,1274],{"class":41,"line":1273},70,[39,1275,1276],{},"            st.write(\"テスト用のグラフ\", create_test_hist())\n",[39,1278,1280],{"class":41,"line":1279},71,[39,1281,114],{"emptyLinePlaceholder":113},[39,1283,1285],{"class":41,"line":1284},72,[39,1286,1287],{},"    with tab2:\n",[39,1289,1291],{"class":41,"line":1290},73,[39,1292,1293],{},"        st.write(\"サイドバーで選択した値: \", \"なし\")\n",[39,1295,1297],{"class":41,"line":1296},74,[39,1298,114],{"emptyLinePlaceholder":113},[39,1300,1302],{"class":41,"line":1301},75,[39,1303,1304],{},"    with tab3:\n",[39,1306,1308],{"class":41,"line":1307},76,[39,1309,1310],{},"        st.write(\"## なし\")\n",[39,1312,1314],{"class":41,"line":1313},77,[39,1315,114],{"emptyLinePlaceholder":113},[39,1317,1319],{"class":41,"line":1318},78,[39,1320,114],{"emptyLinePlaceholder":113},[39,1322,1324],{"class":41,"line":1323},79,[39,1325,1326],{},"page_names_to_funcs = {\n",[39,1328,1330],{"class":41,"line":1329},80,[39,1331,1332],{},"    \"—\": intro,\n",[39,1334,1336],{"class":41,"line":1335},81,[39,1337,1338],{},"    \"input Demo\": input_test,\n",[39,1340,1342],{"class":41,"line":1341},82,[39,1343,1344],{},"    \"layout Demo\": layouts_demo,\n",[39,1346,1348],{"class":41,"line":1347},83,[39,1349,1350],{},"}\n",[39,1352,1354],{"class":41,"line":1353},84,[39,1355,114],{"emptyLinePlaceholder":113},[39,1357,1359],{"class":41,"line":1358},85,[39,1360,1361],{},"demo_name = st.sidebar.selectbox(\"Choose a demo\", page_names_to_funcs.keys())\n",[39,1363,1365],{"class":41,"line":1364},86,[39,1366,1367],{},"page_names_to_funcs[demo_name]()\n",[15,1369,1370],{},"以下のようにこれまでのデモを一つにまとめることができます。",[184,1372],{"alt":1373,"img-src":1374},"multipage1","\u002Fimg\u002Fstreamlit\u002Fmultipage1.png",[184,1376],{"alt":1377,"img-src":1378},"multipage2","\u002Fimg\u002Fstreamlit\u002Fmultipage2.png",[55,1380,1381],{},[58,1382,1383],{},[61,1384,1387],{"href":1385,"rel":1386},"https:\u002F\u002Fdocs.streamlit.io\u002Flibrary\u002Fget-started\u002Fmultipage-apps\u002Fcreate-a-multipage-app",[65],"Create a multipage app",[10,1389,1390],{"id":1390},"感想",[15,1392,1393,1395],{},[22,1394,720],{},"が便利すぎる。これだけ覚えればかなりいろんな表示ができる。",[15,1397,1398],{},"サイドバーやタブ表示を使えばそれなりの情報量を扱うことも簡単そう。",[15,1400,1401],{},"簡単なユースケースなら streamlit で十分対応可能な印象。",[15,1403,1404],{},"一方で細かいレイアウトの調整方法がすぐ分からなかったりするので、カスタマイズ性を求めるなら普通のフロントエンドフレームワークを使ってもいいかもしれない。",[1406,1407,1408],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":35,"searchDepth":104,"depth":104,"links":1410},[1411,1412,1416,1417,1418,1419,1420,1421],{"id":12,"depth":104,"text":13},{"id":69,"depth":104,"text":69,"children":1413},[1414,1415],{"id":86,"depth":110,"text":86},{"id":206,"depth":110,"text":206},{"id":292,"depth":104,"text":293},{"id":470,"depth":104,"text":470},{"id":584,"depth":104,"text":585},{"id":723,"depth":104,"text":724},{"id":925,"depth":104,"text":926},{"id":1390,"depth":104,"text":1390},"2022-10-10","Pythonで簡単にUIを構築可能なStreamlitをドキュメントを参考に色々試してみました",false,"md",{},"\u002Fcontents\u002Fstramlit",{"title":5,"description":1423},"contents\u002Fstramlit",[1431,1432],"2022","Python","\u002Fimg\u002Ftwitter-card.png","_uTw34gVHKctcq7v91ASgInJ4kAUMjOoS9KjHaWa-Ao",[1436,1440],{"title":1437,"path":1438,"stem":1439,"children":-1},"STALE Paper Summary","\u002Fcontents\u002Fstale-memory","contents\u002Fstale-memory",{"title":1441,"path":1442,"stem":1443,"children":-1},"StructMem Paper Summary","\u002Fcontents\u002Fstructmem-memory","contents\u002Fstructmem-memory",1784936718415]