Placement Intelligent des étiquettes de points en R

1) y a-t-il une bibliothèque/Fonction R qui mettrait en œuvre un placement INTELLIGENT des étiquettes dans la parcelle R? J'en ai essayé quelques - uns, mais ils sont tous problématiques-beaucoup d'étiquettes se chevauchent ou se chevauchent sur d'autres points (ou d'autres objets dans la parcelle, mais je vois que c'est beaucoup plus difficile à manipuler).

2) dans la négative, y a-t-il un moyen quelconque d'aider L'algorithme avec L'emplacement de l'étiquette pour des points problématiques particuliers? La solution la plus confortable et efficace désirée.

vous pouvez jouer et tester d'autres possibilités avec mon exemple reproductible et voir si vous pouvez obtenir de meilleurs résultats que moi:

# 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")

pour l'étiquetage, j'ai alors essayé ces possibilités, personne n'est vraiment bon:

1) celui-ci est terrible:

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

2) il est bon si vous ne voulez pas placer des étiquettes pour tous les points, mais juste pour le des valeurs aberrantes, mais quand même, les étiquettes sont souvent mal placées:

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

3) celui-ci semblait promissing mais il y a le problème des étiquettes étant trop près de la j'ai dû les garnir d'espaces, mais cela n'aide pas beaucoup:

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)

Merci d'avance!

EDIT: todo: try labcurve {Hmisc} .

91
demandé sur Community 2011-09-30 17:34:27

7 réponses

tout d'Abord, voici les résultats de ma solution à ce problème:

enter image description here

j'ai fait ceci à la main en Preview (très basique PDF/Image viewer sur OS X) en seulement quelques minutes. ( Edit: Le flux de travail a été exactement ce que vous attendez: j'ai sauvé l'intrigue en tant que fichier PDF à partir de R, ouvert en avant-première et créé des zones de texte avec les étiquettes (9pt Helvetica) et ensuite venez de glisser autour de ma souris, jusqu'à ce qu'ils avait l'air bien. Puis j'ai exporté vers un PNG pour télécharger vers SO.)

maintenant, avant que vous succombiez à la forte envie de descendre votez ceci dans l'oubli et laissez des commentaires sarcastiques sur la façon dont le point est d'automatiser ce processus, écoutez-moi!

chercher des solutions algorithmiques est très bien, et (IMHO) vraiment intéressant. Mais, à mes yeux, les situations d'étiquetage ponctuel se répartissent en trois catégories:

  1. vous avez un petit nombre de points, aucun qui sont très proches l'un de l'autre . Dans ce cas, l'une des solutions que vous avez énumérées dans la question est susceptible de fonctionner avec un minimum de retouches.
  2. vous avez un petit nombre de points, dont certains sont trop serrés pour les solutions algorithmiques typiques pour donner de bons résultats . Dans ce cas, puisque vous n'avez qu'un petit nombre de points, les étiqueter à la main (soit avec un éditeur d'image ou de peaufinage votre appel à text ) n'est pas que beaucoup d'effort.
  3. vous avez un assez grand nombre de points . Dans ce cas, vous ne devriez vraiment pas les étiqueter de toute façon, car il est difficile de traiter un grand nombre d'étiquettes visuellement.

: grimpant sur la boîte de savon:

depuis les gens comme nous amour automatisation, je pense que nous tombons souvent dans le piège de penser quasiment tous les aspects de la production d'une bonne statistique graphique devrait être automatisé. Je suis d' (humblement!) désaccord.

il n'y a pas d'environnement de pointage statistique parfaitement général qui crée automatiquement l'image que vous avez dans votre tête. Des choses comme R, ggplot2, treillis, etc. faire la plupart du travail; mais ce petit supplément de peaufinage, en ajoutant une ligne ici, en ajustant une marge là, est probablement mieux adapté à un outil différent.

: en descendant de soapbox:

je voudrais également noter que je pense que nous pourrions tous venir avec scatterplots avec <10-15 points qui seront presque impossible à étiqueter proprement, même à la main, et ceux-ci vont probablement briser toute solution automatique quelqu'un vient avec.

enfin, je tiens à répéter que je savoir ce n'est pas la réponse que vous recherchez. Et je suis pas disant que algorithmique tentatives sont inutiles ou stupides. J'ai voté en faveur de cette question, et je suis heureux de promouvoir des solutions algorithmiques intéressantes!

la raison pour laquelle j'ai posté cette réponse est que je pense que cette question devrait être la question canonique de" point labelling in R " pour les futurs doublons, et je pense que les solutions impliquant l'étiquetage manuel méritent une place à la table, c'est tout.

46
répondu joran 2011-09-30 15:16:15

ggrepel semble prometteur lorsqu'il est appliqué à ggplot2 scatterplots.

# 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)

enter image description here

31
répondu Sandy Muspratt 2016-01-12 00:47:00

avez-vous essayé le paquet directlabels ?

et, BTW, les arguments pos et offset peuvent prendre des vecteurs pour vous permettre de les obtenir dans les bonnes positions quand il y a un nombre raisonnable de points dans juste quelques passages de parcelle.

10
répondu John 2012-06-25 21:47:20

j'ai trouvé une solution! C'est pas ultime et idéal malheureusement, mais c'est celui qui fonctionne le mieux pour moi maintenant. C'est moitié algorithmique, moitié manuel, donc ça fait gagner du temps par rapport à la solution purement manuelle esquissée par joran.

j'ai négligé très partie importante de la ?identify à l'aide!

L'algorithme utilisé pour placer les étiquettes est le même que celui utilisé par le texte si pos y est spécifié, le la différence étant que la position de la pointeur relatif le point identifié détermine la position dans l'identification.

donc si vous utilisez la solution identify() comme je l'ai écrit dans ma question, alors vous pouvez affecter la position de l'étiquette en ne cliquant pas directement sur ce point, mais en en cliquant à côté de ce point relativement dans la direction désirée!!! Fonctionne tout simplement génial!

l'inconvénient est qu'il y a seulement 4 positions (haut, gauche, bas, droite), mais j'ai plus apprécier les 4 autres (haut-gauche, haut-droite, bas-gauche, bas-droite)... Je l'utilise donc pour étiqueter les points où il ne me dérange pas et le reste des points que je étiqueter directement dans ma présentation Powerpoint, comme joran a proposé : -)

P. S.: Je n'ai pas encore essayé la solution de réseau/ggplot de directlabels, je préfère encore utiliser la bibliothèque de base.

5
répondu TMS 2011-10-28 15:44:46

je vous suggère de jeter un oeil au paquet wordcloud . Je sais que ce paquet ne se concentre pas exactement sur les points mais sur les étiquettes elles-mêmes, et aussi le style semble être assez fixe. Mais tout de même, les résultats que j'ai obtenus en l'utilisant étaient assez étourdissants. Notez également que la version du paquet en question a été publiée au moment où vous avez posé la question, donc elle est encore très récente.

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

4
répondu maj 2013-09-05 06:52:55

pas de réponse, mais trop long pour un commentaire. Une approche très simple qui peut fonctionner sur des cas simples, quelque part entre le post-traitement de joran et les algorithmes plus sophistiqués qui ont été présentés est de faire in-place transformations simples à la base de données.

j'illustre ceci avec ggplot2 parce que je suis plus familier avec cette syntaxe que les tracés de base 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)

Comme vous pouvez le voir, dans ce cas, le résultat est pas idéal, mais il peut être assez bon pour certaines fins. Et il est tout à fait sans effort, typiquement quelque chose comme ceci est assez within(df, y <- y+.01)

enter image description here

2
répondu PatrickT 2014-12-29 19:13:38

j'ai écrit une fonction R appelée addTextLabels() avec son propre paquet addTextLabels . Le paquet peut être installé directement dans votre bibliothèque R en utilisant le code suivant:

install.packages("devtools")
library("devtools")
install_github("JosephCrispell/addTextLabels")

pour l'exemple fourni, j'ai utilisé le code suivant pour générer l'exemple de figure lié ci-dessous.

# Load the addTextLabels library
library(addTextLabels)

# Create vectors storing the X and Y coordinates
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)

# Store the labels to be plotted in a vector
ShortSci = c("MotAlb", "PruMod", "EriRub", "LusMeg", "PhoOch", "PhoPho", 
             "SaxRub", "TurMer", "TurPil", "TurPhi")

# Plot the X and Y coordinates without labels
plot(x, y, asp=1)
abline(h = 1, col = "green")
abline(v = 1, col = "green")

# Add non-overlapping text labels
addTextLabels(x, y, ShortSci, cex=0.9, col.background=rgb(0,0,0, 0.75), 
              col.label="white")

il fonctionne en choisissant automatiquement un emplacement alternatif à partir d'une grille fine de points. Les points les plus proches de la grille sont visités d'abord et sélectionné s'ils ne se chevauchent pas avec des points tracés ou des étiquettes. Jetez un oeil à la source code , si vous êtes intéressé.

Exemple De Figure

0
répondu Joseph Crispell 2018-09-26 14:54:44