首页 > 解决方案 > 使 matplotlib 绘图的所有数据点均匀透明

问题描述

我想将两个散点图绘制到相同的 Axes 中,并将上面的数据点变成透明的,这样另一个图就会发光。但是,我希望整个上图具有均匀的透明度级别,这样上图的叠加标记不会像我简单地设置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 有可能吗?

谢谢你的时间!:)

标签: pythonmatplotlibscatter-plot

解决方案


经过一番搜索,我找到了相关的问题和两种解决方案,其中至少一种对我有用:

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

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,因为它对我的用例有太多依赖项(我的解决方案应该是可移植的)。

我仍然很高兴获得额外的意见。:)


推荐阅读