安定したマッピングを持つggplot2のカテゴリー変数に色を割り当てる方法は?


177

私は先月、Rに追いついてきました。

これが私の質問です:

安定したマッピングを持つggplot2のカテゴリー変数に色を割り当てる良い方法は何ですか?異なるサブセットと異なる数のカテゴリ変数を持つ一連のグラフ全体で一貫した色が必要です。

例えば、

plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()

categoricalDataは5つのレベルがあります。

その後

plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset, 
                                 color=categoricaldData.subset)) + geom_line()

categoricalData.subsetは3つのレベルがあります。

ただし、両方のセットに含まれる特定のレベルは異なる色で終わるため、グラフを一緒に読み取るのが難しくなります。

データフレームに色のベクトルを作成する必要がありますか?または、特定の色をカテゴリに割り当てる別の方法はありますか?

回答:


186

OPの正確な例のような単純な状況では、ティエリーの答えが最良であることに同意します。ただし、1 つの大きなデータフレームをサブセット化することですべてが得られるわけではない複数のデータフレームにわたって一貫したカラースキームを維持しようとする場合に、より簡単になる別のアプローチを指摘することは有用だと思います。複数のデータフレームで因子レベルを管理することは、それらが別々のファイルからプルされていて、すべての因子レベルが各ファイルに表示されていない場合、面倒になる可能性があります。

これに対処する1つの方法は、次のようにカスタムの手動カラースケールを作成することです。

#Some test data
dat <- data.frame(x=runif(10),y=runif(10),
        grp = rep(LETTERS[1:5],each = 2),stringsAsFactors = TRUE)

#Create a custom color scale
library(RColorBrewer)
myColors <- brewer.pal(5,"Set1")
names(myColors) <- levels(dat$grp)
colScale <- scale_colour_manual(name = "grp",values = myColors)

必要に応じて、プロットにカラースケールを追加します。

#One plot with all the data
p <- ggplot(dat,aes(x,y,colour = grp)) + geom_point()
p1 <- p + colScale

#A second plot with only four of the levels
p2 <- p %+% droplevels(subset(dat[4:10,])) + colScale

最初のプロットは次のようになります。

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

2番目のプロットは次のようになります。

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

このようにして、各データフレームを覚えたりチェックしたりして、適切なレベルであることを確認する必要はありません。


1
これは機能しますが、おそらく過度に複雑です。このために手動でスケールを作成する必要はないと思います。必要なのは、factorすべてのプロットに共通するです。
Andrie

14
@Andrie-単一のサブセットの場合、そうです。しかし、1つの元のデータフレームをサブセット化することによってすべてが作成されたのではない多くのデータセットをジャグリングする場合、この戦略ははるかに簡単です。
joran

2
@joran Joranに感謝します。これは私のために働いた!適切な数の要素を持つ凡例を作成します。私はこのアプローチが好きで、さまざまなデータセット間でカラーマッピングを取得することは、3行に値します。
ウィンター

3
必要なもの:library( "RColorBrewer")
PatrickT

4
完璧に働いた!fillScale <- scale_fill_manual(name = "grp",values = myColors)これを棒グラフで使用するために追加しました。
ペンダントラス

42

マルククが指摘したのと同じ状況です彼のコメント:残念ながらその答えによって、ティエリーは ggplot2バージョン0.9.3.1では動作しません。

png("figure_%d.png")
set.seed(2014)
library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100),
    x = rnorm(500, mean = rep(1:5, 100)),
    y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))

ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()

これが最初の図です。

ggplot AE、混合色

そして2番目の図:

ggplot ADE、混合色

ご覧のとおり、色は固定されていません。たとえば、Eはマゼンタからブルーに切り替えます。

彼のコメントでマルクックハドリーで示唆されたよう彼のコメント使用するコードlimits作品を適切に:

ggplot(subdata, aes(x = x, y = y, colour = fCategory)) +       
    geom_point() + 
    scale_colour_discrete(drop=TRUE,
        limits = levels(dataset$fCategory))

正しい次の図を示します。

正しいggplot

これはからの出力ですsessionInfo()

R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] methods   stats     graphics  grDevices utils     datasets  base     

other attached packages:
[1] ggplot2_0.9.3.1

loaded via a namespace (and not attached):
 [1] colorspace_1.2-4   dichromat_2.0-0    digest_0.6.4       grid_3.0.2        
 [5] gtable_0.1.2       labeling_0.2       MASS_7.3-29        munsell_0.4.2     
 [9] plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2    
[13] scales_0.2.3       stringr_0.6.2 

3
これを新しい質問として投稿し、この質問を参照して、ここで解決策が機能しない理由を示す必要があります。
ブライアンディグス

同様の質問がここで尋ねられましたが、受け入れられた答えがうまく機能することを指摘したいと思います。
tonytonov 2015年

1
これが古いことはわかっていますが、凡例に余分な色を付けずにこれを行う方法はあるのでしょうか。
goryh

20

最も簡単な解決策は、サブセット化する前に、カテゴリ変数を因子に変換することです。結論として、すべてのサブセットでまったく同じレベルの因子変数が必要です。

library(ggplot2)
dataset <- data.frame(category = rep(LETTERS[1:5], 100), 
    x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100)))
dataset$fCategory <- factor(dataset$category)
subdata <- subset(dataset, category %in% c("A", "D", "E"))

文字変数あり

ggplot(dataset, aes(x = x, y = y, colour = category)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = category)) + geom_point()

因子変数あり

ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point()
ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point()

11
最も簡単な方法は、制限を使用することです
ハドリー2011

1
このコンテキストハドリーの例を提供できますか?ファクターで制限を使用する方法がわかりません。
ティエリー

@ティエリーありがとう。私の最初の投稿で返事をもらってうれしかったです。そして、ティエリーに感謝するか、私の投稿にあるはずのように再現可能なコードを追加しました...私のカテゴリー変数は正しいタイプでした-要因。もう1つの問題は、凡例に未使用の要素が表示されないようにすることです。Rは、凡例を作成するときに未使用の文字変数を無視します。ただし、未使用の要因は残ります。subdata $ category <-factor(subdata $ category)[drop = TRUE]を使用してそれらをドロップすると、凡例には適切な数の因子がありますが、マッピングが失われます。
ウィンター

11
@Thierry-私の手では、ggplot2_0.9.3.1を使用すると、このメソッドは(もはや?)機能しません。fCategoryに割り当てられた色は、2つのプロット間で異なります。しかし、幸いにも、@ wintourは、@ hadleyが+ scale_colour_discrete(drop=TRUE,limits = levels(dataset$fCategory))色と因子の関連付けを維持することを示唆していることを理解しましたが、私の手では、drop = TRUEが尊重されていません(レベルを削除すると期待しています)伝説)。Drat ...それとも私ですか?
Malcook 2013年

1
@ malcook、drop = TRUEの代わりに、「ブレーク」を介して保持するレベルを指定する必要があります:github.com/hadley/ggplot2/issues/1433
Eric

17

これは古い投稿ですが、同じ質問への回答を探していました。

次のようなものを試してみませんか:

scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00"))

カテゴリ値がある場合、これが機能しない理由はわかりません。


3
これは実際にはJoranの答えmyColors <- brewer.pal(5,"Set1"); names(myColors) <- levels(dat$grp)ですが、レベルを手動でコーディングする必要がないように使用しています。
Axeman

しかし、ヨランの答えは、色の値をハードコード化していません。特定の要素に特定の色値が必要な場合があります。
ルネNyffenegger

場合によっては「ハードコーディング」のマイナス面もありますが、開発者/コーダーが追加した抽象化レイヤーが頻繁に原因となって、作業のアクセシビリティが低下するのではなく、そうでない場合もあると思います。この場合、意図は100%明確です。さらに、この例を拡張して特定の色の名前付きベクトルを返すユーティリティ関数を作成する方法を考えるのも簡単です。
Matt Barstead、

16

joranによる非常に役立つ回答に基づいて、ブール係数(TRUEFALSE)の安定したカラースケールのためのこのソリューションを思いつくことができました。

boolColors <- as.character(c("TRUE"="#5aae61", "FALSE"="#7b3294"))
boolScale <- scale_colour_manual(name="myboolean", values=boolColors)

ggplot(myDataFrame, aes(date, duration)) + 
  geom_point(aes(colour = myboolean)) +
  boolScale

ColorBrewerはバイナリカラースケールではあまり役に立たないため、必要な2つの色は手動で定義されます。

これmybooleanは、myDataFrameTRUE / FALSE係数を保持する列の名前です。dateそしてduration、この例では、プロットのxおよびy軸にマッピングされる列名です。


別のアプローチは、「as.character()」を列に適用することです。これにより、scale _ * _ manualで適切に機能する文字列列になります
Sahir Moosvi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.