Создание интерактивных графиков с R и Highcharts

от автора

Иногда в попытках решить простые задачи приходят в голову великие идеи. Это особенно верно для разработчиков, которые готовы приложить массу усилий для решения простой проблемы к полному своему удовлетворению. Эта история о том, как Торстейн Хенси, основатель и СРО Highcharts искал простой инструмент для создания графиков, чтобы поместить на свою домашнюю страницу замеры глубины снега на Викафьеллет, местной горе, где у семьи был коттедж. Разочаровавшись в обычных flash-расширениях и коммерческих решениях, доступных на тот момент, он решил создать собственное и, конечно же, им поделиться.

Для создания красивых графиков в этой статье я воспользуюсь пакетом highcharter Джошуа Кунста, оболочкой для javascript-библиотеки Highcharts и Shiny.

Пожалуйста, учтите, что все продукты в этой библиотеке бесплатны для некоммерческого использования. Для коммерческих проектов и сайтов воспользуйтесь этим.

Пакет highcharter позволяет создавать графики типа Highcharts внутри R.

В пакете есть две основных функции:

  • highchart(): создает объект-график Highchart с помощью htmlwidgets. Виджет можно отобразить на HTML-страницах, созданных в R Markdown, Shiny или других приложениях.
  • hchart(): использует highchart(), чтобы одной простой командой нарисовать график для разных классов объектов в R. В частности, таких: data frame, numeric, histogram, character, density, factor, ts, mts, xts, stl, ohlc, acf, forecast, mforecast, ets, igraph, dist, dendrogram, phylo и survfit.

Графики строятся в духе ggplot2 по слоям, но используют оператор конвеера (%>%) вместо +.

Другие полезные функции пакета:

  • Темизация: можно настроить графики с помощью встроенных тем, например, Economist, Financial Times, Google и FiveThirtyEight.
  • Расширения: motion, drag points, fontawesome, url-pattern, annotations.

Проиллюстрируем функциональность этого пакета и Highcharts в целом рядом примеров-визуализаций.

Пример 1: Родившиеся в пятницу, 13-го, в США

На эту визуализацию меня вдохновила статья в FiveThirtyEight «Некоторые слишком суеверны, чтобы рожать в пятницу, 13-го». FiveThirtyEight любезно предоставляет данные, использующиеся в некоторых статьях, в репозитории на GitHub. Конкретно эти — отсюда.

Наша цель — воссоздать именно эту визуализацию. Для того, чтобы это сделать, необходимо подсчитать разницу между количеством родившихся 13-го и среднее для 6-го и 20-го числа каждого месяца, группируя эти значения по дням недели. С этим прекрасно справятся dplyr и tidyr.

Загрузим необходимые пакеты:

library(highcharter) library(dplyr) library(tidyr) 

и данные:

births <- read.csv("data/births.csv") 

Посчитаем разницы в количестве родившихся, как описано в статье, и сохраним результаты в новый пакет данных (data frame) diff13:

diff13 <- births %>%   filter(date_of_month %in% c(6, 13, 20)) %>%   mutate(day = ifelse(date_of_month == 13, "thirteen", "not_thirteen")) %>%   group_by(day_of_week, day) %>%   summarise(mean_births = mean(births)) %>%   arrange(day_of_week) %>%   spread(day, mean_births) %>%   mutate(diff_ppt = ((thirteen - not_thirteen) / not_thirteen) * 100) 

который выглядит так:

## Source: local data frame [7 x 4] ## Groups: day_of_week [7] ##  ##   day_of_week not_thirteen  thirteen   diff_ppt ##         <int>        <dbl>     <dbl>      <dbl> ## 1           1    11658.071 11431.429 -1.9440853 ## 2           2    12900.417 12629.972 -2.0964008 ## 3           3    12793.886 12424.886 -2.8841902 ## 4           4    12735.145 12310.132 -3.3373249 ## 5           5    12545.100 11744.400 -6.3825717 ## 6           6     8650.625  8592.583 -0.6709534 ## 7           7     7634.500  7557.676 -1.0062784 

Обратите внимание, что рассчитанный процент разниц в процентных пунктах (diff_ppt) может не соответствовать приведенному в статье FiveThirtyEight. На то есть две причины:

  1. В FiveThirtyEight исключены праздники, а в этом анализе — нет.
  2. FiveThirtyEight предоставляют два файла с данными — за 1994-2003 и за 2000-2014 годы соответственно. Количество родившихся в пересекающихся годах (2000-2003) в этих файлах не совсем совпадает. Это приложение использует данные Администрации социального обеспечения (SSA, Social Security Administration) за соответствующие годы, но непонятно, какими данными воспользовались FiveThirtyEight.

Начнем с простенького highchart для этих данных с помощью функции hchart():

hchart(diff13, "scatter", x = day_of_week, y = diff_ppt) 


У этого графика есть ряд хороших свойств. Например, если навести мышкой на точки, можно увидеть фактические значения, взятые для построения. Однако, для того, чтобы график выглядел, как в FiveThirtyEight, понадобится определенная настройка. Этого можно добиться с помощью функции highchart() и некоторых других. Обратите внимание, мы разделяем слои оператором конвеера.

highchart() %>%   hc_add_series(data = round(diff13$diff_ppt, 4), type = "column",                 name = "Difference, in ppt",                 color = "#F0A1EA", showInLegend = FALSE) %>%   hc_yAxis(title = list(text = "Difference, in ppt"), allowDecimals = FALSE) %>%   hc_xAxis(categories = c("Monday", "Tuesday", "Wednesday", "Thursday",                            "Friday", "Saturday", "Sunday"),            tickmarkPlacement = "on",            opposite = TRUE) %>%   hc_title(text = "The Friday the 13th effect",            style = list(fontWeight = "bold")) %>%    hc_subtitle(text = "Difference in the share of U.S. births on 13th of each month                       from the average of births on the 6th and the 20th,                      1994 - 2004") %>%   hc_tooltip(valueDecimals = 4,              pointFormat = "Day: {point.x} <br> Diff: {point.y}") %>%   hc_credits(enabled = TRUE,               text = "Sources: CDC/NCHS, SOCIAL SECURITY ADMINISTRATION",              style = list(fontSize = "10px")) %>%   hc_add_theme(hc_theme_538()) 


Заголовок: Эффект пятницы, 13-го
Подзаголовок: Разница в количестве родившихся в США 13-го числа каждого месяца и среднего количества родившихся 6-го и 20-го, 1994 — 2004
Метки по оси 0Х: понедельник, вторник, среда, четверг, пятница, суббота, воскресенье
Подпись по оси 0Y: Разница, в процентных пунктах

Полезное свойство в этой визуализации — тоже всплывающая подсказка. Также темы позволяют легко поменять внешний вид графика (в этом случае тема hc_theme_538() сильно приближает нас к оригиналу). Еще можно легко менять метки (например, названия дней) без внесения изменений в исходные данные.

Пример 2: Родившиеся в пятницу, 13-го, в США, интерактивность

Поскольку пакет highcharter использует htmlwidlgets, он также совместим с Shiny. Для того, чтобы построить highchart внутри приложения на Shiny, используют функцию renderHighchart().

Мы написали приложение, расширяющее созданную ранее визуализацию и позволяющее настраивать диапазон лет, для которых берутся данные на графике, его тип и тему. Скриншот приведен ниже, а само приложение и его исходный код можно посмотреть здесь.

Чего стоит опасаться

Наиболее привлекательные функции highcharts — встроенная и настраиваемая всплывающая подсказка и масштабирование. Но будут ли эти функции полезны, зависит от каждого конкретного случая.

Например, всплывающие подсказки не настолько хороши, если строить график по данным большего объема. Посмотрите на этот график задержек приземлений и вылетов рейсов в Лос-Анджелес в октябре 2013 в разных аэропортах Нью-Йорка. Скопление точек в левой нижней части графика делает всплывающие подсказки не такими удобными.

library(nycflights13) oct_lax_flights <- flights %>%   filter(month == 10, dest == "LAX") hchart(oct_lax_flights, "scatter", x = dep_delay, y = arr_delay, group = origin) 


Но если немного сгруппировать данные, чтобы уменьшить количество точек, эта функциональность снова может пригодиться. Например, ниже мы группируем рейсы по 15-минутным интервалам в задержке вылета и выводим медиану задержки приземления для этих интервалов.

oct_lax_flights_agg <- oct_lax_flights %>%   mutate(dep_delay_cat = cut(dep_delay, breaks = seq(-15, 255, 15))) %>%   group_by(origin, dep_delay_cat) %>%   summarise(med_arr_delay = median(arr_delay, na.rm = TRUE)) hchart(oct_lax_flights_agg, "line", x = dep_delay_cat, y = med_arr_delay, group = origin) 

Заключение

Highcharts предоставляет веб-графику отличного качества с возможностью тонкой настройки, и пакет highcharter дает возможность пользователям R в полной мере этим воспользоваться. Если вас заинтересовали функции, доступные в пакете, очень рекомендую заглянуть на страницу пакета highcharter: там есть множество графиков Highcharts, Highstock и Highmaps с примерами кода. Также, если нужно проверить синтаксис каких-то настроек, чрезвычайно полезна страница с описанием опций Highcharts.
ссылка на оригинал статьи https://habrahabr.ru/post/314086/