Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing hue of rgba color

I'm plotting a bunch of data on a logscale as a scatter plot in matplotlib (just in case the medium is relevant) using RGBA colors. What I would like to be able to do is once I plotted everything, I want to pick out individual scatter points and change their hue to the hue of some RGB color, but preserving the old alpha value. The way I currently do it is this:

oldHSV = rgb_to_hsv(oldRGBA[:3])
newHSV = rgb_to_hsv(newRGB)
oldHSV[0] = newHSV[0]
newRGBA = hsv_to_rgb(oldHSV).tolist() + [oldRGBA[3]]

i.e. I take the RGB part of the old RGBA value, turn it to HSV, do the same for the new intended RGB color, then replace the hue, turn it back to RGB and add on the old alpha value.

Since I'm doing this thousands of times, this can take significantly longer than I would like to spend here. One possible fix would be to dig into the conversion between RGB and HSV and figure out how to do this in one go, but I was hoping that folks who know how to handle color (I really don't) have figured out simple and efficient ways to do this.

How do I change the hue of a given RGBA color A to that of a given RGB color B while preserving the alpha value of A? Would using a different color model (HSL for example) simplify the task, and if so, which would help?

like image 570
G. Bach Avatar asked May 06 '15 10:05

G. Bach


People also ask

How does RGBA extend the RGB Colour values?

RGBA Colors RGBA color values are an extension of RGB color values with an alpha channel - which specifies the opacity for a color. An RGBA color value is specified with: rgba(red, green, blue, alpha). The alpha parameter is a number between 0.0 (fully transparent) and 1.0 (fully opaque).

What is the difference between RGBA and RGB?

RGB is a three-channel format containing data for Red, Green, and Blue. RGBA is a four-channel format containing data for Red, Green, Blue, and an Alpha value. The CSS function rgb() has wide browser support. The CSS function rgba() may have limited support in the older browser.

How do you convert RGBA to hex?

Converting RGBA to hex with the #rgba or #rrggbbaa notation follows virtually the same process as the opaque counterpart. Since the alpha ( a ) is normally a value between 0 and 1, we need to multiply it by 255, round the result, then convert it to hexadecimal.


2 Answers

Here is the solution to do all the replacement in one go :

import matplotlib.colors as clr
import matplotlib.pyplot as plt
import numpy as np


N = 100000
x = 1.2 + 800.0 * np.random.rand(N)
y = 1.2 + 800.0 * np.random.rand(N)
# Generate random colors of the form (r, g, b, a) where r = 0.0
colors = np.random.rand(4 * N).reshape((N, 4))
colors[:, 0] = 0.0
area = np.pi * (5 * np.random.rand(N))**2

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
pcol = ax.scatter(x, y, s=area, c=colors)
ax.set_xscale('log')
ax.set_yscale('log')

# Save initial figure
plt.savefig("hue.jpg")

oldRGBA = pcol.get_facecolors().reshape((N, 1, 4))
oldRGB = oldRGBA[:, :, :3]
newRGB = oldRGB
newRGB[:, :, 0] = 1.0 # Set red component to 1.0
oldHSV = clr.rgb_to_hsv(oldRGB)
newHSV = clr.rgb_to_hsv(newRGB)
oldHSV[:, :, 0] = newHSV[:, :, 0]
newRGBA = np.copy(oldRGBA)
newRGBA[:, :, :3] = clr.rgb_to_hsv(oldHSV)
pcol.set_facecolors(newRGBA[:, 0, :])

# Save modified figure
plt.savefig("hue_bis.jpg")

plt.close()

As you can see, this code attempts to plot 100000 points and in fact it managed to do this in about 2 seconds. Here are the figures produced :

hue.jpg

and :

hue_bis.jpg

With regard to your last two questions :

How do I change the hue of a given RGBA color A to that of a given RGB color B while preserving the alpha value of A ?

and :

Would using a different color model (HSL for example) simplify the task, and if so, which would help

I think that your approach to do such a modification is appreciable, it avoids making calculations by hand (see HSL and HSV). Using a different color model is possible, both HSL and HSV allow to change the hue without affecting other parameters, but that is only an other way to do it and not a better one.

Hope this will help.

like image 122
Flabetvibes Avatar answered Sep 21 '22 16:09

Flabetvibes


It should be possible to extract the alpha from oldRGBA and apply it to newRGB directly:

newRGBA = colors.to_rgba(newRGB, alpha=oldRGBA[3])

Note: I never used matplotlib, I assume the alpha component is the 4th element of the color

like image 44
nicopico Avatar answered Sep 22 '22 16:09

nicopico