如何在Matplotlib中仅显示圆形位于x、y0-9范围的区域
仅对圆形与0-9区域交集着色的Matplotlib实现
问题描述
现有如下Matplotlib代码,绘制了网格、散点和两个同心圆,但需要仅保留圆形中x、y范围为0到9的区域着色,其余区域为白色背景:
import matplotlib.pyplot as plt from matplotlib.patches import Circle import numpy as np plt.yticks(np.arange(-10, 10.01, 1)) plt.xticks(np.arange(-10, 10.01, 1)) plt.xlim(-10,9) plt.ylim(-10,9) plt.gca().invert_yaxis() # Set aspect ratio to be equal plt.gca().set_aspect('equal', adjustable='box') plt.grid() np.random.seed(40) square = np.empty((10, 10), dtype=np.int_) for x in np.arange(0, 10, 1): for y in np.arange(0, 10, 1): plt.scatter(x, y, color="blue", s=2, zorder=2, clip_on=False) for x in np.arange(0, 10, 1): for y in np.arange(0, 10, 1): value = np.random.randint(-3, 4) square[int(x), int(y)] = value r1 = 3 circle1 = Circle((0, 0), r1, color="blue", alpha=0.5, ec='k', lw=1) r2 = 6 circle2 = Circle((0, 0), r2, color="blue", alpha=0.5, ec='k', lw=1) plt.gca().add_patch(circle1) plt.gca().add_patch(circle2)
解决方案
核心思路是通过**裁剪(clipping)**限制圆形的显示范围,只保留与x∈[0,9]、y∈[0,9]矩形区域的交集部分。以下提供两种实现方式:
方法1:使用边界框裁剪(简洁高效)
直接给圆形patch设置裁剪边界框,只保留矩形范围内的圆形部分:
import matplotlib.pyplot as plt from matplotlib.patches import Circle from matplotlib.transforms import Bbox import numpy as np plt.yticks(np.arange(-10, 10.01, 1)) plt.xticks(np.arange(-10, 10.01, 1)) plt.xlim(-10,9) plt.ylim(-10,9) plt.gca().invert_yaxis() plt.gca().set_aspect('equal', adjustable='box') plt.grid() np.random.seed(40) square = np.empty((10, 10), dtype=np.int_) for x in np.arange(0, 10, 1): for y in np.arange(0, 10, 1): plt.scatter(x, y, color="blue", s=2, zorder=2, clip_on=False) for x in np.arange(0, 10, 1): for y in np.arange(0, 10, 1): value = np.random.randint(-3, 4) square[int(x), int(y)] = value # 创建0-9范围的裁剪边界框 clip_bbox = Bbox.from_extents(0, 0, 9, 9) # 添加第一个带裁剪的圆 r1 = 3 circle1 = Circle((0, 0), r1, color="blue", alpha=0.5, ec='k', lw=1) circle1.set_clip_bbox(clip_bbox) plt.gca().add_patch(circle1) # 添加第二个带裁剪的圆 r2 = 6 circle2 = Circle((0, 0), r2, color="blue", alpha=0.5, ec='k', lw=1) circle2.set_clip_bbox(clip_bbox) plt.gca().add_patch(circle2) plt.show()
方法2:使用复合路径裁剪(灵活支持复杂形状)
如果需要更复杂的裁剪形状(比如非矩形),可以通过路径交集创建复合裁剪区域:
import matplotlib.pyplot as plt from matplotlib.patches import Circle, Rectangle from matplotlib.path import Path import numpy as np plt.yticks(np.arange(-10, 10.01, 1)) plt.xticks(np.arange(-10, 10.01, 1)) plt.xlim(-10,9) plt.ylim(-10,9) plt.gca().invert_yaxis() plt.gca().set_aspect('equal', adjustable='box') plt.grid() np.random.seed(40) square = np.empty((10, 10), dtype=np.int_) for x in np.arange(0, 10, 1): for y in np.arange(0, 10, 1): plt.scatter(x, y, color="blue", s=2, zorder=2, clip_on=False) for x in np.arange(0, 10, 1): for y in np.arange(0, 10, 1): value = np.random.randint(-3, 4) square[int(x), int(y)] = value # 获取0-9矩形的路径(转换为轴坐标) rect = Rectangle((0, 0), 9, 9) rect_path = rect.get_path().transformed(plt.gca().transData.inverted()) # 处理第一个圆 r1 = 3 circle1 = Circle((0, 0), r1, color="blue", alpha=0.5, ec='k', lw=1) # 获取圆形路径并转换坐标 circle_path = circle1.get_path().transformed(circle1.get_transform()) # 创建圆形与矩形的交集路径 intersection_path = Path.make_compound_path(circle_path, rect_path) # 设置裁剪路径 circle1.set_clip_path(intersection_path, plt.gca().transData) plt.gca().add_patch(circle1) # 处理第二个圆 r2 = 6 circle2 = Circle((0, 0), r2, color="blue", alpha=0.5, ec='k', lw=1) circle_path2 = circle2.get_path().transformed(circle2.get_transform()) intersection_path2 = Path.make_compound_path(circle_path2, rect_path) circle2.set_clip_path(intersection_path2, plt.gca().transData) plt.gca().add_patch(circle2) plt.show()
内容的提问来源于stack exchange,提问作者Simd
相关产品推荐
相关产品推荐

