Sabit haritalamaya sahip ggplot2'deki kategorik değişkenlere renkler nasıl atanır?


178

Geçen ay R ile hızlanmaya başladım.

İşte sorum:

Sabit haritalamaya sahip ggplot2'deki kategorik değişkenlere renkler atamanın iyi bir yolu nedir? Farklı altkümeleri ve farklı kategorik değişkenleri olan bir dizi grafikte tutarlı renklere ihtiyacım var.

Örneğin,

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

burada categoricalData5 seviyesi vardır.

Ve sonra

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

burada categoricalData.subset3 seviyesi vardır.

Bununla birlikte, her iki sette bulunan belirli bir seviye, farklı bir renkle sonuçlanacak ve bu da grafikleri birlikte okumayı zorlaştıracaktır.

Veri çerçevesinde bir renk vektörü oluşturmam gerekir mi? Veya kategorilere belirli renkler atamanın başka bir yolu var mı?

Yanıtlar:


187

OP'deki örnek gibi basit durumlar için Thierry'nin cevabının en iyisi olduğunu kabul ediyorum. Bununla birlikte, tek bir büyük veri çerçevesini alt kümeye ayırarak elde edilmeyen birden fazla veri karesinde tutarlı renk şemalarını korumaya çalıştığınızda daha kolay hale gelen başka bir yaklaşımı belirtmenin yararlı olduğunu düşünüyorum . Birden çok veri çerçevesindeki faktör düzeylerini yönetmek, ayrı dosyalardan alınmaları ve her dosyada tüm faktör düzeylerinin görünmemesi durumunda can sıkıcı olabilir.

Bunu ele almanın bir yolu, aşağıdaki gibi özel bir manuel renk skalası oluşturmaktır:

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

ve sonra renk skalasını grafiğe gerektiği gibi ekleyin:

#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

İlk arsa şuna benzer:

resim açıklamasını buraya girin

ve ikinci arsa şuna benzer:

resim açıklamasını buraya girin

Bu şekilde, uygun düzeylere sahip olduklarını görmek için her veri çerçevesini hatırlamanıza veya kontrol etmenize gerek yoktur.


1
Bu işe yarayacaktır, ancak muhtemelen aşırı karmaşıktır. Bunun için manuel bir ölçek oluşturmanız gerektiğini düşünmüyorum. Tüm ihtiyacınız olan factortüm araziler arasında yaygın olan bir şeydir.
Andrie

14
@Andrie - Tek bir alt küme için, evet. Ancak, tek bir orijinal veri çerçevesini alt kümelere ayırarak oluşturulmamış birçok veri kümesini dengeliyorsan, bu stratejiyi çok daha basit buluyorum.
joran

2
@joran Teşekkürler Joran. Bu benim için çalıştı! Doğru sayıda faktöre sahip bir efsane yaratır. Yaklaşımı seviyorum ve farklı veri kümelerinde renk eşlemeleri elde etmek üç çizgiye değer.
wintour

3
İhtiyacım olan: library ("RColorBrewer")
PatrickT

4
mükemmel çalıştı! Bunu fillScale <- scale_fill_manual(name = "grp",values = myColors)bar arazileri ile kullanmak için ekledim .
pentandrous

42

Aynı durum tarafından işaret içindeyim malcook içinde onun comment : maalesef cevap tarafından Thierry ggplot2 sürümü 0.9.3.1 ile çalışma yok.

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

İşte ilk rakam:

ggplot AE, karışık renkler

ve ikinci figür:

ggplot ADE, karışık renkler

Gördüğümüz gibi, renkler sabit kalmıyor, örneğin E eflatundan maviye geçer.

Tarafından önerildiği gibi malcook içinde yaptığı açıklama ve tarafından Hadley de onun comment kullanan kod limitsişleri düzgün:

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

doğru olan aşağıdaki şekli verir:

doğru ggplot

Bu çıktı 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
Bunu yeni bir soru olarak göndermelisiniz, bu soruyu referans alarak ve buradaki çözümlerin neden işe yaramadığını göstermelisiniz.
Brian Diggs

Benzer bir soru sorulmuştur burada , ama ben kabul cevap çalışıyor işaret etmek istiyorum.
tonytonov

1
Bunun eski olduğunu biliyorum ama efsanede fazladan renklere sahip olmadan bunu yapmanın bir yolu olup olmadığını merak ediyorum.
goryh

20

En kolay çözüm, kategorik değişkeninizi alt ayardan önce bir faktöre dönüştürmektir. Alt satır, tüm alt kümelerinizde tam olarak aynı düzeylere sahip bir faktör değişkenine ihtiyacınız olmasıdır.

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

Karakter değişkeni ile

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

Faktör değişkeni ile

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

11
En kolay yol limitleri kullanmaktır
hadley

1
Bu bağlamda Hadley'e bir örnek verebilir misiniz? Sınırları bir faktörle nasıl kullanacağımdan emin değilim.
Thierry

@Thierry Teşekkürler. İlk yazımda yanıt almaktan mutluluk duydum. Ve teşekkürler Thierry veya yazımda olması gerektiği gibi tekrarlanabilir kod ekleyerek ... Kategorik değişkenlerim doğru tip faktörlerdi. Diğer konu efsanenin kullanılmayan faktörleri göstermemesini istiyorum. Gösterge oluşturulurken R kullanılmayan karakter değişkenlerini yok sayar. Bununla birlikte, kullanılmayan faktörler devam etmektedir. Bunları kullanarak şunu bırakırsam: subdata $ category <- factor (subdata $ category) [drop = TRUE] o zaman efsane doğru sayıda faktöre sahiptir, ancak eşlemeyi kaybeder.
wintour

11
@Thierry - ellerimde, ggplot2_0.9.3.1 kullanarak, bu yöntem (artık?) Çalışmıyor; fKategoriye atanan renkler iki grafik arasında farklıdır. Ancak mutlu bir şekilde @wintour, @hadley'in şunu önerdiğini anladım+ scale_colour_discrete(drop=TRUE,limits = levels(dataset$fCategory)) renk korumak için | faktör dernek ama, işler hangi ellerimde, hariç damla = DOĞRU edilir DEĞİL uyulmuyor (Ben den düzeye çıkarmak bekliyoruz efsane). Drat ... yoksa ben miyim?
malcook

1
@malcook, drop = TRUE yerine, "molalar" ile hangi seviyeleri korumak istediğinizi belirtmeniz gerekir: github.com/hadley/ggplot2/issues/1433
Eric

17

Bu eski bir gönderi, ama aynı sorunun cevabını arıyordum,

Neden böyle bir şey denemiyorsunuz:

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

Kategorik değerleriniz varsa, bunun işe yaramaması için bir neden göremiyorum.


3
Aslında Joran'ın cevabı budur, ancak myColors <- brewer.pal(5,"Set1"); names(myColors) <- levels(dat$grp)seviyeleri manuel olarak kodlamaktan kaçınmak için kullanılır .
Axeman

Ancak, Joran'ın cevabı renklerin değerlerini zorla kodlamaz. Belirli bir faktör için belirli bir renk değerine ihtiyaç duyduğunuz durumlar vardır.
René Nyffenegger

Bazı durumlarda "sabit kodlamanın" dezavantajını alırken, çoğu zaman soyutlama geliştiricileri / kodlayıcıların katmanlarının çalışmalarını daha az değil, daha az erişilebilir hale getirdiğini düşünüyorum. Bu durumda amaç% 100 açıktır. Ayrıca, belirli renklerin adlandırılmış bir vektörünü döndüren bu örnek üzerinde genişleyen bir yardımcı program işlevinin nasıl yapılacağını düşünmek yeterince kolaydır.
Matt Barstead

16

Joran'ın çok yardımcı cevabına dayanarak, bir boolean faktörü ( TRUE, FALSE) için kararlı bir renk ölçeği için bu çözümü bulmayı başardım .

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 ikili renk ölçeklerinde çok yardımcı olmadığından, gerekli iki renk manuel olarak tanımlanır.

İşte mybooleansütunun adıdır myDataFrameDOĞRU / YANLIŞ faktör tutan. dateve durationbu örnekte grafiğin x ve y ekseniyle eşlenecek sütun adlarıdır.


Diğer bir yaklaşım sütuna "as.character ()" uygulamaktır. Bu, _ * _ manuel ölçeği ile iyi çalışan bir dize sütunu yapar
Sahir Moosvi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.