Интеллектуальное размещение меток в R

1) Есть ли какая-либо R-библиотека/функция, которая будет внедрять размещение меток INTELLIGENT в R-графике? Я пробовал некоторые, но все они проблематичны - многие метки накладываются друг на друга или другие точки (или другие объекты на сюжете, но я вижу, что это гораздо сложнее в обращении).

2) Если нет, есть ли способ, как УДОСТОВЕРИТЬ алгоритм с размещением меток для конкретных проблемных точек? Самое удобное и эффективное решение.

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

# data
x = c(0.8846, 1.1554, 0.9317, 0.9703, 0.9053, 0.9454, 1.0146, 0.9012, 
0.9055, 1.3307)
y = c(0.9828, 1.0329, 0.931, 1.3794, 0.9273, 0.9605, 1.0259, 0.9542, 
0.9717, 0.9357)
ShortSci = c("MotAlb", "PruMod", "EriRub", "LusMeg", "PhoOch", "PhoPho", 
"SaxRub", "TurMer", "TurPil", "TurPhi")

# basic plot
plot(x, y, asp=1)
abline(h = 1, col = "green")
abline(v = 1, col = "green")

Для маркировки я тогда пробовал эти возможности, никто не очень хорош:

1) это ужасно:

text(x, y, labels = ShortSci, cex= 0.7, offset = 10)

2) это хорошо, если вы не хотите размещать метки для всех точек, но только для выбросы, но все же метки часто ошибочны:

identify(x, y, labels = ShortSci, cex = 0.7)

3) это выглядело перспективным, но проблема с ярлыками слишком близка к точки; Мне пришлось проложить их пробелами, но это не сильно помогает:

require(maptools)
pointLabel(x, y, labels = paste("  ", ShortSci, "  ", sep=""), cex=0.7)

4)

require(plotrix)
thigmophobe.labels(x, y, labels = ShortSci, cex=0.7, offset=0.5)

5)

require(calibrate)
textxy(x, y, labs=ShortSci, cx=0.7)

Заранее благодарю вас!

EDIT: todo: попробуйте labcurve {Hmisc}.

Ответ 1

Я нашел какое-то решение! Это не окончательно и идеально, но это тот, который работает для меня лучше всего. Он наполовину алгоритмичен, наполовину ручной, поэтому он экономит время по сравнению с чисто ручным решением, набросанным joran.

Я упустил очень важную важную часть справки ?identify

Алгоритм, используемый для размещения меток, совпадает с используемым текстом, если pos указывается там, причем разница заключается в том, что положение указатель относительно идентифицированной точки определяет pos в идентификации.

Итак, если вы используете решение identify(), как я писал в моем вопросе, тогда вы можете повлиять на позицию метки, не нажимая непосредственно на эту точку, а щелкнув рядом с этой точкой относительно желаемого направление!!! Работает просто отлично!

Недостатком является то, что есть только 4 позиции (верхний, левый, нижний, правый), но я бы более оценил остальные 4 (верхние левые, верхние правые, нижние левые, нижние правые). Поэтому я использую это для меток точек, где это не мешает мне и остальным точкам, которые я помещаю непосредственно в презентации Powerpoint, поскольку joran предложил: -)

P.S.: Я еще не пробовал решение решетки /ggplot, я по-прежнему предпочитаю использовать базовую библиотеку сюжетов.

Ответ 2

Во-первых, вот результаты моего решения этой проблемы:

enter image description here

Я сделал это вручную в Preview (очень простой PDF/просмотрщик изображений на OS X) всего за несколько минут. (Изменить: рабочий процесс был именно тем, что вы ожидали: я сохранил график как PDF файл из R, открыл его в Preview и создал текстовые поля с нужными ярлыками (9pt Helvetica), а затем просто перетащил их с помощью мыши, пока они не посмотрели Тогда я экспортировал в PNG для загрузки в SO.)

Теперь, прежде чем вы уступите сильному призыву спустить это в забвение и оставить сдержанные комментарии о том, как нужно автоматизировать этот процесс, выслушайте меня!

Поиск алгоритмических решений полностью прекрасен, и (IMHO) действительно интересен. Но для меня ситуации с маркировкой точек относятся к примерно трем категориям:

  • У вас есть небольшое количество очков, ни одна из которых не ужасно близка. В этом случае одно из решений, которые вы указали в вопросе, скорее всего, будет работать с минимальной настройкой.
  • У вас есть небольшое количество точек, некоторые из которых слишком тесно упакованы для типичных алгоритмических решений, чтобы дать хорошие результаты. В этом случае, поскольку у вас есть только небольшое количество точек, маркировка их вручную (либо с помощью редактора изображений, либо с тонкой настройкой вашего вызова на text) не так много усилий.
  • У вас довольно большое количество очков. В этом случае вы действительно не должны их маркировать, так как визуально обрабатывать большое количество ярлыков сложно.

: подняться на мыльницу:

Поскольку такие люди, как мы, любят автоматизацию, я думаю, что мы часто попадаем в ловушку мысли о том, что почти каждый аспект создания хорошей статистической графики должен быть автоматизирован. Я с уважением (смиренно!) Не согласен.

Не существует абсолютно общей статистической среды построения, которая автоматически создает изображение, которое у вас есть в голове. Такие вещи, как R, ggplot2, решетка и т.д., Выполняют большую часть работы; но эта небольшая корректировка, добавив здесь строку, корректируя запас, вероятно, лучше подходит для другого инструмента.

: спуститься с мыльной коробки:

Я также хотел бы отметить, что я думаю, что мы могли бы придумать диаграммы рассеяния с < 10-15 точек, которые будут почти невозможны для чистой маркировки, даже вручную, и это, вероятно, нарушит любое автоматическое решение, с которым кто-то сталкивается.

Наконец, я хочу повторить, что знаю, что это не тот ответ, который вы ищете. И я не говорю, что алгоритмические попытки бесполезны или немыслимы. Я проголосовал за этот вопрос и буду счастливо продвигать интересные алгоритмические решения!

Причина, по которой я опубликовал этот ответ, заключается в том, что я думаю, что этот вопрос должен быть каноническим вопросом "маркировки точки в R" для будущих дубликатов, и я думаю, что решения, связанные с маркировкой рук, заслуживают места за столом, что все.

Ответ 3

ggrepel выглядит многообещающим при применении к диаграммам рассеяния ggplot2.

# data
x = c(0.8846, 1.1554, 0.9317, 0.9703, 0.9053, 0.9454, 1.0146, 0.9012, 
0.9055, 1.3307)
y = c(0.9828, 1.0329, 0.931, 1.3794, 0.9273, 0.9605, 1.0259, 0.9542, 
0.9717, 0.9357)
ShortSci = c("MotAlb", "PruMod", "EriRub", "LusMeg", "PhoOch", "PhoPho", 
"SaxRub", "TurMer", "TurPil", "TurPhi")


df <- data.frame(x = x, y = y, z = ShortSci)
library(ggplot2)
library(ggrepel)

ggplot(data = df, aes(x = x, y = y)) + theme_bw() + 

    geom_text_repel(aes(label = z), 
       box.padding = unit(0.45, "lines")) +

    geom_point(colour = "green", size = 3)

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

Ответ 4

Вы пробовали пакет directlabels?

И, BTW, аргументы pos и offset могут принимать векторы, чтобы вы могли получить их в правильных положениях, когда имеется достаточное количество точек всего за несколько прогонов графика.

Ответ 5

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

http://blog.fellstat.com/?cat=11

Ответ 6

Не ответ, но слишком длинный для комментария. Очень простой подход, который может работать в простых случаях, где-то между пост-обработкой joran и более сложными алгоритмами, которые были представлены, состоит в том, чтобы сделать in-place простые преобразования в dataframe.

Я иллюстрирую это с помощью ggplot2, потому что я больше знаком с этим синтаксисом, чем с базовыми R-графиками.

df <- data.frame(x = x, y = y, z = ShortSci)
library("ggplot2")
ggplot(data = df, aes(x = x, y = y, label = z)) + theme_bw() + 
    geom_point(shape = 1, colour = "green", size = 5) + 
    geom_text(data = within(df, c(y <- y+.01, x <- x-.01)), hjust = 0, vjust = 0)

Как вы можете видеть, в этом случае результат не идеален, но он может быть достаточно хорош для некоторых целей. И это довольно легко, обычно чего-то подобного достаточно within(df, y <- y+.01)

enter image description here