Як намалювати акуратні багатокутники навколо областей розсіювання в 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працює аналогічно пошуку опуклого корпусу, але дозволяє регулювати його всередину / назовні, щоб спробувати зробити щось на зразок довірчих інтервалів.
Уейн

@Wayne, альфа-корпус не є довірчим інтервалом (будь-яким способом уявити). Дивіться це питання gis.se для короткого опису та деяких посилань на те, що таке альфа-корпус. Можливо, ваша думка про двовимірні еліпси впевненості, а може бути навіть мішки (двовимірні коробки для визначення оточуючих людей).
Енді Ш

Відповіді:


33

З деяким googling я натрапив на веб-сайт Gota Morota, який має приклад робити це вже на своєму веб-сайті . Нижче наведений приклад, який поширюється на ваші дані.

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

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. Я б уявив, що точки сортуються по порядку по периметру, але вам доведеться це перевірити.

EDIT: Ось приклад, який не використовується 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,])

EDIT 2: Гаразд, ось щось із використанням ggplot2. Перетворимось Xв a 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()

Зауважте, що the geom_pointвикористовує дані ( X) та aes з ggplot, тоді як я переосмислюю їх у geom_polygon.

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


Правильно про опуклий корпус. Я намагався використовувати chullдля генерації опуклого корпусу, але не зміг використати результати ggplot2.
о.

@ Fr .: Я швидко змінив свою відповідь. Подивіться, чи це ставить вас на правильний шлях.
Уейн

Я бачу, як це працює самостійно, але мені цікаво, як отримати цей останній рядок ggplot2.
о.

@ Fr .: Гаразд, а як тепер?
Уейн

Це спрацювало! Спасибі. Мені довелося додати, na.omitщоб позбутися від NA, що припинила chullроботу. Знову дякую.
о.

5

Станом на сьогодні вдень, я загорнув цю chullфункцію всередині пакету R як geom_convexhullфункції.

Після завантаження пакета він може бути використаний як будь-який інший гем, у вашому випадку це має бути щось на зразок:

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.