आर में बुद्धिमान बिंदु लेबल प्लेसमेंट


102

1) क्या कोई R लाइब्रेरी / फ़ंक्शन है जो R प्लॉट में INTELLIGENT लेबल प्लेसमेंट को लागू करेगा? मैंने कुछ कोशिश की लेकिन वे सभी समस्याग्रस्त हैं - कई लेबल या तो एक दूसरे या अन्य बिंदुओं (या भूखंड में अन्य वस्तुओं) पर ओवरलैपिंग कर रहे हैं, लेकिन मुझे लगता है कि यह संभालना बहुत कठिन है)।

2) यदि नहीं, तो क्या कोई तरीका है कि विशेष रूप से समस्याग्रस्त बिंदुओं के लिए लेबल प्लेसमेंट के साथ एल्गोरिदम को COMFORTABLY कैसे मदद करें? सबसे आरामदायक और कुशल समाधान चाहता था।

आप मेरे प्रजनन उदाहरण के साथ अन्य संभावनाओं को खेल सकते हैं और उनका परीक्षण कर सकते हैं और देख सकते हैं कि क्या आप मेरे मुकाबले बेहतर परिणाम प्राप्त करने में सक्षम हैं:

# 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: टूडू: labcurve {Hmisc} कोशिश करें


2
R प्रश्नों के उत्तर दुर्भाग्य से, StackOverflow और CrossValidated के बीच समान रूप से विभाजित होने के लिए प्रतीत होते हैं। इस मामले में, सवाल वहाँ पर 4 दिन पहले से एक की नकल है ।
एड स्टब सिप

3
मैं एक समान समस्या में भाग गया और एक मूल पैकेज लिखा जो ऑब्जेक्ट स्थान को समायोजित करने के लिए बल क्षेत्र सिमुलेशन का उपयोग करता है। जबकि ggplot, आदि के साथ एकीकरण सहित बहुत सुधार संभव है, यह कार्य को पूरा करने के लिए लगता है। निम्न कार्यक्षमता दिखाता है। यदि कोई इस मुद्दे पर चलता है और जवाब की तलाश करता है, तो उम्मीद है कि यह कुछ सहायता करेगा:install.packages("FField") library(FField) FFieldPtRepDemo()
gregk

क्या मैं आपसे ggrepel आज़माने के लिए कह सकता हूँ ?
कामिल स्लोविकॉस्की

प्रिय @ जोरान, कृपया अपनी टिप्पणी "6) ggplot2 रेखांकन के लिए, एक नया विकल्प है जिसे ggrepel कहा जाता है जिसे बहुत से लोग पसंद करते हैं।" एक टिप्पणी या एक जवाब में। यहां मैंने केवल उन विकल्पों की सूची को शामिल किया, जिनकी मैंने कोशिश की लेकिन संतोषजनक नहीं हैं । यदि यह ऐसा कुछ है जो अच्छी तरह से काम करता है तो यह एक उत्तर में होना चाहिए।
टीएमएस

जवाबों:


49

सबसे पहले, यहाँ इस समस्या के समाधान के परिणाम हैं:

यहां छवि विवरण दर्ज करें

मैंने कुछ ही मिनटों में प्रीव्यू (ओएस एक्स पर बहुत ही बुनियादी पीडीएफ / इमेज व्यूअर) में हाथ से ऐसा किया। ( संपादित करें: वर्कफ़्लो वास्तव में आप क्या उम्मीद करेंगे: मैंने आर से पीडीएफ के रूप में प्लॉट को बचाया, पूर्वावलोकन में खोला और वांछित लेबल (9pt हेल्वेटिका) के साथ टेक्स्टबॉक्स बनाया और फिर उन्हें अपने माउस के साथ तब तक घसीटा जब तक वे नहीं दिखे। अच्छा। फिर मैंने एसओ को अपलोड करने के लिए एक पीएनजी को निर्यात किया। '

अब, इससे पहले कि आप इस गुमनामी में वोट डालने के लिए मजबूत आग्रह के आगे झुकें और इस प्रक्रिया को स्वचालित करने के बारे में भद्दे कमेंट्स छोड़ें, मुझे सुनाइए!

एल्गोरिदम समाधान की तलाश पूरी तरह से ठीक है, और (IMHO) वास्तव में दिलचस्प है। लेकिन, मेरे लिए, बिंदु लेबलिंग की स्थिति लगभग तीन श्रेणियों में आती है:

  1. आपके पास अंकों की एक छोटी संख्या है, जो कोई भी एक साथ बहुत करीब नहीं हैं । इस मामले में, आपके द्वारा प्रश्न में सूचीबद्ध समाधानों में से एक काफी न्यूनतम ट्विकिंग के साथ काम करने की संभावना है।
  2. आपके पास कम संख्या में अंक हैं, जिनमें से कुछ अच्छे परिणाम देने के लिए विशिष्ट एल्गोरिदम समाधानों के लिए बहुत निकट हैं । इस मामले में, चूंकि आपके पास बहुत कम अंक हैं, इसलिए उन्हें हाथ से लेबल करना (या तो एक छवि संपादक या आपके कॉल को ठीक करने के लिए text) इतना प्रयास नहीं है
  3. आपके पास अंकों की एक बड़ी संख्या है । इस मामले में, आपको वास्तव में वैसे भी लेबल नहीं करना चाहिए, क्योंकि बड़ी संख्या में लेबल नेत्रहीन रूप से संसाधित करना मुश्किल है।

: साबुन बॉक्स पर चढ़ना:

चूंकि हम जैसे लोग स्वचालन से प्यार करते हैं, मुझे लगता है कि हम अक्सर इस सोच के जाल में पड़ जाते हैं कि एक अच्छा सांख्यिकीय ग्राफिक बनाने का लगभग हर पहलू स्वचालित होना चाहिए। मैं आदरपूर्वक (विनम्रतापूर्वक!) असहमत हूं।

पूरी तरह से सामान्य सांख्यिकीय प्लॉटिंग वातावरण नहीं है जो आपके सिर में आपके द्वारा बनाई गई तस्वीर को स्वचालित रूप से बनाता है। आर, ggplot2, जाली आदि जैसी चीजें अधिकांश काम करती हैं; लेकिन उस अतिरिक्त को थोड़ा अलग करने, यहाँ एक लाइन जोड़ने, वहाँ एक मार्जिन को समायोजित करने, शायद एक अलग उपकरण के लिए बेहतर है।

: साबुन बॉक्स से नीचे चढ़ना:

मैं यह भी नोट करूंगा कि मुझे लगता है कि हम सभी 10-15 अंकों के साथ स्कैल्पलैट्स के साथ आ सकते हैं, जो कि हाथ से भी साफ-सुथरा लेबल करना लगभग असंभव होगा, और ये संभवत: किसी भी स्वचालित समाधान को तोड़ देगा, जो किसी के साथ आता है।

अंत में, मैं दोहराना चाहता हूं कि मुझे पता है कि यह वह उत्तर नहीं है जिसकी आपको तलाश है। और मैं यह नहीं कह रहा हूं कि एल्गोरिदमिक प्रयास बेकार या गूंगे हैं। मैंने इस सवाल को वोट दिया, और दिलचस्प एल्गोरिदम समाधानों को खुशी से बढ़ाऊंगा!

कारण यह है कि मैंने इस उत्तर को पोस्ट किया है, मुझे लगता है कि यह प्रश्न भविष्य के डुप्लिकेट के लिए "आर" प्रश्न में कैनोनिकल "पॉइंट लेबलिंग" होना चाहिए, और मुझे लगता है कि हैंड-लेबलिंग से जुड़े समाधान टेबल पर एक सीट के लायक हैं।


10
एक अन्य मैनुअल तरीका है कि प्लॉट को एसवीजी के रूप में सहेजना और इंकस्केप का उपयोग करके इसे संपादित करना, फिर उसी से पीडीएफ का उत्पादन करें।
15

हाय joran, आपके उत्तर के लिए धन्यवाद। ठीक है, मैं इस समाधान को स्वीकार करता हूं, हालांकि मुझे लगता है कि कंप्यूटर को यह सबसे पहले करना चाहिए और फिर मैनुअल अनुरोध करना चाहिए। यहां मैं सबसे आरामदायक और तेज समाधान की तलाश कर रहा हूं। क्या आप यह बता सकते हैं कि आपने प्लॉट, स्टेप बाई स्टेप कैसे बनाया? क्या आपने R में निर्यात किया, निर्यात किया, पूर्वावलोकन में लेबल को स्थानांतरित किया, आदि?
TMS

1
@TomasT। ओह मैं समझा। उस मामले में मैं "धोखा", तरह का। मैंने आपके तरीकों में से एक के ऊपर और एक के बिना लेबल के साथ एक पीडीएफ उत्पन्न किया और एक गाइड के रूप में लेबल के साथ एक का उपयोग किया।
जोरन

1
+1 यह एक बेहतरीन जवाब है। मेटा-सीवी पर क्यों दिखाई देता है की कुछ व्याख्या : वहां टिप्पणियों को देखें।
whuber

1
हाथ से लेबल के एक छोटे से सेट को स्थानांतरित करना समझदारी भरा लगता है, लेकिन आप उन्हें पहले स्वचालित रूप से बना सकते हैं , और फिर उन्हें स्थानांतरित कर सकते हैं। इस तरह आप अपने आप को बहुत काम बचा रहे हैं, और मिस-लेबलिंग की संभावना को भी कम कर रहे हैं ...
naught101

42

ggrepelggplot2स्कैल्प्लॉट्स पर लागू होने पर आशाजनक लगता है ।

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

यहां छवि विवरण दर्ज करें


10

क्या आपने डायरेक्टलैबल्स पैकेज की कोशिश की है?

और, बीटीडब्ल्यू, पॉज़ और ऑफसेट तर्क आपको वैक्टर ले सकते हैं ताकि आप उन्हें सही स्थिति में ले सकें जब प्लॉट के कुछ ही रन में उचित संख्या में अंक हों।


क्या डायरेक्टलैबल्स पैकेज का इस्तेमाल सामान्य plot()प्लॉट के साथ किया जा सकता है ? मैं सफल होने की कोशिश नहीं कर रहा था ... धन्यवाद! PS: @SpacedMan & Ben, मैंने R अपडेट के बारे में अपनी टिप्पणी साफ कर दी, क्योंकि वे इतने दिलचस्प नहीं हैं - आप भी ऐसा कर सकते हैं।
टीएमएस

6

मुझे कुछ हल मिला! यह अंतिम और आदर्श दुर्भाग्यपूर्ण नहीं है, लेकिन यह एक है जो अब मेरे लिए सबसे अच्छा काम करता है। यह आधा अल्‍गोरिटमिक, आधा मैनुअल है, इसलिए यह शुद्ध मैनुअल सॉल्यूशन की तुलना में समय की बचत करता है।

मैंने मदद के बहुत महत्वपूर्ण हिस्से की अनदेखी की !?identify

लेबल रखने के लिए उपयोग किया जाने वाला एल्गोरिथ्म पाठ द्वारा उपयोग किया जाने वाला समान है यदि पॉज़ को वहां निर्दिष्ट किया गया है, तो अंतर यह है कि सूचक की स्थिति पहचाने गए बिंदु के सापेक्ष स्थिति पहचान में स्थिति निर्धारित करती है।

इसलिए यदि आप identify()मेरे प्रश्न में लिखे अनुसार समाधान का उपयोग करते हैं, तो आप उस बिंदु पर सीधे क्लिक न करके लेबल की स्थिति को प्रभावित कर सकते हैं, लेकिन वांछित दिशा में अपेक्षाकृत उस बिंदु के बगल में क्लिक करके !!! बस महान काम करता है!

नकारात्मक पक्ष यह है कि केवल 4 स्थान हैं (शीर्ष, बाएं, नीचे, दाएं), लेकिन मैं अन्य 4 (शीर्ष-बाएं, शीर्ष-दाएं, नीचे-बाएं, नीचे-दाएं) की सराहना करूंगा ... इसलिए मैं इसका उपयोग उन पॉइंट्स पर करें जहाँ यह मुझे परेशान नहीं करता है और बाकी पॉइंट्स को मैं सीधे अपने पावरपॉइंट प्रेजेंटेशन में लेबल करता हूँ, जैसा कि joran :-)

पुनश्च: मैंने अभी तक Directlabels जाली / ggplot समाधान की कोशिश नहीं की है, मैं अभी भी मूल भूखंड पुस्तकालय का उपयोग करना पसंद करता हूं।


4

मेरा सुझाव है कि आप wordcloudपैकेज पर एक नज़र डालेंगे । मुझे पता है कि यह पैकेज केवल अंकों पर नहीं बल्कि स्वयं लेबल पर केंद्रित है, और यह भी कि शैली निश्चित रूप से तय होती है। लेकिन फिर भी, मुझे इसके उपयोग से जो परिणाम मिले, वे बहुत आश्चर्यजनक थे। यह भी ध्यान दें कि प्रश्न में पैकेज संस्करण उस समय के बारे में जारी किया गया था जब आपने प्रश्न पूछा था, इसलिए यह अभी भी बहुत नया है।

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


3

मैंने एक R फंक्शन लिखा है जिसे addTextLabels()पैकेज के भीतर कहा जाता है plotteR। पैकेज को निम्नलिखित कोड का उपयोग करके सीधे अपने आर लाइब्रेरी में स्थापित किया जा सकता है:

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

दिए गए उदाहरण के लिए, मैंने नीचे दिए गए उदाहरण के आंकड़े को उत्पन्न करने के लिए निम्न कोड का उपयोग किया।

# Load the plotteR library
library(plotteR)

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

यह स्वचालित रूप से बिंदुओं के ठीक ग्रिड से एक वैकल्पिक स्थान का चयन करके काम करता है। यदि वे किसी भी प्लॉट किए गए बिंदुओं या लेबल के साथ ओवरलैप नहीं करते हैं, तो ग्रिड पर निकटतम बिंदुओं को पहले देखा जाता है और चुना जाता है। यदि आप रुचि रखते हैं, तो स्रोत कोड पर एक नज़र डालें ।

उदाहरण चित्र


2

उत्तर नहीं है, लेकिन एक टिप्पणी के लिए बहुत लंबा है। एक बहुत ही सरल दृष्टिकोण जो सरल मामलों पर काम कर सकता है, कहीं-कहीं जोरन के बाद के प्रसंस्करण और अधिक परिष्कृत एल्गोरिदम को प्रस्तुत किया गया है जो डेटाफ़्रेम में in-placeसरल परिवर्तन करना है।

मैं इसका वर्णन ggplot2इसलिए करता हूं क्योंकि मैं बेस आर प्लॉट की तुलना में उस सिंटैक्स से अधिक परिचित हूं।

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)

यहां छवि विवरण दर्ज करें


2
dfउपयोग को संशोधित करने के बजाय within, मैं अक्सर सौंदर्यशास्त्र को समायोजित करके ऐसा करता हूं: geom_text(aes(x = x - .01, y = y + .01), hjust = 0, vjust = 0)क्लीनर लगता है।
ग्रेगर थॉमस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.