Иногда в попытках решить простые задачи приходят в голову великие идеи. Это особенно верно для разработчиков, которые готовы приложить массу усилий для решения простой проблемы к полному своему удовлетворению. Эта история о том, как Торстейн Хенси, основатель и СРО Highcharts искал простой инструмент для создания графиков, чтобы поместить на свою домашнюю страницу замеры глубины снега на Викафьеллет, местной горе, где у семьи был коттедж. Разочаровавшись в обычных flash-расширениях и коммерческих решениях, доступных на тот момент, он решил создать собственное и, конечно же, им поделиться.
Для создания красивых графиков в этой статье я воспользуюсь пакетом highcharter Джошуа Кунста, оболочкой для javascript-библиотеки Highcharts и Shiny.
Пожалуйста, учтите, что все продукты в этой библиотеке бесплатны для некоммерческого использования. Для коммерческих проектов и сайтов воспользуйтесь этим.
Пакет highcharter позволяет создавать графики типа Highcharts внутри R.
В пакете есть две основных функции:
Графики строятся в духе ggplot2 по слоям, но используют оператор конвеера (%>%) вместо +.
Другие полезные функции пакета:
Проиллюстрируем функциональность этого пакета и Highcharts в целом рядом примеров-визуализаций.
На эту визуализацию меня вдохновила статья в FiveThirtyEight «Некоторые слишком суеверны, чтобы рожать в пятницу, 13-го». FiveThirtyEight любезно предоставляет данные, использующиеся в некоторых статьях, в репозитории на GitHub. Конкретно эти — отсюда.
Наша цель — воссоздать именно эту визуализацию. Для того, чтобы это сделать, необходимо подсчитать разницу между количеством родившихся 13-го и среднее для 6-го и 20-го числа каждого месяца, группируя эти значения по дням недели. С этим прекрасно справятся dplyr и tidyr.
Загрузим необходимые пакеты:
И данные:
Посчитаем разницы в количестве родившихся, как описано в статье, и сохраним результаты в новый пакет данных (data frame)
Который выглядит так:
Обратите внимание, что рассчитанный процент разниц в процентных пунктах (
Начнем с простенького highchart для этих данных с помощью функции
У этого графика есть ряд хороших свойств. Например, если навести мышкой на точки, можно увидеть фактические значения, взятые для построения. Однако, для того, чтобы график выглядел, как в FiveThirtyEight, понадобится определенная настройка. Этого можно добиться с помощью функции
Заголовок: Эффект пятницы, 13-го
Подзаголовок: Разница в количестве родившихся в США 13-го числа каждого месяца и среднего количества родившихся 6-го и 20-го, 1994 — 2004
Метки по оси 0Х: понедельник, вторник, среда, четверг, пятница, суббота, воскресенье
Подпись по оси 0Y: Разница, в процентных пунктах
Полезное свойство в этой визуализации — тоже всплывающая подсказка. Также темы позволяют легко поменять внешний вид графика (в этом случае тема
Поскольку пакет highcharter использует htmlwidlgets, он также совместим с Shiny. Для того, чтобы построить highchart внутри приложения на Shiny, используют функцию
Мы написали приложение, расширяющее созданную ранее визуализацию и позволяющее настраивать диапазон лет, для которых берутся данные на графике, его тип и тему. Скриншот приведен ниже, а само приложение и его исходный код можно посмотреть здесь.
Наиболее привлекательные функции highcharts — встроенная и настраиваемая всплывающая подсказка и масштабирование. Но будут ли эти функции полезны, зависит от каждого конкретного случая.
Например, всплывающие подсказки не настолько хороши, если строить график по данным большего объема. Посмотрите на этот график задержек приземлений и вылетов рейсов в Лос-Анджелес в октябре 2013 в разных аэропортах Нью-Йорка. Скопление точек в левой нижней части графика делает всплывающие подсказки не такими удобными.
Но если немного сгруппировать данные, чтобы уменьшить количество точек, эта функциональность снова может пригодиться. Например, ниже мы группируем рейсы по 15-минутным интервалам в задержке вылета и выводим медиану задержки приземления для этих интервалов.
Highcharts предоставляет веб-графику отличного качества с возможностью тонкой настройки, и пакет highcharter дает возможность пользователям R в полной мере этим воспользоваться. Если вас заинтересовали функции, доступные в пакете, очень рекомендую заглянуть на страницу пакета highcharter: там есть множество графиков Highcharts, Highstock и Highmaps с примерами кода. Также, если нужно проверить синтаксис каких-то настроек, чрезвычайно полезна страница с описанием опций Highcharts.
Для создания красивых графиков в этой статье я воспользуюсь пакетом 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. На то есть две причины:- В FiveThirtyEight исключены праздники, а в этом анализе — нет.
- 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.