calculate RGB equivalent of base colors with alpha of 0.5 over white background in matplotlib
Asked Answered
W

2

9

I would like to be able to replicate the look of a primary color ('r','g' or 'b') in matplotlib with an alpha of 0.5 over a white background, while keeping the alpha at 1.

Here is an example below, where through manual experimentation I've found the RGB values that with an alpha of 1, look similar to matplotlib default colors with an alpha 0.5.

I was wondering if someone had an automated way of achieving this.

import matplotlib.pyplot as plt

s=1000

plt.xlim([4,8])
plt.ylim([0,10])

red=(1,0.55,0.55)
blue=(0.55,0.55,1)
green=(0.54,0.77,0.56)

plt.scatter([5],[5],c='r',edgecolors='none',s=s,alpha=0.5,marker='s')
plt.scatter([6],[5],c='b',edgecolors='none',s=s,alpha=0.5,marker='s')
plt.scatter([7],[5],c='g',edgecolors='none',s=s,alpha=0.5,marker='s')

plt.scatter([5],[5.915],c=red,edgecolors='none',s=s,marker='s')
plt.scatter([6],[5.915],c=blue,edgecolors='none',s=s,marker='s')
plt.scatter([7],[5.915],c=green,edgecolors='none',s=s,marker='s')

enter image description here

Wales answered 27/10, 2015 at 15:23 Comment(2)
Similar quesion here: https://mcmap.net/q/122707/-convert-rgba-color-to-rgbRip
@Rip my bad for not spotting that; however i wish you hadn't deleted your answer; matplotlib users would find your answer useful, e.g. your python function for doing the mappingWales
R
13

Edit: you can use the formula from this answer

Converted to Python, it looks like this:

def make_rgb_transparent(rgb, bg_rgb, alpha):
    return [alpha * c1 + (1 - alpha) * c2
            for (c1, c2) in zip(rgb, bg_rgb)]

So you can do:

red = [1, 0, 0]
white = [1, 1, 1]
alpha = 0.5

make_rgb_transparent(red, white, alpha)
# [1.0, 0.5, 0.5]

Using this function now, we can create a plot that confirms this works:

from matplotlib import colors
import matplotlib.pyplot as plt

alpha = 0.5

kwargs = dict(edgecolors='none', s=3900, marker='s')
for i, color in enumerate(['red', 'blue', 'green']):
    rgb = colors.colorConverter.to_rgb(color)
    rgb_new = make_rgb_transparent(rgb, (1, 1, 1), alpha)
    print(color, rgb, rgb_new)
    plt.scatter([i], [0], color=color, **kwargs)
    plt.scatter([i], [1], color=color, alpha=alpha, **kwargs)
    plt.scatter([i], [2], color=rgb_new, **kwargs)

enter image description here

Rip answered 27/10, 2015 at 18:24 Comment(0)
M
2

I don't know if it is standard, but on my computer the following works:

newColor = tuple (x + (1 - x) * (1 - a) for x in oldColor)

Basically, for each component, you have c + (1 - c) * (1 - a) where a is the alpha value you are trying to simulate.

For "simple" color like (1, 0, 0) you get (1, 1 - a, 1 - a), for black (0, 0, 0) you get (1 - a, 1 - a, 1 - a) which is correct and for white (1, 1, 1) you get (1, 1, 1) which is also correct.

I tried with various combinations of alpha and colors, and I still did not find any values for which it did not work, but still, this is not proven ;)

Here is a small code I used to randomly checked different values of c and alpha:

def p (c1, a, f):
    plt.cla()
    plt.xlim([4, 6])
    plt.ylim([0, 10])
    plt.scatter([5], [5], c = c1, edgecolors = 'none', s = 1000, alpha = a, marker = 's')
    plt.scatter([5], [5.915], c = f(c1, a), edgecolors = 'none', s = 1000, marker = 's')

from numpy.random import rand
import matplotlib.pyplot as plt
p (rand(3), rand(), lambda c, a: c + (1 - c) * (1 - a))
Mohammadmohammed answered 27/10, 2015 at 15:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.