matplotlib 的 alpha 透明度值是否有可能 "sum" 到 1?

Is it possible for matplotlib's alpha transparency values to "sum" to 1?

我正在使用 matplotlib 绘制一系列重叠的水平线。我想(以一种非常粗略的方式)通过透明度指出有多少重叠。例如,如果我有 10 行,其中 5 行在某个时间间隔内重叠,我希望该时间间隔的 alpha 值为 0.5。如果它们都在某个间隔内重叠,则该间隔的 alpha 值应为 1.0。下面的代码应该说明我想要什么:

import matplotlib.pyplot as plt

y = [1,1,1,1,1,1,1,1,1,1]
x_start = [0,0,0,0,0,0,0,0,0,0]
x_end = [1,2,3,4,5,6,7,8,9,10]

plt.hlines(y, x_start, x_end, linewidth=7, colors='red', alpha=0.1)
plt.hlines(1.2, 0, 10, linewidth=7, colors='red', alpha=1)
plt.ylim(0.8, 1.4)
plt.show()

我希望 y=1 处的线从 x=0 到 x=1 的红色透明度与 y=1.2 处的水平线的透明度相同(根本不透明)。然而事实并非如此。

有没有办法用 matplotlib 和 alpha 值实现我想要的?我会知道可能重叠的总行数(即,多少行重叠应对应于 0 透明度)。

感谢@cphlewis 为我指明了正确的方向,我现在有了一个可以很好地满足我需要的近似值。

我的问题比一般问题容易得多,因为我想为每条线(层)分配完全相同的透明度级别 s。如果有 n=2 行,我希望两条线重叠时的透明度接近于 0,例如alpha=0.97.

如果n=2alpha=0.97,求解

0.97 = s + s(1-s)

对于 s 产生 s=0.827

将此推广到任何 n 导致求解一个多项式,其中系数由 Pascal's triangle 的第 n 行给出,并且每个系数的符号等于

(-1)^(n + pos)

其中 pos 是帕斯卡三角形中系数从左到右的位置,其中 pos 从 1 开始。此外,帕斯卡三角形中的最后一个系数被替换为所需的 alpha值。

所以对于n=5要求解的多项式是

s^5 - 5s^4 + 10s^3 - 10s^2 + 5s - 0.97 = 0

下面的 Python 代码解决了给定 nalpha 的最小实根(这是我想要的 alpha 值)(注意 alpha < 1).

import numpy as np
import scipy.linalg

num_lines = 5
end_alpha_value = 0.97  ## end_alpha_value must be in the interval (0, 1)

pascal_triangle = scipy.linalg.pascal(num_lines + 1, kind='lower')

print 'num_reps: 1, minimum real root: %.3f' % end_alpha_value
for i in range(2, num_lines + 1):
    coeff_list = []
    for j, coeff in enumerate(pascal_triangle[i][:i]):
        coeff_list.append(coeff * ((-1)**(i+j+1)))
    coeff_list.append(-end_alpha_value)

    all_roots = np.roots(coeff_list)
    real_roots = all_roots[np.isreal(all_roots)]
    min_real_root = min(real_roots)
    real_valued = min_real_root.real[abs(min_real_root.imag) < 1e-5]

    print 'num_reps: %i, minimum real root: %.3f' % (i, real_valued[0])

对于案例 n=10,如果所需透明度为 alpha=0.97,则 s=0.296 会产生以下输出:

我相信使用黑色作为颜色会更好地显示正在发生的事情: