Tipps & Tricks bei der Entwicklung eines Dashboards mit Streamlit & Plotly
Um dieses Dashboard zu entwickeln, haben wir größtenteils mit bekannten Bibliotheken, wie Pandas und NumPy (zur Datenmanipulation) sowie der Plotting-Bibliothek plotly.express gearbeitet. Lediglich Überschriften und interaktive Elemente, wie beispielsweise Slider oder Auswahlboxen, mussten mit Streamlit implementiert werden. Die Plots können mit der Streamlit-Methode st.plotly_chart in die Streamlit-Anwendung eingebunden werden.
Layout mit zusätzlichen Befehlen anpassen
Das resultierende Standardlayout sieht jedoch nicht an allen Stellen ansprechend aus, z.B. entstehen zu viele Leerräume oder eine verzerrte Anzeige auf kleineren Bildschirmen. Daher bedarf es einiger Anpassungen, sowohl bei den Codefragementen, die mittels Streamlit implementiert wurden, als auch bei den Plotly-Abbildungen selbst.
Hovering
Beispielsweise gibt es die Möglichkeit, Nutzer:innen die visualisierten Werte beim Fahren mit der Maus (Hovering) über ein ausgewähltes Diagramm anzuzeigen (Abb. 2). Bei plotly.express lässt sich die Darstellung des Hoverings mittels einem hovertemplate bei update_layout über mehrere Plots hinweg vereinheitlichen und individuell anpassen (Abb. 3).
fig.data[0].hovertemplate = "CO2 Emissions [Mio t]: %{value}"
Verbindung von Streamlit und plotly.express
Die Überschriften der einzelnen Diagramme sollten mit dem Streamlit-Textelement st.markdown erstellt werden, anstatt mit plotly.express direkt. Dadurch wird ermöglicht, dass sich Textelemente und Titel auf kleineren Geräten automatisch an die Seitenbreite anpassen können und nicht abgeschnitten werden. Zusätzlich ermöglicht das Deaktivieren (displayModeBar=False) des automatischen Menu-Tools von plotly.express-Abbildungen eine bessere Darstellung auf mobilen Geräten.
st.plotly_chart([plot], use_container_width=True, config={displayModeBar: False})
Leider gibt es jedoch standardmäßig recht große Abstände zwischen Streamlit-Elementen, wie Titeln, und den Plotly-Abbildungen (Abb. 4). So kann es hilfreich sein, bei Plots mittels plotly.express, über update_layout die Werte des Parameters margins kleiner zu wählen, um dadurch nicht ausgefüllte Fläche zu reduzieren (Abb. 5).
fig.update_layout(margin={l: 15, r: 15, t: 15, b: 15})
Weiße Flächen
Neben der weißen Fläche zwischen Titel und Diagramm, gibt es einen großen leeren Bereich zwischen dem Dashboard-Titel und den eigentlichen Abbildungen. Dadurch ist das Dashboard schwer auf einer Seite anzeigbar (bei einer entsprechenden Bildschirmgröße). Wir konnten diese weiße Fläche – wie im folgenden Codeabschnitt zu erkennen – mittels st.markdown und einigen Zeilen CSS beheben.
st.markdown( """ .css-18e3th9 {padding-top: 1.5rem; padding-bottom: 2rem; padding-left: 2rem;bpadding-right: 2rem;} .css-1d391kg {padding-top: 1rem; padding-right: 1rem; padding-bottom: 1rem; padding-left: 1rem;} """, unsafe_allow_html=True )
Darstellung
Um die gesamte Bildschirmbreite für die Darstellung der Anwendung zu nutzen, sollte zusätzlich in der Hauptdatei der Streamlit-App, für die Methode st.set_page_config, der Parameter layout auf wide festgelegt werden.
st.set_page_config(layout="wide", page_title="Dashboard CO2 Emissions")
Performance durch Caching verbessern
Streamlit-Anwendungen werden in Python-Skripten geschrieben. Dadurch wird bei jeder notwendigen Aktualisierung des Screens das Skript komplett ausgeführt. Um dennoch eine flüssige Dashboard-Performance zu erreichen, ist es empfehlenswert, Ergebnisse von rechenintensiven Funktionen, wie dem Laden von Daten, mittels des Decorators st.cache zu cachen.
@st.cache def load_data(self, path_to_csv: Path) -> pd.DataFrame: pass
Vorsicht ist jedoch geboten bei Verwendung der Caching-Funktion im Zusammenhang mit Klassenmethoden; man sollte sich bewusst sein, inwiefern man den aktuellen Zustand des Objekts cachen möchte oder nicht. Weiterhin kann es sein, dass die zurückgegebenen Werte standardmäßig nicht außerhalb der Funktion verändert werden dürfen, d.h. bestimmte Instanzvariablen dürfen z.B. nur durch die gecachte Klassenmethode verändert werden. Neben dem Caching-Decorator gibt es seit einiger Zeit noch weitere Möglichkeiten in Streamlit-Anwendungen zu cachen, welche sich aktuell noch in einer Testphase befinden.
Dashboard mit Streamlit Cloud einfach deployen
Vorbereitung und Deployment
Nachdem das Layout und die Dashboard-Performance unseren Vorstellungen entsprochen haben, war unser Ziel, das Dashboard öffentlich verfügbar zu machen. Dafür waren verschiedene Schritte notwendig. Der gesamte Code sowie die Daten liegen zusammen mit einer “requirements.txt”-Datei in einem GitHub-Repository. Die “requirements.txt”-Datei befindet sich dabei entweder im Hauptverzeichnis oder im gleichen Ordner wie das Hauptskript der Streamlit-App. Um unsere Anwendung online verfügbar zu machen, haben wir mit Streamlit Cloud direkt unser GitHub-Repository deployed. Streamlit Cloud übernimmt die Prozesse im Hintergrund, sodass sich Entwickler:innen keine Gedanken über Dinge, wie Serverkapazitäten oder Sicherheit, machen müssen.
Die Geschwindigkeit des Deployments wird wesentlich von der Vielzahl der Abhängigkeiten beeinflusst. Unser Dashboard, das nur wenige Abhängigkeiten (Pandas, NumPy, plotly.express) enthält, wurde innerhalb einer knappen Minute deployed. Nachdem das Deployment erfolgreich abgeschlossen ist, steht die Anwendung unter einer eindeutigen URL zur Verfügung. Wird ein Neustart der Anwendung vorgenommen, so wird diese auf allen Clients aktualisiert.
Konfiguration
Standardmäßig ist der Zugriff auf eine mit Streamit Cloud gehostete Anwendung privat, wenn das GitHub-Repository privat ist; bei einem öffentlichen Repository dementsprechend nicht. Über die Weboberfläche von Streamlit Cloud lässt sich diese Konfiguration anpassen. Wichtig zu wissen ist, dass Entwickler:innen die GitHub-Administrator-Rolle haben müssen, um eine Streamlit-Anwendung in der Cloud deployen zu dürfen. Bei einem Organisations-Account muss der Organisations-Owner zusätzlich eine einmalige Zustimmung erteilen, dass Streamlit Cloud auf die Repositories der Organisation zugreifen darf.
Einbettung in eine bestehende Webseite
Unsere ursprüngliche Idee war, den bereitgestellten Link zum Dashboard in einem HTML-iframe in unsere bestehende WordPress-Seite einzubetten. Dies hat sich jedoch leider als nicht möglich herausgestellt aufgrund von Cookies, die unsere Streamlit-Anwendung für das Caching benötigt. Somit gilt Streamlit Cloud in einem iframe eingebettet als Drittseite, und für diese Seiten werden Cookies in modernen Browsern standardmäßig nicht erlaubt. Falls ein:e Leser:in eine Lösung findet, darf diese gerne mit uns geteilt werden.
Der Prozess von der Entwicklung eines Streamlit-Dashboards bis zum endgültigen Deployment umfasst also verschiedene Komponenten. Abbildung 6 zeigt eine Übersicht über unseren Entwicklungs- und Deployment-Prozess.
Erkentnisse aus dem Dashboard
Durch unterschiedliche Darstellungsarten bietet unser Dashboard die Möglichkeit, die weltweiten CO2-Emissionen aus verschiedenen Blickwinkeln zu betrachten. Dabei ist beispielsweise gut zu erkennen, dass Asien insgesamt viel mehr CO2-Emissionen verursacht hat als Südamerika (Abb. 7). In Anbetracht der deutlich größeren Bevölkerung in Asien ist dies jedoch auf den zweiten Blick nicht erstaunlich. Weiterhin lässt sich im Zeitraum 1950 – 2020 ein ansteigender Trend der CO2-Emissionen in Asien erkennen, während ab 1990 die CO2-Emissionen in Europa leicht sinken (Abb. 8). Nicht zuletzt sind die Sektoren Kohle, Konsum, Gas und Öl auf allen Kontinenten für den Großteil der CO2-Emissionen verantwortlich. Es gibt jedoch Unterschiede zwischen den einzelnen Kontinenten: so werden in Südamerika prozentual gesehen weniger CO2-Emissionen durch Kohle verursacht als auf anderen Kontinenten (Abb. 9).
Zusammenfassung
Streamlit bietet eine einfache Lösung, um Dashboards mittels Python-Skripten zu implementieren und bereitzustellen. Die Bedienbarkeit ist weitestgehend leicht verständlich und es lassen sich schnell erste Ergebnisse erzielen. Um eine einigermaßen flüssige Performance zu erreichen sowie gute Layouts zu erstellen, mussten wir dennoch an einigen Details drehen.
In der Zukunft könnte Web Assembly eine weitere Option zum Deployment von Python-Dashboards als Web-Anwendungen sein. Die im September 2022 zur Verfügung stehenden Möglichkeiten waren aufgrund von zu langen Ladezeiten (>10 Sekunden) leider noch ungeeignet. An dieser Stelle ist beispielsweise die Bibliothek stlite zu nennen, die versucht, eine Streamlit-Anwendung direkt im Browser laufen zu lassen.
Alina Bickel & Alina Dallmann