切割部分绘制的艺术家
Cut parts of plotted artists
假设我画了这样的背景图片:
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
im = ax.imshow(imdata, extent=(0, 1, 0, 1), aspect='auto',
cmap='coolwarm', interpolation='nearest')
现在我要添加一些矩形,例如:
rect = matplotlib.patches.Rectangle((0.3,0.3),0.4,0.4)
ax.add_artist(rect)
现在我想从之前添加的矩形中裁剪出其他几个矩形,以便再次显示下面的图像。所谓剪切,我的意思是指定这样的 "deletion rectangle" 将从先前绘制的矩形中剪切出部分。所以如果它们重叠,只有重叠的部分会被切掉。 "deletion rectangles"与上面矩形所占space不相交的地方,可见区域不发生任何变化。
我怎样才能做到这一点?
您可以使用路径来构建矩形。要定位矩形,可以平移和变换路径的顶点。然后,利用倒置顶点将从路径中切出这一事实,在外部矩形中创建孔洞。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch, Rectangle
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
# create rectangle, coordinates are ignored
rec = Rectangle((0,0),1,1).get_path()
#the big rectangle
r0 = rec.vertices+0.5
# r1 and r2 are the rectangles to cut out of r0
r1 = 0.6+rec.vertices[::-1]*0.35
r2 = 1+rec.vertices[::-1]*0.35
path = Path(vertices=np.concatenate([r0, r1, r2]),
codes=np.concatenate([rec.codes]*3))
im = ax.imshow(imdata, extent=(0, 2, 0, 2), aspect='equal',
cmap='coolwarm', interpolation='nearest')
patch = PathPatch(path, facecolor='w')
ax.add_patch(patch)
plt.tight_layout()
plt.show()
或者,一种更容易指定矩形坐标的解决方案:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch, Rectangle
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
def create_rec(x0, y0, width, height):
rec_patch = Rectangle((x0, y0),width, height)
rec_path = rec_patch.get_path()
rec_path = rec_patch.get_patch_transform().transform_path(rec_path)
return rec_path.vertices, rec_path.codes
#the big rectangle
r0,c = create_rec(0.3, 0.6, 1, 1.2)
# r1 and r2 are the rectangles to cut out of r0
r1,c = create_rec(0.4, 0.7, 0.3, 0.4)
r2,c = create_rec(0.8, 1, 0.4, 0.5)
path = Path(vertices=np.concatenate([r0, r1[::-1], r2[::-1]]),
codes=np.concatenate([c]*3))
im = ax.imshow(imdata, extent=(0, 2, 0, 2), aspect='equal',
cmap='coolwarm', interpolation='nearest')
patch = PathPatch(path, facecolor='w')
ax.add_patch(patch)
plt.tight_layout()
plt.show()
为了解决矩形部分位于原始矩形之外的情况,以下(基于第二种解决方案)可能会有所帮助:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch, Rectangle
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
def create_rec(x0, y0, width, height):
rec_patch = Rectangle((x0, y0),width, height)
rec_path = rec_patch.get_path()
rec_path = rec_patch.get_patch_transform().transform_path(rec_path)
return rec_path.vertices, rec_path.codes
#the big rectangle
r0,c = create_rec(0.3, 0.6, 1, 1.2)
# r1 and r2 are the rectangles to cut out of r0
r1,c = create_rec(0.2, 0.5, 0.3, 0.4)
r2,c = create_rec(0.8, 1, 0.4, 0.5)
path = Path(vertices=np.concatenate([r0, r1[::-1], r2[::-1]]),
codes=np.concatenate([c]*3))
im = ax.imshow(imdata, extent=(0, 2, 0, 2), aspect='equal',
cmap='coolwarm', interpolation='nearest')
patho = Path(vertices=r0,codes=c)
patcho = PathPatch(patho, facecolor='none', edgecolor="none")
ax.add_patch(patcho)
patch = PathPatch(path, facecolor='w', clip_path=patcho, edgecolor="none")
ax.add_patch(patch)
plt.show()
假设我画了这样的背景图片:
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
im = ax.imshow(imdata, extent=(0, 1, 0, 1), aspect='auto',
cmap='coolwarm', interpolation='nearest')
现在我要添加一些矩形,例如:
rect = matplotlib.patches.Rectangle((0.3,0.3),0.4,0.4)
ax.add_artist(rect)
现在我想从之前添加的矩形中裁剪出其他几个矩形,以便再次显示下面的图像。所谓剪切,我的意思是指定这样的 "deletion rectangle" 将从先前绘制的矩形中剪切出部分。所以如果它们重叠,只有重叠的部分会被切掉。 "deletion rectangles"与上面矩形所占space不相交的地方,可见区域不发生任何变化。
我怎样才能做到这一点?
您可以使用路径来构建矩形。要定位矩形,可以平移和变换路径的顶点。然后,利用倒置顶点将从路径中切出这一事实,在外部矩形中创建孔洞。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch, Rectangle
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
# create rectangle, coordinates are ignored
rec = Rectangle((0,0),1,1).get_path()
#the big rectangle
r0 = rec.vertices+0.5
# r1 and r2 are the rectangles to cut out of r0
r1 = 0.6+rec.vertices[::-1]*0.35
r2 = 1+rec.vertices[::-1]*0.35
path = Path(vertices=np.concatenate([r0, r1, r2]),
codes=np.concatenate([rec.codes]*3))
im = ax.imshow(imdata, extent=(0, 2, 0, 2), aspect='equal',
cmap='coolwarm', interpolation='nearest')
patch = PathPatch(path, facecolor='w')
ax.add_patch(patch)
plt.tight_layout()
plt.show()
或者,一种更容易指定矩形坐标的解决方案:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch, Rectangle
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
def create_rec(x0, y0, width, height):
rec_patch = Rectangle((x0, y0),width, height)
rec_path = rec_patch.get_path()
rec_path = rec_patch.get_patch_transform().transform_path(rec_path)
return rec_path.vertices, rec_path.codes
#the big rectangle
r0,c = create_rec(0.3, 0.6, 1, 1.2)
# r1 and r2 are the rectangles to cut out of r0
r1,c = create_rec(0.4, 0.7, 0.3, 0.4)
r2,c = create_rec(0.8, 1, 0.4, 0.5)
path = Path(vertices=np.concatenate([r0, r1[::-1], r2[::-1]]),
codes=np.concatenate([c]*3))
im = ax.imshow(imdata, extent=(0, 2, 0, 2), aspect='equal',
cmap='coolwarm', interpolation='nearest')
patch = PathPatch(path, facecolor='w')
ax.add_patch(patch)
plt.tight_layout()
plt.show()
为了解决矩形部分位于原始矩形之外的情况,以下(基于第二种解决方案)可能会有所帮助:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch, Rectangle
fig, ax = plt.subplots()
imdata = np.random.randn(10, 10)
def create_rec(x0, y0, width, height):
rec_patch = Rectangle((x0, y0),width, height)
rec_path = rec_patch.get_path()
rec_path = rec_patch.get_patch_transform().transform_path(rec_path)
return rec_path.vertices, rec_path.codes
#the big rectangle
r0,c = create_rec(0.3, 0.6, 1, 1.2)
# r1 and r2 are the rectangles to cut out of r0
r1,c = create_rec(0.2, 0.5, 0.3, 0.4)
r2,c = create_rec(0.8, 1, 0.4, 0.5)
path = Path(vertices=np.concatenate([r0, r1[::-1], r2[::-1]]),
codes=np.concatenate([c]*3))
im = ax.imshow(imdata, extent=(0, 2, 0, 2), aspect='equal',
cmap='coolwarm', interpolation='nearest')
patho = Path(vertices=r0,codes=c)
patcho = PathPatch(patho, facecolor='none', edgecolor="none")
ax.add_patch(patcho)
patch = PathPatch(path, facecolor='w', clip_path=patcho, edgecolor="none")
ax.add_patch(patch)
plt.show()