The RImagePalette
package is a pure R implementation of
the median cut algorithm for extracting the dominant colors from an
image. This package lets you use the colors from an image you like to
create pretty plots, or to swap colors from one image to another.
Install from CRAN using:
install.packages("RImagePalette")
Or from github, using:
::install_github("joelcarlson/RImagePalette") devtools
It’s simple to create palettes from an image using the
image_palette()
function:
library(RImagePalette)
#Load an image
<- jpeg::readJPEG("figs/LifeAquatic.jpg")
lifeAquatic display_image(lifeAquatic)
#Create a palette of 9 colors
<- image_palette(lifeAquatic, n=9)
lifeAquaticPalette ::show_col(lifeAquaticPalette) scales
Not happy with the results? We can tweak some settings until the scale is to our liking:
<- image_palette(lifeAquatic, n=9, choice=median, volume=TRUE)
lifeAquaticPalette ::show_col(lifeAquaticPalette) scales
If it contains colors we like, we can pick and choose, and use them as a scale:
library(ggplot2)
#Create plot
<- ggplot(data = iris, aes(x=Species, y=Sepal.Width, fill=Species)) + geom_bar(stat="identity")
p #Apply scale
+ theme_bw() + scale_fill_manual(values=lifeAquaticPalette[c(2,3,6)]) p
RImagePalette
can create both discrete and continuous
scales from images for use with ggplot2
using the new
scale_color_image
(or for plots requiring fills, the
scale_fill_image()
) function:
#Load an image
<- jpeg::readJPEG("figs/Desert.jpg")
desert display_image(desert)
#Create plot
<- ggplot(data = iris, aes(x=Sepal.Length, y=Sepal.Width, col=Species)) + geom_point(size=3)
p #Add discrete scale from image
+ theme_bw() + scale_color_image(image=desert) p
#Create plot
<- ggplot(data = iris, aes(x=Sepal.Length, y=Sepal.Width, col=Sepal.Length)) + geom_point(size=3)
p #Use discrete=FALSE for a continuous scale
+ theme_bw() + scale_color_image(image=desert, discrete=FALSE) p
Note: This feature is experimental at the moment, and as such is
non-optimized, and slow. You must install from github to access the
quantize_image
function
We can also quantize images into a discrete number of colors using
the quantize_image
function:
#Load the famous mandrill
<- png::readPNG("figs/mandrill.png")
mandrill
#Quantize using 7 colors
<- quantize_image(mandrill, n=7) quant_mandrill
When displayed closely reproduces the original image:
Another method for doing so is to use the kmeans approach, as discussed in this blog post by Ryan Walker. Here is the comparison between kmeans (on the left) and median cut (on the right) using 4 colors:
We can swap colors across images using the
switch_colors()
function:
<- jpeg::readJPEG("figs/CeleryLunch.jpg")
celery <- jpeg::readJPEG("figs/BillMurray.jpg") billMurray
switch_colors(billMurray, celery, source_colors = 10)
There is an element of randomness in the median cut algorithm, so set
your seeds carefully, and try running the algorithm a few times if you
aren’t happy with the results. Other ways to alter the palette: try
using choice = median
, volume = TRUE
or change
the value of n
.
There are a number of projects that inspired or helped this project along, and they deserve some recognition:
color-thief.js by Lokesh Dhakar.
Wes Anderson Palettes by Karthik Ram.
this blog post from Jo Fai Chow.
and this blog post by Ryan Walker
Thank you all for your great work!