使 matplotlib 图的所有数据点均匀透明

Make all data points of a matplotlib plot homogeneously transparent

我想将两个散点图绘制到同一个轴上,并将上面一个的数据点变成透明的,这样另一个散点图就可以透过。但是,我希望整个上图具有均匀的透明度级别,这样上图的叠加标记就不会像我简单地设置 alpha=0.5.

那样增加它们的不透明度。

换句话说,我希望首先渲染两个散点图并将其设置为一个恒定的透明度级别。从技术上讲,这对于光栅图形和矢量图形都是可行的(因为 SVG 支持图层透明度,afaik),但对我来说都可以。

下面是一些示例代码,显示了我不想实现的内容。 ;)

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(1, figsize=(6,4), dpi=160)
ax = fig.gca()

s1 = ax.scatter(np.random.randn(1000), np.random.randn(1000), color="b", edgecolors="none")
s2 = ax.scatter(np.random.randn(1000), np.random.randn(1000), color="g", edgecolors="none")

s2.set_alpha(0.5)  # sadly the same as setting `alpha=0.5`

fig.show()  # or display(fig)

例如,我希望 (2,2) 周围的绿色标记在它们叠加的地方不会变暗。这可以用 matplotlib 实现吗?

感谢您的宝贵时间! :)

再找了一些,找到了相关问题two solutions,其中至少有一种对我有用:

正如我希望的那样,可以渲染一层,然后像这样将它们混合在一起:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(1, figsize=(6,4), dpi=160)
ax1 = fig.gca()
s1 = ax1.scatter(np.random.randn(1000), np.random.randn(1000), color="#3355ff", edgecolors="none")
ax1.set_xlim(-3.5,3.5)
ax1.set_ylim(-3.5,3.5)
ax1.patch.set_facecolor("none")
ax1.patch.set_edgecolor("none")
fig.canvas.draw()
w, h = fig.canvas.get_width_height()
img1 = np.frombuffer(fig.canvas.buffer_rgba(), np.uint8).reshape(h, w, -1).copy()

ax1.clear()
s2 = ax1.scatter(np.random.randn(1000), np.random.randn(1000), color="#11aa44", edgecolors="none")
ax1.set_xlim(-3.5,3.5)
ax1.set_ylim(-3.5,3.5)
ax1.patch.set_facecolor("none")
ax1.patch.set_edgecolor("none")
fig.canvas.draw()
img2 = np.frombuffer(fig.canvas.buffer_rgba(), np.uint8).reshape(h, w, -1).copy()

fig.clf()

plt.imshow(np.minimum(img1,img2))
plt.subplots_adjust(0, 0, 1, 1)
plt.axis("off")
plt.show()

我可能不得不想出更好的方法,而不是仅仅采用两层的 np.minimum 来保留更多颜色选项(并且可能将轴和标签保存到第三层)。 我没有按照其他链接答案中的建议尝试 mplcairo,因为它对我的用例有太多依赖性(我的解决方案应该是可移植的)。

我仍然很高兴有更多的意见。 :)