Python tutorial: 40 lines of code interface (part 2)

4 min


image

Demonstrating a Python project with a user interface has never been so easy. With the Streamlit Framework, you can create a browser user interface using only Python code. In this article, we will create a user interface for the maze program described in detail in the previous article.

Streamlit

Streamlit is a web framework designed for data researchers to easily deploy models and visualizations using Python. It is fast and minimalistic, as well as beautiful and comfortable. There are built-in widgets for user input, such as loading images, sliders, text input, and other familiar HTML elements such as check boxes and radio buttons. Whenever a user interacts with a streaming application, the python script is restarted from top to bottom, which is important to consider when considering the various states of your application.
You can install Streamlit using pip:

pip install streamlit

And run streamlit in a Python script:

streamlit run app.py

Use cases

In a previous article, we created a program in Python that will go through a maze, given the image file and the start / end locations. We would like to turn this program into a one-page web application where the user can download the maze image (or use the default maze image), configure the start and end location of the maze and see the maze passed.

First, let’s create a user interface for the image downloader and the ability to use the default image. We can add text output using functions such as st.write () or st.title (). We store a dynamically loaded file using the st.file_uploader () function. Finally, st.checkbox () will return a boolean depending on whether the user has checked the box.

import streamlit as st
import cv2
import matplotlib.pyplot as plt
import numpy as np
import maze

st.title('Maze Solver')
uploaded_file = st.file_uploader("Choose an image", ["jpg","jpeg","png"]) #image uploader
st.write('Or')
use_default_image = st.checkbox('Use default maze')

Result:

image

Then we can display our default image or the loaded image in a usable OpenCV image format.

if use_default_image:
    opencv_image = cv2.imread('maze5.jpg')

elif uploaded_file is not None:
    file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
    opencv_image = cv2.imdecode(file_bytes, 1)

As soon as the image is loaded, we want to show the image marked with the start and end points. We will use the sliders to allow the user to move these points. The st.sidebar () function adds a sidebar to the page, and st.slider () accepts numerically within a certain minimum and maximum. We can determine the minimum and maximum values ​​of the slider dynamically depending on the size of our maze image.

if opencv_image is not None:
    st.subheader('Use the sliders on the left to position the start and end points')
    start_x = st.sidebar.slider("Start X", value= 24 if use_default_image  else 50, min_value=0, max_value=opencv_image.shape[1], key='sx')
    start_y = st.sidebar.slider("Start Y", value= 332 if use_default_image  else 100, min_value=0, max_value=opencv_image.shape[0], key='sy')
    finish_x = st.sidebar.slider("Finish X", value= 309 if use_default_image  else 100, min_value=0, max_value=opencv_image.shape[1], key='fx')
    finish_y = st.sidebar.slider("Finish Y", value= 330 if use_default_image  else 100, min_value=0, max_value=opencv_image.shape[0], key='fy')
    marked_image = opencv_image.copy()
    circle_thickness=(marked_image.shape[0]+marked_image.shape[0])//2//100 #circle thickness based on img size
    cv2.circle(marked_image, (start_x, start_y), circle_thickness, (0,255,0),-1)
    cv2.circle(marked_image, (finish_x, finish_y), circle_thickness, (255,0,0),-1)
    st.image(marked_image, channels="RGB", width=800)

image

Whenever the user adjusts the sliders, the image is quickly redrawn and the points change.

After the user has defined the start and end positions, we want a button to solve the maze and display the solution. The st.spinner () element is only displayed while its child process is running, and the call to st.image () is used to display the image.

if marked_image is not None:
    if st.button('Solve Maze'):
        with st.spinner('Solving your maze'):
            path = maze.find_shortest_path(opencv_image,(start_x, start_y),(finish_x, finish_y))
        pathed_image = opencv_image.copy()
        path_thickness = (pathed_image.shape[0]+pathed_image.shape[0])//200
        maze.drawPath(pathed_image, path, path_thickness)
        st.image(pathed_image, channels="RGB", width=800)

image

Button

image

Decision conclusion

Output

In less than 40 lines of code, we created a simple user interface for a Python image processing application. We did not need to write any traditional interface code. Besides Streamlit’s ability to digest simple Python code, Streamlit intelligently restarts the necessary parts of your script from top to bottom each time a user interacts with a page or when a script changes. This provides direct data flow and rapid development.

you can find full github code and the first part explaining the algorithm for solving the maze here. Streamlit documentation including important concepts and additional widgets is located here.

image

Learn the details of how to get a sought-after profession from scratch or Level Up in skills and salary by taking paid SkillFactory online courses:


Read more

  • Trends in Data Scenсe 2020
  • Data Science is dead. Long live Business Science
  • The coolest Data Scientist does not waste time on statistics
  • How to Become a Data Scientist Without Online Courses
  • Sorting cheat sheet for Data Science
  • Data Science for the Humanities: What is Data
  • Steroid Data Scenario: Introducing Decision Intelligence

0 Comments

Leave a Reply