web-dev-qa-db-ja.com

Rのggplot2のポイントの順序を制御しますか?

Rのggplot2に密な散布図をプロットし、各点に異なる色のラベルを付けると仮定します。

df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
df$label <- c("a")
df$label[50] <- "point"
df$size <- 2
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size))

これを行うと、 "point"(緑)というラベルの散布点が、 "a"というラベルの付いた赤い点の上にプロットされます。 ggplotでこのz順序を制御するもの、つまり、どのポイントがどのポイントの上にあるかを制御しますか?たとえば、すべての「a」ポイントを「point」というラベルの付いたすべてのポイントの上に配置したい場合はどうすればよいでしょうか(ポイントが部分的または完全に非表示になる場合があることを意味します)。これは、ラベルのアルファベット順に依存していますか? rpy2に簡単に変換できるソリューションを見つけたいです。ありがとう

46
user248237

_ggplot2_はレイヤーごとにプロットを作成し、各レイヤー内でプロット順序はgeomタイプで定義されます。デフォルトでは、dataに表示される順序でプロットします。

これが異なる場合は、注意が必要です。例えば

_geom_line_

X値で順序付けられた観測値を接続します。

そして

_geom_path_

観測値をデータ順に接続します


factorsの順序に関する既知の問題 もあり、パッケージ作成者Hadleyの応答に注目するのは興味深い

プロットの表示は、データフレームの順序に対して不変である必要があります。それ以外はバグです。


この引用を念頭に置いて、レイヤーは指定された順序で描画されるため、特に密な散布図を作成する場合は、オーバープロットcanが問題になります。したがって、一貫性のあるプロット(データフレームの順序に依存しないプロット)が必要な場合は、もう少し考える必要があります。


2番目のレイヤーを作成する

特定の値を他の値の上に表示したい場合は、subset引数を使用して、後で確実に描画される2番目のレイヤーを作成できます。 plyrパッケージを明示的にロードして、.()が機能するようにする必要があります。

_set.seed(1234)
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
df$label <- c("a")
df$label[50] <- "point"
df$size <- 2
library(plyr)
ggplot(df) + geom_point(aes(x = x, y = y, color = label, size = size)) +
  geom_point(aes(x = x, y = y, color = label, size = size), 
             subset = .(label == 'point'))
_

enter image description here

更新

_ggplot2_2.0.0_では、subset引数は非推奨です。使用する_base::subset_は、data引数で指定された関連データを選択します。 plyrをロードする必要はありません:

_ggplot(df) +
  geom_point(aes(x = x, y = y, color = label,  size = size)) +
  geom_point(data = subset(df, label == 'point'),
             aes(x = x, y = y, color = label, size = size))
_

またはalphaを使用します

オーバープロットの問題を回避する別のアプローチは、ポイントのalpha(透明度)を設定することです。これは上記の明示的な第2層アプローチほど効果的ではありませんが、_scale_alpha_manual_を慎重に使用すると、何かを機能させることができます。

例えば

_# set alpha = 1 (no transparency) for your point(s) of interest
# and a low value otherwise
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size,alpha = label)) + 
  scale_alpha_manual(guide='none', values = list(a = 0.2, point = 1))
_

enter image description here

47
mnel

2016アップデート:

順序の美学 廃止予定 ので、この時点で最も簡単なアプローチはdata.frameをソートして緑のポイントが一番下になり、最後にプロットされるようにすることです。元のdata.frameを変更したくない場合は、ggplot呼び出し中に並べ替えることができます-dplyrパッケージの%>%およびarrangeを使用してオンザ-フライソート:

library(dplyr)
ggplot(df %>%
         arrange(label),
       aes(x = x, y = y, color = label, size = size)) +
  geom_point()

enter image description here

ggplot2バージョン<2.0.0の元の2015年の回答

Ggplot2では、 order aesthetic を使用して、ポイントをプロットする順序を指定できます。最後にプロットされたものが一番上に表示されます。これを適用するには、ポイントを描画する順序を保持する変数を作成します。

緑色のドットを他の後にプロットして上に配置するには:

df$order <- ifelse(df$label=="a", 1, 2)
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=order))

または、最初に緑のドットをプロットして埋めるには、逆の順序でポイントをプロットします。

ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=-order))

この簡単な例では、新しい並べ替え変数の作成をスキップして、label変数を因子に強制してから数値に強制することができます。

ggplot(df) +
  geom_point(aes(x=x, y=y, color=label, size=size, order=as.numeric(factor(df$label))))
33
Sam Firke

ここでの基本的な質問は、次のように言い換えることができます。

プロットのレイヤーをどのように制御しますか?

'ggplot2'パッケージでは、各レイヤーを異なるコマンドに分割することにより、これをすばやく行うことができます。レイヤーの観点から考えるには少し練習が必要ですが、基本的には他のものの上にプロットしたいものになります。バックグラウンドから上にビルドします。

Prep:サンプルデータを準備します。作業する実際のデータがないため、この手順はこの例でのみ必要です。

_# Establish random seed to make data reproducible.
set.seed(1)

# Generate sample data.
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x

# Initialize 'label' and 'size' default values.
df$label <- "a"
df$size <- 2

# Label and size our "special" point.
df$label[50] <- "point"
df$size[50] <- 4
_

レイヤーの違いを明確にするために、サンプルに異なるサイズを追加したことに気づくかもしれません。

ステップ1:データをレイヤーに分離します。 「ggplot」関数を使用する前に、常にこれを実行してください。 「ggplot」関数を使用してデータ操作を行おうとすると、行き詰まる人が多すぎます。ここでは、2つのレイヤーを作成します。1つは「a」ラベル、もう1つは「point」ラベル付きです。

_df_layer_1 <- df[df$label=="a",]
df_layer_2 <- df[df$label=="point",]
_

他の関数を使用してこれを行うこともできますが、データフレームマッチングロジックを使用してデータをプルするだけです。

ステップ2:データをレイヤーとしてプロットします。最初にすべての「a」データをプロットしてから、すべての「ポイント」データをプロットします。

_ggplot() + 
    geom_point(
        data=df_layer_1,
        aes(x=x, y=y), 
        colour="orange", 
        size=df_layer_1$size) +
    geom_point(
        data=df_layer_2, 
        aes(x=x, y=y), 
        colour="blue", 
        size=df_layer_2$size)
_

demo chart

ベースプロットレイヤーggplot()にはデータが割り当てられていないことに注意してください。各レイヤーのデータをオーバーライドするため、これは重要です。次に、独自の仕様を使用する2つの別個のポイントジオメトリレイヤーgeom_point(...)があります。 x軸とy軸は共有されますが、異なるデータ、色、サイズを使用します。

色とサイズの指定をaes(...)関数の外側に移動することが重要です。そのため、これらの値をそのまま指定できます。それ以外の場合、「ggplot」関数は通常、データにあるレベルに応じて色とサイズを割り当てます。たとえば、データに2と5のサイズ値がある場合、値2の出現にデフォルトサイズを割り当て、値5の出現により大きいサイズを割り当てます。An 'aes '関数仕様では、サイズに値2と5を使用しません。色についても同じことが言えます。使用したい正確なサイズと色があるので、これらの引数を「geom_plot」関数自体に移動します。また、「aes」関数の指定はすべて凡例に入れられますが、これは本当に役に立たない可能性があります。

最終ノート:この例では、さまざまな方法で目的の結果を達成できますが、「ggplot」チャートを最大限に活用するには、「ggplot2」レイヤーの仕組みを理解することが重要です。 'ggplot'関数を呼び出す前にデータを異なるレイヤーに分離している限り、画面上でのグラフの表示方法を細かく制御できます。

12
Dinre

Data.frameの行の順にプロットされます。これを試して:

df2 <- rbind(df[-50,],df[50,])
ggplot(df2) + geom_point(aes(x=x, y=y, color=label, size=size))

ご覧のように、緑の点はdata.frameの最後の行を表すため、最後に描画されます。

次に、data.frameを順序付けて、緑の点を最初に描画する方法を示します。

df2 <- df[order(-as.numeric(factor(df$label))),]
7
Roland