Як генерувати декілька найбільш характерних кольорів у R?


130

Я будую категоричний набір даних і хочу використовувати відмінні кольори для представлення різних категорій. З огляду на число n, як я можу отримати nкількість МОСТО відмітних кольорів у R? Дякую.



Відповіді:


108

Я приєднався до всіх якісних палітри з RColorBrewerпакета. Якісні палітри повинні забезпечувати X найбільш характерними кольорами. Звичайно, їх змішування об'єднує в одну палітру також подібні кольори, але це найкраще, що я можу отримати (74 кольори).

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

Іншим рішенням є: візьміть усі кольори R з графічних пристроїв і зразок з них. Я зняла відтінки сірого, оскільки вони занадто схожі. Це дає 433 кольори

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

набір з 20 кольорів

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

з 200 кольорами n = 200:

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

набір з 200 кольорів


Чи є можливість перетворити шістнадцяткові коди у colвідповідні назви кольорів?
Prradep

@Prradep який col ти маєш на увазі? colorвід графічних пристроїв має назву. Якщо ви маєте на увазі загалом, не всі шістнадцяткові коди мають відповідні назви кольорів (є лише 433 кольори, grDevicesале ще багато шістнадцяткових кодів)
JelenaČuklina

Я згадую про col=sample(col_vector, n)відRColorBrewer пакету в вашому фрагменті коду. Наприклад, як знайти назви кольорів, #B3E2CD, #E78AC3, #B3DE69доступних для sample(col_vector,3). Як варіант, як знайти всі шістнадцяткові коди, задані brewer.palфункцією, з їх назвами кольорів.
Prradep

2
@Prradep, оскільки RColorBrewerпалітри не походять від grDevicesкольорів, які мають назви, нанесені на карту, але це лише шістнадцяткові коди , наскільки мені відомо, ви не можете це зробити з RColorBrewerпалітрами, навіть якісними.
JelenaČuklina

1
@ytu, то кольори не відрізняються. Якщо це абсолютно необхідно, я б запропонував шукати "створення градієнта" в R, а потім використовувати рандомізовану вибірку кольорів. Але відображення від кольорів до факторів не вийде, сприйняття людини може обробити, можливо, 20 - 40 кольорів, решта не так сильно відрізняється.
JelenaČuklina

70

Ось кілька варіантів:

  1. Погляньте на paletteфункцію:

     palette(rainbow(6))     # six color rainbow
     (palette(gray(seq(0,.9,len = 25)))) #grey scale
    
  2. І colorRampPaletteфункція:

     ##Move from blue to red in four colours
     colorRampPalette(c("blue", "red"))( 4) 
    
  3. Подивись на colorBrewer пакет (та веб-сайт ). Якщо ви хочете, щоб розбігалися кольори, виберіть розходяться на сайті. Наприклад,

     library(colorBrewer)
     brewer.pal(7, "BrBG")
    
  4. Я хочу , щоб відтінок веб - сайт дає багато хороших палітр. Знову ж таки, просто виберіть потрібну вам палітру. Наприклад, ви можете отримати кольори rgb з сайту та зробити власну палітру:

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

Дякую за вашу відповідь. Він генерує кольори, але деякі не дуже відмінні між собою. можливо, я мав би на цьому більше наголосити на своїх питаннях.
РНК

1
@RNAer Я оновив свою відповідь. Ви можете скористатися пропозиціями 3 та 4, щоб отримати розбіжні палітри.
csgillespie

1
I want hueце приголомшливий веб-сайт. Це саме те, що я хочу. Дано число, як генерувати палітру кількості кольорів. але чи можемо ми зробити це в R автоматично?
РНК

Це приголомшливо. Однак за цим веб-сайтом стоїть багато техніки. Я не думаю, що повторювати їх буде тривіально. Було б добре, якби i want hueAPI, який дозволив йому автоматично запитуватись (можливо, це так - я не витрачав довго на пошуки)
Бен Болкер

8
@BenBolker - Я зробив суть для версії R з i want hue, тут . Ефективність може бути підвищена (наприклад, збереження зразків кольорів як об’єктів даних), але загальна ідея є. (Завантажити з devtools::source_gist('45b49da5e260a9fc1cd7'))
jbaums

36

Ви також можете спробувати randomcoloRпакет :

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

Ви можете бачити, що набір чітко виражених кольорів вибирається під час візуалізації на круговій діаграмі (як пропонують інші відповіді тут):

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

введіть тут опис зображення

Показано на пиріжковій діаграмі з 50 кольорами:

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

введіть тут опис зображення


3
Дякую. Мені довелося скористатися, unname(distinctColorPalette(n))щоб зробити цю роботу з ggplot. Я думаю, що ggplot потребує безіменного вектора. col_vector <- unname(distinctColorPalette(n))а потім... + scale_color_manual(values=col_vector) ...
Гаурав

19

Не відповідь на питання ОП, але варто зазначити, що є viridisпакет, який має гарні кольорові палітри для послідовних даних. Вони сприймаються рівномірно, безпечно для кольорів і друкують.

Щоб отримати палітру, просто встановіть пакет і скористайтеся функцією viridis_pal(). Можна вибрати чотири варіанти "A", "B", "C" і "D"

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

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення

Також є чудова розмова, що пояснює складність хороших кольорових карт на YouTube:

Краща кольорова карта за замовчуванням для Matplotlib | SciPy 2015 | Натаніель Сміт і Стефан ван дер Уолт


17
Це не так підходить для відмітних кольорів.
Крістофер Джон

13

Ви можете використовувати colorRampPaletteз бази або RColorBrewerпакету:

За допомогою colorRampPaletteкольорів можна вказати наступним чином:

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

Ви також можете надати шістнадцяткові коди:

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

З RColorBrewerвами можна використовувати кольори з раніше існуючої палітри:

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

Подивіться на RColorBrewerупаковку для інших доступних палітри. Сподіваюся, це допомагає.


1
Дякую. Мені подобається останній варіант brewer.pal. але він обмежений до 9 кольорів. У мене насправді більше 9 категорій. Перші альтернативи генерують кольори градієнта, що не настільки виразно, як я хочу.
РНК

2
ви не зможете вибрати багато "чітких" кольорів. Ви можете отримати максимум 12, я думаю. Ви повинні перевірити colorbrewer2.org і отримати кольори (якщо я маю рацію, є 12 кольорової палітри).
Арун

Шукати більше 12 відмінних кольорів буде складно - я думаю, що про це йдеться на сторінці
colorbrewer

це добре, якщо вони є "найбільш" характерними кольорами, навіть вони стають менш відмітними, коли кількість збільшується.
РНК

3
Якщо ваша проблема має схожі кольори поруч, якщо їх присвоюють сусіднім категоріям (як це зробить палітра веселки), то ви можете просто рандомізувати вихід веселки таким чином: райдуга (n = 10) [зразок (10)]
Девід Робертс

11

Я б рекомендував використовувати зовнішнє джерело для великих кольорових палітр.

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

має сервіс для складання будь-якого розміру палітри відповідно до різних параметрів і

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

обговорює загальну проблему з точки зору графічних дизайнерів та наводить безліч прикладів корисної палітри.

Щоб скласти палітру зі значень RGB, потрібно просто скопіювати значення у вектор, як наприклад:

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

Я знайшов веб-сайт, що пропонує список 20 відмінних кольорів: 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')

Ви можете спробувати!


1
Це насправді не відповідає на питання, яке стосується генерування n відмінних кольорів, а не набору визначених кольорів. Спробуйте оновити свою відповідь
Michal

1

Ви можете створити такий набір кольорів:

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

Ці кольори максимально виразні. Для таких схожих кольорів вони утворюють градієнт, щоб ви могли легко визначити відмінності між ними.


0

На мій погляд, пошук відмінних кольорів пов'язаний з ефективним пошуком з одиничного куба, де 3 розміри куба - це три вектори вздовж червоної, зеленої та синьої осей. Це можна спростити для пошуку в циліндрі (аналогія HSV), де ви фіксуєте насиченість (S) і значення (V) і знаходите випадкові значення відтінку. Він працює у багатьох випадках, і переконатися в цьому можна тут:

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

В 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)
}

Альтернативний спосіб - використовувати пакет R "рівномірно" https://cran.r-project.org/web/packages/uniformly/index.html

і ця проста функція може створювати відмінні кольори:

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])
}

Можна придумати трохи більше залучену функцію шляхом пошуку в сітці:

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]
} 

перевірити ці функції:

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

Однак зауважте, що визначити чітку палітру із сприйнятливими для людини кольорами не просто. Який із вищезазначених підходів генерує різноманітний набір кольорів, ще належить перевірити.


0

Для цієї мети можна використовувати пакет поліхрому . Просто потрібно кількість кольорів і кілька seedcolors. Наприклад:

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

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

Ви можете дізнатися більше про цей пакет на https://www.jstatsoft.org/article/view/v090c01 .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.