在相交的 Matplotlib 补丁上统一应用 Alpha

Posted

技术标签:

【中文标题】在相交的 Matplotlib 补丁上统一应用 Alpha【英文标题】:Apply Alpha Uniformly on Intersecting Matplotlib Patches 【发布时间】:2021-11-25 22:15:58 【问题描述】:

我正在寻找有关如何使用 Matplotlib 补丁创建绘图的建议,其中透明度可以统一应用于所有补丁。具体来说,如果我有重叠的补丁,我希望将 alpha 值应用于两个补丁的联合,而不是单独应用。交叉区域应与单个结构看起来相同,如果补丁定义(例如颜色)存在差异,则应优先添加到集合中的最后一个补丁。

下面是一个不起作用的简单示例。

import matplotlib.pylab as plt
import matplotlib as mpl

f, (ax1, ax2) = plt.subplots(1, 2, tight_layout=True)

# assign alpha to individual patches
patch1 = mpl.patches.Rectangle((0.4, 0.4), .5, .5, alpha=0.5)
patch2 = mpl.patches.Rectangle((0.1, 0.1), .5, .5, alpha=0.5)
ax1.add_patch(patch1)
ax1.add_patch(patch2)
ax1.set_title('individual patches')

# try assigning alpha to collection
patch3 = mpl.patches.Rectangle((0.4, 0.4), .5, .5)
patch4 = mpl.patches.Rectangle((0.1, 0.1), .5, .5)
collection = mpl.collections.PatchCollection([patch3, patch4], alpha=0.5)
ax2.add_collection(collection)
ax2.set_title('patch collection')

# overlap region is darker
plt.show()

基于网上的一些其他讨论,我研究了一些其他技术,例如从与alpha=1 的交叉点渲染图像,然后用alpha < 1 绘制此图像,但因为图像在我的应用程序中会很大,我更喜欢使用几何图元,例如补丁。

关于如何完成这项工作的任何想法?

【问题讨论】:

您是否需要使用 alpha(即是否还有其他需要透明度的绘图元素?)如果没有,并且您只是在绘制这些补丁,您可以通过绘制一个不使用 Alpha 通道的纯色 不幸的是,我确实需要 alpha,因为这些补丁被应用在 pcolormesh 或 imshow 之上,我希望在整个图像中都可见。 这能回答你的问题吗? matplotlib Circle patch with alpha produces overlap of edge and facecolor 很遗憾没有,但我已经通读了几遍试图理解它。在那个问题中,边缘与面部重叠,这与我的情况不同,补丁在哪里相交。 这能回答你的问题吗? Plot unions of polygons in matplotlib 【参考方案1】:

如果它对任何人有帮助,我想出了一个基于修改 this 讨论的解决方案。

import matplotlib.pylab as plt
import shapely.geometry as sg
import shapely.ops as so
from typing import List

class Structure:
    """ stores a shapely shape and a facecolor """
    def __init__(self, shape, fc):
        self.shape = shape
        self.fc = fc

#constructing the first rect as a polygon
bot_left = Structure(shape=sg.box(0.1,0.1,0.6,0.6), fc='blue')

#a shortcut for constructing a rectangular polygon
top_right = Structure(shape=sg.box(0.4,0.4,0.9,0.9), fc='red')

#constructing the first rect as a polygon
top_left = Structure(shape=sg.box(0.1,0.4,0.6,0.9), fc='brown')

#constructing the first rect as a polygon
bot_right = Structure(shape=sg.box(0.4,0.05,0.9,0.6), fc='blue')

def overlap_union(structures: List[Structure]) -> List[Structure]:
    """ returns polygons """
    structs_exist = []
    for s in structures:
        for _s in structs_exist:
            intersection = s.shape & _s.shape
            _s.shape = _s.shape - intersection
        structs_exist.append(s)
    return structs_exist


def overlap_union_merge(structures: List[Structure]) -> List[Structure]:
    """ merges two polygons if they intersect with same facecolor """
    structs_exist = []
    for s in structures:
        append_this_struct = True
        for _s in structs_exist:
            if s.shape & _s.shape:
                if s.fc == _s.fc:
                    _s.shape = _s.shape | (s.shape - _s.shape)
                    append_this_struct = False
                else:
                    _s.shape = _s.shape - s.shape
        if append_this_struct:
            structs_exist.append(s)
    return structs_exist


structs_before = [bot_left, top_right, top_left, bot_right]

plot_edges = True
ec = 'k' if plot_edges else 'none'

_, (ax1, ax2, ax3) = plt.subplots(1, 3, tight_layout=True, figsize=(15, 5))

for struct in structs_before:
    xs, ys = struct.shape.exterior.xy
    ax1.fill(xs, ys, alpha=0.4, fc=struct.fc, ec=ec)
    ax1.set_title('naive (no union)')

structs_after = overlap_union(structs_before)
for struct in structs_after:
    xs, ys = struct.shape.exterior.xy
    ax2.fill(xs, ys, alpha=0.4, fc=struct.fc, ec=ec)
    ax2.set_title('simple version')

structs_after_merge = overlap_union_merge(structs_before)
for struct in structs_after_merge:
    xs, ys = struct.shape.exterior.xy
    ax3.fill(xs, ys, alpha=0.4, fc=struct.fc, ec=ec)
    ax3.set_title('merged version')

for ax in (ax1, ax2, ax3):
    ax.set_xlim(0, 1)
    ax.set_ylim(0,1)
plt.show()

【讨论】:

以上是关于在相交的 Matplotlib 补丁上统一应用 Alpha的主要内容,如果未能解决你的问题,请参考以下文章

为啥 matplotlib.PatchCollection 会弄乱补丁的颜色?

python数据图形化—— matplotlib 基础应用

探索 dotnet core 为何在 Windows7 系统需要补丁的原因

matplotlib 中 Poly3DCollection 图的透明度

如何系统地学习Python 中 matplotlib,numpy,scipy,pandas

数据结构——不相交集