Pull to refresh

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

Reading time6 min
Views7.5K
Original author: Mine Cetinkaya-Rundel
Иногда в попытках решить простые задачи приходят в голову великие идеи. Это особенно верно для разработчиков, которые готовы приложить массу усилий для решения простой проблемы к полному своему удовлетворению. Эта история о том, как Торстейн Хенси, основатель и СРО 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.
Tags:
Hubs:
Total votes 13: ↑13 and ↓0+13
Comments0

Articles