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.
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.
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.py
kemudian 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