Визуализации при помощи Shiny
Оглавление
Основная информация о Shiny
Shiny — это веб-фреймворк для разработки веб-приложений, изначально на R, а с 2022 года на Python. Это мощный инструмент для визуализации данных, анализа и обмена результатами с широкой аудиторией.
Документация
- Официальный сайт проекта;
- Быстрый старт на языке R;
- Быстрый старт на Python.
Основные компоненты Shiny
- Реактивность. Когда пользователь изменяет элемент управления (например, слайдер, поле ввода), Shiny автоматически пересчитывает результаты и обновляет выходные данные (например, графики, таблицы). Это создает отзывчивый и динамичный пользовательский интерфейс.
- UI (User Interface). Определяет визуальную структуру приложения. Он включает в себя элементы управления (виджеты) для ввода данных и элементы для отображения выходных данных, которые и обеспечивают реактивность запускаемых приложений.
- Server. Содержит логику приложения. Здесь происходит вся тяжелая работа: обработка данных, выполнение расчетов, создание графиков и таблиц.
Применение Shiny
- Визуализация данных и дашборды. Создание интерактивных дашбордов для отслеживания ключевых показателей, визуализации трендов и предоставления информации.
- Интерактивный анализ данных. Позволяет пользователям проводить анализ данных, экспериментировать с параметрами и видеть результаты в реальном времени.
- Образование и обучение. Создание интерактивных инструментов для обучения статистике, программированию и другим темам.
- Разработка веб-приложений. Создание веб-приложений для анализа данных, моделирования и принятия решений.
- Научные исследования. Позволяет ученым делиться своими исследованиями и результатами с коллегами и широкой аудиторией в интерактивном формате.
Установка Shiny
Использование на R
Перейти по ссылке и скачать установщик языка R: https://cran.rstudio.com/bin/windows/base/. После запуска установщика можно выбрать предпочитаемый язык и корневую директорию языка, после чего установить его.
Со станицы установки RStudio скачать его установщик:
https://posit.co/download/rstudio-desktop/. После его загрузки также можно выбрать корневую директорию утилиты.
Установка Shiny возможна либо через консоль, либо с помощью интерфейса среды. В первом случае необходимо открыть консоль (Console) и установить пакет:
install.packages("shiny")Второй способ: при указании библиотеки Shiny в коде приложения RStudio сам предложит установить необходимые зависимости.
Использование на Python
pip install --upgrade pip wheel # обновление утановщика пакетов
pip install shiny # установка библиотеки
pip install --upgrade shiny htmltools # или её обновление
Онлайн редактор
Помимо локальной разработки своих приложений Shiny имеет официальный онлайн редактор, который позволяет писать код приложения Shiny на R прямо в браузере и наблюдать изменения в реальном времени.
Элементы приложения Shiny
После установки всех инструментов становится возможным создание визуализаций на Shiny. Для использования библиотеки в файле с расширением .R:
library(shiny)
Приложение Shiny создаётся вызовом функции shinyApp:
shinyApp(ui = ui, server = server)
В ней указываются 2 основных элемента:
ui- пользовательский интерфейс, определяющий инструменты ввода данных и параметров, вывода текста или визуализаций, фильтры. Все эти функции генерируют HTML-разметку.server- логика приложения, обрабатывающая передаваемые интерфейсом данные и производящая рендер графиков.
UI
Разметку макета можно задавать несколькими функциями, которые будут задавать вёрстку и расположение её дочерних элементов. Вот основные из них:
fluidPage: создает макет, который масштабируется в зависимости от размера окна браузера. Рекомендуется для большинства приложений. Он использует систему сеток Bootstrap.fixedPage: создает макет фиксированной ширины.sidebarLayout: создает макет с боковой панелью и основной панелью. Принимает два аргумента:sidebarPanelиmainPanel.- Другие макеты:
fillPage,splitLayout,verticalLayout.
Элементы управления ввода (input widgets) позволяют пользователям вводить данные или взаимодействовать с приложением:
textInput- текстовое поле для ввода текста.numericInput- числовое поле для ввода чисел.sliderInput- слайдер для выбора числового значения.selectInput- выпадающий список для выбора из списка вариантов.radioButtons- радиокнопки для выбора одного варианта из списка.checkboxGroupInput- набор флажков для выбора нескольких вариантов из списка.checkboxInput- одиночный флажок (логическое значение).dateInput- выбор даты.dateRangeInput- выбор диапазона дат.fileInput- загрузка файла.actionButton- кнопка.
Элементы вывода (output elements) отображают результаты в приложении. Связываются с Server через output$ переменную. Примеры:
plotOutput- место для отображения графика.tableOutput- место для отображения таблицы.dataTableOutput- место для отображения интерактивной таблицы данных.
Server
Server содержит логику приложения. Он получает входные данные от UI (input), выполняет расчеты и рендерит выходные данные для отображения в UI (output). server в коде - это R-фукнция, имеющая 2 параметра:
server <- function(input, output) {
// Логика обработки данных
}Функции рендеринга (rendering functions) преобразуют результаты R-кода в формат, который можно отобразить в UI. Они всегда должны быть внутри функции server.
renderPlot: рендерит график, созданный с использованием функций plot(), ggplot2 и т.д. Возвращает графический объект.renderTable: рендерит таблицу данных (например, data.frame). Возвращает таблицу.renderDataTable: рендерит интерактивную таблицу данных с возможностью сортировки, фильтрации и постраничной навигации (требует пакет DT). Возвращает таблицу.renderText: рендерит текстовую строку. Возвращает строку.renderPrint: рендерит вывод R-кода. Возвращает результат, который можно распечатать в консоли.renderUI: рендерит UI-элементы. Используется для динамического создания UI. Возвращает HTML-код для элемента UI.renderImage: рендерит изображение. Возвращает список, содержащий информацию об изображении (путь, mime-тип, ширина, высота).
Пример на датасете "Породы собак"
Далее будет разобран простой пример приложения Shiny с 2 визуализациями, построенными на датасете "Породы собак", а также развёрнутом в сервисе shinyapps.io.
Объяснение примера
Сперва, подключаются библиотеки:
library(shiny) # Сама Shiny library(readr) # Библиотека для чтения датасета из файла CSV
Затем читается датасет из файла, добавляются вычисляемые поля и устанавливаются константы:
dogsData <- read_csv("dogs.csv") # Чтение датасета из файла в той же директории, что и приложение
customFields <- c("Вес", "Рост", "Продолжительность жизни", "Стоимость")
for (field in customFields) {
fieldMin <- paste0(field, " мин")
fieldMax <- paste0(field, " макс")
dogsData[field] <- (dogsData[fieldMin] + dogsData[fieldMax]) / 2 # Добавление поля из списка customFields как среднее между 2 соответствующими полями
}
dogsData[["Итоговый рейтинг"]] <- dogsData[["Рейтинг"]] - dogsData[["Антирейтинг"]] # Вычисление поля итогового рейтинга
DOGS_TOP_DEFAULT <- 10ui содержит разметку окна, основанную на функции fluidPage. Здесь задаётся название приложения (titlePanel), а также две визуализации, каждая из которых состоит из панели ввода (sidebarPanel) и главной панели с визуализацией (mainPanel):
ui <- fluidPage(
titlePanel("Породы собак"),
sidebarLayout( # Контейнер точечного графика
sidebarPanel(
# выпадающие списки с ранее заданными кастомными полями в customFields
selectInput("paramX", "Ось X:", choices = customFields, selected = customFields[1]),
selectInput("paramY", "Ось Y:", choices = customFields, selected = customFields[2]),
selectInput("paramSize", "Размер точек:", choices = customFields, selected = customFields[3]),
),
mainPanel(
plotOutput("scatterplot") # тег, заменяемый в server на график (plot)
)
),
sidebarLayout( # Контейнер столбчатой диаграммы
sidebarPanel(
numericInput("dogsTopCount", "Сколько пород в топе:", min = 3, max = 20, value = DOGS_TOP_DEFAULT), # поле ввода целого числа
),
mainPanel(
plotOutput("barplot") # такой же тег графика, но с другим id
)
)
)Компонент server задаётся как функция с ссылками на объекты input и output. Через input передаются фильтры и параметры, меняющиеся в разметке ui, а в output - ссылки на объекты plotOutput.
В компоненте server отдельно обрабатываются два plotOutput. В первой части рисуется точечный график, ось X, ось Y и размер точек которого зависит от выбранных в разметке полей в выпадающих списках:
output$scatterplot <- renderPlot({ # Ссылке scatterplot из output присваивается реактивный элемент
# Далее поле, выбранное для отображения меняюегося размера точек, нормализуется в диапазоне [1; 5]
size_data <- dogsData[[input$paramSize]]
min_size <- min(dogsData[[input$paramSize]], na.rm = TRUE)
max_size <- max(dogsData[[input$paramSize]], na.rm = TRUE)
cex_values <- (size_data - min_size) / (max_size - min_size) * 4 + 1
# Объявление самого точечного графика
plot(dogsData[[input$paramX]], # Испольуются значения по полю input$paramX
dogsData[[input$paramY]], # Испольуются значения по полю input$paramY
xlab = input$paramX, ylab = input$paramY, # Меняются подписи осей
cex = cex_values, # Устанавливаются нормализованные значения размера точек
pch = 21, # Фигура точки - заполненная точка
col = "black", # Цвет границы
bg = "blue", # Цвет заполнения
main = "Диаграмма рассеивания по средним показателям") # Название графика
})Столбчатая диаграмма строится на основе ранее вычисленного поля "Итоговый рейтинг":
output$barplot <- renderPlot({
dogsTopCount <- reactive({ # Переменная, хранящее количество отображаемых пород в топе
num <- input$dogsTopCount
if (is.na(num)) { # Если поле в интерфейсе не заполнено, присваивается значение по умолчанию
num <- DOGS_TOP_DEFAULT
}
return(num)
})
# Далее данные агрегируются по породе для правильной обработки
agg_data <- aggregate(dogsData[["Итоговый рейтинг"]],
by = list(Порода = dogsData[["Порода собак"]]),
FUN = mean,
na.rm = TRUE)
names(agg_data) <- c("Порода", "СреднийРейтинг")
# Берутся только первые dogsTopCount пород
topDogs <- head(agg_data[order(agg_data$СреднийРейтинг, decreasing = TRUE), ], dogsTopCount())
topDogs <- topDogs[nrow(topDogs):1, ]
# Изменение отступов графика
par(mar = c(5, 12, 4, 2) + 0.1)
barplot(topDogs$СреднийРейтинг, # Значения - рейтинг породы
names.arg = topDogs$Порода, # Подписи столбцов
horiz = TRUE, # Горизонтальная ориентация
xlab = "Итоговый рейтинг", # Подпись для оси X
main = paste0("Топ-", dogsTopCount(), " пород"), # Адаптивное название графика
col = "blue",
border = "black",
las = 2) # Подписи пород горизонтальны
})shinyApp(ui = ui, server = server)
Развёртывание на shinyapps.io
1. Установить библиотеку в консоли RStudio:
install.packages("rsconnect")2. Авторизоваться на shinyapps.io.
3. Получить токен: перейти в раздел Account -> Tokens:
4. При нажатии на кнопку Show можно будет скопировать строку подключения приложения Shiny к учётной записи:
5. Вставить в консоль RStudio скопированную строку подключения и выполнить.
6. Развернуть приложение с помощью консольной команды. Укажите полный путь к директории приложения, на Windows также экранируйте символы '\'. В этой директории должен находится app.R с полным кодом приложения, а также вспомогательный файл (для примера выше это dogs.csv):
rsconnect::deployApp("path\\to\\your\\app")По завершении развёртывания приложение отобразится на shinyapps.io и будет доступно для просмотра и взаимодействия.
Подведение итогов
Преимущества
- Использование в веб-визуализациях. Возможность браузерной реализации без знания HTML, CSS или JavaScript, и с использованием инструментария R.
- Разнообразие виджетов и шаблонов. Достаточно обширный выбор UI элементов.
- Возможность глубокой настройки внешнего вида.
- Бесплатное размещение на shinyapps.io.