【matplotlib】可视化之路——Patch类详解

概述

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()

画图结果如下:
在这里插入图片描述

文中难免会出现一些描述不当之处(尽管我已反复检查多次),欢迎在留言区指正,相关的知识点也可进行分享,希望大家都能有所收获!!如果觉得我的文章写得还行,不妨支持一下。你的每一个转发、关注、点赞、评论都是对我最大的支持!

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小猪猪家的大猪猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值