<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Максим Олифиренко</title><generator>teletype.in</generator><description><![CDATA[Максим Олифиренко]]></description><image><url>https://img1.teletype.in/files/0d/be/0dbe1b20-4691-4cf3-9ecd-7436fd1b5114.png</url><title>Максим Олифиренко</title><link>https://teletype.in/@putenchik</link></image><link>https://teletype.in/@putenchik?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=putenchik</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/putenchik?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/putenchik?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sun, 26 Jul 2026 12:59:49 GMT</pubDate><lastBuildDate>Sun, 26 Jul 2026 12:59:49 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@putenchik/RMcr2tLkcLV</guid><link>https://teletype.in/@putenchik/RMcr2tLkcLV?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=putenchik</link><comments>https://teletype.in/@putenchik/RMcr2tLkcLV?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=putenchik#comments</comments><dc:creator>putenchik</dc:creator><title>Визуализации при помощи Shiny</title><pubDate>Sun, 11 May 2025 11:03:26 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/80/ad/80ad662b-10e4-441c-a0d3-77c3bf06769e.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/e8/d0/e8d06b1b-0884-47af-a25d-8b6f820b69aa.png"></img>Shiny - это R-пакет, который позволяет создавать интерактивные веб-приложения непосредственно из R. Это мощный инструмент для визуализации данных, анализа и обмена результатами с широкой аудиторией.]]></description><content:encoded><![CDATA[
  <h2 id="oNXo">Оглавление</h2>
  <nav>
    <ul>
      <li class="m_level_1"><a href="#oNXo">Оглавление</a></li>
      <li class="m_level_1"><a href="#PQTH">Основная информация о Shiny</a></li>
      <li class="m_level_2"><a href="#iHxM">Документация</a></li>
      <li class="m_level_2"><a href="#K5iF">Основные компоненты Shiny</a></li>
      <li class="m_level_2"><a href="#GILo">Применение Shiny</a></li>
      <li class="m_level_1"><a href="#XWqa">Установка Shiny</a></li>
      <li class="m_level_2"><a href="#eHBv">Использование на R</a></li>
      <li class="m_level_2"><a href="#Gfuv">Использование на Python</a></li>
      <li class="m_level_2"><a href="#Cwk1">Онлайн редактор</a></li>
      <li class="m_level_1"><a href="#x0z9">Элементы приложения Shiny</a></li>
      <li class="m_level_2"><a href="#xUGl">UI</a></li>
      <li class="m_level_2"><a href="#2V88">Server</a></li>
      <li class="m_level_1"><a href="#pjTU">Пример на датасете "Породы собак"</a></li>
      <li class="m_level_2"><a href="#smt5">Объяснение примера</a></li>
      <li class="m_level_2"><a href="#72D4">Развёртывание на shinyapps.io</a></li>
      <li class="m_level_1"><a href="#vPKe">Подведение итогов</a></li>
      <li class="m_level_2"><a href="#3dxR">Преимущества</a></li>
      <li class="m_level_2"><a href="#ZgMm">Недостатки</a></li>
    </ul>
  </nav>
  <h2 id="PQTH">Основная информация о Shiny</h2>
  <p id="0ysZ">Shiny — это веб-фреймворк для разработки веб-приложений, изначально на R, а с 2022 года на Python. Это мощный инструмент для визуализации данных, анализа и обмена результатами с широкой аудиторией.</p>
  <h3 id="iHxM">Документация</h3>
  <ul id="IGM0">
    <li id="kovr"><a href="https://shiny.posit.co" target="_blank">Официальный сайт</a> проекта;</li>
    <li id="EnVR">Быстрый старт на <a href="https://shiny.posit.co/r/getstarted/shiny-basics/lesson1/" target="_blank">языке R</a>;</li>
    <li id="9fMd">Быстрый старт на <a href="https://shiny.posit.co/py/docs/overview.html" target="_blank">Python</a>.</li>
  </ul>
  <h3 id="K5iF">Основные компоненты Shiny</h3>
  <ul id="s9CC">
    <li id="X8yq"><strong>Реактивность</strong>.Когда пользователь изменяет элемент управления (например, слайдер, поле ввода), Shiny автоматически пересчитывает результаты и обновляет выходные данные (например, графики, таблицы). Это создает отзывчивый и динамичный пользовательский интерфейс.</li>
    <li id="MF55"><strong>UI (User Interface)</strong>. Определяет визуальную структуру приложения. Он включает в себя элементы управления (виджеты) для ввода данных и элементы для отображения выходных данных, которые и обеспечивают реактивность запускаемых приложений.</li>
    <li id="7aMX"><strong>Server</strong>. Содержит логику приложения. Здесь происходит вся тяжелая работа: обработка данных, выполнение расчетов, создание графиков и таблиц.</li>
  </ul>
  <h3 id="GILo">Применение Shiny</h3>
  <ul id="Whhm">
    <li id="eBjN"><strong>Визуализация данных и дашборды</strong>. Создание интерактивных дашбордов для отслеживания ключевых показателей, визуализации трендов и предоставления информации.</li>
    <li id="6CDE"><strong>Интерактивный анализ данных</strong>. Позволяет пользователям проводить анализ данных, экспериментировать с параметрами и видеть результаты в реальном времени.</li>
    <li id="5idz"><strong>Образование и обучение</strong>. Создание интерактивных инструментов для обучения статистике, программированию и другим темам.</li>
    <li id="pirk"><strong>Разработка веб-приложений</strong>. Создание веб-приложений для анализа данных, моделирования и принятия решений.</li>
    <li id="gssS"><strong>Научные исследования</strong>. Позволяет ученым делиться своими исследованиями и результатами с коллегами и широкой аудиторией в интерактивном формате.</li>
  </ul>
  <h2 id="XWqa">Установка Shiny</h2>
  <h3 id="eHBv">Использование на R</h3>
  <p id="tVqC">Перейти по ссылке и скачать установщик языка R: <a href="https://cran.rstudio.com/bin/windows/base/" target="_blank">https://cran.rstudio.com/bin/windows/base/</a>. После запуска установщика можно выбрать предпочитаемый язык и корневую директорию языка, после чего установить его.</p>
  <p id="Spq6">Со станицы установки RStudio скачать его установщик:<br /><a href="https://posit.co/download/rstudio-desktop/" target="_blank">https://posit.co/download/rstudio-desktop/</a>. После его загрузки также можно выбрать корневую директорию утилиты.</p>
  <p id="LlIG">Установка Shiny возможна либо через консоль, либо с помощью интерфейса среды. В первом случае необходимо открыть консоль (Console) и установить пакет:</p>
  <pre id="6jpw" data-lang="r">install.packages(&quot;shiny&quot;)</pre>
  <p id="4HMV">Второй способ: при указании библиотеки Shiny в коде приложения RStudio сам предложит установить необходимые зависимости.</p>
  <h3 id="Gfuv">Использование на Python</h3>
  <pre id="vOCC" data-lang="bash">pip install --upgrade pip wheel           # обновление утановщика пакетов</pre>
  <pre id="nERA" data-lang="bash">pip install shiny                         # установка библиотеки</pre>
  <pre id="Q8cZ" data-lang="bash">pip install --upgrade shiny htmltools     # или её обновление</pre>
  <h3 id="Cwk1">Онлайн редактор</h3>
  <p id="00pM">Помимо локальной разработки своих приложений Shiny имеет официальный <a href="https://shinylive.io/r/editor/" target="_blank">онлайн редактор</a>, который позволяет писать код приложения Shiny на R прямо в браузере и наблюдать изменения в реальном времени.</p>
  <figure id="LpfP" class="m_column">
    <img src="https://img4.teletype.in/files/fa/ee/faee0974-8123-47d0-8a4b-ad76b688ea2a.png" width="1920" />
    <figcaption>Исходный пример в онлайн редакторе Shiny</figcaption>
  </figure>
  <h2 id="x0z9">Элементы приложения Shiny</h2>
  <p id="2p9C">После установки всех инструментов становится возможным создание визуализаций на Shiny. Для использования библиотеки в файле с расширением <code>.R</code>:</p>
  <pre id="vKx9" data-lang="r">library(shiny)</pre>
  <p id="ej5v">Приложение Shiny создаётся вызовом функции <code>shinyApp</code>:</p>
  <pre id="3wsm" data-lang="r">shinyApp(ui = ui, server = server)</pre>
  <p id="2s7u">В ней указываются 2 основных элемента:</p>
  <ul id="N1qm">
    <li id="jdIO"><code>ui</code> - пользовательский интерфейс, определяющий инструменты ввода данных и параметров, вывода текста или визуализаций, фильтры. Все эти функции генерируют HTML-разметку.</li>
    <li id="2hJQ"><code>server</code> - логика приложения, обрабатывающая передаваемые интерфейсом данные и производящая рендер графиков.</li>
  </ul>
  <h3 id="xUGl">UI</h3>
  <p id="R9MX">Разметку макета можно задавать несколькими функциями, которые будут задавать вёрстку и расположение её дочерних элементов. Вот основные из них:</p>
  <ul id="Qbhe">
    <li id="kXF3"><code>fluidPage</code>: создает макет, который масштабируется в зависимости от размера окна браузера. Рекомендуется для большинства приложений. Он использует систему сеток Bootstrap.</li>
    <li id="gLyO"><code>fixedPage</code>: создает макет фиксированной ширины.</li>
    <li id="AAcM"><code>sidebarLayout</code>: создает макет с боковой панелью и основной панелью. Принимает два аргумента: <code>sidebarPanel</code> и <code>mainPanel</code>.</li>
    <li id="zUZl">Другие макеты: <code>fillPage</code>, <code>splitLayout</code>, <code>verticalLayout</code> .</li>
  </ul>
  <p id="IY7a">Элементы управления ввода (input widgets) позволяют пользователям вводить данные или взаимодействовать с приложением:</p>
  <ul id="gzZQ">
    <li id="cBV4"><code>textInput</code> - текстовое поле для ввода текста.</li>
    <li id="jsz2"><code>numericInput</code> - числовое поле для ввода чисел.</li>
    <li id="cFTP"><code>sliderInput</code> - слайдер для выбора числового значения.</li>
    <li id="38RF"><code>selectInput</code> - выпадающий список для выбора из списка вариантов.</li>
    <li id="HRY9"><code>radioButtons</code> - радиокнопки для выбора одного варианта из списка.</li>
    <li id="d14p"><code>checkboxGroupInput</code> - набор флажков для выбора нескольких вариантов из списка.</li>
    <li id="zMlI"><code>checkboxInput</code> - одиночный флажок (логическое значение).</li>
    <li id="CURq"><code>dateInput</code> - выбор даты.</li>
    <li id="wXaY"><code>dateRangeInput</code> - выбор диапазона дат.</li>
    <li id="8LwJ"><code>fileInput</code> - загрузка файла.</li>
    <li id="GkT3"><code>actionButton</code> - кнопка.</li>
  </ul>
  <p id="kmmT">Элементы вывода (output elements) отображают результаты в приложении. Связываются с Server через <code>output$</code> переменную. Примеры:</p>
  <ul id="E8rM">
    <li id="EZzQ"><code>plotOutput</code> - место для отображения графика.</li>
    <li id="Mobr"><code>tableOutput</code> - место для отображения таблицы.</li>
    <li id="c2aE"><code>dataTableOutput</code> - место для отображения интерактивной таблицы данных.</li>
  </ul>
  <h3 id="2V88">Server</h3>
  <p id="hEjE">Server содержит логику приложения. Он получает входные данные от UI (input), выполняет расчеты и рендерит выходные данные для отображения в UI (output). <code>server</code> в коде - это R-фукнция, имеющая 2 параметра:</p>
  <pre id="xP76" data-lang="r">server &lt;- function(input, output) {
     // Логика обработки данных
}</pre>
  <p id="WRxx">Функции рендеринга (rendering functions) преобразуют результаты R-кода в формат, который можно отобразить в UI. Они всегда должны быть внутри функции server.</p>
  <ul id="zman">
    <li id="9U1B"><code>renderPlot</code>: рендерит график, созданный с использованием функций plot(), ggplot2 и т.д. Возвращает графический объект.</li>
    <li id="VSQJ"><code>renderTable</code>: рендерит таблицу данных (например, data.frame). Возвращает таблицу.</li>
    <li id="Owrx"><code>renderDataTable</code>: рендерит интерактивную таблицу данных с возможностью сортировки, фильтрации и постраничной навигации (требует пакет DT). Возвращает таблицу.</li>
    <li id="k3XB"><code>renderText</code>: рендерит текстовую строку. Возвращает строку.</li>
    <li id="FU3G"><code>renderPrint</code>: рендерит вывод R-кода. Возвращает результат, который можно распечатать в консоли.</li>
    <li id="Q0Yl"><code>renderUI</code>: рендерит UI-элементы. Используется для динамического создания UI. Возвращает HTML-код для элемента UI.</li>
    <li id="5QkG"><code>renderImage</code>: рендерит изображение. Возвращает список, содержащий информацию об изображении (путь, mime-тип, ширина, высота).</li>
  </ul>
  <h2 id="pjTU">Пример на датасете &quot;Породы собак&quot;</h2>
  <p id="v96r">Далее будет разобран простой пример приложения Shiny с 2 визуализациями, построенными на датасете <a href="https://raw.githubusercontent.com/yupest/nti/master/%D0%9D%D0%A2%D0%98-2021/dogs.csv" target="_blank">&quot;Породы собак&quot;</a>, а также развёрнутом в сервисе <a href="https://www.shinyapps.io" target="_blank">shinyapps.io</a>.</p>
  <figure id="ypbx" class="m_column">
    <img src="https://img3.teletype.in/files/e8/d0/e8d06b1b-0884-47af-a25d-8b6f820b69aa.png" width="834" />
    <figcaption>Внешний вид получившегося приложения</figcaption>
  </figure>
  <h3 id="smt5">Объяснение примера</h3>
  <p id="nVUr">Сперва, подключаются библиотеки:</p>
  <pre id="4l1P" data-lang="r">library(shiny)     # Сама Shiny
library(readr)     # Библиотека для чтения датасета из файла CSV</pre>
  <p id="Ccdo">Затем читается датасет из файла, добавляются вычисляемые поля и устанавливаются константы:</p>
  <pre id="elxm" data-lang="r">dogsData &lt;- read_csv(&quot;dogs.csv&quot;)  # Чтение датасета из файла в той же директории, что и приложение
customFields &lt;- c(&quot;Вес&quot;, &quot;Рост&quot;, &quot;Продолжительность жизни&quot;, &quot;Стоимость&quot;)
for (field in customFields) {
  fieldMin &lt;- paste0(field, &quot; мин&quot;)
  fieldMax &lt;- paste0(field, &quot; макс&quot;)
  dogsData[field] &lt;- (dogsData[fieldMin] + dogsData[fieldMax]) / 2  # Добавление поля из списка customFields как среднее между 2 соответствующими полями
}
dogsData[[&quot;Итоговый рейтинг&quot;]] &lt;- dogsData[[&quot;Рейтинг&quot;]] - dogsData[[&quot;Антирейтинг&quot;]]  # Вычисление поля итогового рейтинга

DOGS_TOP_DEFAULT &lt;- 10</pre>
  <p id="Ul6B"><code>ui</code> содержит разметку окна, основанную на функции <code>fluidPage</code>. Здесь задаётся название приложения (<code>titlePanel</code>), а также две визуализации, каждая из которых состоит из панели ввода (<code>sidebarPanel</code>) и главной панели с визуализацией (<code>mainPanel</code>):</p>
  <pre id="3zvg" data-lang="r">ui &lt;- fluidPage(
  titlePanel(&quot;Породы собак&quot;),
  sidebarLayout(   # Контейнер точечного графика
    sidebarPanel(
      # выпадающие списки с ранее заданными кастомными полями в customFields
      selectInput(&quot;paramX&quot;, &quot;Ось X:&quot;, choices = customFields, selected = customFields[1]),
      selectInput(&quot;paramY&quot;, &quot;Ось Y:&quot;, choices = customFields, selected = customFields[2]),
      selectInput(&quot;paramSize&quot;, &quot;Размер точек:&quot;, choices = customFields, selected = customFields[3]),
    ),
    mainPanel(
      plotOutput(&quot;scatterplot&quot;)  # тег, заменяемый в server на график (plot)
    )
  ),
  sidebarLayout(   # Контейнер столбчатой диаграммы
    sidebarPanel(
      numericInput(&quot;dogsTopCount&quot;, &quot;Сколько пород в топе:&quot;, min = 3, max = 20, value = DOGS_TOP_DEFAULT),  # поле ввода целого числа
    ),
    mainPanel(
      plotOutput(&quot;barplot&quot;)  # такой же тег графика, но с другим id
    )
  )
)</pre>
  <p id="QUwt">Компонент <code>server</code> задаётся как функция с ссылками на объекты <code>input</code> и <code>output</code>. Через <code>input</code> передаются фильтры и параметры, меняющиеся в разметке <code>ui</code>, а в <code>output</code> - ссылки на объекты <code>plotOutput</code>.</p>
  <p id="yz49">В компоненте <code>server</code> отдельно обрабатываются два <code>plotOutput</code>. В первой части рисуется точечный график, ось X, ось Y и размер точек которого зависит от выбранных в разметке полей в выпадающих списках:</p>
  <pre id="l4Zv" data-lang="r">output$scatterplot &lt;- renderPlot({  # Ссылке scatterplot из output присваивается реактивный элемент
    # Далее поле, выбранное для отображения меняюегося размера точек, нормализуется в диапазоне [1; 5]
    size_data &lt;- dogsData[[input$paramSize]]
    min_size &lt;- min(dogsData[[input$paramSize]], na.rm = TRUE)
    max_size &lt;- max(dogsData[[input$paramSize]], na.rm = TRUE)
    cex_values &lt;- (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 = &quot;black&quot;,     # Цвет границы
         bg = &quot;blue&quot;,       # Цвет заполнения
         main = &quot;Диаграмма рассеивания по средним показателям&quot;)  # Название графика
  })</pre>
  <p id="x7qv">Столбчатая диаграмма строится на основе ранее вычисленного поля <code>&quot;Итоговый рейтинг&quot;</code>:</p>
  <pre id="NJ3S" data-lang="r">output$barplot &lt;- renderPlot({
    dogsTopCount &lt;- reactive({     # Переменная, хранящее количество отображаемых пород в топе
      num &lt;- input$dogsTopCount
      if (is.na(num)) {            # Если поле в интерфейсе не заполнено, присваивается значение по умолчанию
        num &lt;- DOGS_TOP_DEFAULT
      }
      return(num)
    })
    
    # Далее данные агрегируются по породе для правильной обработки
    agg_data &lt;- aggregate(dogsData[[&quot;Итоговый рейтинг&quot;]],
                          by = list(Порода = dogsData[[&quot;Порода собак&quot;]]),
                          FUN = mean,
                          na.rm = TRUE)
    names(agg_data) &lt;- c(&quot;Порода&quot;, &quot;СреднийРейтинг&quot;)
    # Берутся только первые dogsTopCount пород
    topDogs &lt;- head(agg_data[order(agg_data$СреднийРейтинг, decreasing = TRUE), ], dogsTopCount())
    topDogs &lt;- topDogs[nrow(topDogs):1, ]
    
    # Изменение отступов графика
    par(mar = c(5, 12, 4, 2) + 0.1)
    
    barplot(topDogs$СреднийРейтинг,          # Значения - рейтинг породы
            names.arg = topDogs$Порода,      # Подписи столбцов
            horiz = TRUE,                    # Горизонтальная ориентация
            xlab = &quot;Итоговый рейтинг&quot;,       # Подпись для оси X
            main = paste0(&quot;Топ-&quot;, dogsTopCount(), &quot; пород&quot;),   # Адаптивное название графика
            col = &quot;blue&quot;,
            border = &quot;black&quot;,
            las = 2)                         # Подписи пород горизонтальны
  })</pre>
  <p id="Jtw7">Запуск приложения:</p>
  <pre id="cyvN" data-lang="r">shinyApp(ui = ui, server = server)</pre>
  <h3 id="72D4">Развёртывание на shinyapps.io</h3>
  <p id="3l1Z">1. Установить библиотеку в консоли RStudio:</p>
  <pre id="r127" data-lang="r">install.packages(&quot;rsconnect&quot;)</pre>
  <p id="KVmG">2. Авторизоваться на <a href="https://www.shinyapps.io" target="_blank">shinyapps.io</a>.</p>
  <p id="JZ3f">3. Получить токен: перейти в раздел Account -&gt; Tokens:</p>
  <figure id="dajZ" class="m_column">
    <img src="https://img2.teletype.in/files/d2/67/d267e7c5-6445-45a4-896e-72ad6484766e.png" width="974" />
    <figcaption>Блок с токеном <a href="https://www.shinyapps.io" target="_blank">shinyapps.io</a></figcaption>
  </figure>
  <p id="OHwm">4. При нажатии на кнопку <code>Show</code> можно будет скопировать строку подключения приложения Shiny к учётной записи:</p>
  <figure id="8r1o" class="m_column">
    <img src="https://img3.teletype.in/files/22/6f/226fd4de-1bc0-427a-a0d7-6413e560b6be.png" width="898" />
    <figcaption>Строка подключения приложения Shiny к <a href="https://www.shinyapps.io" target="_blank">shinyapps.io</a></figcaption>
  </figure>
  <p id="ccJn">5. Вставить в консоль RStudio скопированную строку подключения и выполнить.</p>
  <p id="NtEq">6. Развернуть приложение с помощью консольной команды. Укажите полный путь к директории приложения, на Windows также экранируйте символы <code>&#x27;\&#x27;</code>. В этой директории должен находится <code>app.R</code> с полным кодом приложения, а также вспомогательный файл (для примера выше это <code>dogs.csv</code>):</p>
  <pre id="DyCa" data-lang="r">rsconnect::deployApp(&quot;path\\to\\your\\app&quot;)</pre>
  <p id="wuVe">По завершении развёртывания приложение отобразится на <a href="https://www.shinyapps.io" target="_blank">shinyapps.io</a> и будет доступно для просмотра и взаимодействия.</p>
  <h2 id="vPKe">Подведение итогов</h2>
  <h3 id="3dxR">Преимущества</h3>
  <ul id="RYIF">
    <li id="qgbe">Использование в веб-визуализациях. Возможность браузерной реализации без знания HTML, CSS или JavaScript, и с использованием инструментария R.</li>
    <li id="8Yy9">Разнообразие виджетов и шаблонов. Достаточно обширный выбор UI элементов.</li>
    <li id="50kM">Возможность глубокой настройки внешнего вида.</li>
    <li id="Ph4I">Бесплатное размещение на <a href="https://www.shinyapps.io" target="_blank">shinyapps.io</a>.</li>
  </ul>
  <h3 id="ZgMm">Недостатки</h3>
  <ul id="Wo50">
    <li id="K17V">Использование непопулярного R.</li>
    <li id="2crr">Плохая производительность языка R.</li>
    <li id="mFaR">Невозможность или большая сложность постройки сложных UI.</li>
  </ul>

]]></content:encoded></item></channel></rss>