├── .gitignore ├── LICENSE ├── README.md └── scripts ├── Readme.md ├── Streamlit-demo-one.py ├── gauss2d.py ├── hello-world.py └── is_prime_app.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Tirthajyoti Sarkar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![forthebadge made-with-python](http://ForTheBadge.com/images/badges/made-with-python.svg)](https://www.python.org/) 2 | 3 | # ML and data apps with Streamlit 4 | Building simple ML and data apps with Streamlit. 5 | 6 | ## See my article 7 | See [my article on Medium](https://towardsdatascience.com/data-analytics-to-web-app-streamlit-made-easy-ed687266f0e8) on this topic. 8 | 9 | ## How to run the apps (scripts) 10 | 11 | ### First, 12 | 13 | `pip install -U streamlit` 14 | 15 | ### Second, 16 | Make sure you also have other packages as featured in the scripts (the following list is not exhaustive), 17 | 18 | - `Numpy` 19 | - `Pandas` 20 | - `Matplotlib` 21 | - `Scikit-learn` 22 | - `Seaborn` 23 | 24 | etc. 25 | 26 | ### Finally, 27 | Open your terminal. Go to the folder/directory where these scripts reside. Then, run, 28 | 29 | `streamlit run ` 30 | 31 | where `` must be replaced by the actual name of the Python script file. 32 | -------------------------------------------------------------------------------- /scripts/Readme.md: -------------------------------------------------------------------------------- 1 | ## General scripts 2 | -------------------------------------------------------------------------------- /scripts/Streamlit-demo-one.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import numpy as np 3 | import pandas as pd 4 | import matplotlib.pyplot as plt 5 | from sklearn.linear_model import LinearRegression 6 | 7 | st.title('Streamlit app demo (with Numpy, Pandas, Scikit-learn)') 8 | """ 9 | ## Dr. Tirthajyoti Sarkar, Fremont, CA, July 2020 10 | [My LinkedIn profile](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/), 11 | [My Github profile](https://github.com/tirthajyoti.) 12 | 13 | --- 14 | ### What are we covering in this app/demo? 15 | 16 | In this demo, we will cover the following aspects with Streamlit, 17 | 18 | - Basic markdown 19 | - Displaying image 20 | - LaTeX and code rendering 21 | - Python objects rendering 22 | - Numpy arrays rendering 23 | - Working with Pandas DataFrame 24 | - Filtering data 25 | - Bar chart 26 | - Line chart (Altair) 27 | - Widget magic and interactivity 28 | - Pyplot (Matplotlib graphs) 29 | - A linear regression problem (interactive) 30 | 31 | ### What's the goal? 32 | The primary goal in this app is to show the application of Streamlit working 33 | synergistically with **Python objects** - numbers, strings, Numpy arrays, 34 | Pandas DataFrames, Matplotlib graphs, Scikit-learn estimators, 35 | and **interactive web-app elements** - textboxes, sliders, file-explorer, etc. 36 | 37 | As a secondary goal, we illustrate the **rendering capabilities** of Streamlit for 38 | other type of content such as LaTeX, code, markdown, images, etc. 39 | 40 | ### How to run this app? 41 | We basically write a Python script called `Streamlit-demo-one.py` and 42 | just run it with the following command on the terminal, 43 | 44 | ```streamlit run Streamlit-demo-one.py``` 45 | 46 | It starts a server and we point to `localhost:8501` to see this app. 47 | """ 48 | 49 | """ 50 | --- 51 | ## Some basic markdown 52 | We start off by showing some basic markdown syntaxt rendering. 53 | Streamlit can handle markdown content just like your Jupyter notebook. 54 | 55 | We just need to put the markdown text within two pairs of multiline comment 56 | symbols like 57 | `""\" {markdown text here...} ""\"`. 58 | 59 | Here is a **bold** text in *italic* format. 60 | 61 | Here is a $$L^AT_EX$$ equation: 62 | $$E(m_0,v)=\\frac{m_0.c^2}{\sqrt{1-\\frac{v^2}{c^2}}}$$. 63 | 64 | And here is my [home page](https://tirthajyoti.github.io) i.e. **Github.io**. 65 | """ 66 | 67 | """ 68 | --- 69 | ## Displaying image 70 | 71 | The default markdown image tag is not suitable for controlling the image size. 72 | So, we should use `st.image()` method to display image. 73 | 74 | Here is a screenshot from the Streamlit website. 75 | The image is hosted on my 76 | [Github repo](https://github.com/tirthajyoti/Machine-Learning-with-Python) 77 | and we just pass on the URL. 78 | """ 79 | st.code(''' 80 | image_URL = "https://raw.githubusercontent.com/tirthajyoti/ 81 | Machine-Learning-with-Python/master/Images/st-1.PNG" 82 | 83 | st.image(image_URL, width=800) 84 | ''') 85 | 86 | st.image("https://raw.githubusercontent.com/tirthajyoti/\ 87 | Machine-Learning-with-Python/master/Images/st-1.PNG", 88 | width=800) 89 | 90 | """ 91 | --- 92 | ## Special function for LaTeX rendering 93 | 94 | We can separately use `st.latex()` to render latex content. 95 | 96 | ``` 97 | st.latex(r''' 98 | a + ar + a r^2 + a r^3 + \cdots + a r^{n-1} = 99 | \sum_{k=0}^{n-1} ar^k = 100 | a \left(\frac{1-r^{n}}{1-r}\right) 101 | ''') 102 | """ 103 | 104 | st.latex(r''' 105 | a + ar + a r^2 + a r^3 + \cdots + a r^{n-1} = 106 | \sum_{k=0}^{n-1} ar^k = 107 | a \left(\frac{1-r^{n}}{1-r}\right) 108 | ''') 109 | 110 | """ 111 | --- 112 | ## Code rendering 113 | We can use `st.code()` to render code blocks nicely with optional 114 | syntax highlighting. 115 | 116 | ``` 117 | code_block = '''a, b = 10, 20 118 | def add(x,y): 119 | return x+y 120 | print(add(a,b))''' 121 | 122 | st.code(code_block,'python') 123 | """ 124 | 125 | """This results in the following...""" 126 | 127 | code_py = '''a, b = 10, 20 128 | def add(x,y): 129 | return x+y 130 | print(add(a,b))''' 131 | 132 | st.code(code_py,'python') 133 | 134 | """ 135 | Some JavaScript code, 136 | 137 | ``` 138 | code_js = ''' 139 | let a = 10; 140 | const b = parseFloat('20.5'); 141 | add = (x,y) => x + y 142 | console.log(add(a,b)) 143 | ''' 144 | st.code(code_js,'javascript') 145 | """ 146 | 147 | """Results in...""" 148 | 149 | code_js = ''' 150 | let a = 10; 151 | const b = parseFloat('20.5'); 152 | add = (x,y) => x + y 153 | console.log(add(a,b)) 154 | ''' 155 | 156 | st.code(code_js,'javascript') 157 | 158 | """ 159 | --- 160 | ## Native Python objects are rendered pretty 161 | 162 | Python objects like list and dictionaries are rendered in a 163 | pretty and visually appealing manner. We use the versatile `st.write()` method 164 | for all such rendering. 165 | """ 166 | 167 | """ 168 | ### A list 169 | Here is how the list `list1 = ['Apple', 2.5, [-3,3]]` gets renderd... 170 | """ 171 | list1 = ['Apple', 2.5, [-3, 3]] 172 | st.write("list1: ", list1) 173 | 174 | """ 175 | ### A tuple 176 | Here is how the list `tuple1 = ((1,2),(100,110),(35,45))` gets renderd... 177 | """ 178 | tuple1 = ((1, 2), (100, 110), (35, 45)) 179 | st.write("tuple1: ",tuple1) 180 | 181 | """ 182 | ### A dictionary 183 | Here is how the dict `dict1 = {'Item1':10, 'Item2':[1,3,5],'Item3':-5}` gets rendered... 184 | """ 185 | dict1 = {'Item1':10, 'Item2':[1,3,5],'Item3':-5} 186 | st.write("dict1: ", dict1) 187 | 188 | """ 189 | ### A function 190 | The docstring/description of the function is rendered by the `st.write()` method. 191 | For example, we define, 192 | 193 | ``` 194 | def square (x): 195 | \""" 196 | Squares a given number 197 | \""" 198 | return x*x 199 | """ 200 | 201 | def square (x): 202 | """ 203 | Squares a given number 204 | """ 205 | return x*x 206 | 207 | st.write(square) 208 | 209 | """ 210 | --- 211 | ## Numpy arrays 212 | 213 | Numpy arrays (one- and two-dimensional) are also rendered nicely 214 | by the `st.write()` method, 215 | although for long arrays the vertical rendering can become unwieldy. 216 | 217 | ``` 218 | a = np.arange(1, 20, 2) #Positive odd integers up to 20 219 | st.write(a) 220 | """ 221 | 222 | a = np.arange(1, 20, 2) 223 | st.write(a) 224 | 225 | """ 226 | ### Two-dimensional arrays 227 | ``` 228 | b = np.arange(1, 21).reshape(5, 4) 229 | st.write(b) 230 | """ 231 | b = np.arange(1, 21).reshape(5, 4) 232 | st.write(b) 233 | 234 | """ 235 | ### Three-dimensional arrays (rendered normally) 236 | ``` 237 | c = np.arange(1, 21).reshape(5, 2, 2) 238 | st.write(c) 239 | """ 240 | c = np.arange(1, 21).reshape(5, 2, 2) 241 | st.write(c) 242 | 243 | """ 244 | ### The transpose 245 | 246 | ``` 247 | st.write(b.T) 248 | """ 249 | st.write(b.T) 250 | 251 | """ 252 | --- 253 | ## Working with Pandas DataFrame 254 | 255 | We can render a Pandas DataFrame either by using `st.write()` or `st.dataframe()` 256 | methods. 257 | 258 | """ 259 | code_df = ''' 260 | # Random data-filled coulmns 261 | df = pd.DataFrame(np.random.normal(loc=5, 262 | scale=5, size=50).reshape(10, 5), 263 | columns = ['A'+ str(i) for i in range(1, 6)]) 264 | 265 | # Two derived columns 266 | df['A6'] = 10*np.sin(df['A1']) 267 | df['A7'] = 0.1*df['A2']**2 268 | 269 | st.write(df) 270 | ''' 271 | 272 | st.code(code_df) 273 | 274 | """ 275 | ### Page refresh generates new data 276 | Every time the page refreshes, the code generates new random data, 277 | and the plot below regenerates as well. 278 | """ 279 | # Random data-filled coulmns 280 | df = pd.DataFrame(np.random.normal(loc=5, 281 | scale=5, size=50).reshape(10, 5), 282 | columns = ['A'+ str(i) for i in range(1, 6)]) 283 | 284 | # Two derived columns 285 | df['A6'] = 10*np.sin(df['A1']) 286 | df['A7'] = 0.1*df['A2']**2 287 | 288 | st.write(df) 289 | 290 | """ 291 | ### Applying a filter on the DataFrame 292 | 293 | We filter the DataFrame by selecting only those rows where `A1` > 0 and `A3` > 3. 294 | Note that due to the random nature of the DataFrame generation, **there is no guarantee that 295 | we will get a non-empty DataFrame every time we re-run the code**. 296 | """ 297 | 298 | code_df2 = ''' 299 | df_filtered = df[(df['A1']>0) & (df['A2']>3)] 300 | st.write(df_filtered)''' 301 | 302 | st.code(code_df2) 303 | 304 | df_filtered = df[(df['A1']>0) & (df['A2']>3)] 305 | st.write(df_filtered) 306 | 307 | """ 308 | ### Now, write the filtered DataFrame on the disk 309 | We can easily ask the user a filename and write the filtered data to that file! 310 | """ 311 | 312 | csv_filename = str(st.text_input("Enter a filename for saving the DataFrame as a CSV file", 313 | max_chars=30)) 314 | 315 | if ('.csv' not in csv_filename and len(csv_filename)>0): 316 | csv_filename += ".csv" 317 | if len(csv_filename)>0: 318 | df_filtered.to_csv(csv_filename) 319 | st.markdown("#### File was saved.") 320 | else: 321 | st.markdown("#### No filename was provided. Nothing was saved.") 322 | 323 | """ 324 | ### Reading a CSV from the web 325 | 326 | Reading data from a remotely hosted file (and rendering in a DataFrame) 327 | is as easy as the short code below, 328 | """ 329 | code_df_csv = ''' 330 | data_url = "https://raw.githubusercontent.com/tirthajyoti/ 331 | D3.js-examples/master/html/data/worldcup.csv" 332 | df_csv = pd.read_csv(data_url) 333 | df_csv=df_csv.shift(2,axis=1).reset_index().drop(['team','region'],axis=1) 334 | df_csv.columns = ['team','region','win','loss','draw','points','gf','ga','cs','yc','rc'] 335 | st.write(df_csv) 336 | ''' 337 | 338 | st.code(code_df_csv) 339 | 340 | data_url = "https://raw.githubusercontent.com/tirthajyoti/D3.js-examples/master/html/data/worldcup.csv" 341 | df_csv = pd.read_csv(data_url) 342 | df_csv=df_csv.shift(2,axis=1).reset_index().drop(['team','region'],axis=1) 343 | df_csv.columns = ['team','region','win','loss','draw','points','gf','ga','cs','yc','rc'] 344 | st.write(df_csv) 345 | 346 | """ 347 | ### A simple bar chart using Pandas built-in `plot` module 348 | """ 349 | code_bar = ''' 350 | # Goal difference => gf - ga 351 | df_csv['gd'] = df_csv['gf'] - df_csv['ga'] 352 | fig=df_csv.sort_values(by='gd', ascending=False)[['team','gd']].plot.bar(x='team', 353 | y='gd',figsize=(7, 6)) 354 | plt.grid(True) 355 | plt.title("Goal difference bar chart") 356 | plt.xticks(rotation=30) 357 | st.pyplot() 358 | ''' 359 | 360 | st.code(code_bar) 361 | 362 | # Goal difference => gf - ga 363 | df_csv['gd'] = df_csv['gf'] - df_csv['ga'] 364 | fig=df_csv.sort_values(by='gd', ascending=False)[['team','gd']].plot.bar(x='team', 365 | y='gd',figsize=(7, 6)) 366 | plt.grid(True) 367 | plt.title("Goal difference bar chart") 368 | plt.xticks(rotation=30) 369 | st.pyplot() 370 | 371 | """ 372 | ## Line chart with Altair library 373 | 374 | We take some of the columns from the DataFrame and create a line chart. 375 | This line chart is based on the 376 | [`Altair` library](https://altair-viz.github.io/getting_started/overview.html) 377 | charting function. 378 | You can zoom and pan the chart and even see the HTML code behind it. 379 | """ 380 | 381 | st.line_chart(df[['A1', 'A2', 'A6', 'A7']]) 382 | 383 | """ 384 | --- 385 | ## Widget magic 386 | 387 | Below we are showing the evaluation of the 388 | function $$f(x)=\sin(x).e^{-0.1x}$$ with the help of a simple slidebar widget. 389 | ``` 390 | def f(x): 391 | return np.sin(x)*np.exp(-0.1*x) 392 | """ 393 | 394 | def f(x): 395 | return np.sin(x)*np.exp(-0.1*x) 396 | 397 | 398 | """ 399 | The slidebar widget is created by this code, 400 | ``` 401 | x = st.slider('x', -8, 8) 402 | """ 403 | x = st.slider('x', -8, 8) 404 | 405 | """ 406 | ### Function value 407 | The variable `x` is defined above as the returned value from the slidebar widget. 408 | Therefore, we can dynamically evaluate the `f(x)` by passing on this `x` value 409 | as we move the slider up and down. 410 | 411 | We are printing the function value below. Move the slidebar and see how the 412 | evaluation changes. 413 | """ 414 | st.write(f"$f(x)$ evaluated at {x} is: "+str(round(f(x), 3))) 415 | 416 | """ 417 | --- 418 | ## A Matplotlib graph of the function 419 | The code below graphs the function above using plain vanila `Matplotlib` and 420 | a single `Streamlit` call `st.pyplot()` for rendering. 421 | 422 | This chart, unlike the Altair chart above, is **not a dynamic chart**. 423 | However, note that the `Matplotlib` code contains fair bit of sophistication 424 | (even a LaTeX formatted string in the title). All of that is flawlessly handeled 425 | by the `st.pyplot()` function. 426 | """ 427 | code_plt = ''' 428 | # Some plain vanila Matplotlib code 429 | var_x = np.arange(-8, 8, 0.2) 430 | var_y = np.apply_along_axis(f, 0, var_x) 431 | plt.figure(figsize=(7,4)) 432 | plt.title("Plot of $sin(x).e^{-0.1x}$", 433 | fontsize=16) 434 | plt.scatter(var_x, var_y, 435 | c='green', alpha=0.5) 436 | plt.plot(var_x, var_y, 437 | c='k') 438 | plt.grid(True) 439 | 440 | #This is the Streamlit callback 441 | st.pyplot() 442 | ''' 443 | 444 | st.code(code_plt, 'Python') 445 | 446 | # Some plain vanila Matplotlib code 447 | var_x = np.arange(-8, 8, 0.2) 448 | var_y = np.apply_along_axis(f, 0, var_x) 449 | plt.figure(figsize=(7, 4)) 450 | plt.title("Plot of $sin(x).e^{-0.1x}$", fontsize=16) 451 | plt.scatter(var_x, var_y, c='green', alpha=0.5) 452 | plt.plot(var_x, var_y, c='k') 453 | plt.grid(True) 454 | 455 | # This is the Streamlit callback 456 | st.pyplot() 457 | 458 | """ 459 | --- 460 | ## A (simple) linear regression problem 461 | 462 | Next, we show, how to generate a linear regression dataset with **tunable level 463 | of noise** using simple widgets from Streamlit. In the previous two sections, 464 | we introduced the slider widget and the pyplot. In this section, we combine them 465 | in a dynamic fashion. 466 | 467 | ### One-dimensional linear regression problem 468 | 469 | A simple linear regression (with one variable) can be written as, 470 | """ 471 | st.latex(r'''y = a_1.x+ b_1+ N(\mu, \sigma^2)''') 472 | 473 | """ 474 | where, 475 | 476 | $y$ : The observed data, 477 | 478 | $x$ : The feature data, 479 | 480 | $N(\mu, \sigma^2)$ : The **noise drawn from a Gaussian Normal distribution** 481 | 482 | $\mu$ : The mean of the noise 483 | 484 | $\sigma^2$ : The variance of the noise 485 | """ 486 | """ 487 | ### Adjust the noise to dynamically generate a linear regression dataset 488 | 489 | We choose $a_1=2.5$ and $b_1=5$ for the illustration. 490 | 491 | Below, the sliders can be adjusted to tune the level of the noise. 492 | **Every time you move the sliders, you essentially generate a new 493 | linear regression problem** 494 | (with the same features but with slightly different observed data). 495 | 496 | The data vs. feature plot, which is dynamically updated, is shown below 497 | to illustrate this point. 498 | 499 | Move the "Noise std. dev" slider all the way from left end to right end to 500 | observe the impact on the observed data. **Do you see the observed data becoming 501 | _more noisy_ as you mode the slider towards right**? 502 | """ 503 | 504 | feature = np.arange(1,10,0.1) 505 | noise_mu = st.slider("Noise mean", 506 | min_value=-4.0, 507 | max_value=4.0, 508 | value=0.0, 509 | step=0.5) 510 | noise_std = st.slider("Noise std. dev", 511 | min_value=0.0, 512 | max_value=3.0, 513 | value=1.0, 514 | step=0.1) 515 | len_dataset = feature.size 516 | data = 2.5*feature+5+np.random.normal(noise_mu, 517 | noise_std, 518 | size=len_dataset) 519 | def plot_xy(x,y): 520 | plt.figure(figsize=(5, 4)) 521 | plt.title("Data vs. feature", fontsize=12) 522 | plt.scatter(x, y, c='orange', edgecolor='k', alpha=0.5) 523 | plt.xlabel("Feature values", fontsize=10) 524 | plt.ylabel("Observed data (with noise)", fontsize=10) 525 | plt.xlim(0,12) 526 | plt.ylim(0,35) 527 | #plt.plot(x, y, c='k') 528 | plt.grid(True) 529 | 530 | fig = plot_xy(feature, data) 531 | st.pyplot(fig) 532 | 533 | """ 534 | ### Fitting a model with the data (using `scikit-learn`) 535 | 536 | Next, we fit a `LinearRegression()` model from the famous `scikit-learn` package 537 | with our data, and show the model coefficients and the $R^2$ metric. 538 | 539 | Note, how they change slightly with each iteration of a new problem generation. 540 | Note that we chose $a_1=2.5$ and $b_1=5$ and the estimates should come close to 541 | these numbers. 542 | 543 | **Move the sliders (above) around and observe the changes in the estimates of the 544 | linear coefficient and the bias term**. Note that the noise mean primarily impacts 545 | the bias term whereas noise std. dev primarily impacts the linear coefficient. 546 | You will also notice that the $R^2$ score generally becomes lower as the 547 | noise std. dev increases i.e. **the linear model has a hard time explaining the 548 | variance in the observed data (if the spread of the noise is high)**. 549 | """ 550 | 551 | code_sklearn=''' 552 | from sklearn.linear_model import LinearRegression 553 | 554 | data = data.reshape(-1, 1) 555 | feature = feature.reshape(-1, 1) 556 | 557 | lr = LinearRegression() 558 | lr.fit(feature, data) 559 | 560 | lr_coef = round(float(lr.coef_[0]), 3) 561 | lr_bias = round(float(lr.intercept_), 3) 562 | lr_r2 = round(float(lr.score(feature, data)), 3) 563 | 564 | st.write("The linear coefficient estimated: ", lr_coef) 565 | st.write("The bias term estimated: ", lr_bias) 566 | st.write("The R^2 score estimated: ", lr_r2) 567 | ''' 568 | 569 | st.code(code_sklearn) 570 | 571 | data = data.reshape(-1, 1) 572 | feature = feature.reshape(-1, 1) 573 | lr = LinearRegression() 574 | lr.fit(feature, data) 575 | 576 | lr_coef = round(float(lr.coef_[0]), 3) 577 | lr_bias = round(float(lr.intercept_), 3) 578 | lr_r2 = round(float(lr.score(feature, data)), 3) 579 | 580 | st.write("The linear coefficient estimated: ", lr_coef) 581 | st.write("The bias term estimated: ", lr_bias) 582 | st.write("The R^2 score estimated: ", lr_r2) 583 | -------------------------------------------------------------------------------- /scripts/gauss2d.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import pandas as pd 3 | import numpy as np 4 | import seaborn as sns 5 | 6 | st.title("2-D Gaussian heatmap using Seaborn") 7 | 8 | code = """ 9 | data_density = st.slider("Data density", 10 | min_value= 25, 11 | max_value=200, 12 | value=75, 13 | step=25) 14 | 15 | sigma = st.slider("Sigma", 16 | min_value= 0.1, 17 | max_value=2.0, 18 | value=1.0, 19 | step=0.1) 20 | 21 | mu = st.slider("Sigma", 22 | min_value= -1.0, 23 | max_value=1.0, 24 | value=0.0, 25 | step=0.1) 26 | 27 | x, y = np.meshgrid(np.linspace(-2,2,data_density), np.linspace(-2,2,data_density)) 28 | d = np.sqrt(x*x+y*y) 29 | sigma, mu = sigma, mu 30 | g = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) ) 31 | sns.heatmap(g) 32 | """ 33 | 34 | st.markdown("## Code") 35 | st.code(code) 36 | 37 | st.markdown("## Controls") 38 | 39 | data_density = st.slider("Data density", 40 | min_value= 25, 41 | max_value=200, 42 | value=75, 43 | step=25) 44 | 45 | sigma = st.slider("Sigma", 46 | min_value= 0.1, 47 | max_value=2.0, 48 | value=1.0, 49 | step=0.1) 50 | 51 | mu = st.slider("Sigma", 52 | min_value= -1.0, 53 | max_value=1.0, 54 | value=0.0, 55 | step=0.1) 56 | 57 | x, y = np.meshgrid(np.linspace(-2,2,data_density), np.linspace(-2,2,data_density)) 58 | d = np.sqrt(x*x+y*y) 59 | sigma, mu = sigma, mu 60 | g = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) ) 61 | sns.heatmap(g) 62 | 63 | st.markdown("## Plot") 64 | st.pyplot() -------------------------------------------------------------------------------- /scripts/hello-world.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | 3 | st.write("Hello World with Streamlit!") 4 | st.header("With a header and a little markdown...") 5 | st.markdown("_Hello World_ with __Streamlit__!") 6 | 7 | 8 | -------------------------------------------------------------------------------- /scripts/is_prime_app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | 3 | st.title("A primality test app with Streamlit") 4 | """ 5 | ## Dr. Tirthajyoti Sarkar, Fremont, CA, July 2020 6 | [My LinkedIn profile](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/), 7 | [My Github profile](https://github.com/tirthajyoti.) 8 | 9 | --- 10 | """ 11 | st.header("Is it prime?") 12 | 13 | st.markdown("We determine primality using a simple code as follows") 14 | st.code('''def is_prime(number): 15 | """ 16 | Determines primality 17 | """ 18 | from math import ceil,sqrt 19 | flag = True 20 | if number%2==0: 21 | flag=False 22 | return flag,0 23 | sqrt_num = ceil(sqrt(number)) 24 | st.write(f"Checking divisibility up to **{sqrt_num}**") 25 | for i in range(2,sqrt_num): 26 | if number%i == 0: 27 | flag = False 28 | return flag,i 29 | return flag,i''',language='python') 30 | 31 | number = st.number_input('Insert a number') 32 | number = int(number) 33 | st.write('The current number is ', number) 34 | 35 | def is_prime(number): 36 | """ 37 | Determines primality 38 | """ 39 | from math import ceil,sqrt 40 | flag = True 41 | if number%2==0: 42 | flag= False 43 | return flag, 2 44 | sqrt_num = ceil(sqrt(number)) 45 | st.write(f"Checking divisibility up to **{sqrt_num}**") 46 | for i in range(2,sqrt_num): 47 | if number%i == 0: 48 | flag = False 49 | return flag,i 50 | return flag,i 51 | 52 | decision, divisor = is_prime(number) 53 | 54 | if decision: 55 | st.markdown("### Yes, the given number is prime") 56 | else: 57 | st.markdown("### No, the given number is not a prime.") 58 | --------------------------------------------------------------------------------