Spaces:
Sleeping
Sleeping
reorg for multipage
Browse files- Hello.py +78 -0
- README.md +3 -3
- app.py +35 -49
- pages/1_Data_Introduction.py +17 -0
- pages/2_Widget_Exploration.py +129 -0
- pages/3_Altair_Plots.py +50 -0
- pages/4_Other_Tools.py +12 -0
- requirements.txt +1 -1
Hello.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
st.set_page_config(
|
| 5 |
+
page_title="Hello",
|
| 6 |
+
page_icon="👋",
|
| 7 |
+
)
|
| 8 |
+
|
| 9 |
+
st.sidebar.success("Select a Page")
|
| 10 |
+
|
| 11 |
+
st.header('Multi-page Apps')
|
| 12 |
+
|
| 13 |
+
st.markdown("""
|
| 14 |
+
So far our apps have been rather long and have many parts! We can organize this a bit better by building [multi-page apps](https://docs.streamlit.io/get-started/tutorials/create-a-multipage-app).
|
| 15 |
+
""")
|
| 16 |
+
|
| 17 |
+
st.subheader('Reorganize our App')
|
| 18 |
+
|
| 19 |
+
st.markdown("""We need to do several things including:
|
| 20 |
+
* Rename our app file to something that starts with a capital letter
|
| 21 |
+
* Make sure this is the name that is in the `README.md` file
|
| 22 |
+
* Add in some page info on our "main" page
|
| 23 |
+
* Add in a sidebar on our main page to view all pages
|
| 24 |
+
* Add in a `pages` directory
|
| 25 |
+
* Add pages with the correct format to the `pages` directory
|
| 26 |
+
* Reorganize our page into this new format
|
| 27 |
+
""")
|
| 28 |
+
|
| 29 |
+
st.write("Let's get to each of these!")
|
| 30 |
+
|
| 31 |
+
st.subheader('Step 1: Create our "landing" page')
|
| 32 |
+
|
| 33 |
+
st.markdown("""
|
| 34 |
+
First, let's rename our `app.py` file to `Hello.py`.
|
| 35 |
+
|
| 36 |
+
Then, we need to make sure this is also updated in our `README.md` file.
|
| 37 |
+
|
| 38 |
+
We can then start running our script with `streamlit run Hello.py`.
|
| 39 |
+
""")
|
| 40 |
+
|
| 41 |
+
st.subheader('Step 2: Add some page info to our "landing" page')
|
| 42 |
+
|
| 43 |
+
st.markdown("""Now, let's add in some page info for this landing page:
|
| 44 |
+
""")
|
| 45 |
+
st.code("""
|
| 46 |
+
st.set_page_config(
|
| 47 |
+
page_title="Hello",
|
| 48 |
+
page_icon="👋",
|
| 49 |
+
)
|
| 50 |
+
""")
|
| 51 |
+
|
| 52 |
+
st.markdown("""Finally, let's add a sidebar to display all our pages:""")
|
| 53 |
+
st.code("""
|
| 54 |
+
st.sidebar.success("Select a Page")
|
| 55 |
+
""")
|
| 56 |
+
st.markdown("**Make sure both of these last items are at the top of your `Hello.py` file!**")
|
| 57 |
+
|
| 58 |
+
st.subheader('Step 3: Create pages')
|
| 59 |
+
|
| 60 |
+
st.markdown("""First, create a folder called `pages/`.
|
| 61 |
+
|
| 62 |
+
Then, create four pages:
|
| 63 |
+
1. `1_Data_Introduction.py`
|
| 64 |
+
1. `2_Widget_Exploration.py`
|
| 65 |
+
1. `3_Altair_Plots.py`
|
| 66 |
+
1. `4_Other_Tools.py`
|
| 67 |
+
|
| 68 |
+
**NOTE: The formatting here of the file names is specific!** It determines their order and how they appear on the sidebar.
|
| 69 |
+
|
| 70 |
+
Each page will need to have:
|
| 71 |
+
1. A `set_page_config` call, including a title and an icon
|
| 72 |
+
1. A message displayed on page selection with a `sidebar.header` call
|
| 73 |
+
""")
|
| 74 |
+
|
| 75 |
+
st.markdown("""
|
| 76 |
+
Once this is done, we can then move the items from our original `app.py` file to each page.
|
| 77 |
+
""")
|
| 78 |
+
|
README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
---
|
| 2 |
-
title: Prep notebook -- My Streamlit App
|
| 3 |
emoji: 🏢
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: gray
|
| 6 |
sdk: streamlit
|
| 7 |
-
sdk_version: 1.
|
| 8 |
-
app_file:
|
| 9 |
pinned: false
|
| 10 |
license: mit
|
| 11 |
---
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Prep notebook -- My Multi-page Streamlit App (Day 2)
|
| 3 |
emoji: 🏢
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: gray
|
| 6 |
sdk: streamlit
|
| 7 |
+
sdk_version: 1.39.0
|
| 8 |
+
app_file: Hello.py
|
| 9 |
pinned: false
|
| 10 |
license: mit
|
| 11 |
---
|
app.py
CHANGED
|
@@ -1,12 +1,4 @@
|
|
| 1 |
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
# day 2/3 -- "grab bag" of other things
|
| 5 |
-
# multi-page apps? ==> maybe day 2? ==> does this work with HF apps??
|
| 6 |
-
# Week 12 -- https://docs.streamlit.io/develop/tutorials/databases <- touch on but say we'll be just doing csv files
|
| 7 |
-
# Week 12 -- embedding streamlit spaces on other webpages? wait until Jekyll? https://huggingface.co/docs/hub/en/spaces-sdks-streamlit#embed-streamlit-spaces-on-other-webpages
|
| 8 |
-
|
| 9 |
-
|
| 10 |
#######################################################
|
| 11 |
# 1. Getting setup -- using our HF template
|
| 12 |
#######################################################
|
|
@@ -109,7 +101,7 @@ st.pyplot(fig)
|
|
| 109 |
st.write('''The requirements.txt file contains all the packages needed
|
| 110 |
for our app to run. These include (for our application):''')
|
| 111 |
st.code('''
|
| 112 |
-
streamlit
|
| 113 |
altair
|
| 114 |
numpy
|
| 115 |
pandas
|
|
@@ -119,6 +111,8 @@ matplotlib
|
|
| 119 |
# NOTE: for any package you want to use in your app.py file, you must include it in
|
| 120 |
# the requirements.txt file!
|
| 121 |
|
|
|
|
|
|
|
| 122 |
### 3.3 Push these changes to HF -- README.md ###
|
| 123 |
|
| 124 |
# While we're doing this, let's also take a look at the README.md file!
|
|
@@ -132,12 +126,13 @@ emoji: 🏢
|
|
| 132 |
colorFrom: blue
|
| 133 |
colorTo: gray
|
| 134 |
sdk: streamlit
|
| 135 |
-
sdk_version: 1.
|
| 136 |
app_file: app.py
|
| 137 |
pinned: false
|
| 138 |
license: mit
|
| 139 |
---
|
| 140 |
''')
|
|
|
|
| 141 |
|
| 142 |
# Some important things to note here:
|
| 143 |
|
|
@@ -232,9 +227,6 @@ Note here that we made use of text highlight [colors](https://docs.streamlit.io/
|
|
| 232 |
|
| 233 |
st.subheader('Connecting Widgets and Plots')
|
| 234 |
|
| 235 |
-
st.markdown("""
|
| 236 |
-
We can also
|
| 237 |
-
""")
|
| 238 |
|
| 239 |
st.markdown("""
|
| 240 |
There are actually [many types of charts](https://docs.streamlit.io/develop/api-reference/charts)
|
|
@@ -303,7 +295,7 @@ fig.tight_layout()
|
|
| 303 |
fig.savefig(buf, format="png")
|
| 304 |
st.image(buf, width = 500) # can mess around with width, figsize/etc
|
| 305 |
|
| 306 |
-
st.write("Now, let's make this interactive")
|
| 307 |
st.markdown("""We'll first use the [multiselect](https://docs.streamlit.io/develop/api-reference/widgets/st.multiselect)
|
| 308 |
tool in order to allow for multiple state selection. """)
|
| 309 |
|
|
@@ -403,44 +395,38 @@ if len(states_selected2) > 0: # here we set a default value for the slider, so n
|
|
| 403 |
fig2.savefig(buf2, format="png")
|
| 404 |
fig_col2.image(buf2, width = 400) # changed here to fit better
|
| 405 |
else:
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
ax2.imshow(table.values, cmap='hot', interpolation='nearest', extent=extent2)
|
| 409 |
-
ax2.set_yticks(range(len(table.index)))
|
| 410 |
-
ax2.set_yticklabels(table.index)
|
| 411 |
-
|
| 412 |
-
buf2 = BytesIO()
|
| 413 |
-
fig2.tight_layout()
|
| 414 |
-
fig2.savefig(buf2, format="png")
|
| 415 |
-
fig_col2.image(buf2, width = 500) # can mess around with width, figsize/etc
|
| 416 |
-
|
| 417 |
-
# THEN: slider for range of student teacher ratios -- do the RANGE slider: https://docs.streamlit.io/develop/api-reference/widgets/st.slider
|
| 418 |
-
|
| 419 |
-
# with st.expander('Favorite product by Gender within city'):
|
| 420 |
-
# column1, column2 = st.columns([3,1])
|
| 421 |
-
|
| 422 |
-
# # Allow the user to select a gender.
|
| 423 |
-
# selected_gender = st.radio('What is your Gender:', df.gender.unique(), index = 0)
|
| 424 |
-
|
| 425 |
-
# # Apply gender filter.
|
| 426 |
-
# gender_product = df[df['gender'] == selected_gender]
|
| 427 |
|
| 428 |
-
|
| 429 |
-
# select_city = column2.selectbox('Select City', df.sort_values('City').City.unique())
|
| 430 |
|
| 431 |
-
#
|
| 432 |
-
|
| 433 |
|
| 434 |
-
#
|
| 435 |
-
|
|
|
|
|
|
|
| 436 |
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 441 |
|
| 442 |
-
|
|
|
|
|
|
|
|
|
|
| 443 |
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
#######################################################
|
| 3 |
# 1. Getting setup -- using our HF template
|
| 4 |
#######################################################
|
|
|
|
| 101 |
st.write('''The requirements.txt file contains all the packages needed
|
| 102 |
for our app to run. These include (for our application):''')
|
| 103 |
st.code('''
|
| 104 |
+
streamlit==1.39.0
|
| 105 |
altair
|
| 106 |
numpy
|
| 107 |
pandas
|
|
|
|
| 111 |
# NOTE: for any package you want to use in your app.py file, you must include it in
|
| 112 |
# the requirements.txt file!
|
| 113 |
|
| 114 |
+
# Note #2: we specified a version of streamlit so we can use some specific widgets
|
| 115 |
+
|
| 116 |
### 3.3 Push these changes to HF -- README.md ###
|
| 117 |
|
| 118 |
# While we're doing this, let's also take a look at the README.md file!
|
|
|
|
| 126 |
colorFrom: blue
|
| 127 |
colorTo: gray
|
| 128 |
sdk: streamlit
|
| 129 |
+
sdk_version: 1.39.0
|
| 130 |
app_file: app.py
|
| 131 |
pinned: false
|
| 132 |
license: mit
|
| 133 |
---
|
| 134 |
''')
|
| 135 |
+
st.write("Note: the sdk version has to match what is in your requirements.txt (and with whatever widgets you want to be able to use).")
|
| 136 |
|
| 137 |
# Some important things to note here:
|
| 138 |
|
|
|
|
| 227 |
|
| 228 |
st.subheader('Connecting Widgets and Plots')
|
| 229 |
|
|
|
|
|
|
|
|
|
|
| 230 |
|
| 231 |
st.markdown("""
|
| 232 |
There are actually [many types of charts](https://docs.streamlit.io/develop/api-reference/charts)
|
|
|
|
| 295 |
fig.savefig(buf, format="png")
|
| 296 |
st.image(buf, width = 500) # can mess around with width, figsize/etc
|
| 297 |
|
| 298 |
+
st.write("Now, let's make this interactive.")
|
| 299 |
st.markdown("""We'll first use the [multiselect](https://docs.streamlit.io/develop/api-reference/widgets/st.multiselect)
|
| 300 |
tool in order to allow for multiple state selection. """)
|
| 301 |
|
|
|
|
| 395 |
fig2.savefig(buf2, format="png")
|
| 396 |
fig_col2.image(buf2, width = 400) # changed here to fit better
|
| 397 |
else:
|
| 398 |
+
min_range = student_teacher_ratio_range[0] # added
|
| 399 |
+
max_range = student_teacher_ratio_range[1] # added
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
|
| 401 |
+
df_subset2 = df[(df['Student_teacher_ratio'] >= min_range) & (df['Student_teacher_ratio']<=max_range)] # changed
|
|
|
|
| 402 |
|
| 403 |
+
# just 10 bins over the full range --> changed
|
| 404 |
+
bins2 = 10 #np.linspace(df['Student_teacher_ratio'].min(),df['Student_teacher_ratio'].max(), 10)
|
| 405 |
|
| 406 |
+
# make pivot table -- changed
|
| 407 |
+
table_sub2 = df_subset2.pivot_table(index='State',
|
| 408 |
+
columns=pd.cut(df_subset2['Student_teacher_ratio'], bins2),
|
| 409 |
+
aggfunc='size')
|
| 410 |
|
| 411 |
+
base_size = 4
|
| 412 |
+
fig2,ax2 = plt.subplots(figsize=(base_size,2*base_size)) # this changed too for different size
|
| 413 |
+
extent2 = [df_subset2['Student_teacher_ratio'].min(),
|
| 414 |
+
df_subset2['Student_teacher_ratio'].max(),
|
| 415 |
+
0, len(table_sub2.index)]
|
| 416 |
+
ax2.imshow(table_sub2.values, cmap='hot', interpolation='nearest', extent=extent2)
|
| 417 |
+
ax2.set_yticks(range(len(table_sub2.index)))
|
| 418 |
+
ax2.set_yticklabels(table_sub2.index)
|
| 419 |
+
#ax2.set_xticklabels()
|
| 420 |
|
| 421 |
+
buf2 = BytesIO()
|
| 422 |
+
fig2.tight_layout()
|
| 423 |
+
fig2.savefig(buf2, format="png")
|
| 424 |
+
fig_col2.image(buf2, width = 400) # changed here to fit better
|
| 425 |
|
| 426 |
+
st.header('Push final page to HF')
|
| 427 |
+
st.markdown("""When ready, do:""")
|
| 428 |
+
st.code("""
|
| 429 |
+
git add -A
|
| 430 |
+
git commit -m "final push of day 1"
|
| 431 |
+
git push
|
| 432 |
+
""")
|
pages/1_Data_Introduction.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
st.set_page_config(page_title="Introduction to Data", page_icon=":1234:") # not sure what this adds?
|
| 4 |
+
st.sidebar.header("Introduction to Data")
|
| 5 |
+
|
| 6 |
+
st.title('Info about our Dataset')
|
| 7 |
+
mobility_url = 'https://raw.githubusercontent.com/UIUC-iSchool-DataViz/is445_data/main/mobility.csv'
|
| 8 |
+
|
| 9 |
+
st.write("Here is where we could give some background about our dataset.")
|
| 10 |
+
st.write("This would be a good place to include links, references, and images.")
|
| 11 |
+
|
| 12 |
+
import pandas as pd
|
| 13 |
+
df = pd.read_csv(mobility_url)
|
| 14 |
+
|
| 15 |
+
# There are a few ways to show the dataframe if we want our viewer to see the table:
|
| 16 |
+
#df
|
| 17 |
+
st.write(df)
|
pages/2_Widget_Exploration.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
st.set_page_config(page_title="Widget Exploration", page_icon=":1234:")
|
| 4 |
+
st.sidebar.header("Widget Exploration")
|
| 5 |
+
|
| 6 |
+
st.title('Widget Exploration')
|
| 7 |
+
|
| 8 |
+
st.write("""In a "real" app, we probably wouldn't
|
| 9 |
+
publish our explorations, but here it is a nice excuse to use pages here :smiley:.""")
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
st.write("How great are you feeling right now?")
|
| 13 |
+
sentiment_mapping = ["one", "two", "three", "four", "five"] # map to these numers
|
| 14 |
+
selected = st.feedback("stars")
|
| 15 |
+
if selected is not None: # make sure we have a selection
|
| 16 |
+
st.markdown(f"You selected {sentiment_mapping[selected]} star(s).")
|
| 17 |
+
if selected < 1:
|
| 18 |
+
st.markdown('Sorry to hear you are so sad :(')
|
| 19 |
+
elif selected < 3:
|
| 20 |
+
st.markdown('A solid medium is great!')
|
| 21 |
+
else:
|
| 22 |
+
st.markdown('Fantastic you are having such a great day!')
|
| 23 |
+
|
| 24 |
+
st.subheader('Radio Buttons')
|
| 25 |
+
|
| 26 |
+
st.markdown("""
|
| 27 |
+
Let's try out a [radio button](https://docs.streamlit.io/develop/api-reference/widgets/st.radio) example.
|
| 28 |
+
""")
|
| 29 |
+
|
| 30 |
+
favoriteViz = st.radio(
|
| 31 |
+
"What's your visualization tool so far?",
|
| 32 |
+
[":rainbow[Streamlit]", "vega-lite :sparkles:", "matplotlib :material/Home:"],
|
| 33 |
+
captions=[
|
| 34 |
+
"New and cool!",
|
| 35 |
+
"So sparkly.",
|
| 36 |
+
"Familiar and comforting.",
|
| 37 |
+
],
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
if favoriteViz == ":rainbow[Streamlit]":
|
| 41 |
+
st.write("You selected Streamlit!")
|
| 42 |
+
else:
|
| 43 |
+
st.write("You didn't select Streamlit but that's ok, Data Viz still likes you :grin:")
|
| 44 |
+
|
| 45 |
+
st.header('Connecting Plots and Widgets')
|
| 46 |
+
|
| 47 |
+
import pandas as pd
|
| 48 |
+
import numpy as np
|
| 49 |
+
import matplotlib.pyplot as plt
|
| 50 |
+
from io import BytesIO
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
df = pd.read_csv("https://raw.githubusercontent.com/UIUC-iSchool-DataViz/is445_data/main/mobility.csv")
|
| 54 |
+
|
| 55 |
+
# vertical alignment so they end up side by side
|
| 56 |
+
fig_col2, controls_col2 = st.columns([2,1], vertical_alignment='center')
|
| 57 |
+
|
| 58 |
+
bins = np.linspace(df['Student_teacher_ratio'].min(),df['Student_teacher_ratio'].max(), 10)
|
| 59 |
+
table = df.pivot_table(index='State', columns=pd.cut(df['Student_teacher_ratio'], bins), aggfunc='size')
|
| 60 |
+
|
| 61 |
+
# multi-select
|
| 62 |
+
states_selected2 = controls_col2.multiselect('Which states do you want to view?',
|
| 63 |
+
table.index.values)#, key='unik1155')
|
| 64 |
+
# had to pass unique key to have double widgets with same value
|
| 65 |
+
|
| 66 |
+
# range slider -- added
|
| 67 |
+
student_teacher_ratio_range = controls_col2.slider("Range of student teacher ratio:",
|
| 68 |
+
df['Student_teacher_ratio'].min(),
|
| 69 |
+
df['Student_teacher_ratio'].max(),
|
| 70 |
+
(0.25*df['Student_teacher_ratio'].mean(),
|
| 71 |
+
0.75*df['Student_teacher_ratio'].mean()))
|
| 72 |
+
|
| 73 |
+
# note all the "2's" here, probably will just update the original one
|
| 74 |
+
if len(states_selected2) > 0: # here we set a default value for the slider, so no need to have a tag
|
| 75 |
+
min_range = student_teacher_ratio_range[0] # added
|
| 76 |
+
max_range = student_teacher_ratio_range[1] # added
|
| 77 |
+
|
| 78 |
+
df_subset2 = df[(df['State'].isin(states_selected2)) & (df['Student_teacher_ratio'] >= min_range) & (df['Student_teacher_ratio']<=max_range)] # changed
|
| 79 |
+
|
| 80 |
+
# just 10 bins over the full range --> changed
|
| 81 |
+
bins2 = 10 #np.linspace(df['Student_teacher_ratio'].min(),df['Student_teacher_ratio'].max(), 10)
|
| 82 |
+
|
| 83 |
+
# make pivot table -- changed
|
| 84 |
+
table_sub2 = df_subset2.pivot_table(index='State',
|
| 85 |
+
columns=pd.cut(df_subset2['Student_teacher_ratio'], bins2),
|
| 86 |
+
aggfunc='size')
|
| 87 |
+
|
| 88 |
+
base_size = 4
|
| 89 |
+
fig2,ax2 = plt.subplots(figsize=(base_size,2*base_size)) # this changed too for different size
|
| 90 |
+
extent2 = [df_subset2['Student_teacher_ratio'].min(),
|
| 91 |
+
df_subset2['Student_teacher_ratio'].max(),
|
| 92 |
+
0, len(table_sub2.index)]
|
| 93 |
+
ax2.imshow(table_sub2.values, cmap='hot', interpolation='nearest', extent=extent2)
|
| 94 |
+
ax2.set_yticks(range(len(table_sub2.index)))
|
| 95 |
+
ax2.set_yticklabels(table_sub2.index)
|
| 96 |
+
#ax2.set_xticklabels()
|
| 97 |
+
|
| 98 |
+
buf2 = BytesIO()
|
| 99 |
+
fig2.tight_layout()
|
| 100 |
+
fig2.savefig(buf2, format="png")
|
| 101 |
+
fig_col2.image(buf2, width = 400) # changed here to fit better
|
| 102 |
+
else:
|
| 103 |
+
min_range = student_teacher_ratio_range[0] # added
|
| 104 |
+
max_range = student_teacher_ratio_range[1] # added
|
| 105 |
+
|
| 106 |
+
df_subset2 = df[(df['Student_teacher_ratio'] >= min_range) & (df['Student_teacher_ratio']<=max_range)] # changed
|
| 107 |
+
|
| 108 |
+
# just 10 bins over the full range --> changed
|
| 109 |
+
bins2 = 10 #np.linspace(df['Student_teacher_ratio'].min(),df['Student_teacher_ratio'].max(), 10)
|
| 110 |
+
|
| 111 |
+
# make pivot table -- changed
|
| 112 |
+
table_sub2 = df_subset2.pivot_table(index='State',
|
| 113 |
+
columns=pd.cut(df_subset2['Student_teacher_ratio'], bins2),
|
| 114 |
+
aggfunc='size')
|
| 115 |
+
|
| 116 |
+
base_size = 4
|
| 117 |
+
fig2,ax2 = plt.subplots(figsize=(base_size,2*base_size)) # this changed too for different size
|
| 118 |
+
extent2 = [df_subset2['Student_teacher_ratio'].min(),
|
| 119 |
+
df_subset2['Student_teacher_ratio'].max(),
|
| 120 |
+
0, len(table_sub2.index)]
|
| 121 |
+
ax2.imshow(table_sub2.values, cmap='hot', interpolation='nearest', extent=extent2)
|
| 122 |
+
ax2.set_yticks(range(len(table_sub2.index)))
|
| 123 |
+
ax2.set_yticklabels(table_sub2.index)
|
| 124 |
+
#ax2.set_xticklabels()
|
| 125 |
+
|
| 126 |
+
buf2 = BytesIO()
|
| 127 |
+
fig2.tight_layout()
|
| 128 |
+
fig2.savefig(buf2, format="png")
|
| 129 |
+
fig_col2.image(buf2, width = 400) # changed here to fit better
|
pages/3_Altair_Plots.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
st.set_page_config(page_title="Altair Plots", page_icon=":1234:")
|
| 4 |
+
st.sidebar.header("Altair Plots")
|
| 5 |
+
|
| 6 |
+
st.title('Altair Plots!')
|
| 7 |
+
st.write("""This is probably the main page we'd be showing in a "real" app.""")
|
| 8 |
+
|
| 9 |
+
# Let's start by copying things we did last time
|
| 10 |
+
import streamlit as st
|
| 11 |
+
import altair as alt
|
| 12 |
+
|
| 13 |
+
# Let's recall a plot that we made with Altair in Jupyterlab:
|
| 14 |
+
# Make sure we copy the URL as well!
|
| 15 |
+
mobility_url = 'https://raw.githubusercontent.com/UIUC-iSchool-DataViz/is445_data/main/mobility.csv'
|
| 16 |
+
|
| 17 |
+
scatters = alt.Chart(mobility_url).mark_point().encode(
|
| 18 |
+
x='Mobility:Q', # "Q for quantiative"
|
| 19 |
+
#y='Population:Q',
|
| 20 |
+
y=alt.Y('Population:Q', scale=alt.Scale(type='log')),
|
| 21 |
+
color=alt.Color('Income:Q', scale=alt.Scale(scheme='sinebow'),bin=alt.Bin(maxbins=5))
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
brush = alt.selection_interval(encodings=['x','y'])
|
| 25 |
+
|
| 26 |
+
chart1 = alt.Chart(mobility_url).mark_rect().encode(
|
| 27 |
+
alt.X("Student_teacher_ratio:Q", bin=alt.Bin(maxbins=10)),
|
| 28 |
+
alt.Y("State:O"),
|
| 29 |
+
alt.Color("count()")
|
| 30 |
+
).properties(
|
| 31 |
+
height=400
|
| 32 |
+
).add_params(
|
| 33 |
+
brush
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
chart2 = alt.Chart(mobility_url).mark_bar().encode(
|
| 37 |
+
alt.X("Mobility:Q", bin=True,axis=alt.Axis(title='Mobility Score')),
|
| 38 |
+
alt.Y('count()', axis=alt.Axis(title='Mobility Score Distribution'))
|
| 39 |
+
).transform_filter(
|
| 40 |
+
brush
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
chart = (chart1.properties(width=300) | chart2.properties(width=300))
|
| 44 |
+
|
| 45 |
+
tab1, tab2 = st.tabs(["Mobility interactive", "Scatter plot"])
|
| 46 |
+
|
| 47 |
+
with tab1:
|
| 48 |
+
st.altair_chart(chart, theme=None, use_container_width=True)
|
| 49 |
+
with tab2:
|
| 50 |
+
st.altair_chart(scatters, theme=None, use_container_width=True)
|
pages/4_Other_Tools.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
|
| 3 |
+
st.set_page_config(page_title="Other Tools", page_icon=":1234:")
|
| 4 |
+
st.sidebar.header("Other Tools")
|
| 5 |
+
|
| 6 |
+
st.title("Other cool things to check out")
|
| 7 |
+
|
| 8 |
+
st.markdown(""" While we won't have time to cover everything, a few things you might want to check out later:
|
| 9 |
+
1. You can connect databases to Streamlit [like AWS, MongoDB, etc](https://docs.streamlit.io/develop/tutorials/databases)
|
| 10 |
+
1. You can embed Streamlit Spaces [within other webpages](https://huggingface.co/docs/hub/en/spaces-sdks-streamlit#embed-streamlit-spaces-on-other-webpages)
|
| 11 |
+
1. If you have models hosted on HuggingFace, you can build [apps that use those models](https://huggingface.co/blog/streamlit-spaces) (like LLMs) and let others use them.
|
| 12 |
+
""")
|
requirements.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
streamlit
|
| 2 |
altair
|
| 3 |
numpy
|
| 4 |
pandas
|
|
|
|
| 1 |
+
streamlit==1.39.0
|
| 2 |
altair
|
| 3 |
numpy
|
| 4 |
pandas
|