Matplotlib 如何在特定区域上绘制矩形
在使用matplotlib绘制图表时,我们有时需要在图中标记出某些特定区域,比如说标记出一个异常数据点所处的位置。这时候,我们可以通过在图表上绘制一个矩形来完成这个任务。本文将介绍如何在matplotlib中绘制矩形并将其限制在特定的区域内。
阅读更多:Matplotlib 教程
绘制矩形
在matplotlib中,我们可以通过使用Rectangle类来创建一个矩形对象。这个类的构造函数的参数有左下角的坐标、矩形的宽度和高度。下面是一个使用Rectangle类绘制矩形的示例代码:
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
fig, ax = plt.subplots()
rect = Rectangle((0.2, 0.3), 0.4, 0.5, color='red', alpha=0.3)
# 左下角坐标为(0.2, 0.3),宽度为0.4,高度为0.5,颜色为红色,透明度为0.3
ax.add_patch(rect)
运行这段代码,我们可以得到一个左下角坐标为(0.2, 0.3),宽度为0.4,高度为0.5,颜色为红色,透明度为0.3的矩形。
限制矩形的区域
在实际应用中,我们并不希望矩形随意地漂浮在图表中。我们需要将矩形限制在特定的区域内。最常见的情况是将其限制在某个坐标轴包含的区域内。
首先,我们需要得到该坐标轴的范围。可以通过调用坐标轴的get_xlim()和get_ylim()方法来得到x轴和y轴的范围:
x_range = ax.get_xlim()
y_range = ax.get_ylim()
然后,我们需要创建一个新的Rectangle对象,它的左下角坐标是x_range和y_range的组合,而不是直接指定一个坐标点。我们可以使用numpy模块的meshgrid函数来生成所有可能的坐标点,然后用这些点来新建一个新的Rectangle对象,然后就可以将其添加到图表中。
import numpy as np
x, y = np.meshgrid(x_range, y_range)
xy = np.column_stack([x.flat, y.flat])
new_rect = Rectangle(xy.min(axis=0), np.diff(xy, axis=0).max(),
np.diff(xy, axis=0).max(),
linewidth=1, edgecolor='r', facecolor='none')
在上面的代码中,我们首先将网格中的所有点的坐标按行列排列,并将其合并为一个2D的数组xy。然后我们计算xy中最小的x,最小的y,以及x和y方向上的差,这些信息就足以定义出一个新的Rectangle对象了。
最后,我们可以将新的Rectangle对象添加到图表中:
ax.add_patch(new_rect)
运行这段代码,我们会得到一个代表整个坐标轴范围的红色矩形
将矩形限制在特定的区域内
接下来,我们将矩形限制在某个特定的区域内,比如说一个由4个点确定的四边形。我们只需要在生成所有点的网格时,将点的范围限制在这个区域内即可。
假设我们有如下的四边形:
polygon= [(0.4, 0.2), (0.7, 0.2), (0.6, 0.5), (0.3, 0.5)]
我们需要将矩形限制在这个四边形内。我们可以利用matplotlib的Path类来判断一个点是否在指定的多边形内。具体做法是先通过Polygon类创建一个多边形对象,然后将其转化为一个Path对象。然后可以使用Path对象中的contains_points()方法来判断一个点是否在多边形中。下面是示例代码:
from matplotlib.patches import Polygon, Path
polygon_patch = Polygon(polygon, facecolor='none', edgecolor='blue')
ax.add_patch(polygon_patch)
path = Path(polygon)
inside_points = [xy[i] for i in range(len(xy)) if path.contains_point(xy[i])]
在上面的代码中,我们首先使用Polygon类创建一个多边形对象,并将其添加到图表上。注意,我们将这个多边形的填充颜色设置为’none’,这样就不会挡住图表中其他的元素。
然后,我们使用Path类创建一个路径对象,并使用它的contains_point()方法,遍历所有可以用来生成矩形的点,将其保存到inside_points列表中。
现在,我们已经得到了所有在多边形内部的点。我们只需要使用这些点来确定矩形的范围即可。
if len(inside_points) > 0: # 如果存在满足条件的点
ix, iy = zip(*inside_points)
new_rect = Rectangle((min(ix), min(iy)), max(ix) - min(ix), max(iy) - min(iy),
linewidth=1, edgecolor='r', facecolor='none')
ax.add_patch(new_rect)
在上面的代码中,我们首先检查inside_points列表是否为空。如果不为空,那么我们就使用最小点的横坐标和纵坐标作为矩形的左下角坐标,使用所有点中的最大横坐标和最大纵坐标减去最小横坐标和最小纵坐标,分别作为矩形的宽度和高度。然后,我们将这个新的Rectangle对象添加到图表中。
现在,我们可以将所有的代码连起来,得到完整的示例代码。下面的代码会在一个图表中绘制出一个随机生成的数据点集,并在其中一个特定的区域上添加一个矩形。这个区域由四个坐标点确定,它们按顺序连接起来可以得到一个四边形。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Polygon, Path
fig, ax = plt.subplots()
# 随机生成一些数据
x = np.random.rand(100)
y = np.random.rand(100)
# 绘制散点图
ax.plot(x, y, 'o', color='black', markersize=5, alpha=0.5)
# 得到坐标轴的范围
x_range = ax.get_xlim()
y_range = ax.get_ylim()
# 绘制整个坐标轴的范围
x, y = np.meshgrid(x_range, y_range)
xy = np.column_stack([x.flat, y.flat])
new_rect = Rectangle(xy.min(axis=0), np.diff(xy, axis=0).max(), np.diff(xy, axis=0).max(),
linewidth=1, edgecolor='r', facecolor='none')
ax.add_patch(new_rect)
# 绘制一个四边形,将矩形限制在这个区域内
polygon = [(0.4, 0.2), (0.7, 0.2), (0.6, 0.5), (0.3, 0.5)]
polygon_patch = Polygon(polygon, facecolor='none', edgecolor='blue')
ax.add_patch(polygon_patch)
path = Path(polygon)
inside_points = [xy[i] fori in range(len(xy)) if path.contains_point(xy[i])]
if len(inside_points) > 0:
ix, iy = zip(*inside_points)
new_rect = Rectangle((min(ix), min(iy)), max(ix) - min(ix), max(iy) - min(iy),
linewidth=1, edgecolor='r', facecolor='none')
ax.add_patch(new_rect)
plt.show()
运行上面的代码,可以看到图中红色矩形的位置正好在我们前面定义的四边形内,也正好包含了图中那个比较明显的异常点。
总结
本文介绍了如何在matplotlib中绘制矩形,并将其限制在特定的区域内。首先我们使用Rectangle类来创建矩形对象,然后通过检查点是否在指定的多边形内,来确定矩形的范围。这个方法可以应用于各种不同的场景中,比如说在数据可视化中标注异常点、在图表中高亮某个特定区域等等。