Nano Hash - криптовалюты, майнинг, программирование

Как расширить коробку ggplot2 с помощью ggproto?

Я часто использую боксплоты в своей работе, и мне нравится ggplot2 эстетика. Но стандартному geom_boxplot не хватает двух важных для меня вещей: концов усов и срединных меток. Благодаря информации отсюда я написал функцию:

gBoxplot <- function(formula = NULL, data = NULL, font = "CMU Serif", fsize = 18){
  require(ggplot2)
  vars <- all.vars(formula)
  response <- vars[1]
  factor <- vars[2]
  # A function for medians labelling
  fun_med <- function(x){
    return(data.frame(y = median(x), label = round(median(x), 3)))
  }
  p <- ggplot(data, aes_string(x = factor, y = response)) +
  stat_boxplot(geom = "errorbar", width = 0.6) +
  geom_boxplot() +
  stat_summary(fun.data = fun_med, geom = "label", family = font, size = fsize/3, 
                                                                         vjust = -0.1) +
  theme_grey(base_size = fsize, base_family = font)
  return(p)
}

Там же есть настройки шрифтов, но это только потому, что мне лень делать тему. Вот пример:

gBoxplot(hwy ~ class, mpg)

plot1

Для меня достаточно хорошо, но есть некоторые ограничения (нельзя использовать автоматическое уклонение и т. д.), и будет лучше сделать новый геом на основе geom_boxplot. Я прочитал виньетку Расширение ggplot2, но не могу понять, как реализовать это. Любая помощь будет оценена.


  • Так что ты думаешь? 19.02.2016
  • Большое спасибо, @MikeWise! Смотрите комментарий для вашего ответа. 02.03.2016
  • Эээ, какой комментарий? И если вам это нравится, вы могли бы принять ответ? Для этого нажмите на серую галочку под номером голосования в левом верхнем углу моего ответа. 02.03.2016
  • Хорошо, я принял! 22.03.2016

Ответы:


1

Так что думал об этом некоторое время. В основном, когда вы создаете новый примитив, вы обычно пишете комбинацию:

  1. функция слоя
  2. stat-ggproto,
  3. geom-ggproto

Только функция слоя должна быть видна пользователю. Вам нужно написать stat-ggproto только в том случае, если вам нужен какой-то новый способ преобразования ваших данных для создания вашего примитива. И вам нужно написать geom-ggproto только в том случае, если вам нужно создать новую графику на основе сетки.

В этом случае, когда мы в основном компостируем уже существующие функции слоя, нам не нужно писать новые ggprotos. Достаточно написать новую функцию слоя. Эта функция слоя создаст три слоя, которые вы уже используете, и сопоставит параметры так, как вы задумали. В таком случае:

  • Layer1 — использует geom_errorbar и stat_boxplot — чтобы получить наши полосы ошибок
  • Layer2 — использует geom_boxplot и stat_boxplot — для создания коробчатых диаграмм.
  • Layer3 — пользователи geom_label и stat_summary — для создания текстовых меток со средним значением в центре полей.

Конечно, вы можете написать новый stat-ggproto и новый geom-ggproto, которые делают все эти вещи одновременно. Или, может быть, вы компостируете stat_summary и stat_boxplot в один, а также три geom-protos, и делаете это одним слоем. Но в этом мало смысла, если у нас нет проблем с эффективностью.

В любом случае, вот код:

geom_myboxplot <- function(formula = NULL, data = NULL,
                           stat = "boxplot", position = "dodge",coef=1.5,
                           font = "sans", fsize = 18, width=0.6,
                           fun.data = NULL, fun.y = NULL, fun.ymax = NULL,
                           fun.ymin = NULL, fun.args = list(),
                           outlier.colour = NULL, outlier.color = NULL,
                           outlier.shape = 19, outlier.size = 1.5,outlier.stroke = 0.5,
                           notch = FALSE,  notchwidth = 0.5,varwidth = FALSE,
                           na.rm = FALSE, show.legend = NA,
                           inherit.aes = TRUE,...) {
    vars <- all.vars(formula)
    response <- vars[1]
    factor <- vars[2]
    mymap <- aes_string(x=factor,y=response)
    fun_med <- function(x) {
        return(data.frame(y = median(x), label = round(median(x), 3)))
    }
    position <- position_dodge(width)
    l1 <- layer(data = data, mapping = mymap, stat = StatBoxplot,
            geom = "errorbar", position = position, show.legend = show.legend,
            inherit.aes = inherit.aes, params = list(na.rm = na.rm,
                coef = coef, width = width, ...))
    l2 <- layer(data = data, mapping = mymap, stat = stat, geom = GeomBoxplot,
            position = position, show.legend = show.legend, inherit.aes = inherit.aes,
            params = list(outlier.colour = outlier.colour, outlier.shape = outlier.shape,
                outlier.size = outlier.size, outlier.stroke = outlier.stroke,
                notch = notch, notchwidth = notchwidth, varwidth = varwidth,
                na.rm = na.rm, ...))
    l3 <- layer(data = data, mapping = mymap, stat = StatSummary,
            geom = "label", position = position, show.legend = show.legend,
            inherit.aes = inherit.aes, params = list(fun.data = fun_med,
                fun.y = fun.y, fun.ymax = fun.ymax, fun.ymin = fun.ymin,
                fun.args = fun.args, na.rm=na.rm,family=font,size=fsize/3,vjust=-0.1,...))
    return(list(l1,l2,l3))
}

что позволяет вам создавать свои индивидуальные диаграммы, которые теперь выглядят так:

ggplot(mpg) +
  geom_myboxplot( hwy ~ class, font = "sans",fsize = 18)+
  theme_grey(base_family = "sans",base_size = 18 )

И выглядят они так:

введите описание изображения здесь

Примечание: на самом деле нам не нужно было использовать функцию layer, вместо них мы могли бы использовать исходные вызовы stat_boxplot, geom_boxplot и stat_summary. Но нам все равно пришлось бы заполнять все параметры, если бы мы хотели иметь возможность управлять ими из нашей пользовательской диаграммы, поэтому я думаю, что так было понятнее — по крайней мере, с точки зрения структуры, а не функциональности. . А может и нет, это дело вкуса...

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

18.02.2016
  • Я потерял надежду на какой-либо ответ, поэтому просмотрите ваш прямо сейчас. Действительно самое то: рабочий пример и немного теории для размышлений. Нужно некоторое время, чтобы загрузить идею в голову (английский не является моим родным языком). Я использую шрифт Computer Modern Unicode, юникодную версию классического шрифта Д. Кнута. 02.03.2016
  • Большой. Рад, что вам это нравится. Пожалуйста, примите ответ. 02.03.2016
  • Спасибо. Если бы у вас было еще два балла, вы тоже могли бы проголосовать за него. Может в следующий раз :) 22.03.2016
  • @MikeWise Знаете ли вы, как я могу адаптировать этот подход для настройки позиций, например, для точки или полигоны? Я пытаюсь разработать функцию, в которой перекрывающиеся геометрические объекты смещаются, чтобы они не перекрывались, возможно, с использованием подхода направления силы. Любые указатели высоко ценятся 11.02.2017
  • В приведенном выше примере точки смещаются, чтобы избежать столкновений. Вы говорите о новых драгоценных камнях, которые вы определяете, или вы хотите наложить другие уже существующие геометрии. 12.02.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..