Как нарисовать аккуратные полигоны вокруг областей диаграммы рассеяния в ggplot2 [закрыто]


32

Как добавить аккуратный многоугольник вокруг группы точек на диаграмме рассеяния? Я использую ggplot2, но разочарован результатами geom_polygon.

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

диаграмма рассеяния с плотностью 2d

Я хотел бы перейти от geom_density2dменее причудливой, но эмпирически более правильной geom_polygon. Результат на несортированных данных бесполезен:

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

Как нарисовать «аккуратные» многоугольники, которые ведут себя как контурные контуры вокруг значений min-max yx? Я попытался сортировать данные безрезультатно.

Код:

print(fig2 <- ggplot(d, aes(man, eff, colour=issue, fill=issue)) + 
geom_point() + geom_density2d(alpha=.5) + labs(x = "Efficiency", y = "Mandate"))

dОбъект получен с этим CSV - файлом .

Решение:

Спасибо Уэйну , Энди У и другим за их советы! Данные, код и графики были размещены на GitHub . Результат выглядит так:

результат


6
Термин, который вы можете искать, является выпуклой оболочкой точек (или, возможно, альфа-оболочкой). Вы должны быть в состоянии найти функцию R для их вычисления, а затем сможете добавить их в виде слоев на график.
Энди В.

Спасибо за указание правильной терминологии! Я не смог использовать ?chullс ggplot2до сих пор. Я не уверен, что кодирую это правильно, и надеюсь, что кто-то уже сделал это.
о.

Не могли бы вы добавить свой код R на вопрос?
Юрий Петровский

Следует отметить одну вещь: то, что вы отображаете, это максимумы, которые могут быть «выбросами». Я считаю, что пакет R alphahullработает аналогично нахождению выпуклой оболочки, но позволяет вам регулировать его внутрь / наружу, чтобы попытаться сделать что-то вроде доверительных интервалов.
Уэйн

@ Уэйн, альфа-корпус не является доверительным интервалом (никак не мыслимым). Посмотрите этот вопрос gis.se для краткого описания и некоторых ссылок на то, что такое альфа-корпус. Возможно, вы думаете о двумерных доверительных эллипсах, или, может быть, даже о багплотах (бипарийные боксы для определения выбросов).
Энди W

Ответы:


33

С некоторым гуглом я наткнулся на сайт Готы Мороты, у которого уже есть пример сделать это на ее сайте . Ниже этот пример распространяется на ваши данные.

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

library(ggplot2)
work <- "E:\\Forum_Post_Stuff\\convex_hull_ggplot2"
setwd(work)

#note you have some missing data
mydata <- read.table(file = "emD71JT5.txt",header = TRUE, fill = TRUE)
nomissing <- na.omit(mydata) #chull function does not work with missing data

#getting the convex hull of each unique point set
df <- nomissing
find_hull <- function(df) df[chull(df$eff, df$man), ]
hulls <- ddply(df, "issue", find_hull)

plot <- ggplot(data = nomissing, aes(x = eff, y = man, colour=issue, fill = issue)) +
geom_point() + 
geom_polygon(data = hulls, alpha = 0.5) +
labs(x = "Efficiency", y = "Mandate")
plot

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

@Fr. , В чем именно проблема?
Энди Ш

@AndyW К сожалению, код не поддерживает пропущенные значения, и я не нашел способа настроить его для этого.
о.

@ FR., Как именно вы хотите обрабатывать пропущенные значения данных, кроме устранения этих наблюдений? Любой разумный метод вменения приведет к тому, что точки будут находиться внутри выпуклых оболочек не пропущенных наблюдений.
Энди В.

@ AndyW Я имею в виду, что NAубить chullфункцию. Я ожидал бы, что это просто проигнорирует это, но это терпит неудачу, и я не нашел способа использовать это, na.omit()чтобы заставить это работать. Я уверен, что это возможно, у меня просто нет навыков взлома, чтобы выйти за рамки предыдущего решения.
о.

8

Если я понимаю вашу проблему, вы ищете выпуклый корпус healthи unemployment. Вероятно, есть несколько пакетов для этого в R, один из которых - пакет geometry. Я предполагаю, что точки отсортированы по периметру, но вам нужно это проверить.

РЕДАКТИРОВАТЬ: Вот пример, который не использует ggplot, но я надеюсь, что это полезно. Пример в chullдокументации кажется неправильным, что может сбить вас с толку:

X <- matrix(rnorm(2000), ncol = 2)
X.chull <- chull (X)
X.chull <- c(X.chull, X.chull[1])
plot (X)
lines (X[X.chull,])

РЕДАКТИРОВАТЬ 2: ОК, вот что-то с помощью ggplot2. Переходим Xв data.frameс переменными xи y. Затем:

library(ggplot2)
X <- as.data.frame(X)
hull <- chull(X)
hull <- c(hull, hull[1])
ggplot(X, aes(x=x, y=y)) + geom_polygon(data=X[hull,], fill="red") + geom_point()

Обратите внимание, что geom_pointиспользуется data ( X) и aes из ggplot, а я переопределяю его в geom_polygon.

Чтобы получить его полностью, вам нужно поместить x и y для корпуса для обеих проблем bar, используя третий столбец issueдля их дифференциации.


Поправьте насчет выпуклой оболочки. Я пытался использовать chullдля создания выпуклой оболочки, но не удалось использовать результаты с ggplot2.
о.

@ Фр .: Я быстро отредактировал свой ответ. Смотрите, если это ставит вас на правильный путь.
Уэйн

Я могу видеть, как это работает само по себе, но мне интересно, как получить эту последнюю строку с ggplot2.
о.

@Fr .: Хорошо, а теперь?
Уэйн

Это сработало! Спасибо. Я должен был добавить, na.omitчтобы избавиться от АН, которые перестают chullработать. Еще раз спасибо.
о.

5

На сегодняшний день я обернул chullфункцию внутри пакета R как geom_convexhullфункцию.

После того, как пакет загружен, его можно использовать как любой другой geom, в вашем случае это должно быть что-то вроде:

ggplot(d, aes(man, eff, colour=issue, fill=issue)) + 
  geom_convexhull(alpha=.5) + 
  geom_point() + 
  labs(x = "Efficiency", y = "Mandate"))

Пакет доступен на github: https://github.com/cmartin/ggConvexHull


Большое спасибо за это! Я получал разочарование от нежелательных результатов при попытке применить chullчерез фактор группировки, пока не нашел это.
Jogall
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.