Jak wygenerować kilka najbardziej charakterystycznych kolorów w R?


141

Kreślę kategoryczny zbiór danych i chcę używać charakterystycznych kolorów do reprezentowania różnych kategorii. Biorąc pod uwagę liczbę n, w jaki sposób mogę uzyskać nNAJBARDZIEJ charakterystycznych kolorów w R? Dzięki.



Odpowiedzi:


118

Dołączyłem wszystkie jakościowe palety z RColorBreweropakowania. Jakościowe palety mają zapewnić po X najbardziej wyrazistych kolorów. Oczywiście ich zmieszanie łączy w jedną paletę również podobne kolory, ale to najlepsze, co mogę uzyskać (74 kolory).

library(RColorBrewer)
n <- 60
qual_col_pals = brewer.pal.info[brewer.pal.info$category == 'qual',]
col_vector = unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals)))
pie(rep(1,n), col=sample(col_vector, n))

colour_Brewer_qual_60

Innym rozwiązaniem jest: pobranie wszystkich kolorów R z urządzeń graficznych i próbkowanie z nich. Usunąłem odcienie szarości, ponieważ są zbyt podobne. Daje to 433 kolory

color = grDevices::colors()[grep('gr(a|e)y', grDevices::colors(), invert = T)]

zestaw 20 kolorów

pie(rep(1,n), col=sample(color, n))

z 200 kolorami n = 200:

pie(rep(1,n), col=sample(color, n))

zestaw 200 kolorów


Czy istnieje możliwość zamiany kodów szesnastkowych colna odpowiadające im nazwy kolorów?
Prradep

@Prradep, co colmasz na myśli? colorz urządzeniami graficznymi ma nazwy. Jeśli masz na myśli ogólnie, nie wszystkie kody szesnastkowe mają odpowiednie nazwy kolorów (są tylko 433 kolory wgrDevices ale o wiele więcej kodów szesnastkowych)
JelenaČuklina

Wspominam o col=sample(col_vector, n)z RColorBrewerpakietu w Twoim fragmencie kodu. Na przykład, jak znaleźć nazwy kolorów dla #B3E2CD, #E78AC3, #B3DE69dostępnych z sample(col_vector,3). Alternatywnie, jak znaleźć wszystkie kody szesnastkowe podane przezbrewer.pal funkcję wraz z ich nazwami kolorów.
Prradep

2
@Prradep, as RColorBrewer palety nie pochodzą z grDeviceskolorów, które mają odwzorowane nazwy, ale są tylko kodami szesnastkowymi, o ile mi wiadomo, nie można tego zrobić z RColorBrewerpaletami, nawet jakościowymi.
JelenaČuklina

1
@ytu to kolory nie są rozróżnialne. Jeśli jest to absolutnie konieczne, sugerowałbym szukanie „tworzenia gradientu” w R, a następnie użycie losowego próbkowania kolorów. Ale mapowanie kolorów na czynniki nie zadziała, ludzka percepcja może obsłużyć może 20 - 40 kolorów, reszta niewiele się różni.
JelenaČuklina

75

Oto kilka opcji:

  1. Spójrz na palettefunkcję:

     palette(rainbow(6))     # six color rainbow
     (palette(gray(seq(0,.9,len = 25)))) #grey scale
    
  2. I colorRampPalettefunkcja:

     ##Move from blue to red in four colours
     colorRampPalette(c("blue", "red"))( 4) 
    
  3. Spójrz na colorBrewer pakiet (i stronę internetową ). Jeśli chcesz rozbieżne kolory, wybierz rozbieżne na stronie. Na przykład,

     library(colorBrewer)
     brewer.pal(7, "BrBG")
    
  4. Witryna internetowa I want hue oferuje wiele ładnych palet. Ponownie, po prostu wybierz potrzebną paletę. Na przykład możesz pobrać kolory rgb ze strony i stworzyć własną paletę:

     palette(c(rgb(170,93,152, maxColorValue=255),
         rgb(103,143,57, maxColorValue=255),
         rgb(196,95,46, maxColorValue=255),
         rgb(79,134,165, maxColorValue=255),
         rgb(205,71,103, maxColorValue=255),
         rgb(203,77,202, maxColorValue=255),
         rgb(115,113,206, maxColorValue=255)))
    

dzięki za odpowiedź. Generuje kolory, ale niektóre niezbyt się od siebie różnią. może powinienem był bardziej położyć na to nacisk w moich pytaniach.
RNA

1
@RNAer Zaktualizowałem moją odpowiedź. Możesz użyć sugestii 3 i 4, aby uzyskać rozbieżne palety.
csgillespie

1
I want hueto niesamowita witryna internetowa. Właśnie tego chcę. Biorąc pod uwagę liczbę, jak wygenerować paletę liczby kolorów. ale czy możemy to zrobić w R automatycznie?
RNA

To jest wspaniałe. Jednak za tą witryną stoi wiele maszyn. Nie sądzę, że ponowne wdrożenie będzie trywialne. Byłoby miło, gdyby i want huemiał API, które pozwala na automatyczne odpytywanie (może tak - nie spędziłem długo na szukaniu)
Ben Bolker

8
@BenBolker - Zrobiłem sens dla wersji R i want hue, tutaj . Wydajność można poprawić (np. Zapisując próbki kolorów jako obiekty danych), ale istnieje ogólna idea. (Załaduj z devtools::source_gist('45b49da5e260a9fc1cd7'))
jbaums

41

Możesz także wypróbować randomcoloRpakiet :

library(randomcoloR)
n <- 20
palette <- distinctColorPalette(n)

Możesz zobaczyć, że podczas wizualizacji na wykresie kołowym wybierany jest zestaw bardzo różnych kolorów (zgodnie z sugestiami innych odpowiedzi tutaj):

pie(rep(1, n), col=palette)

wprowadź opis obrazu tutaj

Przedstawione na wykresie kołowym z 50 kolorami:

n <- 50
palette <- distinctColorPalette(n)
pie(rep(1, n), col=palette)

wprowadź opis obrazu tutaj


4
Dzięki. Musiałem użyć, unname(distinctColorPalette(n))aby ta działała z ggplot. Myślę, że ggplot potrzebuje nienazwanego wektora. col_vector <- unname(distinctColorPalette(n))a potem... + scale_color_manual(values=col_vector) ...
Gaurav

21

Nie jest to odpowiedź na pytanie OP, ale warto wspomnieć, że istnieje viridispakiet, który ma dobre palety kolorów dla danych sekwencyjnych. Są percepcyjnie jednolite, dla daltonistów bezpieczne i łatwe w drukowaniu.

Aby uzyskać paletę, po prostu zainstaluj pakiet i użyj funkcji viridis_pal(). Do wyboru są cztery opcje „A”, „B”, „C” i „D”

install.packages("viridis")
library(viridis)
viridis_pal(option = "D")(n)  # n = number of colors seeked

wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

Jest też doskonały wykład wyjaśniający złożoność dobrych map kolorów na YouTube:

Lepsza domyślna mapa kolorów dla Matplotlib | SciPy 2015 | Nathaniel Smith i Stéfan van der Walt


17
To nie jest odpowiednie dla charakterystycznych kolorów.
Christopher John

14

Możesz użyć colorRampPalettez bazy lub RColorBrewerpakietu:

Za pomocą colorRampPalettemożna określić kolory w następujący sposób:

colorRampPalette(c("red", "green"))(5)
# [1] "#FF0000" "#BF3F00" "#7F7F00" "#3FBF00" "#00FF00"

Alternatywnie możesz również podać kody szesnastkowe:

colorRampPalette(c("#3794bf", "#FFFFFF", "#df8640"))(5)
# [1] "#3794BF" "#9BC9DF" "#FFFFFF" "#EFC29F" "#DF8640"
# Note that the mid color is the mid value...

W programie RColorBrewermożna użyć kolorów z istniejących palet:

require(RColorBrewer)
brewer.pal(9, "Set1")
# [1] "#E41A1C" "#377EB8" "#4DAF4A" "#984EA3" "#FF7F00" "#FFFF33" "#A65628" "#F781BF"
# [9] "#999999"

Spójrz na RColorBreweropakowanie, aby znaleźć inne dostępne palety. Mam nadzieję że to pomoże.


1
Dzięki. Podoba mi się ostatnia opcja brewer.pal. ale jest ograniczony do 9 kolorów. Właściwie mam więcej niż 9 kategorii. Pierwsze alternatywy generują kolory gradientu, które nie są tak charakterystyczne, jak bym chciał.
RNA

2
nie będziesz w stanie wybrać wielu „odrębnych” kolorów. Przypuszczam, że możesz dostać maksymalnie 12. Powinieneś sprawdzić colorbrewer2.org i pobrać kolory (jest 1 paleta 12 kolorów, jeśli mam rację).
Arun

Poszukiwanie więcej niż 12 charakterystycznych coloutów będzie trudne - myślę, że jest o tym dyskusja na stronie colorbrewer
alexwhan

w porządku, o ile są to „najbardziej” dostępne kolory, nawet one stają się mniej wyraziste, gdy liczba wzrasta.
RNA

3
Jeśli Twoim problemem są podobne kolory obok siebie, gdy są przypisane do sąsiednich kategorii (tak jak zrobi to paleta tęczy), możesz po prostu losowo ustawić wynik tęczy na przykład: tęcza (n = 10) [próbka (10)]
David Roberts,

12

W przypadku dużych palet kolorów zalecałbym użycie zewnętrznego źródła.

http://tools.medialab.sciences-po.fr/iwanthue/

posiada usługę skomponowania dowolnego rozmiaru palety według różnych parametrów oraz

/graphicdesign/3682/where-can-i-find-a-large-palette-set-of-contrasting-colors-for-coloring-many-d/3815

omawia ogólny problem z perspektywy grafików i podaje wiele przykładów palet, które można wykorzystać.

Aby ułożyć paletę z wartości RGB wystarczy skopiować wartości w wektorze jak np .:

colors37 = c("#466791","#60bf37","#953ada","#4fbe6c","#ce49d3","#a7b43d","#5a51dc","#d49f36","#552095","#507f2d","#db37aa","#84b67c","#a06fda","#df462a","#5b83db","#c76c2d","#4f49a3","#82702d","#dd6bbb","#334c22","#d83979","#55baad","#dc4555","#62aad3","#8c3025","#417d61","#862977","#bba672","#403367","#da8a6d","#a79cd4","#71482c","#c689d0","#6b2940","#d593a7","#895c8b","#bd5975")

3

Znalazłem stronę oferującą listę 20 charakterystycznych kolorów: https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors/

col_vector<-c('#e6194b', '#3cb44b', '#ffe119', '#4363d8', '#f58231', '#911eb4', '#46f0f0', '#f032e6', '#bcf60c', '#fabebe', '#008080', '#e6beff', '#9a6324', '#fffac8', '#800000', '#aaffc3', '#808000', '#ffd8b1', '#000075', '#808080', '#ffffff', '#000000')

Możesz spróbować!


1
To tak naprawdę nie odpowiada na pytanie, które polega na generowaniu n charakterystycznych kolorów, a nie zestawu zdefiniowanych kolorów. Spróbuj zaktualizować swoją odpowiedź
Michał

1

Możesz wygenerować zestaw kolorów w następujący sposób:

myCol = c("pink1", "violet", "mediumpurple1", "slateblue1", "purple", "purple3",
          "turquoise2", "skyblue", "steelblue", "blue2", "navyblue",
          "orange", "tomato", "coral2", "palevioletred", "violetred", "red2",
          "springgreen2", "yellowgreen", "palegreen4",
          "wheat2", "tan", "tan2", "tan3", "brown",
          "grey70", "grey50", "grey30")

Te kolory są tak wyraźne, jak to tylko możliwe. W przypadku tych podobnych kolorów tworzą gradient, dzięki czemu można łatwo odróżnić między nimi różnice.


1

W moim rozumieniu wyszukiwanie wyróżniających się kolorów wiąże się z efektywnym wyszukiwaniem z jednostki sześcianu, gdzie 3 wymiary sześcianu to trzy wektory wzdłuż czerwonej, zielonej i niebieskiej osi. Można to uprościć, szukając w cylindrze (analogia HSV), w którym ustalasz nasycenie (S) i wartość (V) i znajdujesz losowe wartości odcienia. Działa w wielu przypadkach i zobacz to tutaj:

https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/

W R,

get_distinct_hues <- function(ncolor,s=0.5,v=0.95,seed=40) {
  golden_ratio_conjugate <- 0.618033988749895
  set.seed(seed)
  h <- runif(1)
  H <- vector("numeric",ncolor)
  for(i in seq_len(ncolor)) {
    h <- (h + golden_ratio_conjugate) %% 1
    H[i] <- h
  }
  hsv(H,s=s,v=v)
}

Alternatywnym sposobem jest użycie pakietu R „jednolicie” https://cran.r-project.org/web/packages/uniformly/index.html

a ta prosta funkcja może generować charakterystyczne kolory:

get_random_distinct_colors <- function(ncolor,seed = 100) {
  require(uniformly)
  set.seed(seed)
  rgb_mat <- runif_in_cube(n=ncolor,d=3,O=rep(0.5,3),r=0.5)
  rgb(r=rgb_mat[,1],g=rgb_mat[,2],b=rgb_mat[,3])
}

Można sobie wyobrazić nieco bardziej zaangażowaną funkcję poprzez przeszukiwanie siatki:

get_random_grid_colors <- function(ncolor,seed = 100) {
  require(uniformly)
  set.seed(seed)
  ngrid <- ceiling(ncolor^(1/3))
  x <- seq(0,1,length=ngrid+1)[1:ngrid]
  dx <- (x[2] - x[1])/2
  x <- x + dx
  origins <- expand.grid(x,x,x)
  nbox <- nrow(origins) 
  RGB <- vector("numeric",nbox)
  for(i in seq_len(nbox)) {
    rgb <- runif_in_cube(n=1,d=3,O=as.numeric(origins[i,]),r=dx)
    RGB[i] <- rgb(rgb[1,1],rgb[1,2],rgb[1,3])
  }
  index <- sample(seq(1,nbox),ncolor)
  RGB[index]
} 

sprawdź te funkcje poprzez:

ncolor <- 20
barplot(rep(1,ncolor),col=get_distinct_hues(ncolor))          # approach 1
barplot(rep(1,ncolor),col=get_random_distinct_colors(ncolor)) # approach 2
barplot(rep(1,ncolor),col=get_random_grid_colors(ncolor))     # approach 3

Należy jednak pamiętać, że zdefiniowanie odrębnej palety za pomocą dostrzegalnych dla człowieka kolorów nie jest proste. Które z powyższych podejść generuje zróżnicowany zestaw kolorów, nie zostało jeszcze przetestowane.


0

W tym celu możesz skorzystać z pakietu Polychrome . Wymaga tylko kilku kolorów i kilku seedcolors. Na przykład:

# install.packages("Polychrome")
library(Polychrome)

# create your own color palette based on `seedcolors`
P36 = createPalette(36,  c("#ff0000", "#00ff00", "#0000ff"))
swatch(P36)

Więcej informacji na temat tego pakietu można znaleźć pod adresem https://www.jstatsoft.org/article/view/v090c01 .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.