6. Experiment 6: [Datenvisualisierung mit Shiny in Python und R]

Datum: [13.06.2024] Thema: [Datenvisualisierung in Python und R mit Shiny]

6.1. Einleitung

Daten sind oft schwer interpretierbar. Als gängige Option, Daten einfacher verständlich zu machen, werden diese in Diagrammen abgebildet. Hieraus sind oftmals Zusammenhänge herauslesbar, jedoch können Daten noch interaktiver betrachtet werden. Diese Untersuchung soll nach der ursprünglichen Betrachtung von Datenvisualisierung das Ziel dieses Versuches sein.

6.1.1. Motivation

Um Daten leichter verständlich zu machen, werden diese prinzipiell in Diagrammen dargestellt. Da diese dann oft aber noch nicht genau analysiert werden können, gibt es Frameworks, die es uns erlauben, die Datenvisualisierung interaktiver zu gestalten. Hiermit kann dann ein gegebenes Datenset auch für Personen mit wenig Ahnung vom Thema betrachtet werden und insbesondere sind durch die Interaktivität Details in Diagrammen ersichtlich.

6.1.2. Aufgabenstellung

Die Interaktivität wird mithilfe von „Shiny“ realisiert. Die Umsetzung der dort gegebenen Bibliotheken mithilfe von Python und R war nachzusehen. Die Verarbeitung von Tabellen muss dann ebenso erfolgen. Dann kann begonnen werden, die Diagramme so zu bearbeiten, dass sie den Wünschen entsprechen. Im letzten Schritt wird betrachtet, wie das Ergebnis auch öffentlich in einer Web-App dargestellt werden kann.

6.2. Grundlagen

Shiny ist eine Anwendung, mit der Web-Apps erstellt werden können, welche es ermöglichen, Daten interaktiv darzustellen und darüber hinaus noch verschiedenste andere Dinge zu realisieren. Auf der Shiny Webseite wird Schritt für Schritt erklärt, wie eine Anwendung eingerichtet werden muss und dazu werden die Beispielprojekte angezeigt. Die Installation erfolgt über pip in Python bzw. über install.packages() in R. Für Python wird die Version 3.10 verwendet, da für das spätere Veröffentlichen auf der Webseite von Shiny nur diese Version sich als funktionierend herausgestellt hat. Für das Darstellen lokal ist die Version egal. In R haben wir R-4.3.2 verwendet. Es sollte jedoch auch mit anderen Versionen funktionieren.

6.3. Versuchsdurchführung

6.3.1. Python

Dieser Abschnitt beschreibt die Vorbereitung, Durchführung, erzielten Ergebnisse und eventuelle Probleme während des Versuchs. Im ersten Schritt muss Shiny installiert werden. Dies geschieht im Fall von Python einfach mit dem Befehl „pip install shiny“. Da wir Daten betrachten wollen, besteht das Grundgerüst immer aus einer App und einer Datei, welche die Daten enthält. Für das beispielhafte Demonstrieren werden 2 verschiedene Möglichkeiten gezeigt, Daten zu visualisieren. Die erste Möglichkeit ist auch die, die dann auf der Webseite von Shiny Shiny Apps IO hochgeladen werden kann.

Shiny funktioniert auch außerhalb von IDEs, jedoch wurde für diesen Versuch Visual Studio Code verwendet. Hierbei sollte im ersten Schritt ein virtuelles Environment erstellt werden mit der Python Version 3.10. Die Befehle in der Kommandozeile in Linux/Mac sind

python3 -m virtualenv ~/Envs/shiny und dann source ~/Envs/shiny/bin/activate. Alternativ kann man einfach mit dem Befehl CTRL+SHIFT+P „Select Python Interpreter“ auswählen und hier dann ein Virtuelles Environment erstellen und alle Requirements installieren lassen. Hierzu muss virtualenv installiert sein, was notfalls mit „pip install virtualenv“ nachgeholt werden kann. Wenn man über die Kommandozeile das Environment erstellt hat, müssen die Requirements im nächsten Schritt erstellt werden. Dies geschieht mit pip install -r requirements.txt. Wenn VSCode verwendet wird, sollte Shiny und Python als Plugin installiert werden.

Außerhalb von VSCode kann das Ganze auch so auf einem lokalen Browser laufen gelassen werden. Dies geht, wenn man im entsprechenden Ordner ist (z.B. sales für Versuch1, cars für V2) mit dem Kommando shiny run –reload –launch-browser ./app.py

Nun jedoch zu den genauen Versuchen und was hierbei rauskommt.

Im Ordner sales wird eine .csv Datei benutzt, in welcher Verkäufe von Produkten aufgelistet ist. Diese Verkäufe können analyisert werden auf Menge.

Für das Einlesen wird pandas benutzt, eine Python-Bibliothek, welche ein Standard für die Arbeit mit Tabellen ist:

    @reactive.calc
def dat():
    file = Path(__file__).parent / "data/sales.csv"
    return pd.read_csv(file)

Wir lesen hier einfach die .csv Datei „sales“ ein und lassen pandas diese Datei lesen. Im nächsten Schritt müssen wir nun einfach nur noch filtern, wonach wir das Diagramm filtern möchten. Dies geht mit Shiny und der Bibliothek „plotly“ sehr leicht. Plotly erlaubt es uns, Diagramme darzustellen. Die UI-Elemente, welche für die Interaktivität sorgen, kommen von Shiny.

    with ui.layout_columns():

@render_plotly
def plot1():
    df = dat()
    highest_num = df.groupby('product')['quantity_ordered'].sum().nlargest(input.n()).reset_index()
    return px.bar(highest_num, x='product', y='quantity_ordered')

In diesem Beispiel werden die Elemente in der Tabelle nach der Spalte „Produkt“ sortiert und es wird betrachtet, wie viele davon bestellt worden sind. Dann wird hieraus die Summe gebildet. Zusätzlich wird noch ein Wert eingeführt, der es uns erlaubt, nur eine gewisse Menge an Produkten darzustellen. Diese Menge ist variabel einstellbar mithilfe von Shiny, indem ein Zähler, der von 0 bis 15 einstellbar ist, erstellt wird:

ui.input_numeric("n", "Number of items", 5, min=0, max=15)

Die UI kann um viele weitere Elemente in der Theorie erweitert werden. Wie dieser Versuch dann in der Web-App angezeigt wird, wird nach dem zweiten Beispiel erläutert.

Im zweiten Beispiel wird eine Tabelle eingelesen, welche verschiedenste Autodetails enthält. Diese werden dann in einem Scatterplot als Punkte dargestellt. Die Interaktivität hier wird dadurch gegeben, dass wir mithilfe von Mausklicks Bereiche markieren können, die dann dazu führen, dass Details zu den Autos in diesen Bereichen als eine Unterliste angezeigt werden. Es werden auch noch weitere Möglichkeiten eingebaut, die Daten mehr oder weniger anzeigen zu lassen:

    app_ui = ui.page_fluid(
ui.head_content(
    ui.tags.style(
        """
    pre, table.table {
        font-size: smaller;
    }
    """
    )
),
ui.row(
    ui.column(
        4,
        ui.panel_well(
            ui.input_checkbox("facet", "Use facets", False),
            ui.input_radio_buttons(
                "brush_dir", "Brush direction", ["xy", "x", "y"], inline=True
            ),
            ui.input_checkbox(
                "fast",
                f"Fast hovering/brushing (throttled with {FAST_INTERACT_INTERVAL}ms interval)",
            ),
            ui.input_checkbox("all_rows", "Return all rows in data frame", False),
            ui.input_slider(
                "max_distance", "Max distance of point from hover", 1, 20, 5
            ),
        ),
    ),
    ui.column(
        8,
        ui.output_ui("plot_ui"),
    ),
),
ui.row(
    ui.column(6, ui.tags.b("Points near cursor"), ui.output_table("near_hover")),
    ui.column(6, ui.tags.b("Points in brush"), ui.output_table("in_brush")),
),
)

Die verschiedenen Optionen werden alle über die UI gesteuert. So kann man einen Modus anschalten, welcher die Erfassung der Autos im ausgewählten Bereich schneller ermöglicht. Auch können alle Zeilen angezeigt werden. Es werden unten links die Autos angezeigt, bei denen sich der Cursor in der Nähe befindet. Dieser Radius kann erhöht oder verkleinert werden. Auch können Facets (genaue Infos für die Daten in einer Zeile) eingeschalten werden.

Um den ersten Versuch nun noch auf der Webseite Shiny Apps IO verfügbar zu machen, muss man sich auf der Webseite registrieren. Theoretisch kann die App auch selbst gehosted werden, allerdings ist dies eher eine Option für Firmen. Nachdem sich registriert wurde, so muss noch die Bibliothek „rsconnect-python“ installiert werden (Diese befindet sich in unserem Fall in der requirements.txt). Dies geht mit pip install rsconnect-python. Danach muss im Ordner sales der folgende Befehl ausgeführt werden: rsconnect add –account dvatest2024 –name dvatest2024 –token 649366FCA65EED112B634BC28852CB73 –secret 5Wwh1uN3ruBALpx2c7STgmElarmM3ZEzLMTXbGFH Hiermit ist die App dort verifiziert. Dann kann die App auf der Webseite deployed werden mit rsconnect deploy shiny ./ –name dvatest2024 –title your-app-name“ wobei der Name ein custom Name sein kann.

Hier gab es auch Probleme. Einerseits wird hier nur Python unter Version 3.12 unterstützt und manche Bibliotheken sind nur auf Python 3.11 laufbar. Weiterhin muss die requirements.txt im Ordner sales sein, weshalb es zwei requirements.txt gibt, die eine ist etwas ausführlicher.

Shiny Screenshot 1 Shiny Screenshot 2

6.3.2. R

Da R eine Sprache ist, welche für die Datenanalyse sehr gut geeignet ist, wird hier auch ein Beispiel gezeigt. Die Installation von Shiny erfolgt hier über install.packages(„shiny“). Damit es einfach „Plug n Play“ ist, haben wir die install.packages Commands im Code eingebaut:

# List of required packages
packages <- c("shiny", "shinyjs", "shinydashboard", "ggplot2", "DT", "plotly", "zoo", "GGally", "randomForest")

# Check if packages are installed, if not, install them
for (package in packages) {
    if (!require(package, character.only = TRUE)) {
        install.packages(package)
    }
}

# Load required libraries
library(shiny)
library(shinyjs)
library(shinydashboard)
library(ggplot2)
library(DT)
library(plotly)
library(zoo)
library(GGally)
library(randomForest)

Eine Shiny App in R besteht aus zwei Teilen: der UI und dem Server. Die UI ist das, was der Nutzer sieht und der Server ist das, was die App macht. Mit shinyApp(ui, server) wird die App gestartet.

ui <- dashboardPage(
    dashboardHeader("Title of the App"),
    dashboardSidebar(
        # Sidebar content
    ),
    dashboardBody(
        # Body content
    )
)

server <- function(input, output, session) {
    # Server code
}

shinyApp(ui, server)
Shiny Cheatsheet

Es gibt sehr viele Möglichkeiten, für input und output Elemente, mit denen man seine Shiny App interaktiv gestalten kann. Egal ob Buttons, Slider, Textboxen oder Dropdown Menüs, es gibt für alles eine Funktion. Mit shinyjs kann man sogar JavaScript Funktionen in die App einbauen, falls eine Funktion nicht in R vorhanden ist. Für unser Projekt haben wir mit Testdaten gearbeitet. Diese sind in R schon eingebaut und frei zugänglich Dataset Im der server Funktion haben wir dann die Daten eingelesen und über die input Elemente gesteuert. Mit dem dplyr Package kann man Daten filtern, sortieren und zusammenfassen. Mit dem ggplot2 Package konnten wir schöne Visualisierungen erstellen, welche dann in plotlyOutputs interaktiv gerendert werden.

Für unser Testprojekt haben wir uns für eine Dashboardseite entschieden, welche 5 Tabs enthält. Je einen pro Testdatensatz. Über den input Parameter können wir den ausgewählten Tab auslesen und so die Seitenleiste dynamisch an den Tab anpassen zu können.

## ----- Interactive sidebar -----
manage_sidebar_visibility <- function(selected_tab) {
    shinyjs::hide("sidebar_mtcars")
    shinyjs::hide("sidebar_iris")
    shinyjs::hide("sidebar_toothgrowth")
    shinyjs::hide("sidebar_chickweight")
    shinyjs::hide("sidebar_presidents")

    if (selected_tab == "mtcars") {
    shinyjs::show("sidebar_mtcars")
    } else if (selected_tab == "iris") {
    shinyjs::show("sidebar_iris")
    } else if (selected_tab == "ToothGrowth") {
    shinyjs::show("sidebar_toothgrowth")
    } else if (selected_tab == "ChickWeight") {
    shinyjs::show("sidebar_chickweight")
    } else if (selected_tab == "Presidents") {
    shinyjs::show("sidebar_presidents")
    }
}

observeEvent(input$selected_tab, {
    manage_sidebar_visibility(input$selected_tab)
})

In den einzelnen Tabs haben wir verschiedene Visualisierungen erstellt um die Möglichkeiten von Shiny zu zeigen.

Das hochladen auf der Shiny Apps IO Webseite haben wir in R nicht getestet. Eine grobe Anleitung dazu gibt es aber im Cheatsheet von Shiny.

Shiny Screenshot 3 Shiny Screenshot 4

6.3.3. Ergebnisse

Shiny läuft sowohl auf Linux als auch auf Windows. Der eingebaute lokale Browser funktioniert einwandfrei. Weiterhin können die Apps auf der Webseite schnell und einfach dargestellt werden.

6.3.4. Fazit

Durch die hohe Automatisierung der meisten Bibliotheken ist die Datenvisualisierung mit Python und R sehr einfach. Shiny bietet eine sehr gute Möglichkeit, Daten interaktiv darzustellen. Da im Rahmen von Bachelor- oder Masterarbeiten oft mit Daten gearbeitet werden muss, kann dieser Versuch in dieser Hinsicht auch dafür helfen, da mit Shiny Daten schnell so ersichtlich gemacht werden können, dass wichtige Erkenntnisse damit einsehbar sind. Das einzige Manko ist die fehlende Aktualisierung von Shiny, um auf der Webseite die Apps zur Verfügung zu stellen, wenn man Python 3.12 verwendet.

Insgesamt ist Shiny aber eine sehr gute Möglichkeit, um Datenvisualisierung kreativ und effizient zu ermöglichen.

6.4. Literaturangaben

[1] https://shiny.posit.co/py/docs/overview.html

[2] https://www.shinyapps.io

[3] https://pandas.pydata.org/

[4] https://shiny.posit.co/r/getstarted/shiny-basics/lesson1/index.html

[5] https://rstudio.github.io/cheatsheets/shiny.pdf

[6] https://www.rdocumentation.org/packages/datasets/versions/3.6.2