在 matplotlib 的白色背景上计算 alpha 为 0.5 的基色的 RGB 等效值

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

我希望能够在 matplotlib 中复制原色('r'、'g' 或 'b')的外观,在白色背景上的 alpha 为 0.5,同时保持 alpha 为 1。

下面是一个示例,通过手动实验,我发现 alpha 为 1 的 RGB 值看起来类似于 alpha 为 0.5 的 matplotlib 默认颜色。

我想知道是否有人有实现此目的的自动化方法。

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

我不知道它是否是标准的,但在我的电脑上可以正常工作:

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

基本上,对于每个组件,您有 c + (1 - c) * (1 - a),其中 a 是您要模拟的 alpha 值。

对于 "simple" 颜色 (1, 0, 0) 你得到 (1, 1 - a, 1 - a),对于黑色 (0, 0, 0) 你得到 (1 - a, 1 - a, 1 - a) 这是正确的,对于白色 (1, 1, 1) 你得到 (1, 1, 1) 这也是正确的。

我尝试了 alpha 和颜色的各种组合,但我仍然没有找到任何它不起作用的值,但这仍然没有得到证实 ;)

这是我用来随机检查 calpha 的不同值的小代码:

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

编辑:您可以使用 this answer

中的公式

转换为Python,看起来像这样:

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

所以你可以这样做:

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

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

现在使用这个函数,我们可以创建一个图来确认它有效:

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)