在后台回复【阅读书籍】
即可获取python相关电子书~
Hi,我是山月。
今天我们来讲解Matplotlib里的文本教程,这也是这个系列的倒数第二篇,还没有学习的小伙伴可以学习起来啦~
在公众号后台选择【往期】--【Matplotlib】即可查看已更新的全部教程哦~
01
Matplotlib 图中的文本
下面来介绍下如何在 Matplotlib 中绘制和处理文本。
1、基本文本命令
以下命令用于在 pyplot 界面和面向对象的 API 中创建文本:
所有这些函数都会创建并返回一个 Text 实例,该实例可以配置各种字体和其他属性。
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
fig.subplots_adjust(top=0.85)
# 分别为图形和子图设置标题
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# 将x轴和y轴限制设置为[0,10],而不是默认值[0,1]
ax.axis([0, 10, 0, 10])
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15)
ax.text(3, 2, 'unicode: Institut für Festkörperphysik')
ax.text(0.95, 0.01, 'colored text in axes coords',
verticalalignment='bottom', horizontalalignment='right',
transform=ax.transAxes,
color='green', fontsize=15)
ax.plot([2], [1], 'o')
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
效果:
2、x 轴和 y 轴标签
可以通过 set_xlabel 和 set_ylabel 方法指定 x 轴和 y 轴的标签:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
效果:
x和y标签会自动放置,以便清除x和y标签。
比较下面的图和上面的图,注意y标签的位置。
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
效果:
如果要移动标签,可以指定 labelpad 关键字参数,其中值是磅(1磅=1/72英寸,与字体大小是相同的单位,12磅高即是12号字)。
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]', labelpad=18)
plt.show()
效果:
标签也接受所有 Text 关键字参数,包括位置。
所以我们可以通过手动指定标签位置,比如将 x轴标签放在轴的最左侧。
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', position=(0., 1e6), horizontalalignment='left')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
效果:
标签也可以通过 matplotlib.font_manager.FontProperties 方法更改,或者使它作为参数添加到set_ylabel:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
font = FontProperties()
font.set_family('serif')
font.set_name('Times New Roman')
font.set_style('italic')
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', fontsize='large', fontweight='bold')
ax.set_ylabel('Damped oscillation [V]', fontproperties=font)
plt.show()
效果:
最后,我们可以在所有文本对象中使用本机 TeX 渲染并拥有多行:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.2, left=0.2)
ax.plot(x1, np.cumsum(y1**2))
ax.set_xlabel('time [s] \n This was a long experiment')
ax.set_ylabel(r'$\int\ Y^2\ dt\ \ [V^2 s]$')
plt.show()
效果:
3、标题
子图标题的设置方式与标签大致相同,但可以通过 loc( 默认loc=center ) 关键字参数更改位置和对齐方式。
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(3, 1, figsize=(5, 6), tight_layout=True)
locs = ['center', 'left', 'right']
for ax, loc in zip(axs, locs):
ax.plot(x1, y1)
ax.set_title('Title with loc at '+loc, loc=loc)
plt.show()
效果:
标题的垂直间距通过参数pad(默认值 6.0)控制,设置不同的间距会移动标题位置。
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(top=0.8)
ax.plot(x1, y1)
ax.set_title('Vertically offset title', pad=30)
plt.show()
效果:
4、刻度和刻度标签
1、术语解释
Axes 具有用于 ax.xaxis 和 ax.yaxis 的 matplotlib.axis.Axis 对象,其中包含轴标签如何布局的信息。
Axis 对象具有主/次刻度。
Axis可以通过Axis.set_major_locator 和 Axis.set_minor_locator 方法,使用正在绘制的数据来确定主和次刻度的位置。
还有用于格式化刻度标签的 Axis.set_major_formatter 和 Axis.set_minor_formatter 方法。
2、简单的刻度
Matplotlib 会自动给我们定义基础的刻度,如第一个图。
不过我们也可以在这个基础上进行一些设置,比如重置轴限制,如第二个图。
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
axs[1].xaxis.set_ticks(np.arange(0., 8.1, 2.))
plt.show()
效果:
更改刻度的格式:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
tickla = ['%1.2f' % tick for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla)
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
效果:
3、刻度定位器和格式化程序
我们可以使用 matplotlib.ticker.StrMethodFormatter ( str.format() 格式字符串)或 matplotlib.ticker.FormatStrFormatter ( '%' 格式字符串)并将其传递给ax.xaxis,而不是列出所有刻度标签的列表。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
formatter = matplotlib.ticker.StrMethodFormatter('{x:1.1f}')
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_major_formatter(formatter)
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
效果:
当然,我们可以使用非默认定位器来设置刻度位置:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
ticks = np.arange(0., 8.1, 2.)
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
locator = matplotlib.ticker.FixedLocator(ticks)
axs[1].xaxis.set_major_locator(locator)
axs[1].xaxis.set_major_formatter(formatter)
plt.show()
效果:
默认的格式化程序是 matplotlib.ticker.MaxNLocator:
ticker.MaxNLocator(self, nbins='auto', steps=[1, 2, 2.5, 5, 10])
steps 关键字包含一个可用于刻度值的倍数列表。
即在 steps=[1, 2, 2.5, 5, 10]) 的情况下,2、4、6 是可接受的刻度,20、40、60 或 0.2、0.4、0.6 也是如此。
但是,3、6、9 是不可接受的,因为 3 没有出现在步骤列表中。
nbins=auto 根据轴的长度使用算法来确定可接受的刻度数,但它只考虑了刻度标签的字体大小,但没有考虑刻度标签的的长度。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
locator = matplotlib.ticker.MaxNLocator(nbins='auto', steps=[1, 4, 10])
axs[0, 1].xaxis.set_major_locator(locator)
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.AutoLocator()
axs[1, 0].xaxis.set_major_formatter(formatter)
axs[1, 0].xaxis.set_major_locator(locator)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.MaxNLocator(nbins=4)
axs[1, 1].xaxis.set_major_formatter(formatter)
axs[1, 1].xaxis.set_major_locator(locator)
plt.show()
效果:
最后,我们可以使用 matplotlib.ticker.FuncFormatter 为格式化程序指定函数。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
def formatoddticks(x, pos):
# 设置奇数刻度位置的格式
if x % 2:
return '%1.2f' % x
else:
return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
formatter = matplotlib.ticker.FuncFormatter(formatoddticks)
locator = matplotlib.ticker.MaxNLocator(nbins=6)
ax.xaxis.set_major_formatter(formatter)
ax.xaxis.set_major_locator(locator)
plt.show()
效果:
4、日期刻度
Matplotlib 可接受 datetime.datetime 和 numpy.datetime64 对象作为绘图参数。
由于日期和时间需要特殊格式,所以它通常手动设置。
日期具有的特殊定位器和格式化程序,这在 matplotlib.dates 模块中定义了。
一个简单的例子如下:
import matplotlib.pyplot as plt
import numpy as np
import datetime
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
效果:
我们可以将格式传递给 matplotlib.dates.DateFormatter。
注意29号和下个月的时间很接近,所以我们可以通过使用 dates.DayLocator 类来指定要使用的月份的日期列表。
matplotlib.dates 模块中也列出了类似的格式化程序。
import matplotlib.pyplot as plt
import numpy as np
import datetime
import matplotlib.dates as mdates
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
locator = mdates.DayLocator(bymonthday=[1, 15])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
效果:
02
文本属性和布局
matplotlib.text.Text 实例有多种属性,可以通过文本命令的关键字参数(例如,title()、xlabel() 和 text())进行配置。
可以使用对齐参数horizontalalignment(水平对齐)、verticalalignment(垂直对齐)和multialignment(多重对齐)来布置文本。
Horizontalalignment 控制文本的 x 位置参数在文本边界框的左侧、中心还是右侧。
verticalalignment 控制文本的 y 位置参数在文本边界框的底部、中心还是顶部。
multialignment,仅用于换行分隔的字符串,控制不同的行是左对齐、居中对齐还是右对齐。
import matplotlib.pyplot as plt
import matplotlib.patches as patches
# 在坐标系中建立一个矩形
left, width = .25, .5
bottom, height = .25, .5
right = left + width
top = bottom + height
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
# 轴坐标:(0,0)为左下角,(1,1)为右上角
p = patches.Rectangle(
(left, bottom), width, height,
fill=False, transform=ax.transAxes, clip_on=False
)
ax.add_patch(p)
ax.text(left, bottom, 'left top',
horizontalalignment='left',
verticalalignment='top',
transform=ax.transAxes)
ax.text(left, bottom, 'left bottom',
horizontalalignment='left',
verticalalignment='bottom',
transform=ax.transAxes)
ax.text(right, top, 'right bottom',
horizontalalignment='right',
verticalalignment='bottom',
transform=ax.transAxes)
ax.text(right, top, 'right top',
horizontalalignment='right',
verticalalignment='top',
transform=ax.transAxes)
ax.text(right, bottom, 'center top',
horizontalalignment='center',
verticalalignment='top',
transform=ax.transAxes)
ax.text(left, 0.5*(bottom+top), 'right center',
horizontalalignment='right',
verticalalignment='center',
rotation='vertical',
transform=ax.transAxes)
ax.text(left, 0.5*(bottom+top), 'left center',
horizontalalignment='left',
verticalalignment='center',
rotation='vertical',
transform=ax.transAxes)
ax.text(0.5*(left+right), 0.5*(bottom+top), 'middle',
horizontalalignment='center',
verticalalignment='center',
fontsize=20, color='red',
transform=ax.transAxes)
ax.text(right, 0.5*(bottom+top), 'centered',
horizontalalignment='center',
verticalalignment='center',
rotation='vertical',
transform=ax.transAxes)
ax.text(left, top, 'rotated\nwith newlines',
horizontalalignment='center',
verticalalignment='center',
rotation=45,
transform=ax.transAxes)
ax.set_axis_off()
plt.show()
效果:
1、默认字体
默认字体由一组参数控制。
比如要设置数学表达式中的字体,可以使用以 mathtext 开头的参数。
family别名({'cursive', 'fantasy', 'monospace', 'sans', 'sans serif', 'sans-serif', 'serif'})和实际字体名称之间的映射由以下参数控制:
2、非拉丁字形文本
从 v2.0 开始,默认字体 DejaVu 包含许多西方字母的字形,但不包含其他文字,例如中文、韩文或日文。
若要将默认字体设置为支持所需码点的字体,可以将字体名称前缀为'font.family'或想要的别名列表。
matplotlib.rcParams['font.sans-serif'] = ['Source Han Sans TW', 'sans-serif']
或将其设置在 .matplotlibrc 文件中:
font.sans-serif: Source Han Sans TW, Arial, sans-serif
要控制每个artist使用的字体,可以使用上面记录的 'name'、'fontname' 或 'fontproperties' 关键字参数。
03
注释
1、基础注释
使用 text() 可以将文本放置在轴上的任意位置。
文本的一个常见用例是对绘图的某些特征进行注释,使用annotate() 方法可以使注释变的简单。
在注释中,有两点需要考虑:被注释的位置由参数xy表示;文本的位置由参数xytext表示。
这两个参数都是(x, y)元组。
示例:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)
ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)
ax.set_ylim(-2, 2)
plt.show()
效果:
在此示例中,xy位置和 xytext 位置都在数据坐标中,但你也可以通过下面的字符串指定xy和xytext的坐标系统:
如果要将文本坐标放在分数轴坐标中,可以这样做:
ax.annotate('local max', xy=(3, 1), xycoords='data',
xytext=(0.8, 0.95), textcoords='axes fraction',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='right', verticalalignment='top',
)
对于物理坐标系(点或像素),原点是图形或axes的左下角。
可以在可选关键字参数 arrowprops 中提供箭头属性字典来启用从文本到注释点的箭头绘制:
示例:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
r = np.arange(0, 1, 0.001)
theta = 2 * 2*np.pi * r
line, = ax.plot(theta, r, color='#ee8d18', lw=3)
ind = 800
thisr, thistheta = r[ind], theta[ind]
ax.plot([thistheta], [thisr], 'o')
ax.annotate('a polar annotation',
xy=(thistheta, thisr), # theta, radius
xytext=(0.05, 0.05), # fraction, fraction
textcoords='figure fraction',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='left',
verticalalignment='bottom',
)
plt.show()
效果:
2、高级注释
1、用框注释文本
让我们从一个简单的例子开始。
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(5, 5))
ax.set_aspect(1)
x1 = -1 + np.random.randn(100)
y1 = -1 + np.random.randn(100)
x2 = 1. + np.random.randn(100)
y2 = 1. + np.random.randn(100)
ax.scatter(x1, y1, color="r")
ax.scatter(x2, y2, color="g")
bbox_props = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9)
ax.text(-2, -2, "Sample A", ha="center", va="center", size=20,
bbox=bbox_props)
ax.text(2, 2, "Sample B", ha="center", va="center", size=20,
bbox=bbox_props)
bbox_props = dict(boxstyle="rarrow", fc=(0.8, 0.9, 0.9), ec="b", lw=2)
t = ax.text(0, 0, "Direction", ha="center", va="center", rotation=45,
size=15,
bbox=bbox_props)
bb = t.get_bbox_patch()
bb.set_boxstyle("rarrow", pad=0.6)
ax.set_xlim(-4, 4)
ax.set_ylim(-4, 4)
plt.show()
效果:
pyplot 模块中的 text() 函数(或 Axes 类的 text 方法)接受 bbox 关键字参数,当给定时,会在文本周围绘制一个框。
bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2)
t = ax.text(0, 0, "Direction", ha="center", va="center", rotation=45,
size=15,
bbox=bbox_props)
可以通过以下方式访问与文本关联的patch对象:
bb = t.get_bbox_patch()
返回值是一个 FancyBboxPatch 实例,并且可以像往常一样访问和修改诸如 facecolor、edgewidth 等的patch属性。
要更改框的形状,可以使用 set_boxstyle 方法。
bb.set_boxstyle("rarrow", pad=0.6)
参数是框样式的名称,其属性作为关键字参数。目前,实现了以下框样式:
import matplotlib.pyplot as plt
import matplotlib.patches as mpatch
styles = mpatch.BoxStyle.get_styles()
spacing = 1.2
figheight = (spacing * len(styles) + .5)
fig = plt.figure(figsize=(4 / 1.5, figheight / 1.5))
fontsize = 0.3 * 72
for i, stylename in enumerate(sorted(styles)):
fig.text(0.5, (spacing * (len(styles) - i) - 0.5) / figheight, stylename,
ha="center",
size=fontsize,
bbox=dict(boxstyle=stylename, fc="w", ec="k"))
plt.show()
效果:
注意,属性参数可以在样式名称中用逗号分隔。
bb.set_boxstyle("rarrow,pad=0.6")
2、用箭头注释
pyplot 模块中的 annotate() 函数(或 Axes 类的 annotate 方法)也可用于绘制连接图上两点的箭头。
ax.annotate("Annotation",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='offset points',
)
这使用 textcoords 中给出的 xytext 坐标处的文本来注释 xycoords 中给出的 xy 坐标处的点。
通常,注释点在数据坐标中指定,注释文本在偏移点中指定。
通过指定 arrowprops 参数,可以选择绘制连接两点(xy 和 xytext)的箭头。
如果仅想绘制箭头,则使用空字符串作为第一个参数:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3, 3))
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"),
)
plt.show()
效果:
绘制箭头图需要以下几个步骤:
创建两点之间的连接路径。这由 connectionstyle 键值对控制。
如果给出了patch对象(patchA和patchB),则剪切路径以避免patch。
路径进一步收缩到给定的像素量(shrinkA & shrinkB)
路径转换为箭头patch,由arrowstyle键值对控制。
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
fig, axs = plt.subplots(2, 2)
x1, y1 = 0.3, 0.3
x2, y2 = 0.7, 0.7
ax = axs.flat[0]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="-",
color="0.5",
patchB=None,
shrinkB=0,
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "connect", transform=ax.transAxes, ha="left", va="top")
ax = axs.flat[1]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="-",
color="0.5",
patchB=el,
shrinkB=0,
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "clip", transform=ax.transAxes, ha="left", va="top")
ax = axs.flat[2]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="-",
color="0.5",
patchB=el,
shrinkB=5,
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "shrink", transform=ax.transAxes, ha="left", va="top")
ax = axs.flat[3]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="fancy",
color="0.5",
patchB=el,
shrinkB=5,
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "mutate", transform=ax.transAxes, ha="left", va="top")
for ax in axs.flat:
ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1)
plt.show()
效果:
两点之间的连接路径的创建由 connectionstyle 键控制,可以使用以下样式:
请注意,angle3 和 arc3 中的“3”表示生成的路径是二次样条线段(三个控制点)。
在下面的示例中(有限地)演示了每种连接样式的行为:
import matplotlib.pyplot as plt
def demo_con_style(ax, connectionstyle):
x1, y1 = 0.3, 0.2
x2, y2 = 0.8, 0.6
ax.plot([x1, x2], [y1, y2], ".")
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="->", color="0.5",
shrinkA=5, shrinkB=5,
patchA=None, patchB=None,
connectionstyle=connectionstyle,
),
)
ax.text(.05, .95, connectionstyle.replace(",", ",\n"),
transform=ax.transAxes, ha="left", va="top")
fig, axs = plt.subplots(3, 5, figsize=(8, 4.8))
demo_con_style(axs[0, 0], "angle3,angleA=90,angleB=0")
demo_con_style(axs[1, 0], "angle3,angleA=0,angleB=90")
demo_con_style(axs[0, 1], "arc3,rad=0.")
demo_con_style(axs[1, 1], "arc3,rad=0.3")
demo_con_style(axs[2, 1], "arc3,rad=-0.3")
demo_con_style(axs[0, 2], "angle,angleA=-90,angleB=180,rad=0")
demo_con_style(axs[1, 2], "angle,angleA=-90,angleB=180,rad=5")
demo_con_style(axs[2, 2], "angle,angleA=-90,angleB=10,rad=5")
demo_con_style(axs[0, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=0")
demo_con_style(axs[1, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5")
demo_con_style(axs[2, 3], "arc,angleA=-90,angleB=0,armA=0,armB=40,rad=0")
demo_con_style(axs[0, 4], "bar,fraction=0.3")
demo_con_style(axs[1, 4], "bar,fraction=-0.3")
demo_con_style(axs[2, 4], "bar,angle=180,fraction=-0.2")
for ax in axs.flat:
ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1)
fig.tight_layout(pad=0.2)
plt.show()
效果:
根据给定的箭头样式,将连接路径(剪切和收缩后)转换为箭头patch。
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
styles = mpatches.ArrowStyle.get_styles()
ncol = 2
nrow = (len(styles) + 1) // ncol
figheight = (nrow + 0.5)
fig = plt.figure(figsize=(4 * ncol / 1.5, figheight / 1.5))
fontsize = 0.2 * 70
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1.)
ax.set_xlim(0, 4 * ncol)
ax.set_ylim(0, figheight)
def to_texstring(s):
s = s.replace("<", r"$<$")
s = s.replace(">", r"$>$")
s = s.replace("|", r"$|$")
return s
for i, (stylename, styleclass) in enumerate(sorted(styles.items())):
x = 3.2 + (i // nrow) * 4
y = (figheight - 0.7 - i % nrow) # /figheight
p = mpatches.Circle((x, y), 0.2)
ax.add_patch(p)
ax.annotate(to_texstring(stylename), (x, y),
(x - 1.2, y),
ha="right", va="center",
size=fontsize,
arrowprops=dict(arrowstyle=stylename,
patchB=p,
shrinkA=5,
shrinkB=5,
fc="k", ec="k",
connectionstyle="arc3,rad=-0.05",
),
bbox=dict(boxstyle="square", fc="w"))
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
plt.show()
效果:
某些箭头样式仅适用于生成二次样条线段的连接样式,如fancy,simple,和 wedge。
对于这些箭头样式,你必须使用“angle3”或“arc3”连接样式。
如果给出了注释字符串,则 patchA 默认设置为文本的 bbox patch。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3, 3))
ax.annotate("Test",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
size=20, va="center", ha="center",
arrowprops=dict(arrowstyle="simple",
connectionstyle="arc3,rad=-0.2"),
)
plt.show()
效果:
与 text 命令一样,可以使用 bbox 参数在文本周围绘制一个框。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3, 3))
ann = ax.annotate("Test",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
size=20, va="center", ha="center",
bbox=dict(boxstyle="round4", fc="w"),
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=-0.2",
fc="w"),
)
plt.show()
效果:
默认情况下,起点设置为文本范围的中心。
这可以通过 relpos 键值对进行调整,其中值根据文本的范围进行规范化。
例如,(0, 0) 表示左下角,(1, 1) 表示右上角。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3, 3))
ann = ax.annotate("Test",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
size=20, va="center", ha="center",
bbox=dict(boxstyle="round4", fc="w"),
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=0.2",
relpos=(0., 0.),
fc="w"),
)
ann = ax.annotate("Test",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
size=20, va="center", ha="center",
bbox=dict(boxstyle="round4", fc="w"),
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=-0.2",
relpos=(1., 0.),
fc="w"),
)
plt.show()
效果:
3、将Artist放置在Axes的锚定位置
可以将某些Artist类别放置在 Axes 中的锚定位置,一个常见的例子是图例,可以使用 OffsetBox 类来创建这种类型的Artist。
mpl_toolkits.axes_grid1.anchored_artists 中提供了一些预定义的类,其他的在matplotlib.offsetbox 中。
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredText
fig, ax = plt.subplots(figsize=(3, 3))
at = AnchoredText("Figure 1a",
prop=dict(size=15), frameon=True, loc='upper left')
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
plt.show()
效果:
loc 关键字的含义与 legend 命令中的含义相同。
一个简单的应用是当artist(或artist集合)的大小在创建期间在创作期间已知像素大小。
例如,如果你想绘制一个固定大小为 20 像素 x 20 像素(半径 = 10 像素)的圆,可以使用 AnchoredDrawingArea。
该实例是使用绘图区域的大小(以像素为单位)创建的,并且可以将任意artist添加到绘图区域。
请注意,添加到绘图区域的artist的范围与绘图区域本身的位置无关。只有初始大小很重要。
from matplotlib.patches import Circle
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDrawingArea
fig, ax = plt.subplots(figsize=(3, 3))
ada = AnchoredDrawingArea(40, 20, 0, 0,
loc='upper right', pad=0., frameon=False)
p1 = Circle((10, 10), 10)
ada.drawing_area.add_artist(p1)
p2 = Circle((30, 10), 5, fc="r")
ada.drawing_area.add_artist(p2)
ax.add_artist(ada)
plt.show()
效果:
有时,你希望你的artist可以根据数据坐标(或画布像素以外的坐标)进行缩放,你可以使用 AnchoredAuxTransformBox 类。
这与 AnchoredDrawingArea 类似,不同之处在于artist的范围是在绘制期间根据指定的转换确定的。
如椭圆在数据坐标中的宽度和高度分别为 0.1 和 0.4,并且会在axes的视图范围发生变化时自动缩放:
from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredAuxTransformBox
fig, ax = plt.subplots(figsize=(3, 3))
box = AnchoredAuxTransformBox(ax.transData, loc='upper left')
el = Ellipse((0, 0), width=0.1, height=0.4, angle=30) # in data coordinates!
box.drawing_area.add_artist(el)
ax.add_artist(box)
plt.show()
效果:
使用 HPacker 和 VPacker,你可以在图例中布置artist(事实上,这就是图例创建的方式)。
from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
from matplotlib.offsetbox import (AnchoredOffsetbox, DrawingArea, HPacker,
TextArea)
fig, ax = plt.subplots(figsize=(3, 3))
box1 = TextArea(" Test : ", textprops=dict(color="k"))
box2 = DrawingArea(60, 20, 0, 0)
el1 = Ellipse((10, 10), width=16, height=5, angle=30, fc="r")
el2 = Ellipse((30, 10), width=16, height=5, angle=170, fc="g")
el3 = Ellipse((50, 10), width=16, height=5, angle=230, fc="b")
box2.add_artist(el1)
box2.add_artist(el2)
box2.add_artist(el3)
box = HPacker(children=[box1, box2],
align="center",
pad=0, sep=5)
anchored_box = AnchoredOffsetbox(loc='lower left',
child=box, pad=0.,
frameon=True,
bbox_to_anchor=(0., 1.02),
bbox_transform=ax.transAxes,
borderpad=0.,
)
ax.add_artist(anchored_box)
fig.subplots_adjust(top=0.8)
plt.show()
效果:
请注意,与图例不同的是,bbox_transform 默认设置为 IdentityTransform。
4、使用带注释的复杂坐标
matplotlib 中的注释支持多种类型的坐标,如基本注释中所述。
对于想要更多控制的高级用户,它也支持一些其他选项。
1)转换实例
例如:
ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes)
等同于:
ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction")
有了这个,你可以在其他轴上注释一个点。
ax1, ax2 = subplot(121), subplot(122)
ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData,
xytext=(0.5, 0.5), textcoords=ax2.transData,
arrowprops=dict(arrowstyle="->"))
2)Artist实例
xy 值(或 xytext)被解释为artist的 bbox (get_window_extent 的返回值)的分数坐标。
ax1, ax2 = subplot(121), subplot(122)
ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData,
xytext=(0.5, 0.5), textcoords=ax2.transData,
arrowprops=dict(arrowstyle="->"))
效果:
请注意,坐标artist的范围(例子中an1)得在an2绘制之前确定。
3)返回 BboxBase 或 Transform 实例的可调用对象
如果返回一个Transform,则它与 1 相同,如果返回一个 bbox,则它与 2 相同。可调用对象应采用渲染器实例的单个参数。
例如,以下两个命令给出相同的结果:
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1,
xytext=(30, 0), textcoords="offset points")
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent,
xytext=(30, 0), textcoords="offset points")
4)两个坐标规范的元组
第一项用于 x 坐标,第二项用于 y 坐标。如:
annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))
0.5 在数据坐标中,1 在标准化轴坐标中。你可以像使用元组一样使用artist或transform。
例如:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3, 2))
an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(boxstyle="round", fc="w"))
an2 = ax.annotate("Test 2", xy=(0.5, 1.), xycoords=an1,
xytext=(0.5, 1.1), textcoords=(an1, "axes fraction"),
va="bottom", ha="center",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
fig.subplots_adjust(top=0.83)
plt.show()
效果:
5)有时,你希望注释带有一些“偏移点”,但不是从注释点,而是从其他点。
OffsetFrom 是这种情况的一个辅助类。
import matplotlib.pyplot as plt
from matplotlib.text import OffsetFrom
fig, ax = plt.subplots(figsize=(3, 2))
an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(boxstyle="round", fc="w"))
offset_from = OffsetFrom(an1, (0.5, 0))
an2 = ax.annotate("Test 2", xy=(0.1, 0.1), xycoords="data",
xytext=(0, -10), textcoords=offset_from,
# xytext是“xy=(0.5,0), xycoords=an1”的偏移点
va="top", ha="center",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
plt.show()
效果:
5、使用ConnectionPatch
ConnectionPatch 就像一个没有文本的注释,当你想要连接不同axes上的点时很有用。
示例:
from matplotlib.patches import ConnectionPatch
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3))
# 在一个axes内的两个轴坐标点之间画一个简单的箭头。
xyA = (0.2, 0.2)
xyB = (0.8, 0.8)
coordsA = "data"
coordsB = "data"
con = ConnectionPatch(xyA, xyB, coordsA, coordsB,
arrowstyle="-|>", shrinkA=5, shrinkB=5,
mutation_scale=20, fc="w")
ax1.plot([xyA[0], xyB[0]], [xyA[1], xyB[1]], "o")
ax1.add_artist(con)
# 在不同的 axes上的同一点之间绘制箭头
xy = (0.3, 0.2)
con = ConnectionPatch(
xyA=xy, coordsA=ax2.transData,
xyB=xy, coordsB=ax1.transData,
arrowstyle="->", shrinkB=5)
ax2.add_artist(con)
# 在不同坐标系中定义的不同点之间画一条线。
con = ConnectionPatch(
# 在 axes 坐标
xyA=(0.6, 1.0), coordsA=ax2.transAxes,
# X表示axes坐标,y表示数据坐标
xyB=(0.0, 0.2), coordsB=ax2.get_yaxis_transform(),
arrowstyle="-")
ax2.add_artist(con)
ax1.set_xlim(0, 1)
ax1.set_ylim(0, 1)
ax2.set_xlim(0, .5)
ax2.set_ylim(0, .5)
plt.show()
效果:
虽然 ConnectionPatch 实例可以添加到任何axes, 但最好将其添加到最新的轴,以防止与其他轴重叠。
3、高级应用
1、轴之间的缩放效果
mpl_toolkits.axes_grid1.inset_locator 定义了一些用于互连两个axes的 patch类。
破解代码需要一些关于mpl转换如何工作的知识。但是,利用它是直接的。
from matplotlib.transforms import (
Bbox, TransformedBbox, blended_transform_factory)
from mpl_toolkits.axes_grid1.inset_locator import (
BboxPatch, BboxConnector, BboxConnectorPatch)
def connect_bbox(bbox1, bbox2,
loc1a, loc2a, loc1b, loc2b,
prop_lines, prop_patches=None):
if prop_patches is None:
prop_patches = {
**prop_lines,
"alpha": prop_lines.get("alpha", 1) * 0.2,
}
c1 = BboxConnector(bbox1, bbox2, loc1=loc1a, loc2=loc2a, **prop_lines)
c1.set_clip_on(False)
c2 = BboxConnector(bbox1, bbox2, loc1=loc1b, loc2=loc2b, **prop_lines)
c2.set_clip_on(False)
bbox_patch1 = BboxPatch(bbox1, **prop_patches)
bbox_patch2 = BboxPatch(bbox2, **prop_patches)
p = BboxConnectorPatch(bbox1, bbox2,
# loc1a=3, loc2a=2, loc1b=4, loc2b=1,
loc1a=loc1a, loc2a=loc2a, loc1b=loc1b, loc2b=loc2b,
**prop_patches)
p.set_clip_on(False)
return c1, c2, bbox_patch1, bbox_patch2, p
def zoom_effect01(ax1, ax2, xmin, xmax, **kwargs):
"""
Connect *ax1* and *ax2*. The *xmin*-to-*xmax* range in both axes will
be marked.
Parameters
----------
ax1
The main axes.
ax2
The zoomed axes.
xmin, xmax
The limits of the colored area in both plot axes.
**kwargs
Arguments passed to the patch constructor.
"""
trans1 = blended_transform_factory(ax1.transData, ax1.transAxes)
trans2 = blended_transform_factory(ax2.transData, ax2.transAxes)
bbox = Bbox.from_extents(xmin, 0, xmax, 1)
mybbox1 = TransformedBbox(bbox, trans1)
mybbox2 = TransformedBbox(bbox, trans2)
prop_patches = {**kwargs, "ec": "none", "alpha": 0.2}
c1, c2, bbox_patch1, bbox_patch2, p = connect_bbox(
mybbox1, mybbox2,
loc1a=3, loc2a=2, loc1b=4, loc2b=1,
prop_lines=kwargs, prop_patches=prop_patches)
ax1.add_patch(bbox_patch1)
ax2.add_patch(bbox_patch2)
ax2.add_patch(c1)
ax2.add_patch(c2)
ax2.add_patch(p)
return c1, c2, bbox_patch1, bbox_patch2, p
def zoom_effect02(ax1, ax2, **kwargs):
"""
ax1 : the main axes
ax1 : the zoomed axes
Similar to zoom_effect01. The xmin & xmax will be taken from the
ax1.viewLim.
"""
tt = ax1.transScale + (ax1.transLimits + ax2.transAxes)
trans = blended_transform_factory(ax2.transData, tt)
mybbox1 = ax1.bbox
mybbox2 = TransformedBbox(ax1.viewLim, trans)
prop_patches = {**kwargs, "ec": "none", "alpha": 0.2}
c1, c2, bbox_patch1, bbox_patch2, p = connect_bbox(
mybbox1, mybbox2,
loc1a=3, loc2a=2, loc1b=4, loc2b=1,
prop_lines=kwargs, prop_patches=prop_patches)
ax1.add_patch(bbox_patch1)
ax2.add_patch(bbox_patch2)
ax2.add_patch(c1)
ax2.add_patch(c2)
ax2.add_patch(p)
return c1, c2, bbox_patch1, bbox_patch2, p
import matplotlib.pyplot as plt
plt.figure(figsize=(5, 5))
ax1 = plt.subplot(221)
ax2 = plt.subplot(212)
ax2.set_xlim(0, 1)
ax2.set_xlim(0, 5)
zoom_effect01(ax1, ax2, 0.2, 0.8)
ax1 = plt.subplot(222)
ax1.set_xlim(2, 3)
ax2.set_xlim(0, 5)
zoom_effect02(ax1, ax2)
plt.show()
效果:
2、自定义 BoxStyle
示例:
from matplotlib.path import Path
import matplotlib.pyplot as plt
def custom_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
"""
给定box的位置和大小,返回box周围的路径。
- *x0*, *y0*, *width*, *height* : box的位置和大小
- *mutation_size* : 转变的的参考尺度
- *aspect_ratio* : 转变的纵横比
"""
# 注意,我们忽略了mutation_aspect。一般来说,这是可以的
# 填充距
mypad = 0.3
pad = mutation_size * mypad
# 给宽度和高度加上填充距
width = width + 2 * pad
height = height + 2 * pad
# 填充框的边界
x0, y0 = x0 - pad, y0 - pad
x1, y1 = x0 + width, y0 + height
cp = [(x0, y0),
(x1, y0), (x1, y1), (x0, y1),
(x0-pad, (y0+y1)/2.), (x0, y0),
(x0, y0)]
com = [Path.MOVETO,
Path.LINETO, Path.LINETO, Path.LINETO,
Path.LINETO, Path.LINETO,
Path.CLOSEPOLY]
path = Path(cp, com)
return path
fig, ax = plt.subplots(figsize=(3, 3))
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center",
bbox=dict(boxstyle=custom_box_style, alpha=0.2))
plt.show()
效果:
04
数学表达式
你可以在任何 matplotlib 文本字符串中使用子集 TeX 标记,方法是将其放在一对美元符号 ($) 中。
注意,不需要额外安装TeX,因为Matplotlib自带了TeX表达式解析器、布局引擎和字体。
数学表达式:在引号前加一个 'r',引号里是用美元符号 ($) 括起来的数学文本。
常规文本和数学文本可以在同一个字符串中交叉。
数学文本可以使用 DejaVu Sans(默认)、DejaVu Serif、Computer Modern 字体、STIX 字体或你自己提供的 Unicode 字体。
也可以使用自定义变量 mathtext.fontset 选择 mathtext 字体。
一个简单的例子:
# 纯文本
plt.title('alpha > beta') # >>> "alpha > beta"
# 数学文本
plt.title(r'$\alpha > \beta$') # >>> "α>β"
1、下标和上标
要制作下标和上标,请使用 '_' 和 '^' 符号:
r'$\alpha_i > \beta_i$'
结果:
要正确显示多字母下标或上标,应将它们放在花括号 {...} 中:
r'$\alpha^{ic} > \beta_{ic}$'
结果:
一些符号会自动将它们的下标/上标放在运算符的下方和上方。
例如要写入x_i 从 0 到 ∞ 的总和,你可以这样做:
r'$\sum_{i=0}^\infty x_i$'
结果:
2、分数、二项式和堆积数
分数、二项式和堆积数可以分别用 \frac{}{}、\binom{}{} 和 \stackrel{}{}{}{}{}{} 命令创建:
r'$\frac{3}{4} \binom{3}{4} \stackrel{}{}{0}{}{3}{4}$'
结果:
分数可以任意嵌套:
r'$\frac{5 - \frac{1}{x}}{4}$'
结果:
需要特别注意在分数周围放置的括号,这样产生的括号太小:
r'$(\frac{5 - \frac{1}{x}}{4})$'
解决方案是在括号前面加上 \left 和 \right 以通知解析器这些括号包含整个对象:
r'$\left(\frac{5 - \frac{1}{x}}{4}\right)$'
3、根号
根号可以用 \sqrt[]{} 命令产生。例如:
r'$\sqrt{2}$'
结果:
可以在方括号内提供开放数(可选地)。注意开放数必须是一个简单的表达式,不能包含像分数或下标/上标这样的布局命令:
r'$\sqrt[3]{x}$'
结果:
4、字体
数学符号的默认字体是斜体。注意:可以使用 mathtext.default参数更改此默认值。
要更改字体,例如,用罗马字体写“sin”,请将文本包含在字体命令中:
r'$s(t) = \mathcal{A}\mathrm{sin}(2 \omega t)$'
结果:
更方便的是,很多常用的以罗马字体排版的函数名都有快捷键。
所以上面的表达式可以写成:
rr'$s(t) = \mathcal{A}\sin(2 \omega t)$'
结果:
这里“s”和“t”是斜体(默认),“sin”是罗马字体,幅度“A”是书法字体。
请注意,在上面的示例中,书法 A 被挤进了sin中。
你可以使用间距命令在它们之间添加一点空格:
r'$s(t) = \mathcal{A}\space\sin(2 \omega t)$'
结果:
所有字体的可用选项包括:
使用 STIX 字体时,可以选择:
还有三个全局“字体集”可供选择,它们是使用 matplotlibrc 中的 mathtext.fontset 参数选择的。
1)cm:Computer Modern (TeX)
2)stix: STIX
3)stixsans: STIX无衬线字体
此外,你还可以使用 \mathdefault{...} 或其别名 \mathregular{...} 来使用用于 mathtext 之外的常规文本的字体。
但这种方法有许多限制,最明显的是可用的符号要少得多,但这能使数学表达式与图中的其他文本很好地融合。
1)自定义字体
mathtext 还提供了一种使用自定义字体进行数学运算的方法。
这种方法使用起来相当棘手,是个仅供用户使用的实验性功能。
具体方法是将参数 mathtext.fontset 设置为自定义,你可以设置以下参数(这些参数控制用于特定数学字符集的字体文件):
每个参数都应该设置为一个 fontconfig 字体描述符。
使用的字体应具有 Unicode 映射,以便找到任何非拉丁字符,如希腊语。
如果要使用自定义字体中不包含的数学符号,可以将 参数mathtext.fallback_to_cm 设置为 True。
但是这将导致 mathtext 系统在自定义字体中找不到特定字符时使用默认Computer Modern字体中的字符。
请注意,在Unicode中指定的数学符号随着时间的推移而演变,许多字体可能没有将符号放在数学文本的正确位置。
5、重音
重音命令可以在任何符号之前添加重音,重音有长重音、短重音。
此外,还有两种特殊的重音,可以自动调整符号的宽度:
在小写 i 和 j 上添加重音时应小心。注意, \imath 是用于去掉 i 上的点:
r"$\hat i\ \ \hat \imath$"
结果:
6、符号
你可以使用大量的 TeX 符号,如 \infty、\leftarrow、\sum、\int。
1、小写希腊语
2、大写希腊语
3、希伯来语
4、分隔符
5、加大符号
6、标准函数名称
7、二元运算和关系符号
8、箭头符号
9、其它符号
如果某个特定符号没有名称,可以使用Unicode字符:
r'$\u23ce$'
7、示例
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)
plt.plot(t, s)
plt.title(r'$\alpha_i > \beta_i$', fontsize=20)
plt.text(1, -0.6, r'$\sum_{i=0}^\infty x_i$', fontsize=20)
plt.text(0.6, 0.6, r'$\mathcal{A}\mathrm{sin}(2 \omega t)$',
fontsize=20)
plt.xlabel('time (s)')
plt.ylabel('volts (mV)')
plt.show()
效果:
好啦,今天的内容就到这~
END
您的“点赞”、“在看”和 “分享”是我们产出的动力。