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
|