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

Обзор библиотеки highcharter для визуализации интерактивной графики

highcharter
Rstats
Автор

Е.Н. Матеров

Дата публикации

16 марта 2022 г.

Обновлено

4 марта 2024 г.

Библиотека highcharter

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

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

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

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

install.packages("highcharter")

так и с GitHub:

remotes::install_github("jbkunst/highcharter")

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

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

library(highcharter)

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

library(tidyverse)
library(magrittr)

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

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

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

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

здесь:

  • <data.frame> – таблица данных для построения диаграммы;
  • <type_of_chart> представляет собой строку для указания типа диаграммы; это значение может быть: линия, сплайн, область, тепловая карта, и т.д;
  • <aesthetics> – используемое отображение для отрисовки данных;
  • hcaes работает подобно aes в ggplot2;
  • ... – другие параметры настройки диаграммы.

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

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

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
# ℹ 55 more rows

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

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

Непосредственно подложка карты скачивается со страницы Highcharts2, затем добавляется слой с городами, параметр 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  
# ℹ 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("Сб", "Вс", "Пн", "Вт", "Ср", "Чт", "Пт")
Полный код локализации
lang$contextButtonTitle <- "Контекстное меню диаграммы"

lang$decimalPoint <- ","

lang$downloadCSV  <- "Загрузить CSV"
lang$downloadJPEG <- "Загрузить JPEG"
lang$downloadPDF  <- "Загрузить PDF"
lang$downloadPNG  <- "Загрузить PNG"
lang$downloadSVG  <- "Загрузить SVG"
lang$downloadXLS  <- "Загрузить XLS"

lang$drillUpText <- "◁ Назад к {series.name}"

lang$exitFullscreen <- "Выход из полноэкранного режима"

lang$exportData$annotationHeader <- "Аннотации"

lang$exportData$categoryHeader <- "Категория"

lang$hideData <- "Скрыть таблицу данных"

lang$loading <- "Загрузка..."

lang$months <- c("Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь")

lang$noData <- "Нет данных для отображения"

lang$printChart <- "Печать диаграммы"

lang$resetZoom <- "Сброс масштабирования"

lang$resetZoomTitle <- "Сброс масштабирования к 1:1"

lang$shortMonths <- c("Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек")

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

lang$thousandsSep <- " "

lang$viewData <- "Просмотр таблицы данных"

lang$viewFullscreen <- "Просмотр в полноэкранном режиме"

lang$weekdays <- c("Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота")

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

options(highcharter.lang = lang)

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

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

Код
library("quantmod")

# https://itecnote.com/tecnote/r-convert-between-zoo-object-and-data-frame-results-inconsistent-for-different-numbers-of-columns/
zooToDf <- function(z) {
  df <- as.data.frame(z) 
  df$Date <- time(z)   #create a Date column
  rownames(df) <- NULL #so row names not filled with dates
  df <- df[,c(ncol(df), 1:(ncol(df)-1))] #reorder columns so Date first
  return(df)
}

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

AAPL <- AAPL |> na.omit()

AAPL.ave <- SMA(Cl(AAPL), n = 5)

AAPL_df <- zooToDf(AAPL) |> as_tibble()

data_flags <- tibble(
  date = as.Date(c("2023-06-05", "2023-09-12", "2023-10-30")),
  title = c("WWDC 2023", "Apple event '23", "Scary fast event"),
  text = c("Apple Vision Pro", "iPhone 15", "M3 chips")
)

highchart(type = "stock") |>
  hc_add_theme(hc_theme_hcrt()) |>
  hc_add_series(AAPL, 
                id = 1,
                yAxis = 0, 
                name  = "AAPL") |>
  hc_add_series(AAPL.ave, 
                yAxis = 0, 
                name  = "скользящее среднее AAPL",
                color = hex_to_rgba("blue", 0.6)) |>
  hc_tooltip(valueDecimals = 2) |>
  hc_yAxis(labels = list(format = "${value}")) |>
  #hc_title(text = "Котировки Apple за последний год") %>% 
    hc_exporting(
    enabled = TRUE
  ) |> 
  hc_add_series(
    data_flags, 
    hcaes(x = date),
    type = "flags", 
    onSeries = 1
    )

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

Загрузим данные GISS Surface Temperature Analysis по средним температурам для оценки глобального изменения температуры земной поверхности за последние несколько лет в г. Красноярске. Графики и таблицы обновлялись примерно в середине каждого месяца с использованием текущих файлов данных NOAA GHCN v4 для метеорологических станций.

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

weather_long
# A tibble: 72 × 3
    year month temp_ave
   <dbl> <fct>    <dbl>
 1  2013 ЯНВ     -16.3 
 2  2013 ФЕВ     -14.3 
 3  2013 МАР      -6.45
 4  2013 АПР       4.71
 5  2013 МАЙ       8.81
 6  2013 ИЮН      15.7 
 7  2013 ИЮЛ      18.1 
 8  2013 АВГ      16.5 
 9  2013 СЕН       7.9 
10  2013 ОКТ       2.4 
# ℹ 62 more rows

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

Код
library(forecast)

weather_month_ts <- ts(weather_long["temp_ave"], 
                       start = c(2013, 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 = 1e-04 
    gamma = 1e-04 

  Initial states:
    l = 2.7551 
    s = -12.3157 -10.3952 -0.9107 6.561 14.5926 16.6841
           15.0192 6.8878 2.8664 -5.9789 -14.7177 -18.2929

  sigma:  2.958

     AIC     AICc      BIC 
478.5228 487.0943 512.6728 

$mean
            Jan        Feb        Mar        Apr        May        Jun
2019 -15.537883 -11.962662  -3.223877   5.621412   9.642804  17.774297
2020 -15.537883 -11.962662  -3.223877   5.621412   9.642804  17.774297
            Jul        Aug        Sep        Oct        Nov        Dec
2019  19.439087  17.347607   9.316062   1.844221  -7.640216  -9.560651
2020  19.439087  17.347607   9.316062   1.844221  -7.640216  -9.560651

$level
[1] 95

Теперь создадим базовый highcharter-график.

Код
hc_weather <- hchart(weather_forecast) |>
  hc_title(
    text = "Прогноз средних температур в г. Красноярске (в °C)"
  ) |>
  hc_yAxis(labels = list(format = "{value} °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-диаграммы в highcharter. Покажем, как выглядит диаграмма средних температур на основе набора данных weather_long выше в г. Красноярске за 3 выбранных года.

# данные
weather_hc <-
weather_long |>
  filter(year %in% c("2016","2017", "2018")) |>
  group_by(year, month) |>
  summarise(ave = round(mean(temp_ave, na.rm = TRUE), 1)) |>
  ungroup()

weather_hc
# A tibble: 36 × 3
    year month   ave
   <dbl> <fct> <dbl>
 1  2016 ЯНВ   -21.8
 2  2016 ФЕВ    -8.6
 3  2016 МАР    -2.4
 4  2016 АПР     5.1
 5  2016 МАЙ     9  
 6  2016 ИЮН    18.5
 7  2016 ИЮЛ    20.7
 8  2016 АВГ    17.2
 9  2016 СЕН    12.2
10  2016 ОКТ    -3.8
# ℹ 26 more rows
Код исходной диаграммы
# базовая диаграмма
hc <- highchart() |>
  hc_xAxis(categories = weather_hc$month) |>
  hc_add_series(
    name = "2016", 
    tooltip = list(
      valueSuffix = "°C"
    ), 
    data = (weather_hc |> dplyr::filter(year == "2016"))$ave
  ) |>
  hc_xAxis(categories = weather_hc$month) |>
  hc_add_series(
    name = "2017", 
    tooltip = list(
      valueSuffix = "°C"
    ),
    data = (weather_hc |> dplyr::filter(year == "2017"))$ave
  ) |>
  hc_xAxis(categories = weather_hc$month) |>
  hc_add_series(
    name = "2018", 
    tooltip = list(
      valueSuffix = "°C"
    ),
    data = (weather_hc |> dplyr::filter(year == "2018"))$ave
  ) |>
  hc_yAxis(labels = list(format = "{value} °C")) |>
  hc_add_theme(hc_theme_bloom()) %>% 
  hc_credits(
    text = "Диаграмма создана при использовании R и highcharter",
    href = "https://jkunst.com/highcharter/",
    enabled = TRUE
  )  |>
  hc_title(
    text = "Средние температуры в г. Красноярске в 2016-2018 гг."
  )

3D-версия диаграммы.

hc |>
  hc_chart(
    type = "column",
    options3d = list(
      enabled = TRUE, 
      beta = 15,
      alpha = 15
    )
  )

Заключение

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

Больше различных примеров визуализаций в библиотеке highcharter можно найти на странице библиотеки, в блоге Joshua Kunst, в блоге Mara Averick, а также в видео доклада

─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.3.2 (2023-10-31)
 os       macOS Monterey 12.1
 system   aarch64, darwin20
 ui       X11
 language (EN)
 collate  ru_RU.UTF-8
 ctype    ru_RU.UTF-8
 tz       Asia/Krasnoyarsk
 date     2024-03-01
 pandoc   2.18 @ /Users/materov/opt/miniconda3/envs/ox/bin/ (via rmarkdown)
 quarto   1.4.550

─ Packages ───────────────────────────────────────────────────────────────────
 package     * version date (UTC) lib source
 dplyr       * 1.1.4   2023-11-17 [1] CRAN (R 4.3.1)
 forcats     * 1.0.0   2023-01-29 [1] CRAN (R 4.3.0)
 forecast    * 8.21.1  2023-08-31 [1] CRAN (R 4.3.0)
 ggplot2     * 3.5.0   2024-02-23 [1] CRAN (R 4.3.1)
 highcharter * 0.9.4   2022-01-03 [1] CRAN (R 4.3.0)
 htmlwidgets * 1.6.4   2023-12-06 [1] CRAN (R 4.3.1)
 lubridate   * 1.9.3   2023-09-27 [1] CRAN (R 4.3.1)
 magrittr    * 2.0.3   2022-03-30 [1] CRAN (R 4.3.0)
 purrr       * 1.0.2   2023-08-10 [1] CRAN (R 4.3.0)
 quantmod    * 0.4.26  2024-02-14 [1] CRAN (R 4.3.1)
 readr       * 2.1.5   2024-01-10 [1] CRAN (R 4.3.1)
 sessioninfo * 1.2.2   2021-12-06 [1] CRAN (R 4.3.0)
 stringr     * 1.5.1   2023-11-14 [1] CRAN (R 4.3.1)
 tibble      * 3.2.1   2023-03-20 [1] CRAN (R 4.3.0)
 tidyr       * 1.3.1   2024-01-24 [1] CRAN (R 4.3.1)
 tidyverse   * 2.0.0   2023-02-22 [1] CRAN (R 4.3.0)
 TTR         * 0.24.4  2023-11-28 [1] CRAN (R 4.3.1)
 widgetframe * 0.3.1   2017-12-20 [1] CRAN (R 4.3.0)
 xts         * 0.13.2  2024-01-21 [1] CRAN (R 4.3.1)
 zoo         * 1.8-12  2023-04-13 [1] CRAN (R 4.3.0)

 [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library

──────────────────────────────────────────────────────────────────────────────

Сноски

  1. Дата обновления: 12.03.2021↩︎

  2. Если карты не скачиваются, см. Bugs in highcharter maps↩︎

Ссылка для цитирования

BibTeX
@online{матеров2022,
  author = {Матеров, Е.Н.},
  title = {Введение в библиотеку highcharter},
  date = {2022-03-16},
  url = {https://www.naukaidannye.netlify.app/blog/posts/2022-03-16-highcharter},
  langid = {ru}
}
На публикацию можно сослаться как
Матеров Е.Н. Введение в библиотеку highcharter [Electronic resource]. 2022. URL: https://www.naukaidannye.netlify.app/blog/posts/2022-03-16-highcharter.