R'de akıllı nokta etiketi yerleştirme


102

1) R grafiğinde AKILLI etiket yerleşimini uygulayacak herhangi bir R kitaplığı / işlevi var mı? Bazılarını denedim ama hepsi sorunlu - birçok etiket ya birbiriyle ya da diğer noktalarla örtüşüyor (ya da arsadaki diğer nesneler, ancak bunun üstesinden gelmenin çok daha zor olduğunu görüyorum).

2) Değilse, belirli sorunlu noktalar için etiket yerleştirme konusunda algoritmaya RAHAT BİR ŞEKİLDE yardımcı olmanın bir yolu var mı? En rahat ve verimli çözüm aranıyor.

Tekrarlanabilir örneğimle diğer olasılıkları oynayabilir ve test edebilir ve benden daha iyi sonuçlar elde edip edemeyeceğinizi görebilirsiniz:

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

Etiketleme için daha sonra bu olasılıkları denedim, kimse gerçekten iyi değil:

1) bu korkunç:

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

2) bu, tüm noktalar için değil, sadece aykırı değerler için etiket yerleştirmek istemiyorsanız iyidir, ancak yine de etiketler genellikle yanlış yerleştirilir:

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

3) bu umut verici görünüyordu ama etiketlerin noktalara çok yakın olması sorunu var; Onları boşluklarla doldurmak zorunda kaldım ama bu pek yardımcı olmuyor:

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)

Şimdiden teşekkür ederim!

DÜZENLEME: yapılacak: labcurve {Hmisc} 'i deneyin .


2
R sorularına verilen yanıtlar maalesef StackOverflow ve CrossValidated arasında eşit olarak bölünmüş görünüyor. Bu durumda, soru oradaki 4 gün öncesinin bir kopyasıdır .
Ed Staub

3
Benzer bir problemle karşılaştım ve nesne konumunu ayarlamak için kuvvet alanı simülasyonunu kullanan temel bir paket yazdım. Ggplot ile entegrasyon vb. Dahil olmak üzere birçok iyileştirme mümkün olsa da, görevi tamamlamış gibi görünüyor. Aşağıda işlevsellik gösterilmektedir. Birisi sorunla karşılaşırsa ve bir cevap install.packages("FField") library(FField) FFieldPtRepDemo()
ararsa

Sizden ggrepel'i denemenizi isteyebilir miyim ?
Kamil Slowikowski

canım @Joran, lütfen yorumunuzu yazın "6) ggplot2 grafikleri için, ggrepel adında birçok insanın hoşuna gittiği yeni bir seçenek var." bir yorum veya cevapta. Burada sadece denediğim ancak tatmin edici olmayan seçeneklerin listesini ekledim . Eğer iyi çalışan bir şeyse, o zaman bir cevap olmalıdır.
TMS

Yanıtlar:


49

İlk olarak, işte bu soruna yönelik çözümümün sonuçları:

görüntü açıklamasını buraya girin

Bunu Preview'de (OS X'te çok basit PDF / resim görüntüleyici) elle birkaç dakika içinde yaptım. ( Düzenleme: İş akışı tam olarak beklediğiniz şeydi: Grafiği R'den bir PDF olarak kaydettim, Önizleme'de açtım ve istenen etiketlerle (9pt Helvetica) metin kutuları oluşturdum ve sonra onları bakana kadar faremle sürükledim iyi. Sonra SO'ya yüklemek için bir PNG'ye aktardım.)

Şimdi, bunu unutulmaya oylama yönündeki güçlü dürtüye yenik düşmeden ve amacın bu süreci otomatikleştirmenin ne olduğu hakkında alaycı yorumlar bırakmadan önce, beni dinleyin!

Algoritmik çözümler aramak tamamen iyi ve (IMHO) gerçekten ilginç. Ancak bana göre nokta etiketleme durumları kabaca üç kategoriye ayrılır:

  1. Az sayıda noktanız var ve hiçbiri birbirine çok yakın değil . Bu durumda, soruda listelediğiniz çözümlerden biri muhtemelen oldukça az ince ayarlarla çalışacaktır.
  2. Bazıları tipik algoritmik çözümlerin iyi sonuçlar vermesi için çok yakın paketlenmiş az sayıda noktanız var . Bu durumda, yalnızca az sayıda noktanız olduğundan, bunları elle etiketlemek (bir görüntü düzenleyiciyle veya aramanızın ince ayarını yapmak text) o kadar da çaba gerektirmez.
  3. Oldukça fazla puanınız var . Bu durumda, görsel olarak çok sayıda etiketi işlemek zor olduğundan, onları gerçekten etiketlememelisiniz.

: sabun kutusuna tırmanma:

Bizim gibi insanlar otomasyonu sevdiğinden , iyi bir istatistiksel grafik oluşturmanın neredeyse her yönünün otomatikleştirilmesi gerektiğini düşünme tuzağına düştüğümüzü düşünüyorum. Saygıyla (alçakgönüllülükle!) Katılmıyorum.

Kafanızdaki resmi otomatik olarak yaratan mükemmel bir genel istatistiksel çizim ortamı yoktur. R, ggplot2, lattice vb. İşlerin çoğunu yapar ; ancak bu ekstra ufak tefek ince ayar, buraya bir çizgi eklemek, orada bir marj ayarlamak, muhtemelen farklı bir araç için daha uygundur.

: sabun kutusundan aşağı inmek:

Ayrıca, hepimizin elle bile temiz bir şekilde etiketlemenin neredeyse imkansız olacağı 10-15 puanlık dağılım grafikleri bulabileceğimizi ve bunların birisinin bulduğu herhangi bir otomatik çözümü muhtemelen bozacağını düşündüğümü de belirtmek isterim.

Son olarak, aradığınız yanıtın bu olmadığını bildiğimi tekrarlamak istiyorum . Ve ben değil algoritmik girişimleri yararsız ya dilsiz olduklarını açıkladı. Bu soruyu yükselttim ve ilginç algoritmik çözümleri memnuniyetle değerlendireceğim!

Bu yanıtı göndermemin nedeni, bu sorunun gelecekteki kopyalar için kurallı "R'de nokta etiketleme" sorusu olması gerektiğini düşünmem ve el ile etiketlemeyi içeren çözümlerin masada bir yeri hak ettiğini düşünüyorum, hepsi bu.


10
Başka bir manuel yol da çizimi SVG olarak kaydetmek ve Inkscape kullanarak düzenlemek, ardından bundan PDF oluşturmaktır.
Spacedman

1
Merhaba joran, cevabınız için teşekkürler. Tamam, bu çözümü kabul ediyorum, bununla birlikte bilgisayarın bunu en iyi şekilde yapması gerektiğini düşünüyorum VE SONRA manuel müdahale talep ediyorum. Burada en rahat ve hızlı çözümü arıyorum. Hikayeyi nasıl yaptığınızı adım adım anlatır mısınız? R, dışa aktarma, etiketleri Önizlemede taşıma vb.'de ne oluşturdunuz?
TMS

1
@TomasT. Ah anlıyorum. Bu durumda bir çeşit "hile yaptım". Yukarıdaki yöntemlerinden birini, diğerini kullanmadan etiketli bir pdf oluşturdum ve etiketli olanı kılavuz olarak kullandım.
joran

1
+1 Bu harika bir cevap. Meta-CV'de neden göründüğüne dair bazı açıklamalar : oradaki yorumlara bakın.
whuber

1
Küçük bir etiket kümesini elle hareket ettirmek mantıklı görünebilir, ancak önce bunları otomatik olarak oluşturabilir ve sonra taşıyabilirsiniz. Bu şekilde kendinize çok fazla işten tasarruf ediyor ve yanlış etiketleme olasılığını azaltıyorsunuz ...
naught101

42

ggrepelggplot2dağılım grafiklerine uygulandığında umut verici görünüyor .

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

görüntü açıklamasını buraya girin


10

Directlabels paketini denediniz mi?

Ve, BTW, konum ve ofset argümanları, sadece birkaç arsa içinde makul sayıda nokta varken onları doğru konumlara getirmenize izin vermek için vektörleri alabilir.


Direkt etiket paketi normal plot()arsa ile kullanılabilir mi? Bunu denemeyi başaramadım ... Teşekkürler! Not: @SpacedMan & Ben, R güncellemesiyle ilgili yorumlarımı temizledim, çünkü çok ilginç değiller - siz de aynısını yapabilirsiniz.
TMS

6

Bir çözüm buldum! Talihsiz bir şekilde nihai ve ideal değil, ama şu anda benim için en iyi olanı. Yarı algoritmik, yarı manuel, bu nedenle Joran tarafından çizilen saf manuel çözüme kıyasla zaman kazandırıyor.

Yardımın çok önemli bir kısmını gözden kaçırdım!?identify

Etiketleri yerleştirmek için kullanılan algoritma, orada konum belirtilmişse metin tarafından kullanılanla aynıdır; aradaki fark, işaretçinin belirlenen noktaya göre konumunun tanımlamada konumu belirlemesidir.

Yani identify()çözümü sorumda yazdığım gibi kullanırsanız, doğrudan o noktaya değil, o noktanın yanına nispeten istenen yönde tıklayarak etiketin konumunu etkileyebilirsiniz !!! Harika çalışıyor!

Dezavantajı ise sadece 4 pozisyon olması (üst, sol, alt, sağ), ancak diğer 4'ü (sol üst, sağ üst, sol alt, sağ alt) daha çok takdir ediyorum ... Yani ben bunu beni rahatsız etmediği noktaları ve joran'ın önerdiği gibi doğrudan Powerpoint sunumumda etiketlediğim geri kalan noktaları etiketlemek için kullanın :-)

Not: Directlabels lattice / ggplot çözümünü henüz denemedim, yine de temel çizim kitaplığını kullanmayı tercih ediyorum.


4

wordcloudPakete bir göz atmanızı öneririm . Bu paketin tam olarak noktalara değil etiketlere odaklandığını biliyorum ve ayrıca stil de oldukça sabit görünüyor. Ama yine de, onu kullanmaktan aldığım sonuçlar oldukça çarpıcıydı. Ayrıca, söz konusu paket sürümünün soruyu sorduğunuz anda piyasaya sürüldüğünü, dolayısıyla hala çok yeni olduğunu unutmayın.

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


3

addTextLabels()Paketin içinde bir R işlevi yazdım basicPlotteR. Paket, aşağıdaki kod kullanılarak doğrudan R kitaplığınıza yüklenebilir:

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

Sağlanan örnek için, aşağıda bağlantısı verilen örnek şekli oluşturmak için aşağıdaki kodu kullandım.

# Load the basicPlotteR library
library(basicPlotteR)

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

İnce bir nokta ızgarasından otomatik olarak alternatif bir konum seçerek çalışır. Izgaradaki en yakın noktalar ilk olarak ziyaret edilir ve çizilen noktalar veya etiketlerle çakışmazlarsa seçilirler. Eğer ilgileniyorsanız , kaynak koduna bir göz atın .

Örnek Şekil


2

Cevap değil ama yorum yapmak için çok uzun. Joran'ın post-processing ile sunulan daha sofistike algoritmalar arasında bir yerde, basit durumlar üzerinde çalışabilen çok basit bir yaklaşım, veri çerçevesine in-placebasit dönüşümler yapmaktır.

Bunu şununla ggplot2açıklıyorum çünkü bu sözdizimine temel R grafiklerinden daha aşinayım.

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)

Gördüğünüz gibi, bu durumda sonuç ideal değil, ancak bazı amaçlar için yeterince iyi olabilir. Ve oldukça zahmetsizdir, genellikle bunun gibi bir şey yeterlidirwithin(df, y <- y+.01)

görüntü açıklamasını buraya girin


2
Değiştirmek yerine dfkullanarak within, sık sık estetik ayarlayarak bunu: geom_text(aes(x = x - .01, y = y + .01), hjust = 0, vjust = 0)süpürgeyi görünüyor.
Gregor Thomas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.