Indice dell'articolo

Il data scientist generalmente già conosce bene strumenti come Pandas, Numpy e tanti altri per il Machine Learning. Le difficoltà che riscontra, a volte, riguardano più la strutturazione del layout e la creazione veloce ma interattiva dell’interfaccia web per le proprie applicazioni di data science e analytics.

Nell’articolo precedente abbiamo visto alcuni aspetti che riguardano questa tematica ma in maniera estremamente veloce per permettere un approccio più completo alla libreria. In particolare, abbiamo visto che Streamlit. 

In questo articolo approfondiremo una serie di tecniche e argomenti al riguardo. Per realizzare pagine web servono elementi che permettano di introdurne le varie componenti. Il problema, per una tecnologia basata su Python, è come relazionarsi con tutte le tipiche difficoltà che, ormai da decenni, il trio HTML/CSS/Javascript riesce a risolvere perfettamente.

  • offre il metodo write per la stampa direttamente su una pagina web di contenuti;
  • permette di trattare il formato Markdown che rappresenta una valida alternativa a HTML.

Ora completeremo il discorso, affiancando a questi una serie di altri strumenti web fondamentali.

Le nostre prime necessità consisteranno nel poter inserire tipici elementi HTML, CSS e Javascript in maniera tale che Streamlit riesca a innestarli non come comune testo ma come elementi operativi che il browser possa interpretare ed eseguire a vantaggio dell’utente.

Tra i metodi che ci faranno più comodo troviamo:

  • set_page_config: permette di impostare alcune proprietà fondamentali della pagina come title (il titolo che apparirà in alto nella scheda del browser), layout (la struttura di fondo che, ad esempio, impostata a wide eviterà di restringere il contenuto ma gli permetterà di sfruttare tutto lo spazio a disposizione), page_icon (un’icona da associare al title che, di default, corrisponde al logo di Streamlit);
  • write: già conosciuto nello scorso articolo e citato in questo, rappresenta il principale vettore di contenuti verso l’interfaccia web. La sua potenzialità principale è quella di poter interpretare direttamente il Markdown che diventa una comodissima alternativa in Streamlit alla formattazione in HTML;
  • title: da non confondere con il titolo della pagina, rappresenta, nello stile di fondo di Streamlit, un modo per poter formattare del testo grande ed in grassetto per rappresentare il titolo della sezione del sito che stiamo realizzando;
  • subheader: un titolo più piccolo che può essere utile per visualizzare testi di contorno a quanto pubblicato con il metodo title;
  • markdown: un ulteriore metodo che permette la pubblicazione in Markdown e consente anche la stampa di normale HTML purchè si passi l’argomento unsafe_allow_html=True. L’introduzione di puro HTML servirà non solo alla formattazione del testo ma anche all’attivazione di funzionalità tipiche delle pagine web come, ad esempio, gli stili CSS.

Un aspetto interessante e facile da sfruttare è l’impiego degli emoji. Nella comunicazione d’oggi, questi sono particolarmente comuni, apprezzati da appartenenti ad ogni generazione ed estremamente espressivi. Per includere un emoji in un testo Streamlit, si dovrà semplicemente fare affidamento ai codici presentati nella pagina https://share.streamlit.io/streamlit/emoji-shortcodes che dovranno essere inclusi nel testo tra una coppia di due punti.

Proviamo un contenuto di esempio in cui mettiamo alla prova questi elementi.

import streamlit as st

st.set_page_config(page_title="Formattazione in Streamlit", layout="wide")

st.subheader("Questo subheader introduce il titolo che segue")

st.title("Come pubblicare contenuti con Streamlit")

st.write("""

Questo testo un pò più lungo servirà a dare tutte le spiegazioni di cui abbiamo bisogno:

- come mostrare testo semplice

- come usare Markdown

- come si visualizzano emoji

- come usare puro HTML

""")

st.write("Abbiamo qui del testo semplice...")

st.write("... ora ecco del **Markdown**...")

st.write("... :writing_hand: gli emoji sicuramente :airplane: rendono di più l'idea :upside_down_face:...")

st.markdown("<h3>... infine non poteva mancare del <em>classico</em> HTML!</h3>", unsafe_allow_html=True)

Il risultato è ciò che si vede nell’immagine che segue.

202202-Streamlit-web_img02

Osservando il codice notiamo che abbiamo potuto utilizzare tutto ciò che abbiamo desiderato, applicando le funzionalità illustrate in precedenza. Puntualizziamo ancora qualcosa. Innanzitutto, se vogliamo rappresentare del testo un po’ più lungo e magari descrittivo, un buon sistema può essere quello di utilizzare le stringhe multiriga Python incluse tra due triple di doppi apici (“””…”””).

Si noti ancora la facilità con cui abbiamo introdotto gli emoji di nostro gradimento (“… :writing_hand:gli emoji sicuramente :airplane: rendono di più l’idea :upside_down_face:…”) semplicemente riportandone il codice tra doppi apici.

Strutturare i layout

Sin dai primi esperimenti con Streamlit ci si abitua all’estrema facilità con cui possono essere trasformati dati in componenti di una pagina web. Tuttavia, si verifica velocemente che la modalità naturale con cui Streamlit visualizza i contenuti è l’accodamento dall’alto verso il basso.

Per esempio, pensiamo a questo semplice codice che non fa altro che generare dati casuali e mostrarli come grafici in due modalità diverse: grafico a linee e ad aree.

Questo il codice:

import streamlit as st

import pandas as pd

import numpy as np

st.set_page_config(page_title="Strutturare layout", age_icon=":chart_with_upwards_trend:",layout="wide")

st.title("Un pò di grafici...")

st.write("""### :books: Impariamo i fondamenti della strutturazione di layout su Streamlit

rappresentando due grafici. In questo caso, verranno accodati, in maniera del tutto naturale, uno di seguito

all'altro in senso verticale""")

st.markdown("---")

data = pd.DataFrame(

          np.random.randn(10, 3),

          columns=['x', 'y', 'z'])

st.write("## Grafico a linee")

st.line_chart(data)

st.write("## Grafico a aree")

st.area_chart(data)

e questo il risultato:

202202-Streamlit-web_img03

Come vediamo i due grafici sono messi uno sopra l’altro e ciò potrebbe rendere meno comoda la consultazione della pagina: primo perché costringerebbe ben presto a scrollare, secondo perché renderebbe in taluni casi più difficile confrontare i due set di curve.

D’altro canto, abbiamo sfruttato la sinteticità di Streamlit che a fronte di poco codice ha offerto un risultato apprezzabile. Si noti che abbiamo utilizzato anche un paio di emoji: una nel testo (la pila di libri) ed una nel titolo della barra come favicon (il simbolo dei grafici).

Inoltre, è bastato utilizzare st.markdown(“—“) per poter ottenere una linea orizzontale larga come l’intera interfaccia.

Se volessimo visualizzare i grafici uno di fianco all’altro potremmo ricorrere ad un sistema a colonne che questo framework già include. Per l’occasione, infatti, sperimenteremo due costrutti molto interessanti:

  • container, un metodo che crea una sorta di contenitore in cui verranno disposti i contenuti;
  • column, un generatore di colonne all’interno di ognuna delle quali potremo stendere il nostro codice e vederne i risultati sviluppati in verticale senza occupare l’intera larghezza della pagina.

Entrambi i costrutti potranno comodamente essere utilizzati con la parola chiave with di Python che permetterà di innestare un blocco di codice da asservire al singolo container o colonna cui ci staremo riferendo.

Capiamo come funzionano questi costrutti con un po’ di codice schematico, i commenti che apporremo ci faranno da didascalia durante la lettura:

import streamlit as st

# creo un container

with st.container():

     # inserisco al suo interno tutto il codice Python che desidero

     # questo container occuperà tutta la larghezza consentita in una pagina

with st.container():

    column1, column2 = st.columns(2)

    with column1:

           # inseriamo il codice che popolerà la prima colonna, quella di sinistra

    with column2:

        # inseriamo il codice che popolerà la seconda colonna, quella di destra

Come vediamo con il costrutto with apriamo un blocco di codice che tipicamente corrisponderà ad una colonna o ad un container. Nel nostro esempio schematico, abbiamo prima creato un container largo come la pagina web e successivamente un altro suddiviso subito in due colonne. Il codice del secondo container – abbiamo immaginato – non conterrà altro se non la struttura a colonne ed i componenti che manipoleranno i dati e l’input utente. Gli elementi di ogni colonna saranno inseriti proprio all’interno dei blocchi corrispondenti a queste, introdotti rispettivamente da with column1 e with column2.

Rielaboriamo l’esempio dei grafici con una struttura di questo tipo:

import streamlit as st

import pandas as pd

import numpy as np

st.set_page_config(page_title="Strutturare layout", page_icon=":chart_with_upwards_trend:",layout="wide")

with st.container():

    st.title("Un pò di grafici...")

    st.write("""### :books: Impariamo i fondamenti della strutturazione di layout su Streamlit

    rappresentando due grafici che non verranno mostrati sequenzialmente ma affiancati

    sulla medesima riga""")

    st.markdown("""---""")

    data = pd.DataFrame(

                np.random.randn(10, 3),

                columns=['x', 'y', 'z'])

with st.container():

    left_column, right_column = st.columns(2)

    with left_column:

        st.write("## Grafico a linee")

        st.line_chart(data)

    with right_column:

        st.write("## Grafico a aree")

        st.area_chart(data)

Ecco l’output, ora le due rappresentazioni appaiono affiancate:

202202-Streamlit-web_img04

Come si può immaginare sarà sufficiente combinare differentemente container e colonne per ottenere la struttura di layout che meglio renderà l’idea che la nostra app vuole fornire. Tra l’altro, questo esempio è stato ancora un buon modo per poter mostrare la completezza di questo framework: abbiamo fatto uso di Pandas, Numpy e librerie grafiche senza dover installare nulla separatamente.

I grafici da noi realizzati sono dei più semplici ma non dimentichiamo che Streamlit include anche molte librerie grafiche come Matplotlib, Altair, Plotly e tante altre. Di queste ed altre meravigliose comodità incorporate, la documentazione ufficiale del progetto sarà una validissima guida.