안정적인 매핑이있는 ggplot2의 범주 형 변수에 색상을 지정하는 방법은 무엇입니까?


178

나는 지난 달에 R에 익숙해졌습니다.

내 질문은 다음과 같습니다.

안정적인 매핑이있는 ggplot2의 범주 형 변수에 색상을 할당하는 좋은 방법은 무엇입니까? 서브 세트와 개수가 다른 범주 형 변수가있는 그래프 세트에서 일관된 색상이 필요합니다.

예를 들어

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

여기서 categoricalData5 단계가 있습니다.

그리고

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

여기서 categoricalData.subset3 레벨이 있습니다.

그러나 두 세트에있는 특정 레벨은 다른 색상으로 끝나므로 그래프를 함께 읽기가 더 어렵습니다.

데이터 프레임에 색 벡터를 만들어야합니까? 아니면 특정 색상을 범주에 할당하는 다른 방법이 있습니까?

답변:


187

OP의 정확한 예와 같은 간단한 상황에서는 Thierry의 답변이 가장 좋습니다. 그러나 하나의 큰 데이터 프레임을 하위 집합으로 설정하여 얻을 수 없는 여러 데이터 프레임에서 일관된 색 구성표를 유지하려고 할 때 더 쉬워지는 또 다른 접근법을 지적하는 것이 유용하다고 생각합니다 . 여러 데이터 프레임에서 요인 수준을 관리하면 별도의 파일에서 가져와 모든 요인 수준이 각 파일에 나타나지 않는 경우 지루할 수 있습니다.

이 문제를 해결하는 한 가지 방법은 다음과 같이 사용자 지정 수동 컬러 스케일을 만드는 것입니다.

#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

첫 번째 줄거리는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

두 번째 줄거리는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

이 방법으로 각 데이터 프레임을 기억하거나 점검 할 필요가 없어 적절한 레벨이 있는지 확인할 수 있습니다.


1
이것은 작동하지만 아마도 너무 복잡합니다. 나는 이것을 위해 수동 스케일을 만들 필요가 없다고 생각합니다. 필요한 것은 factor모든 플롯간에 공통입니다.
— Andrie

14
@Andrie-단일 하위 집합 인 경우 가능합니다. 그러나 하나의 원본 데이터 프레임을 하위 집합으로 만들어지지 않은 많은 데이터 세트를 저글링하는 경우이 전략이 훨씬 간단합니다.
— joran

2
@ Joran 감사합니다 Joran. 이것은 나를 위해 일했다! 적절한 수의 요인으로 범례를 만듭니다. 나는 접근 방식이 마음에 들며 다른 데이터 세트에서 색상 매핑을 얻는 것이 세 줄에 중요합니다.
— wintour

3
필요한 것 : library ( "RColorBrewer")
— PatrickT

4
완벽하게 일했다! fillScale <- scale_fill_manual(name = "grp",values = myColors)이것을 막대 플롯과 함께 사용하기 위해 추가했습니다 .
— pentandrous 2016 년

42

나는 malcook 이 그의 의견 에서 지적한 것과 같은 상황에 처해 있다 . 불행히도 Thierry 의 대답 은 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, 혼합 색상

두 번째 그림 :

ggplot ADE, 혼합 색상

보시다시피 색상이 고정되어 있지 않습니다. 예를 들어 E는 자홍색에서 파란색으로 바뀝니다.

에 의해 제안 malcook 에서 자신의 의견 과에 의해 해들리 에서 자신의 의견 사용하는 코드 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
이 질문을 참조하고 여기에 솔루션이 작동하지 않는 이유를 보여주는 새로운 질문으로 게시해야합니다.
— Brian Diggs

비슷한 질문이 여기 에 요청 되었지만 허용 된 답변이 제대로 작동한다고 지적하고 싶습니다.
— tonytonov

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
가장 쉬운 방법은 한계를 사용하는 것입니다
— hadley

1
이 상황에서 예를 제시 할 수 있습니까? 요인으로 한계를 사용하는 방법을 잘 모르겠습니다.
— Thierry

@Thierry 감사합니다. 첫 번째 게시물에 대한 답변을 받고 기뻤습니다. 그리고 Thierry에게 감사하거나 내 게시물에서해야 할 것처럼 재현 가능한 코드를 추가하는 중입니다 ... 내 범주 변수는 올바른 유형이었습니다. 다른 문제는 범례가 사용되지 않은 요소를 표시하지 않기를 원한다는 것입니다. R은 범례를 작성할 때 사용되지 않는 문자 변수를 무시합니다. 그러나 사용하지 않은 요소는 지속됩니다. subdata $ category <-factor (subdata $ category) [drop = TRUE]를 사용하여 삭제하면 범례에 올바른 수의 요인이 있지만 매핑이 손실됩니다.
— wintour

11
@Thierry-내 손에 ggplot2_0.9.3.1을 사용하면이 방법이 더 이상 작동하지 않습니다. fCategory에 지정된 색상은 두 플롯간에 다릅니다. 그러나 행복하게도 @wintour는 @hadley가 + scale_colour_discrete(drop=TRUE,limits = levels(dataset$fCategory))색상 연관성을 유지하도록 제안 하지만 내 손을 제외하고는 drop = TRUE 가 존중 되지 않는다는 점 을 제외하고 는 효과가 있다고 생각했습니다. 전설). 드랏 ... 아니면 나인가?
— malcook

1
@malcook, drop = TRUE 대신 "breaks"를 통해 유지하려는 레벨을 지정해야합니다. 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

그러나 Joran의 대답은 색상 값을 하드 코딩하지 않습니다. 특정 요인에 대해 특정 색상 값이 필요한 경우가 있습니다.
— René Nyffenegger

어떤 경우에는 "하드 코딩"의 단점이 있지만, 추상화 개발자 / 코더 계층이 너무 자주 추가되어 작업에 액세스하기가 더 어렵다고 생각합니다. 이 경우 의도는 100 % 명확합니다. 또한 특정 색상의 명명 된 벡터를 반환하는이 예제에서 확장되는 유틸리티 함수를 만드는 방법을 생각하기 쉽습니다.
— Matt Barstead

16

joran의 매우 유용한 답변을 바탕으로 부울 팩터 ( TRUE, FALSE) 의 안정적인 색상 스케일을 위해이 솔루션을 만들 수있었습니다 .

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는 이진 색상 스케일에 큰 도움이되지 않기 때문에 필요한 두 가지 색상이 수동으로 정의됩니다.

TRUE / FALSE 인수 myboolean를 myDataFrame보유한 열의 이름은 다음과 같습니다 . date및 duration은 x에 매핑되는 열 이름이고 Y는 본 실시 예에서의 플롯 축.


또 다른 방법은 "as.character ()"를 열에 적용하는 것입니다. 이렇게하면 scale _ * _ manual
— Sahir Moosvi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.