概述
Patch官方文档
以下是 matplotlib 库中的继承图:
由图可知,Patch 类作为 Rectangle 类等基础图形类的父类,个人理解就是这个类是其他2D 图形类的支持类,用以控制各个图形类的公有属性。如果按官方文档的说法,Patch 类是一个具有边缘颜色和表面颜色的平面 Artist 对象。在下文中 Patch 简称块。
A patch is a 2D artist with a face color and an edge color.If any of edgecolor, facecolor, linewidth, or antialiased are None, they default to their rc params setting.
——matplotlib 官方文档
Patch 类定义如下:
class Patch(Artist):
def __init__(self,
edgecolor=None,
facecolor=None,
color=None,
linewidth=None,
linestyle=None,
antialiased=None,
hatch=None,
fill=True,
capstyle=None,
joinstyle=None,
**kwargs):
参数说明如下:
- 参数 1:edgecolor:指定边缘颜色;
- 参数 2:facecolor:指定块表面颜色;
- 参数 3:color:指定包括块颜色和边缘颜色(指定该参数会覆盖参数 1 和参数 2 的设置);
- 参数 4:linewidth:指定线宽,单位 pt;
- 参数 5:linestyle:指定线条风格;
- 参数 6:antialiased:指定是否启用抗锯齿设置;
- 参数 7:hatch:指定内部填充样式;
- 参数 8:fill:指定是否填充色块;
- 参数 9:capstyle:指定未闭合线的两个端点的样式;
- 参数 10:joinstyle:指定两个线段的连接方式;
注意一下,当设置 color 参数的时候不会启用 facecolor 和 edgecolor 参数。具体原因如下:
if color is not None:
if edgecolor is not None or facecolor is not None:
_api.warn_external(
"Setting the 'color' property will override "
"the edgecolor or facecolor properties.")
self.set_color(color)
else:
self.set_edgecolor(edgecolor)
self.set_facecolor(facecolor)
参数详解
color
该参数主要指定块的边缘颜色和表面颜色,其包含 facecolor 和 edgecolor 两个“子参数”:
- Facecolor:主要和fill参数以及hatch参数进行配合,设置块的表面颜色,如果指定
fill=True
,那么色块将会完全填充 facecolor 指定的颜色,如果fill=False
,色块将只保留边缘颜色; - Edgecolor:主要指定块边缘线的颜色;
以矩形块为例,示例程序如下:
fig, ax = plt.subplots(1, 2)
#初始化Rectangle实例
test_Rectangle0 = plt.Rectangle((6, 6), 2, 2, 0, fill=True, label='fill=True') #fill=True
test_Rectangle1 = plt.Rectangle((6, 6), 2, 2, 0, fill=False, label='fill=True') #fill=False
ax[0].add_patch(test_Rectangle0)
ax[0].set_title('fill=True', fontsize=20)
ax[1].add_patch(test_Rectangle1)
ax[1].set_title('fill=False', fontsize=20)
#标注锚点
for i in range(2):
ax[i].plot(6, 6, markersize=6, marker='o', markerfacecolor='#FF0000', linewidth=0)
ax[i].text(6, 6, '锚点(6,6)', va='top')
ax[i].set_xlim([0, 10])
ax[i].set_ylim([0, 10])
画图结果如下:
Hatch
hatch 参数用来指定内部填充样式,其可选样式如下:
/ - diagonal hatching
\ - back diagonal
| - vertical
- - horizontal
+ - crossed
x - crossed diagonal
o - small circle
O - large circle
. - dots
* - stars
完整的示例程序如下:
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
fig, axs = plt.subplots(2, 5, constrained_layout=True, figsize=(6.4, 3.2))
hatches = ['/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*']
def hatches_plot(ax, h):
ax.add_patch(Rectangle((0, 0), 2, 2, fill=False, hatch=h))
ax.text(1, -0.5, f"' {h} '", size=15, ha="center")
ax.axis('equal')
ax.axis('off')
for ax, h in zip(axs.flat, hatches):
hatches_plot(ax, h)
plt.show()
画图结果如下:
这里需要强调一下,hatch 参数可以指定重复参数从而增加图案的密度。示例程序如下:
fig, axs = plt.subplots(2, 5, constrained_layout=True, figsize=(6.4, 3.2))
hatches = ['//', '\\\\', '||', '--', '++', 'xx', 'oo', 'OO', '..', '**']
def hatches_plot(ax, h):
ax.add_patch(Rectangle((0, 0), 2, 2, fill=False, hatch=h))
ax.text(1, -0.5, f"' {h} '", size=15, ha="center")
ax.axis('equal')
ax.axis('off')
for ax, h in zip(axs.flat, hatches):
hatches_plot(ax, h)
plt.show()
画图结果如下:
关于这个参数还需要强调最后一点,可以通过参数组合从而获得更加丰富的阴影种类。其示例程序代码如下:
fig, axs = plt.subplots(2, 5, constrained_layout=True, figsize=(6.4, 3.2))
hatches = ['/o', '\\|', '|*', '-\\', '+o', 'x*', 'o-', 'O|', 'O.', '*-']
def hatches_plot(ax, h):
ax.add_patch(Rectangle((0, 0), 2, 2, fill=False, hatch=h))
ax.text(1, -0.5, f"' {h} '", size=15, ha="center")
ax.axis('equal')
ax.axis('off')
for ax, h in zip(axs.flat, hatches):
hatches_plot(ax, h)
plt.show()
画图结果如下:
Linewidth
该参数主要指定块的边缘线宽,以 pt 为单位,其示例代码如下:
fig, ax = plt.subplots(1, 2)
#初始化Rectangle实例
test_Rectangle0 = plt.Rectangle((6, 6), 2, 2, 0, linewidth=3.2, edgecolor='#00FF00', label='linewidth=0.8') #linewidth=3.2
test_Rectangle1 = plt.Rectangle((6, 6), 2, 2, 0, linewidth=1.6, edgecolor='#00FF00', label='linewidth=1.6') #linewidth=1.6
ax[0].add_patch(test_Rectangle0)
ax[0].set_title('green-linewidth=3.2', fontsize=20)
ax[1].add_patch(test_Rectangle1)
ax[1].set_title('green-linewidth=1.6', fontsize=20)
#标注锚点
for i in range(2):
ax[i].plot(6, 6, markersize=6, marker='o', markerfacecolor='#FF0000', linewidth=0)
ax[i].text(6, 6, '锚点(6,6)', va='top')
ax[i].set_xlim([0, 10])
ax[i].set_ylim([0, 10])
plt.show()
画图结果如下:
Linestyle
详情请见 【matplotlib】可视化解决方案——linestyle参数详解
capstyle
详情请见 【matplotlib】可视化解决方案——capstyle参数详解
joinstyle
详情请见 【matplotlib】可视化解决方案——joinstyle参数详解
contains_point
该方法用于检测点是否在块中,返回一个布尔值。 contains_points()
方法是该方法的迭代变种,用以检测给定的点列表中每一个点是否在块中,并返回一个布尔数组,这里需要注意一点,监测点包括边缘线上的点。 示例程序代码如下:
test_Rectangle0 = plt.Rectangle((6, 6), 2, 2, 0, linewidth=3.2, edgecolor='#00FF00', label='linewidth=0.8')
print('(6, 6) is ', test_Rectangle0.contains_point((6, 6))) #检测(6, 6)
print('(8, 8) is ',test_Rectangle0.contains_point((8, 8))) #检测(8, 8)
print('(10, 6) is ',test_Rectangle0.contains_point((10, 6))) #检测(10, 6)
print( test_Rectangle0.contains_points([(6, 6), (8, 8), (10, 6)]))
输出结果如下:
(6, 6) is True
(8, 8) is True
(10, 6) is False
[ True True False]
Patch 实例属性的获取和设置
所有的属性都可以通过 get_property()
方法进行获取, set_property(value)
方法进行设置。示例程序如下:
test_Rectangle0 = plt.Rectangle((6, 6), 2, 2, 0, linewidth=3.2, edgecolor='#00FF00', label='linewidth=0.8')
print('old linewidth =', test_Rectangle0.get_linewidth())
test_Rectangle0.set_linewidth(5)
print('new linewidth =', test_Rectangle0.get_linewidth())
输出结果如下:
old linewidth = 3.2
new linewidth = 5.0
Patch 应用
Patch 类最简单的应用是给柱状图标注信息,在 matplotlib3.4.1版本中先填了一个 API bar_label()
用来进行标注,继承自 Patch 类的所有类的实例都可以使用这个方法进行标注,比方说 bar 方法返回 Rectangle 实例的列表,还有 hist 方法返回 Patch 实例的列表等等。bar 画图标注示例程序如下:
#添加标签等函数
def label(ax):
ax.set_xlabel('X', fontsize=15)
ax.set_ylabel('Y', fontsize=15)
ax.legend(loc='best')
figure = plt.figure(figsize=(8, 6))
ax1 = figure.add_subplot(2, 1, 1)
ax2 = figure.add_subplot(2, 1, 2)
#初始化数据
x = np.random.randint(0, 10, 10)
#画图1label_type='center'
Rectangle1 = ax1.bar(range(10), x, width=0.8, label='有标注,label_type=center')
ax1.bar_label(Rectangle1, label_type='center') #进行标注
label(ax1)
ax1.set_title('bar画图', fontsize=25)
#画图2label_type='edge'
Rectangle2 = ax2.bar(range(10), x, width=0.8, label='有标注,label_type=edge')
ax2.bar_label(Rectangle2, label_type='edge') #进行标注
label(ax2)
plt.show()
画图结果如下:
hist 画图标注示例程序如下:
array = np.random.randn(1000)
bins = 10
rwidth = 0.6
*_, patch0 = ax[0].hist(array, bins=bins, rwidth=rwidth, density=False)
*_, patch1 = ax[1].hist(array, bins=bins, rwidth=rwidth, density=True)
ax[0].bar_label(patch0, fmt='%.2f')
ax[1].bar_label(patch1, fmt='%.2f')
ax[0].set_title('直方图(不归一化)', fontsize=25)
ax[1].set_title('直方图(归一化)', fontsize=25)
plt.show()
画图结果如下:
文中难免会出现一些描述不当之处(尽管我已反复检查多次),欢迎在留言区指正,相关的知识点也可进行分享,希望大家都能有所收获!!如果觉得我的文章写得还行,不妨支持一下。你的每一个转发、关注、点赞、评论都是对我最大的支持!