如何在matplotlib中很好地绘制裁剪的分层艺术家?

2024-10-01 04:47:13 发布

您现在位置:Python中文网/ 问答频道 /正文

假设在matplotlib绘图中有三个艺术家。最简单的方法是不在顶级艺术家的bbox中显示中级艺术家,同时保留整个区域中可见的低级艺术家?在

我想要实现的目标:

Illustration of layered clipping

它没有要求能够看到最低的水平,一个不透明的脸颜色的顶层图就足够了。这不适用于三个级别,因为两个较低级别将被隐藏。在

this IPython notebook for a solution using ^{}。这是一个尚未完全函数化的纯matplotlib示例,但我希望有一种更简单的方法来获得我还没有想到的相同结果。在

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import patches, cm
from matplotlib.path import Path
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
ax.imshow(imdata, extent=(0, 1, 0, 1), aspect='auto', cmap=cm.coolwarm)
text = ax.text(0.5, 0.5, 'Text', fontsize='xx-large', fontweight='bold',
               color='k', ha='center', va='center')
renderer = fig.canvas.get_renderer()
bbox = text.get_window_extent(renderer).transformed(ax.transData.inverted())
bboxrect = patches.Rectangle((bbox.x0, bbox.y0), bbox.width, bbox.height)
bbpath = bboxrect.get_path().transformed(bboxrect.get_patch_transform())
patch = patches.Rectangle((0.3, 0.3), 0.4, 0.4)
path = patch.get_path().transformed(patch.get_patch_transform())
path = Path.make_compound_path(path, bbpath)
patch = patches.PathPatch(path, facecolor='none', hatch=r'//')
ax.add_patch(patch)

Tags: path方法textimportgetmatplotlibax级别
2条回答

这有点麻烦,但我可能会通过显示图像两次来完成,一次在背景中,一次在前景中使用自定义剪辑路径。下面是一个例子:

fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)

# plot the background image
im = ax.imshow(imdata, extent=(0, 1, 0, 1), aspect='auto',
               cmap=cm.coolwarm, zorder=1)

# plot the hatched rectangle
patch = patches.Rectangle((0.3, 0.3), 0.4, 0.4, facecolor='none',
                          hatch=r'//', zorder=2)
ax.add_patch(patch)

# plot the box around the text
minirect = patches.Rectangle((0.4, 0.45), 0.2, 0.1, facecolor='none',
                             edgecolor='black', zorder=4)
ax.add_patch(minirect)

# duplicate image and set a clip path
im2 = ax.imshow(imdata, extent=(0, 1, 0, 1), aspect='auto',
                cmap=cm.coolwarm, zorder=3)
im2.set_clip_path(minirect)

# add the text on top
text = ax.text(0.5, 0.5, 'Text', fontsize='xx-large', fontweight='bold',
               color='k', ha='center', va='center', zorder=5)

enter image description here

我想出了另一个更简洁的答案:它包括为有洞的阴影区域创建一个剪辑蒙版,这样你就可以在后面的背景中看到所有的。在

from matplotlib.path import Path
from matplotlib.patches import PathPatch

def DoubleRect(xy1, width1, height1,
               xy2, width2, height2, **kwargs):
    base = np.array([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
    verts = np.vstack([xy1 + (width1, height1) * base,
                       xy2 + (width2, height2) * base[::-1],
                       xy1])
    codes = 2 * ([Path.MOVETO] + 4 * [Path.LINETO]) + [Path.CLOSEPOLY]
    return PathPatch(Path(verts, codes), **kwargs)

fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)

# plot the image
im = ax.imshow(imdata, extent=(0, 1, 0, 1), aspect='auto',
               cmap='coolwarm', interpolation='nearest')

# plot the hatched rectangle
patch = plt.Rectangle((0.3, 0.3), 0.4, 0.4, facecolor='none',
                      hatch=r'//')
ax.add_patch(patch)

# add the text
text = ax.text(0.5, 0.5, 'Text', fontsize='xx-large', fontweight='bold',
               color='k', ha='center', va='center')

# create a mask for the hatched rectangle
mask = DoubleRect((0, 0), 1, 1, (0.4, 0.45), 0.2, 0.1,
                  facecolor='none', edgecolor='black')
ax.add_patch(mask)
patch.set_clip_path(mask)

enter image description here

相关问题 更多 >