Posicionamento inteligente de label de ponto em R

1) Existe alguma biblioteca / function R que implementaria a colocação de etiquetas INTELLIGENT na plotagem R? Eu tentei alguns, mas eles são todos problemáticos – muitos labels estão se sobrepondo uns aos outros ou outros pontos (ou outros objects no enredo, mas eu vejo que isso é muito mais difícil de lidar).

2) Se não, existe alguma maneira de ajudar CONFORMADAMENTE o algoritmo com o posicionamento da etiqueta para pontos problemáticos específicos? Solução mais confortável e eficiente queria.

Você pode reproduzir e testar outras possibilidades com o meu exemplo reproduzível e ver se consegue obter melhores resultados do que eu:

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

Para a rotulagem, tentei estas possibilidades, ninguém é realmente bom:

1) este é terrível:

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

2) este é bom se você não quiser colocar labels para todos os pontos, mas apenas para os outliers, mas ainda assim, os labels são frequentemente colocados errados:

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

3) este parecia promissor, mas há o problema de os labels estarem muito próximos dos pontos; Eu tive que preenchê-los com espaços, mas isso não ajuda muito:

 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) 

Agradeço antecipadamente!

EDIT: todo: tente labcurve {Hmisc} .

Primeiro, aqui estão os resultados da minha solução para este problema:

insira a descrição da imagem aqui

Eu fiz isso à mão no Preview (PDF / visualizador de imagens muito básico no OS X) em apenas alguns minutos. ( Edit: O stream de trabalho era exatamente o que você esperaria: eu salvei o enredo como um PDF do R, abri-o no Preview e criei checkboxs de texto com os labels desejados (9pt Helvetica) e então os arrastei com o mouse até eles parecerem Bom. Então eu exportado para um PNG para upload para SO.)

Agora, antes de você sucumbir ao forte anseio de derrubar isso no esquecimento e deixar comentários sarcásticos sobre como o ponto é automatizar esse processo, me escute!

Procurando soluções algorítmicas é totalmente bem, e (IMHO) realmente interessante. Mas, para mim, as situações de rotulagem de ponto caem em aproximadamente três categorias:

  1. Você tem um pequeno número de pontos, nenhum deles terrivelmente próximos . Nesse caso, uma das soluções listadas na pergunta provavelmente funcionará com ajustes mínimos.
  2. Você tem um pequeno número de pontos, alguns dos quais são muito próximos para as soluções algorítmicas típicas para dar bons resultados . Neste caso, uma vez que você tem apenas um pequeno número de pontos, etiquetá-los manualmente (seja com um editor de imagens ou ajustar sua chamada para o text ) não significa muito esforço.
  3. Você tem um número bastante grande de pontos . Nesse caso, você realmente não deveria rotulá-los de qualquer maneira, já que é difícil processar um grande número de labels visualmente.

: subindo para a checkbox de soap:

Como pessoas como nós amam a automação, acho que muitas vezes caímos na armadilha de pensar que quase todos os aspectos da produção de um bom gráfico estatístico devem ser automatizados. Eu respeitosamente (humildemente!) Discordo.

Não existe um ambiente estatístico de plotagem perfeitamente genérico que crie automaticamente a imagem que você tem em sua cabeça. Coisas como R, ggplot2, lattice etc. fazem a maior parte do trabalho; mas esse pouco mais de ajustes, adicionando uma linha aqui, ajustando uma margem lá, provavelmente é mais adequado para uma ferramenta diferente.

: descendo do soapbox:

Também gostaria de observar que todos nós poderíamos chegar a charts de dispersão com <10 a 15 pontos que seriam quase impossíveis de serem rotulados de forma limpa, mesmo à mão, e provavelmente eles quebrariam qualquer solução automática que surgisse com alguém.

Por fim, quero reiterar que sei que essa não é a resposta que você está procurando. E não estou dizendo que tentativas algorítmicas são inúteis ou idiotas. Eu votei a favor desta questão e, felizmente, vou buscar soluções algorítmicas interessantes!

A razão pela qual eu postei essa resposta é que eu acho que essa questão deveria ser a questão canônica de “rotular ponto em R” para duplicatas futuras, e eu acho que soluções envolvendo rotulagem de mão merecem um lugar na mesa, isso é tudo.

ggrepel parece promissor quando aplicado a ggplot2 dispersão 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) 

insira a descrição da imagem aqui

Você já tentou o pacote directlabels ?

E, BTW, os argumentos pos e offset podem receber vetores para permitir que você os coloque nas posições certas quando houver um número razoável de pontos em apenas algumas execuções de plotagem.

Eu encontrei alguma solução! Não é definitivo e ideal, infelizmente, mas é o que funciona melhor para mim agora. É meio algorítmico, meio manual, por isso economiza tempo em comparação com a solução manual pura esboçada pelo joran.

Eu negligenciei parte muito importante da ajuda de ?identify !

O algoritmo usado para colocar etiquetas é o mesmo usado pelo texto, se pos é especificado lá, a diferença é que a posição do ponteiro em relação ao ponto identificado determina pos em identificar.

Então, se você usar a solução identify() como escrevi na minha pergunta, então você pode afetar a posição do label não clicando diretamente nesse ponto, mas clicando próximo a esse ponto relativamente na direção desejada !!! Funciona muito bem!

A desvantagem é que existem apenas 4 posições (superior, esquerda, inferior, direita), mas eu apreciaria mais os outros 4 (superior esquerdo, superior direito, inferior esquerdo, inferior direito) … Então eu use isso para rotular pontos onde isso não me incomoda e o resto dos pontos que eu rotulo diretamente na minha apresentação do Powerpoint, como joran propôs 🙂

PS: Eu não tentei a solução de lattice / ggplot de directlabels ainda, eu ainda prefiro usar a biblioteca de enredo básico.

Eu sugiro que você dê uma olhada no pacote wordcloud . Eu sei que este pacote se concentra não exatamente nos pontos, mas nos labels em si, e também o estilo parece ser bastante fixo. Mas ainda assim, os resultados que obtive ao usá-lo foram bastante impressionantes. Observe também que a versão do pacote em questão foi liberada sobre o tempo que você fez a pergunta, por isso ainda é muito novo.

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

Não é uma resposta, mas muito longa para um comentário. Uma abordagem muito simples que pode trabalhar em casos simples, em algum lugar entre o pós-processamento da joran e os algoritmos mais sofisticados que foram apresentados, é fazer transformações simples in-place para o dataframe.

Eu ggplot2 isso com ggplot2 porque estou mais familiarizado com essa syntax do que os charts 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) 

Como você pode ver, neste exemplo o resultado não é o ideal, mas pode ser bom o suficiente para alguns propósitos. E é bastante fácil, normalmente algo assim é suficiente within(df, y < - y+.01)

insira a descrição da imagem aqui