Build WebApp Streamlit dan Shiny

By | June 5, 2023
Print Friendly, PDF & Email
365 Views

WebApp saat ini sangat disukai untuk bahan demo sebuah aplikasi. Umumnya web app bersifat single app. Single Web App adalah aplikasi web yang dibangun sebagai satu halaman web tunggal (single-page) yang memuat semua komponen aplikasi dan tidak melakukan reload atau navigasi ke halaman web yang berbeda saat pengguna berinteraksi dengan aplikasi. Dalam Single Web App, pengguna melakukan semua interaksi dengan aplikasi melalui interaksi yang terjadi di dalam satu halaman web.

Single Web App biasanya dibangun menggunakan teknologi seperti HTML, CSS, dan JavaScript, dengan menggunakan kerangka kerja seperti Angular, React, atau Vue.js untuk membantu membangun aplikasi.

Keuntungan dari Single Web App adalah pengalaman pengguna yang lebih cepat dan lancar, karena aplikasi hanya memuat data dan komponen yang diperlukan untuk tampilan saat ini, tanpa perlu memuat ulang seluruh halaman web. Selain itu, Single Web App juga memungkinkan pengembang untuk membuat aplikasi yang lebih responsif dan interaktif dengan menggunakan teknologi seperti Ajax untuk mengambil dan memperbarui data tanpa perlu memuat ulang halaman.

Namun, Single Web App juga memiliki kelemahan, yaitu kompleksitas pengembangan yang lebih tinggi karena pengembang harus memperhatikan perubahan state aplikasi dan melakukan manajemen state dengan hati-hati. Selain itu, karena Single Web App lebih banyak melakukan pemrosesan di sisi klien, maka terkadang dapat memerlukan spesifikasi perangkat yang lebih tinggi atau mengalami masalah kompatibilitas dengan browser yang lebih lama.

Antara Streamlit dan Shiny

Yup bila kalian ingin membuat webapp, setidaknya ada 2 pilihan yang bisa kalian gunakan yaitu streamlit dan shiny.  Streamlit adalah platform open-source yang memungkinkan pengembang data science untuk dengan cepat dan mudah membangun aplikasi web interaktif dengan menggunakan bahasa pemrograman Python.

See also  Sortir Foto Wajah dengan Facenet

Dengan Streamlit, pengembang dapat menulis kode Python yang mudah dibaca dan dimengerti untuk membuat visualisasi data, tampilan interaktif, dan pengalaman pengguna. Streamlit secara otomatis menangani proses penataan tampilan (layout) dan penyajian data, sehingga pengembang dapat fokus pada logika bisnis dan data science.

Streamlit menyediakan pustaka Python untuk visualisasi data seperti Matplotlib dan Plotly, serta memungkinkan integrasi dengan pustaka machine learning seperti Scikit-Learn dan TensorFlow. Streamlit juga menyediakan tampilan pre-built dan interaktif seperti dropdown, slider, checkbox, dan tombol, sehingga pengembang dapat membuat aplikasi yang mudah digunakan oleh pengguna.

Keuntungan dari Streamlit adalah kemudahan penggunaan dan cepatnya waktu pengembangan aplikasi, serta integrasi dengan pustaka Python yang populer di bidang data science. Streamlit juga memungkinkan pengembang untuk membagikan aplikasi dengan mudah melalui layanan hosting seperti Heroku atau Google Cloud Platform.

Streamlit sangat cocok untuk pengembangan aplikasi web untuk data science, seperti dashboard analisis data, prediksi, dan visualisasi interaktif.

Bagaimana dengan Shiny?

Kalian bisa belajar sendiri mengenai cara install streamlit, tapi saya cenderung menggunakan Shiny alias RShiny versi Python yang cukup matang. Hal ini disebabkan ada bugs yang belum ketemu di streamlit.  Jadi ceritanya ketika saya ingin membuat versi demo mengenai dekomposisi wavelet

from matplotlib.image import imread
import numpy as np
import matplotlib.pyplot as plt

import pywt
import pywt.data


def rgb2gray(rgb):
    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
    return gray

def dekomposisi(gray,max_level,w):
    c = pywt.wavedec2(gray,wavelet = w, level=max_level)
    #lakukan normalisasi
    c[0]/=np.abs(c[0]).max()
    for detail_level in range(0,max_level):
        #lakukkan normalisasi untuk tiap level
        c[detail_level+1] = [d/np.abs(d).max() for d in c[detail_level + 1]]
    arr, slices = pywt.coeffs_to_array(c)
    return arr

# Load image
original = imread('dog.jpg')

gray = rgb2gray(original)



max_level = 1
w = 'db1'

plt.figure(figsize=(12,4.5))
arr = dekomposisi(gray,max_level,w)
plt.imshow(arr, cmap=plt.cm.gray)
plt.tight_layout()
plt.show()

Kemudian saya buat versi streamlit nya, terjadi error di pywavelet nya, walaupun parameter argument input axes=1 pun akan tetap terjadi error.

See also  Python Image Library Pillow

arr, slices = pywt.coeffs_to_array(c)

dengan message error

ValueError: coeffs corresponds to a DWT performed over only a subset of the axes. In this case, axes must be specified.

Hemm… padahal pada versi consolenya aman2 saja, berikut kode streamlit yang digunakan.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  4 18:23:19 2023

@author: mulkansyarif
"""

import streamlit as st
from PIL import Image
from io import BytesIO
import base64

import pywt
import pywt.data
import numpy as np




st.set_page_config(layout="wide", page_title="Dekomposisi Wavelet")

st.write("## Dekomposisi Wavelet")
st.write(
    "Dekomposisi Multi Level Wavelet"
)
st.sidebar.write("## Upload Gambar :gear:")


my_upload = st.sidebar.file_uploader("Upload Gambar", type=["png", "jpg", "jpeg"])
max_level = st.sidebar.slider('Berapa Level DWT?', 1, 10, 5)



row1 = st.columns(2)
row2 = st.columns(1)


def dekomposisi(gray,max_level,w):
    c = pywt.wavedec2(gray,wavelet = w, level=max_level)
    #lakukan normalisasi
    c[0]/=np.abs(c[0]).max()
    for detail_level in range(0,max_level):
        #lakukkan normalisasi untuk tiap level
        c[detail_level+1] = [d/np.abs(d).max() for d in c[detail_level + 1]]
    arr, slices = pywt.coeffs_to_array(c)
    return arr

def fix_image(upload):
    image = Image.open(upload)
    row1[0].write('Original')
    row1[0].image(image,use_column_width=True)
    
    #grayscale
    grayscale = image.convert('LA')
    row1[1].write("Grayscale ")
    row1[1].image(grayscale,use_column_width=True)

    w = 'db1'
    dekomposisi(grayscale,max_level,w)
    row2[0].write('Hasil Dekomposisi')
    row2[0].image(Image.fromarray(np.uint8(arr*255)),use_column_width=True)
    
    
    


if my_upload is not None:
    fix_image(upload=my_upload)
else:
    fix_image("dog.jpg")
    
    

Alangkah terkejutnya ketika saya run di Shiny dengan hasil yang sangat lancar. Berikut kode yang saya gunakan (disimpan dengan nama app3.py). Untuk run menggunakan kode berikut pada command prompt shiny run app3.pykemudian buka saja browser dengan alamat http://127.0.0.1:8000

 

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr  5 00:22:03 2023

@author: mulkansyarif
"""

from matplotlib.image import imread
import matplotlib.pyplot as plt
import numpy as np
from shiny import *
from shiny.types import FileInfo

from PIL import Image
from io import BytesIO
import base64

import pywt
import pywt.data
import numpy as np




app_ui = ui.page_fluid(
    ui.panel_title('Dekompisisi Wavelet'),
    ui.layout_sidebar(
        ui.panel_sidebar(
            ui.input_file('file1','Pilih file gambar',accept=[".jpg",".jpeg",".png"],multiple=False),
            ui.input_slider("level", "Jumlah Level", min=1, max=5, value=1),
            ui.output_text(id="text")
        ),
        ui.panel_main(
            ui.row(
                ui.column(6,ui.output_image("image1")),
                ui.column(6,ui.output_plot("p"))
                
            )        
            
            
        )
    )
)
def server(input:Inputs,output:Outputs,session:Session):
    
    def localfile(path):
        f: list[FileInfo] = path
        return f[0]["datapath"]
    
    def rgb2gray(rgb):
        r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
        gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
        return gray
    
    def dekomposisi(gray,max_level,w):
        c = pywt.wavedec2(gray,wavelet = w, level=max_level)
        #lakukan normalisasi
        c[0]/=np.abs(c[0]).max()
        for detail_level in range(0,max_level):
            #lakukkan normalisasi untuk tiap level
            c[detail_level+1] = [d/np.abs(d).max() for d in c[detail_level + 1]]
        arr, slices = pywt.coeffs_to_array(c)
        return arr
    
    @output
    @render.text
    def text():
        if input.file1() is None:
            return "..."
        else:
            return "Lokasi File "+localfile(input.file1())    
    @output
    @render.image
    def image1():
        if input.file1()is None:
            img = None            
        else:
            img: ImgData = {"src": localfile(input.file1()), "width": "500px"}
        return img
    @output
    @render.plot
    def p():
        if input.file1()is None:
            return None            
        else:
            original = imread(localfile(input.file1()))
            gray = rgb2gray(original)
            max_level = input.level()
            w = 'db1'
            arr = dekomposisi(gray,max_level,w)
            fig, ax = plt.subplots()
            ax.imshow(arr, cmap=plt.cm.gray)
            ax.set_xticks([])
            ax.set_yticks([])
            return fig
        
    
                
app = App(app_ui,server)

hasilnya lancar2 saja

See also  Membuat Lag time series di Pandas

 

Leave a Reply