从grDevices :: colors()查找最接近的颜色以使用ggplot复制图表

时间:2018-07-19 09:12:57

标签: r ggplot2 colors

说我有一张这样的图表作为图片:

enter image description here

我想提取其颜色并找到table2中最接近的颜色,here可以看到

grDevices::colors()

最简单的输出将是这些颜色的向量。

更出色的输出将是具有真实颜色代码,“圆形”颜色(即head(grDevices::colors()) [1] "white" "aliceblue" "antiquewhite" "antiquewhite1" "antiquewhite2" "antiquewhite3" 的一部分),覆盖的图像表面百分比以及重心坐标的data.frame。它的覆盖区域。

超级精美的输出会将这些颜色名称叠加在原始图表上,或/和/或构建一个新的点阵图,该点位于这些中心位置,颜色名称作为文本标签。

超豪华的输出将建议现有调色板之间最接近的匹配。

1 个答案:

答案 0 :(得分:0)

tldr:request.res.set使用底部定义的功能。


我们将以R加载图像,将其转换为长rgb格式,并获取指定颜色的rgb值,并将其设置为相同格式,然后计算所有相关距离并保持每种颜色的最小值图像,然后从那里得到输出。

get_named_colors("https://i.stack.imgur.com/zdyNO.png")

我们的候选人:

library(ggplot2)
library(dplyr)      
library(png)

我们的颜色:

rgb_named_colors <- t(col2rgb(grDevices::colors())/255)
head(rgb_named_colors,3)
#            red     green      blue
# [1,] 1.0000000 1.0000000 1.0000000
# [2,] 0.9411765 0.9725490 1.0000000
# [3,] 0.9803922 0.9215686 0.8431373

我们有958种颜色,数量很多,我们需要过滤掉出现率较低的颜色, 我们将img像素的截止值设置为img <- readPNG("https://i.stack.imgur.com/zdyNO.png") dim(img) # [1] 476 746 3 # it's a 3d matrix, let's convert it to long format rgb_img <- apply(img,3,c) colnames(rgb_img) <- c("red","green","blue") head(rgb_img,3) # red green blue # [1,] 0.9803922 0.9803922 0.9803922 # [2,] 0.9803922 0.9803922 0.9803922 # [3,] 0.9803922 0.9803922 0.9803922 dim(unique(rgb_img)) # [1] 958 3

0.5%

效果如何?

rgb_img_agg <-
  rgb_img %>%
  as_tibble %>%
  group_by_all %>%
  count %>%
  filter(n > dim(img)[1]* dim(img)[2] *0.5/100)

好多了。

dim(rgb_img_agg) # [1] 11  4

对于所有图像颜色,我们计算到命名颜色的距离并保持最小值

head(rgb_img_agg,3)
# # A tibble: 3 x 4
# # Groups:   red, green, blue [3]
#          red     green      blue     n
#        <dbl>     <dbl>     <dbl> <int>
# 1 0.04705882 0.2627451 0.5137255  2381
# 2 0.27843137 0.5568627 0.7803922 29353
# 3 0.37254902 0.7450980 0.2549020  2170

有效!现在让我们用图例显示所有颜色:

output <- apply(rgb_img_agg[1:3],1, function(row_img)
  grDevices::colors()[which.min(
  apply(rgb_named_colors,1,function(row_named)
    dist(rbind(row_img,row_named))))])

ouput
# [1] "dodgerblue4" "steelblue3"  "limegreen"   "olivedrab"   "gray80"      "olivedrab1"  "chocolate3"  "chocolate1" 
# [9] "ghostwhite"  "gray98"      "white" 

现在,我们将所有内容都放入一个函数中:

ggplot(tibble(named_color=output),aes(named_color,fill=factor(named_color,levels=output))) + geom_bar() +
    scale_fill_manual(values = output)

如果我发现如何实现精美功能,我可能会进行更新。