Rでのインテリジェントなポイントラベル配置


102

1)Rプロットにインテリジェントラベル配置を実装する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)

前もって感謝します!

編集: todo:labcurve {Hmisc}を試してください。


2
Rの質問への回答は、残念ながらStackOverflowとCrossValidatedの間で均等に分割されているようです。この場合、質問はあそこの4日前の質問と重複しています。
Ed Staub、2011

3
私は同様の問題に遭遇し、力場シミュレーションを使用してオブジェクトの位置を調整する基本的なパッケージを作成しました。ggplotとの統合など、多くの改善が可能ですが、タスクは完了したようです。以下に機能を示します。誰かが問題にinstall.packages("FField") library(FField) FFieldPtRepDemo()
遭遇

ggrepelを試してもらえますか?
Kamil Slowikowski、2016

@Joran様、コメントをお寄せください。「6)ggplot2グラフには、ggrepelという新しいオプションがあり、多くの人が気に入っているようです。」コメントまたは回答で。ここでは、私が試したオプションのリストのみを含めましたが、満足できるものではありません。それがうまくいくものであれば、それは答えにあるはずです。
TMS 2016年

回答:


49

まず、この問題に対する私の解決策の結果を次に示します。

ここに画像の説明を入力してください

私はわずか数分でプレビュー(OS Xの非常に基本的なPDF /画像ビューア)でこれを手動で行いました。(編集:ワークフローは期待どおりでした:プロットをRからPDFとして保存し、プレビューで開いて、目的のラベル(9pt Helvetica)でテキストボックスを作成し、マウスで見回すまでドラッグしました次に、SOにアップロードするためにPNGにエクスポートしました。)

さて、あなたがこれを忘却に反対票を投じて、このプロセスを自動化することがポイントである方法について卑劣なコメントを残すという強い衝動に屈する前に、私に聞いてください!

アルゴリズムによる解決策を探すことはまったく問題なく、(IMHO)は本当に興味深いものです。しかし、私には、ポイントラベル付けの状況はおおよそ3つのカテゴリに分類されます。

  1. 少数のポイントがありますが、どれも非常に接近していません。この場合、質問にリストしたソリューションの1つは、最小限の調整で機能する可能性があります。
  2. 少数のポイントがあり、その一部は密集しすぎているため、一般的なアルゴリズムのソリューションでは適切な結果を得ることができません。この場合は、以来、あなただけ(画像エディタや微調整にお電話をしてどちらの手によってそれらを標識、ポイントの数が少ないtextではありません)という多くの努力。
  3. あなたはかなり多くのポイントを持っています。この場合、大量のラベルを視覚的に処理することが難しいため、実際にはラベルを付けないでください。

:soapboxに登る:

私たちのような人々は自動化を愛しているので、優れた統計グラフィックの作成のほぼすべての側面は自動化されるべきであるという考えの罠によく陥ります。私は敬意を表して(謙虚に!)同意しません。

頭の中にある画像を自動的に作成する、完全に一般的な統計プロット環境はありません。R、ggplot2、latticeなどのようなものがほとんどの作業を行います。ただし、ここに線を追加し、余白を調整するという追加の微調整は、おそらく別のツールに適しています。

:soapboxから下る:

また、10〜15ポイント未満の散布図をすべて手作業で作成することは不可能であり、手作業でラベルを付けることはほぼ不可能だと思います。これらは、誰かが思いついた自動ソリューションを壊す可能性があります。

最後に、これがあなたが探している答えではないことを知っています。そして、アルゴリズムの試みが役に立たなかったり、ばかげていると言っているのではありません。私はこの質問に賛成票を投じました。興味深いアルゴリズムソリューションに喜んで反対票を投じます。

私がこの回答を投稿した理由は、この質問が将来の重複のための標準的な「Rでのポイントラベル付け」の質問であるべきだと私が思うからです。


10
もう1つの手動の方法は、プロットをSVGとして保存し、Inkscapeを使用して編集してから、そこからPDFを生成することです。
Spacedman、2011

こんにちはjoran、回答ありがとうございます。OK、私はこのソリューションを受け入れますが、コンピュータがこれを最初に最善の方法で実行し、その後手動での介入を要求すると思います。ここで私は最も快適で高速なソリューションを探しています。どのようにプロットを作成したのか、段階的に説明していただけますか?Rで生成したもの、エクスポート、プレビューでのラベルの移動など。
TMS 2011

1
@TomasT。ああなるほど。その場合、私は一種の「だまされました」。上記の方法のいずれかを使用してラベル付きのPDFを1つ生成し、ラベルなしのPDFをガイドとして使用しました。
joran '30 / 09/30

1
+1これは素晴らしい答えです。meta-CVに表示される理由のいくつかの説明:コメントを参照してください。
whuber '30 / 09/30

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

directlabelsパッケージを試しましたか?

そして、ところで、posとoffset引数はベクトルを取り、プロットの数回の実行で妥当な数のポイントがある場合に正しい位置にそれらを取得できるようにします。


directlabelsパッケージを通常のplot()プロットで使用できますか?私はそうしようとして成功しませんでした...ありがとう!PS:@SpacedMan&Ben、私はRの更新に関するコメントを整理しました。それほど興味深いものではないので、同じことを実行できます。
TMS 2011

6

私はいくつかの解決策を見つけました!それは究極ではなく、快適ではありませんが、私にとって今最もよく機能するものです。それは半分のアルゴリズム、半分の手動なので、joranによってスケッチされた純粋な手動のソリューションと比較して時間を節約できます。

ヘルプの非常に重要な部分を見落としました?identify

ラベルを配置するために使用されるアルゴリズムは、posが指定されている場合にテキストで使用されるアルゴリズムと同じです。違いは、識別されたポイントに対するポインターの位置によって、identのposが決まることです。

したがってidentify()、私の質問に書いたようにソリューションを使用する場合、そのポイントを直接クリックするのではなく、目的の方向にそのポイントの隣をクリックして、ラベルの位置に影響を与えることができます!!! うまくいきます!

欠点は、位置が4つ(上、左、下、右)しかないことですが、他の4つ(左上、右上、左下、右下)に感謝します...だから私はjoranが提案したように、これを使用して、気にしないポイントと、Powerpointプレゼンテーションで直接ラベル付けする残りのポイントにラベルを付けます:-)

PS:directlabelsラティス/ ggplotソリューションをまだ試していませんが、基本的なプロットライブラリを使用することを好みます。


4

wordcloudパッケージをご覧になることをお勧めします。このパッケージは正確にポイントではなくラベル自体に焦点を当てており、スタイルもかなり固定されているようです。しかし、それでも、それを使用して得た結果はかなり驚くべきものでした。また、問題のパッケージバージョンは、質問した時点でリリースされているため、まだ非常に新しいものです。

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


3

addTextLabels()パッケージ内で呼び出されるR関数を記述しましたplotteR。パッケージは、次のコードを使用してRライブラリに直接インストールできます。

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

回答ではありませんが、コメントするには長すぎます。joranの後処理と提示されているより高度なアルゴリズムの間のどこかで、単純なケースで機能する非常に単純なアプローチはin-place、データフレームに単純な変換を行うことです。

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)

ここに画像の説明を入力してください


2
修正するのではなくdf使用してwithin、私は頻繁に美学を調整することにより、次の操作を行います。geom_text(aes(x = x - .01, y = y + .01), hjust = 0, vjust = 0)クリーナーを思わ。
グレゴールトーマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.