Введение в библиотеку Highcharter

примеры работы в библиотеке highcharter для визуализации интерактивных диаграмм в R

Библиотека highcharter

Для внедрения HTML-виджетов в отчеты как веб-приложения, в R имеется большое количество различных инструментов, позволяющих создавать интерактивные диаграммы и карты, таких как

Больше примеров различных HTML-виджетов можно посмотреть на странице www.htmlwidgets.org. Преимуществом этих средств визуализации является то, что они не требуют настройки серверной части как в Shiny. К недостаткам можно отнести необходимость разбираться в “диалектах” каждого из инструментов.

Библиотека highcharter является одним из эффективных средств для интерактивной визуализации данных. Это обертка для JavaScript-библиотеки Highcharts на основе SVG, которая обладает гибкими настройками и мощным API. Отметим, что для коммерческого и правительственного использования highcharts не является бесплатным, при этом лицензия highcharter не предоставляет и не подразумевает лицензию для highcharts.

Установить библиотеку возможно как с CRAN:

install.packages("highcharter")

так и с GitHub:

remotes::install_github("jbkunst/highcharter")

Примеры использования highcharter

Подключим библиотеку:

library(highcharter)

Подключим дополнительные библиотеки.

library(tidyverse)
library(magrittr)

highcharter позволяет создавать графики с использованием двух основных функций:

  • highchart(), которая создает диаграммы с использованием HTML-виджетов, при этом можно добавлять дополнительные геометрические слои к имеющимся построениям.

  • hchart() – универсальная функция для создания диаграмм, представляющих собой объект highchart.

Например, для отрисовки диаграммы в hchart(), используется структура

hchart(<data.frame>, <type_of_chart>, hcaes(<aesthetics>), ...)

здесь:

  • <data.frame> – таблица данных для построения диаграммы,

  • <type_of_chart> представляет собой строку для указания типа диаграммы; это значение может быть: линия, сплайн, область, тепловая карта, и т.д,

  • <aesthetics> – используемое отображение для отрисовки данных,

  • ... – другие параметры настройки диаграммы.

Географические карты в highcharter

Покажем, как можно визуализировать простейшие геоданные в highcharter. В качестве примера визуализируем на карте Российской Федерации города с населением свыше 300 000 чел. Актуальные данные по городам РФ можно получить с сайта ИНИД (на момент написания статьи на 12.03.2021). После простейшей предобработки таблица с данными выглядит следующим образом.

cities_300 
## # A tibble: 65 × 4
##    name             population   lon   lat
##    <chr>                 <dbl> <dbl> <dbl>
##  1 Калининград          467289  20.4  54.7
##  2 Пенза                522317  45    53.2
##  3 Владимир             356168  40.4  56.1
##  4 Иркутск              623479 104.   52.3
##  5 Оренбург             561686  55.1  51.8
##  6 Архангельск          348343  40.5  64.5
##  7 Саранск              318578  45.2  54.2
##  8 Набережные Челны     524444  52.4  55.7
##  9 Ярославль            603961  39.9  57.6
## 10 Чебоксары            492331  47.2  56.1
## # … with 55 more rows

Добавим цвет для визуального отображения количества населения в каждой точке.

cities_300 <- cities_300 %>% 
  mutate(colors = colorize(population))

Непосредственно подложка карты скачивается со страницы Highcharts, затем добавляется слой с городами, tooltip отвечает за всплывающие подсказки.

hcmap("countries/ru/custom/ru-all-disputed", showInLegend = FALSE) %>% 
  hc_add_series(
    data = cities_300, 
    type = "mappoint",
    hcaes(color = colors),
    name = "Город",
    tooltip = list(pointFormat = "{point.name}: {point.population:,.0f} чел.")
  ) %>% 
  hc_title(text = "Города с населением свыше 300 000 чел.") %>% 
  hc_subtitle(text = "на 12.03.2021")

Другой пример построения карт показывает, как можно визуализировать глобальную карту. В качестве примера используем Global Climate Change Data (источник: Berkeley Earth).

AverageTemperature
## # A tibble: 169 × 3
##    country              aveT iso3 
##    <chr>               <dbl> <chr>
##  1 Afghanistan            15 AFG  
##  2 Albania                14 ALB  
##  3 Algeria                24 DZA  
##  4 Andorra                12 ADO  
##  5 Antigua and Barbuda    27 ATG  
##  6 Argentina              15 ARG  
##  7 Armenia                10 ARM  
##  8 Australia              22 AUS  
##  9 Austria                 7 AUT  
## 10 Azerbaijan             13 AZE  
## # … with 159 more rows
hcmap(
  "custom/world-robinson-lowres", 
  data = AverageTemperature,
  name = "температура", 
  value = "aveT",
  # необходимо сделать join стандартных индексов карты "iso-a3"
  # и индексов стран из данных -- переменной "iso3"
  joinBy        = c("iso-a3", "iso3"), 
  borderWidth   = 0,
  nullColor     = "#d3d3d3",
  tooltip       = list(valueSuffix = "°C")
  ) %>%
  hc_colorAxis(
    stops = color_stops(colors = viridisLite::inferno(10, begin = 0.1))
  ) %>% 
  hc_title(text    = "Средняя температура земной поверхности") %>% 
  hc_subtitle(text = "за период 2000-2013 гг.")

Русификация highcharter

Идея переопределения языковых опций в highcharter основана на Stack Overflow 1, Stack Overflow 2 и Highcharts Configuration options. Сначала необходимо получить текущие настройки локализации в переменную lang.

lang <- getOption("highcharter.lang")

Например, для сокращений дней недели:

lang$shortWeekdays <- c("Сб", "Вс", "Пн", "Вт", "Ср", "Чт", "Пт")

После переопределения настроек их необходимо сохранить.

options(highcharter.lang = lang)

Отображение биржевых котировок

Библиотека highcharter может служить для отображения актуальных биржевых котировок на основе API библиотеки quantmod. Ниже приведен пример для отображения торгов Apple.

library(quantmod)

AAPL <- getSymbols("AAPL", 
                  from = Sys.Date() - lubridate::years(1), 
                  auto.assign = FALSE)

AAPL <- AAPL %>% na.omit()

AAPL.ave <- SMA(Cl(AAPL), n = 5)
highchart(type = "stock") %>% 
  hc_add_series(AAPL, 
                yAxis = 0, 
                name  = "AAPL") %>% 
  hc_add_series(AAPL.ave, 
                yAxis = 0, 
                name  = "скользящее среднее AAPL",
                color = hex_to_rgba("blue", 0.7)) %>% 
  hc_tooltip(valueDecimals = 2) %>% 
  hc_title(text = "Котировки Apple") %>% 
    hc_exporting(
    enabled = TRUE
  )

Вложенные диаграммы

Библиотека highcharter позволяет формировать диаграммы, в компактной форме представляющие сложную информацию при помощи вложений. В качестве примера мы рассмотрим ежедневное количество пожаров в Российской Федерации за апрель 2020 года по различным категориям.

fire_hc
## # A tibble: 126 × 3
##    dt         type_name            count
##    <chr>      <chr>                <int>
##  1 01.04.2020 Контролируемый пал     517
##  2 01.04.2020 Лесной пожар            48
##  3 01.04.2020 Неконтролируемый пал   150
##  4 01.04.2020 Природный пожар         83
##  5 02.04.2020 Контролируемый пал     397
##  6 02.04.2020 Лесной пожар            75
##  7 02.04.2020 Неконтролируемый пал   365
##  8 02.04.2020 Природный пожар        124
##  9 03.04.2020 Контролируемый пал     378
## 10 03.04.2020 Лесной пожар            57
## # … with 116 more rows

Создадим переменную fire_column, отвечающую за первый уровень вложенной столбцовой диаграммы.

fire_column <- fire_hc %>% 
  group_by(type_name) %>% 
  summarise(count = sum(count)) %>% 
  ungroup()

fire_column <- fire_column %>% arrange(desc(count))

Внутренней части диаграммы будет отвечать переменная fire_drilldown.

fire_drilldown <- fire_hc %>% 
  group_nest(type_name) %>% 
  mutate(
    id   = type_name,
    type = "column",
    data = map(data, mutate, name = dt, y = count),
    data = map(data, list_parse))

fire_drilldown
## # A tibble: 5 × 4
##   type_name            data        id                   type  
##   <chr>                <list>      <chr>                <chr> 
## 1 Контролируемый пал   <list [30]> Контролируемый пал   column
## 2 Лесной пожар         <list [30]> Лесной пожар         column
## 3 Неконтролируемый пал <list [30]> Неконтролируемый пал column
## 4 Природный пожар      <list [30]> Природный пожар      column
## 5 Торфяной пожар       <list [6]>  Торфяной пожар       column

Отрисовка диаграммы выглядит следующим образом. Кликнув по соответствующему столбцу, можно развернуть ежедневную статистику.

hchart(fire_column,
       "column",
       hcaes(
         x         = type_name,
         y         = count,
         name      = type_name, 
         drilldown = type_name
       ),
       name = "количество пожаров",
       colorByPoint = TRUE
) %>% 
  hc_drilldown(
    allowPointDrilldown = TRUE,
    series = list_parse(fire_drilldown)
  ) %>% 
  hc_xAxis(title   = "") %>% 
  hc_yAxis(title   = "") %>% 
  hc_title(text    = "Количество пожаров на территории Российской Федерации") %>% 
  hc_subtitle(text = "в апреле 2020 года") %>% 
  hc_caption(text  = "по данным МЧС России") %>%
  hc_add_theme(hc_theme_smpl())

highcharter имеет богатые возможности для стилизации отображения диаграмм. Например, можно кастомизировать

Пример применения различных тем

Загрузим данные по погоде за последние несколько лет в г. Красноярске, которые были полученны с Climate Data Online Search NOAA.

Нас будут интересовать средние температуры воздуха в каждом месяце с 2013 года.

weather_month
## # A tibble: 111 × 3
##     YEAR MONTH   TAVE
##    <dbl> <ord>  <dbl>
##  1  2013 янв   -17.1 
##  2  2013 фев   -15.3 
##  3  2013 мар    -7.59
##  4  2013 апр     3.24
##  5  2013 май     7.44
##  6  2013 июн    14.9 
##  7  2013 июл    17.1 
##  8  2013 авг    16.3 
##  9  2013 сен     7.36
## 10  2013 окт     2.71
## # … with 101 more rows

Сформируем из этих данных временной ряд и спрогнозируем значения временного ряда на 2 года (24 месяца) вперед.

library(forecast)
weather_month_ts <- ts(weather_month["TAVE"], 
              start = c(2014, 1), frequency = 12)

weather_forecast <- forecast(ets(weather_month_ts), h = 24, level = 95)

weather_forecast %>% head(3)
## $model
## ETS(A,N,A) 
## 
## Call:
##  ets(y = weather_month_ts) 
## 
##   Smoothing parameters:
##     alpha = 0.0604 
##     gamma = 1e-04 
## 
##   Initial states:
##     l = 1.7846 
##     s = -13.0473 -10.3034 -0.3558 7.0051 14.8059 16.1051
##            14.7342 7.2403 2.0963 -5.9703 -15.0449 -17.2652
## 
##   sigma:  2.896
## 
##      AIC     AICc      BIC 
## 766.0081 771.1145 806.5153 
## 
## $mean
##              Jan         Feb         Mar         Apr         May         Jun
## 2023                          -5.8803329   2.1864264   7.3302530  14.8240981
## 2024 -17.1748906 -14.9548991  -5.8803329   2.1864264   7.3302530  14.8240981
## 2025 -17.1748906 -14.9548991                                                
##              Jul         Aug         Sep         Oct         Nov         Dec
## 2023  16.1950579  14.8957324   7.0949640  -0.2656256 -10.2131336 -12.9573190
## 2024  16.1950579  14.8957324   7.0949640  -0.2656256 -10.2131336 -12.9573190
## 2025                                                                        
## 
## $level
## [1] 95
hc_weather <- hchart(weather_forecast) %>% 
  hc_title(
    text = "Прогноз средних температур воздуха в г. Красноярске (в °C)"
  ) %>% 
  hc_tooltip(shared = TRUE, 
             valueDecimals = 1)

Теперь отобразим полученный результат используя стилизованную тему.

hc_weather %>%
  hc_add_theme(hc_theme_smpl())

Отобразим тот же график используя другие темы.

hc_weather %>%
  hc_add_theme(hc_theme_google())
hc_weather %>%
  hc_add_theme(hc_theme_538())

3D-диаграммы

Эффектно выглядят 3D-диаграммы. Покажем, как выглядит диаграмма средних температур воздуха в г. Красноярске за 3 года.

# данные
weather_hc <-
weather_df %>% 
  filter(YEAR %in% c("2018","2019", "2020")) %>% 
  group_by(YEAR, MONTH) %>% 
  summarise(ave = round(mean(TAVE, na.rm = T), 1)) %>% 
  ungroup()

weather_hc
## # A tibble: 36 × 3
##     YEAR MONTH   ave
##    <dbl> <ord> <dbl>
##  1  2018 Янв   -21.2
##  2  2018 Фев   -15  
##  3  2018 Мар    -6.3
##  4  2018 Апр     3.3
##  5  2018 Май     7.4
##  6  2018 Июн    19.1
##  7  2018 Июл    16.7
##  8  2018 Авг    17.2
##  9  2018 Сен    10.1
## 10  2018 Окт     5.3
## # … with 26 more rows
# базовая диаграмма
hc <- highchart() %>% 
  hc_xAxis(categories = weather_hc$MONTH) %>% 
  hc_add_series(
    name = "2018", 
    tooltip = list(
      valueSuffix = "°C"
    ), 
    data = (weather_hc %>% filter(YEAR == "2018"))$ave
  ) %>% 
  hc_xAxis(categories = weather_hc$MONTH) %>% 
  hc_add_series(
    name = "2019", 
    tooltip = list(
      valueSuffix = "°C"
    ),
    data = (weather_hc %>% filter(YEAR == "2019"))$ave
  ) %>% 
  hc_xAxis(categories = weather_hc$MONTH) %>% 
  hc_add_series(
    name = "2020", 
    tooltip = list(
      valueSuffix = "°C"
    ),
    data = (weather_hc %>% filter(YEAR == "2020"))$ave
  ) %>% 
  hc_add_theme(hc_theme_bloom()) %>% 
  hc_credits(
    text = "Диаграмма создана при использовании R и highcharter",
    href = "https://jkunst.com/highcharter/",
    enabled = TRUE
  )  %>% 
  hc_title(
    text = "Средние температуры воздуха в г. Красноярске в 2018-2020 гг."
  )
# 3D-версия диаграммы
hc %>% 
  hc_chart(
    type = "column",
    options3d = list(
      enabled = TRUE, 
      beta = 15,
      alpha = 15
    )
  )

Заключение

В статье были рассмотрены некоторые простейшие примеры создания визуализаций на основе highcharter и русификации библиотеки.

Больше различных примеров визуализаций в библиотеке highcharter можно найти на

Евгений Матеров
Евгений Матеров
Зав. кафедрой физики, математики и информационных технологий

Область моих научных интересов включает в себя Data Science, машинное обучение, язык программирования R.

Похожие