上一篇我们讲了在Axes层面的一些方法,这时你已经可以画一些比较简单的图,这一篇我们讲关注Artist层面,高度定制Axes中的图形元素
在之前我们使用ax.plot
画一条折线的时候,其实还返回了一个列表,列表中含有一个Line2D
对象,本质上是(继承自)Artist
对象,这也是这篇文章的主角,是matplotlib画图系统中最底层的对象之一。在matplotlib中,其实好多对象都是继承自Artist对象,官网上列出有一张清晰的继承图,这里从官网复制了一张,放到了下面:
artist对象的继承关系
可以发现,线(Line2D),坐标轴(Axis),图例(Legend),文字(Text)这些都是Artist,下面我们以最常见的Line2D和Text为例,介绍Artist上面有哪些常用的方法。
对于之前的文章里面,在一个axis画板中,可以使用下面的代码画一条折线
fig, ax = plt.subplots(figsize=(10, 5)) ax.set_xlim(-1, 7) ax.set_ylim(-1.5, 1.5) x = np.linspace(0, np.pi * 2) y = np.sin(x) # 使用line接收plot的返回值 line, =ax.plot(x, y)
line就是一个artist对象,可以对其进行设置,来获得一条高度定制化的Line 在artist层面进行设置的方法可以简单的记为set_xxx
,这里的xxx即为你需要设置的属性
# 设置线宽 line.set_linewidth(2) # 设置marker类型 line.set_marker('o') # 设置merker的边框颜色 line.set_markeredgecolor('b') # 设置merker的背景颜色 line.set_markerfacecolor('y') # 设置透明度 line.set_alpha(0.6) # 设置marker的大小 line.set_markersize(5) # 设置线条颜色 line.set_color('r') fig
同理,对于一个Text而言,我们也可以使用相同的方式,来进行设置属性
text = ax.text(0,0, 'This is a Text.') # 设置文字颜色 text.set_color('red') # 设置文字大小 text.set_fontsize(16) # 设置文字旋转角度 text.set_rotation(5) # 设置文字为斜体 text.set_fontstyle('italic') # 设置字宽 text.set_fontweight(1000) # 设置文字的背景颜色和边框颜色 text.set_bbox({'edgecolor': 'k', 'facecolor': 'b', 'alpha':0.4}) # 设置新的字体内容 text.set_text('This is a new Text.') fig
到这里,可以发现,我们可以这种方式来控制图表中的任何一个图形元素,只需要知道这个图形元素有哪些属性,然后使用set_xxx
来进行设置 在图层结构中,我们说其实figure、axis和axes其实也是artist,那么我们其实也可以对他们通过这种方式来进行设置
from matplotlib.artist import Artist isinstance(ax, Artist), isinstance(fig, Artist) # True, True
fig.set_figwidth(20) # 设置背景颜色 fig.set_facecolor('#55fde420') fig
ax.set_facecolor('green') ax.set_alpha(0.4) fig
至此,我们已经完成了matplotlib的基础篇的主干部分,后续会将继续介绍基础部分的零散知识。下面,我们从头开始,重新理解matplotlib中的画图逻辑。matplotlib的图由首先由画板(Figure)和画纸(Axes)组成,画纸又含有坐标轴(Axis)和画(Artist),在代码层面即为下面的代码
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(8, 5)) xaxis = ax.xaxis yaxis = ax.yaxis line, = ax.plot(1,1, color='red', marker='o')
- 当需要修改画板的属性的时候,需要修改figure(fig)
- 当需要修改画纸的属性的时候,需要修改axex(ax)
- 当需要修改坐标轴属性的时候,需要修改axis(xaxis, yaxis)
- 当需要修改画的属性的时候, 需要修改artist(line)
下面使用一个稍微复杂的例子,以此结束基础篇主干内容。
import matplotlib.pyplot as plt import numpy as np # 解决中文不显示的问题 plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决负数不显示的问题 plt.rcParams['axes.unicode_minus'] = False # 1行4列 shape = (1, 4) # 创建子图 fig, axs = plt.subplots(*shape, figsize=(15, 2)) string = '塔容万物' def hidden_axis(ax): """ 隐藏坐标轴 """ ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) def beautiful_text(text, i): text.set( fontweight=1000, fontsize=48, color='C%d' % i, # 设置文字边框的样式为 Round, pad=0.2 # 圆角, 圆角大小为0.2 bbox={'edgecolor':'C%d' % i, 'alpha':0.8, 'facecolor': 'none', 'boxstyle':'Round, pad=0.2'} ) def beautiful_points(points, i): points.set( color='C%d' % i, alpha=0.1, zorder=-10, # 值越小,图层越靠下,类似于PS的图层 ) for i in range(shape[1]): ax = axs[i] # 清空图层上的内容 ax.cla() # 隐藏坐标轴 hidden_axis(ax) # 设置子图标题 ax.set_title(string[i]) # 设置x轴和y轴的范围 ax.set_xlim(0, 1) ax.set_ylim(0, 1) # 画一个文本 text = ax.text(0.5, 0.5, string[i], ha='center', va='center') # 对文本美化 beautiful_text(text, i) x = np.random.random(200) y = np.random.random(200) # 画散点图 points = ax.scatter(x, y, label=string[i]) # 对散点图美化 beautiful_points(points, i) # 显示图例,图例格式为4列,位于画板的下方中间位置 fig.legend(ncol=4, loc='lower center') # 解决图例显示不全的问题,将画板上移一点点,使得图例可以显示完整 fig.subplots_adjust(bottom=0.205) fig.set_facecolor('white')