新手教程
基本组成&简单的例子
- 画布
Figure
:整个图的背景Figure
用于保存所有画在上面的axes
,后者是各种Artise
类的几何体,包括标题title
,图例Legend
,坐标axis
等
- 图表
axes
:即图中的ax
axes
包含了构成图表的各种元素,是各种元素的集合。
- 边框
Spine
:整个图像的边框及坐标轴(不同于axis
)
# 创建一个Figure和一个axes
# 注意plt.subplot()和plt.subplots()的区别,前者只返回单个axes,后者同时会返回axes 或者其序列,以及Figure
fig, ax = plt.subplots()
# ax上添加数据
ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plot some data on the axes.
# 展示图表
plt.show()
通过函数绘图
通过函数绘图推荐使用numpy.array
,numpy.ma.masked_array
,或者是能够被传递给numpy.asarray()
的对象进行输入。Pandas
数据和numpy.matrix
不能直接作为输入对象。需要转化为numpy.array
对象,例如:
b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)
大多数函数需要解析一个“字符串索引”的对象,例如:字典dict
,structured numpy array或者是pandas.DataFrame
.在Matplotlib中,你可以传递关键词参数data
,以及相关的“字符串索引”对应xy变量来绘制图像。
np.random.seed(19680801) # seed the random number generator.
data = {'a': np.arange(50),
'c': np.random.randint(0, 50, 50),
'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.scatter('a', 'b', c='c', s='d', data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b')
代码风格
两种代码风格:
- 显式的创建
Figure
和axes
,并通过函数来在上面绘制图形 (the “object-oriented (OO) style”) - 通过
pyplot
隐式的创建和管理Figure
和axes
,并通过pyplot
函数在上面绘图
# 显式风格
x = np.linspace(0, 2, 100) # Sample data.
# Note that even in the OO-style, we use `.pyplot.figure` to create the Figure.
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear') # Plot some data on the axes.
ax.plot(x, x**2, label='quadratic') # Plot more data on the axes...
ax.plot(x, x**3, label='cubic') # ... and some more.
ax.set_xlabel('x label') # Add an x-label to the axes.
ax.set_ylabel('y label') # Add a y-label to the axes.
ax.set_title("Simple Plot") # Add a title to the axes.
ax.legend() # Add a legend.
# 隐式风格
x = np.linspace(0, 2, 100) # Sample data.
plt.figure(figsize=(5, 2.7), layout='constrained')
plt.plot(x, x, label='linear') # Plot some data on the (implicit) axes.
plt.plot(x, x**2, label='quadratic') # etc.
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
创建“便捷”函数
如果你要用不同的数据反复绘制相同的图表,或者想要打包Matplotlib中的函数,推荐用以下的方法:
def my_plotter(ax, data1, data2, param_dict):
"""
A helper function to make a graph.
"""
out = ax.plot(data1, data2, **param_dict)
return out
这样你就可以利用他们创造多个子图:
data1, data2, data3, data4 = np.random.randn(4, 100) # make 4 random data sets
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.7))
my_plotter(ax1, data1, data2, {'marker': 'x'})
my_plotter(ax2, data3, data4, {'marker': 'o'})
作图风格
风格
可以通过plot方法选择风格,也可以通过“setter”函数来修改参数风格,例如下面的例子中修改linestyle
fig, ax = plt.subplots(figsize=(5, 2.7))
x = np.arange(len(data1))
# 通过plot函数选择风格
ax.plot(x, np.cumsum(data1), color='blue', linewidth=3, linestyle='--')
# 通过“setter”函数修改风格
l, = ax.plot(x, np.cumsum(data2), color='orange', linewidth=2)
l.set_linestyle(':')
颜色
Matplotlib中有丰富的颜色表达式,可以参看allowable color definitions中的列表。有些对象,可能会有多个颜色参数,例如散点图,数据点的边缘颜色和内部颜色可以是不一样的
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='C0', edgecolor='k')
线条宽度、线条风格以及数据点大小
- 线条风格可以在手册中参见Linestyle exmple
- 散点图的数据点大小取决于所调用的函数,
plot
产生的数据点大小,与图像大小有比例关系。数据点风格有很多种可供选择,可以参看markers。当然也可以自定义数据点图标,可以参看Marker reference
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(data1, 'o', label='data1')
ax.plot(data2, 'd', label='data2')
ax.plot(data3, 'v', label='data3')
ax.plot(data4, 's', label='data4')
ax.legend()
标识绘制
标签和文本
- 通过
set_xlabel
,set_ylabel
,set_title
来设置指定地点的文本。更多可以参考Text in Matplotlib - 文本也可以通过
text
的直接添加
mu, sigma = 115, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
# the histogram of the data
n, bins, patches = ax.hist(x, 50, density=True, facecolor='C0', alpha=0.75)
ax.set_xlabel('Length [cm]')
ax.set_ylabel('Probability')
ax.set_title('Aardvark lengths\n (not really)')
ax.text(75, .025, r'$\mu=115,\ \sigma=15$')
ax.axis([55, 175, 0, 0.03])
ax.grid(True)
- 所有的文本
text
都会返回一个实例matplotlib.text.Text
。你可以通过传递关键字参数来初始化他们。更多的关于文本的设置可以参考Text properties and layout
t = ax.set_xlabel('my data', fontsize=14, color='red')
数学表达式
- Matplotlib 接受
TeX
表达式,例如 σ i = 15 \sigma _i=15 σi=15,通过Tex
表达式如下:
ax.set_title(r'$\sigma_1=15')
- Matplotlib有一套内置的
TeX
表达式解析器,提供一套自己的数学字体,更多参考Writing mathematical expression - 你也可以直接使用
LaTeX
,更多可以参考Text rendering with LaTeX
标注(Annotation)
你可以在图上的一个点进行标注,通常是从xytext
标注文本text
并引出一个箭头指向xy
:
fig, ax = plt.subplots(figsize=(5, 2.7))
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)
- 在本例中,
xy
和xytext
都在固定的数据点上。更多的坐标定位方式可以参考 Basic annotation 和 Advanced annotation,或者也可以参看Annotating Plots
图例
通常通过Axes.legend
来定义图例
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(np.arange(len(data1)), data1, label='data1')
ax.plot(np.arange(len(data2)), data2, label='data2')
ax.plot(np.arange(len(data3)), data3, 'd', label='data3')
ax.legend()
图例的布局、位置以及他们的风格设置可以参看 Legend guide
标尺及刻度
标尺
除了线性标尺,Matplotlib也提供非线性标尺,例如对数标尺。更多可以参考Scales。
fig, axs = plt.subplots(1, 2, figsize=(5, 2.7), layout='constrained')
xdata = np.arange(len(data1)) # make an ordinal for this
data = 10**data1
axs[0].plot(xdata, data)
axs[1].set_yscale('log')
axs[1].plot(xdata, data)
- 标尺一般是,数据到坐标轴距离的映射。更多的标尺映射方式可以参考Transformations Tutorial
刻度
每一个标尺,都有一个刻度定位locator
和生成器Formatter
。不同的刻度有不同的定位器Tick locator
和生成器Tick formatter
。可以参看 Tick locators 和 Tick formatters
fig, axs = plt.subplots(2, 1, layout='constrained')
axs[0].plot(xdata, data1)
axs[0].set_title('Automatic ticks')
axs[1].plot(xdata, data1)
axs[1].set_xticks(np.arange(0, 100, 30), ['zero', '30', 'sixty', '90'])
axs[1].set_yticks([-1.5, 0, 1.5]) # note that we don't need to specify labels
axs[1].set_title('Manual ticks')
绘制日期和曲线
Matplotlib可以处理日期以及各种数据的曲线,可以参看Date tick labels
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
dates = np.arange(np.datetime64('2021-11-15'), np.datetime64('2021-12-25'),
np.timedelta64(1, 'h'))
data = np.cumsum(np.random.randn(len(dates)))
ax.plot(dates, data)
cdf = mpl.dates.ConciseDateFormatter(ax.xaxis.get_major_locator())
ax.xaxis.set_major_formatter(cdf)
同时,Matplotlib还可以绘制分类图,可以参看Plotting categorical variables
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
categories = ['turnips', 'rutabaga', 'cucumber', 'pumpkins']
ax.bar(categories, np.random.rand(len(categories)))
增加标尺对象
- 可以通过调用
twinx
引入一个新的Axes
包含一个阴性的x标尺和可见的y标尺在右侧(twiny
同理)。更多可参看 Plots with different scales - 同样的你可以通过增加一个
secondary_xaxis
或者secondary_yaxis
来增加一个新标尺。可以参看Secondary Axis
fig, (ax1, ax3) = plt.subplots(1, 2, figsize=(7, 2.7), layout='constrained')
l1, = ax1.plot(t, s)
ax2 = ax1.twinx()
l2, = ax2.plot(t, range(len(t)), 'C1')
ax2.legend([l1, l2], ['Sine (left)', 'Straight (right)'])
ax3.plot(t, s)
ax3.set_xlabel('Angle [rad]')
ax4 = ax3.secondary_xaxis('top', functions=(np.rad2deg, np.deg2rad))
ax4.set_xlabel('Angle [°]')
色谱图
有时候需要通过颜色的变化来引入第三个维度,因此可以使用色谱图。
X, Y = np.meshgrid(np.linspace(-3, 3, 128), np.linspace(-3, 3, 128))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
fig, axs = plt.subplots(2, 2, layout='constrained')
pc = axs[0, 0].pcolormesh(X, Y, Z, vmin=-1, vmax=1, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[0, 0])
axs[0, 0].set_title('pcolormesh()')
co = axs[0, 1].contourf(X, Y, Z, levels=np.linspace(-1.25, 1.25, 11))
fig.colorbar(co, ax=axs[0, 1])
axs[0, 1].set_title('contourf()')
pc = axs[1, 0].imshow(Z**2 * 100, cmap='plasma',
norm=mpl.colors.LogNorm(vmin=0.01, vmax=100))
fig.colorbar(pc, ax=axs[1, 0], extend='both')
axs[1, 0].set_title('imshow() with LogNorm()')
pc = axs[1, 1].scatter(data1, data2, c=data3, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[1, 1], extend='both')
axs[1, 1].set_title('scatter()')
色谱
色谱图对象可以通过ScalarMappable
得到。Matplotlib中有许多色谱可供选择,可以参考Choosing Colormaps in Matplotlib。也可以自自定义色谱,参见Creating Colormaps in Matplotlib。
标准化
有时候我们想将非线性数据引入到色谱图中。我们可以通过采用ScalarMappalbe
中的norm
参数而不是vmin
和vmax
参数来实现。
颜色条
颜色条colorbar
可以通过颜色的指示给予一定的参考,更多可参见Placing colorbars
多图多标尺构建
- 我们可以通过调用
fig = plt.figure()
和fig2,ax = plt.subplots()
来实现多图拼接。 - 多标尺的创建有很多种方式,催常见的方式是使用
plt.subplots()
,如下面的例子所示。同时我们可以通过使用subplot_mosaic
完成更复杂的布局。 - 更多布局技巧可以参见 Arranging multiple Axes in a Figure 和 Complex and semantic figure composition (subplot_mosaic)
fig, axd = plt.subplot_mosaic([['upleft', 'right'],
['lowleft', 'right']], layout='constrained')
axd['upleft'].set_title('upleft')
axd['lowleft'].set_title('lowleft')
axd['right'].set_title('right')
进阶教程
基础元素
基本参数
pyplot
中默认的配置可以通过rcparams
参数来控制,简称rc
参数。rc
参数储存在字典变量中,通过字典的方式进行访问。- 基本格式如下:
plt.rcParams['font.family'] = 'YaHei Consolas Hybrid' # 设置字体样式
plt.rcParams['font.size'] = '16' # 设置字体大小 = '16' # 设置字体大小
plt.rcParams['figure.figsize'] = (5.0, 4.0) # 显示图像的最大范围
plt.rcParams['image.interpolation'] = 'nearest' # 差值方式,设置 interpolation style
plt.rcParams['image.cmap'] = 'gray' # 灰度空间
- rc参数的常用基本种类
- animation开头:
- font开头:字体设置
- axes开头:内框画布
- figure开头:外框画布
- boxplot开头:箱线图
- grid开头:网格标签
- image开头:图片设置
- keymap开头:快捷键设置
- legend开头:图例设置
- lines开头:线条设置
- mathtext开头:数学公式字体相关
- xtick开头:x轴标签
- ytick开头:y轴标签
- rc参数常用事例
- 字体字符
- plt.rcParams[’axes.unicode_minus’] = False 字符显示
- plt.rcParams[’font.sans-serif’] = ‘SimHei’ 设置字体
- plt.rcParams[‘font.family’] = ‘TeX Gyre Schola’
- 线条样式:lines
- plt.rcParams[’lines.linestyle’] = ‘-.’ 线条样式
- plt.rcParams[’lines.linewidth’] = 3 线条宽度
- plt.rcParams[’lines.color’] = ‘blue’ 线条颜色
- plt.rcParams[’lines.marker’] = None 默认标记
- plt.rcParams[’lines.markersize’] = 6 标记大小
- plt.rcParams[’lines.markeredgewidth’] = 0.5 标记附近的线宽
- 横、纵轴:xtick、ytick
- plt.rcParams[’xtick.labelsize’] 横轴字体大小
- plt.rcParams[’ytick.labelsize’] 纵轴字体大小
- plt.rcParams[’xtick.major.size’] x轴最大刻度
- plt.rcParams[’ytick.major.size’] y轴最大刻度
- plt.rcParams[‘tick.labelweight’] xy轴字体粗细
- plt.rcParams[‘tick.labelsize’] = 10 xy轴字体大小
- plt.rcParams[‘xtick.direction’] = ‘in’ 刻度朝里
- figure中的子图:axes
- plt.rcParams[’axes.titlesize’] 子图的标题大小
- plt.rcParams[’axes.labelsize’] 子图的标签大小
- plt.rcParams[‘axes.labelweiht’] 轴刻度标签的字体粗细
- 图像、图片:figure、savefig
- plt.rcParams[’figure.dpi’] 图像分辨率
- plt.rcParams[’figure.figsize’] 图像显示大小
- plt.rcParams[’savefig.dpi’] 图片像素
- 字体字符
风格
常用字体
- Times New Roman
- 黑体:SimHei
- 微软雅黑:Microsoft YaHei
- 微软正黑体:Microsoft JhengHei
- 新宋体:NSimSun
- 新细明体:PMingLiU
- 细明体:MingLiU
- 华文新魏:STXinwei
- 华文行楷:STXingkai
- 华文隶书:STLliti
- 花纹琥珀:STHupo
- 华文彩云:STCaiyun
- 方正姚体:FZYaoti
- 方正舒体:FZShuTi
- 标楷体:DFKai-SB
- 华文仿宋:STFangsong
- 华文中宋:STZhongsong
- 华文宋体:STSong
- 华文楷体:STKaiti
- 华文细黑:STXihei
- 幼圆:YouYuan
- 隶书:LiSu
- 楷体_GB 2313:Kaiti_GB2313
- 仿宋_GB2313:FangSong_GB2313
- 仿宋:FangSong
数据点风格
character | description |
---|---|
'.' | point marker |
',' | pixel marker |
'o' | circle marker |
'v' | triangle_down marker |
'^' | triangle_up marker |
'<' | triangle_left marker |
'>' | triangle_right marker |
'1' | tri_down marker |
'2' | tri_up marker |
'3' | tri_left marker |
'4' | tri_right marker |
'8' | octagon marker |
's' | square marker |
'p' | pentagon marker |
'P' | plus (filled) marker |
'*' | star marker |
'h' | hexagon1 marker |
'H' | hexagon2 marker |
'+' | plus marker |
'x' | x marker |
'X' | x (filled) marker |
'D' | diamond marker |
'd' | thin_diamond marker |
'|' | vline marker |
'_' | hline marker |
线条风格
character | description |
---|---|
'-' | solid line style |
'--' | dashed line style |
'-.' | dash-dot line style |
':' | dotted line style |
颜色
character | color |
---|---|
'b' | blue |
'g' | green |
'r' | red |
'c' | cyan |
'm' | magenta |
'y' | yellow |
'k' | black |
'w' | white |
Format Strings
fmt = '[marker][line][color]'
# 如果没有给予特定的格式字符,则会设为默认
# 示例
# 分别依次绘制3个数据点(1,2), (2,2), (3,3),风格为绿色,圆形数据点,实线连接,记为"line 1", 线条宽度为2
plot([1, 2, 3], [1, 2, 3], 'go-', label='line 1', linewidth=2)
# 分别依次绘制3个数据点(1,1), (2,4), (3,0),风格为红色,方形数据点,记为“line 2”
plot([1, 2, 3], [1, 4, 9], 'rs', label='line 2')
标题设置
Axe.set_title(self, label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)
pad
/rc:axes.titlepad
标签距离图像上方的像素点距离fontdict
字典传参数
{'fontsize': rcParams['axes.titlesize'],
'fontweight' : rcParams['axes.titleweight'],
'color' : rcParams['axes.titlecolor'],
'verticalalignment' : 'baseline',
'horizontalalignment': loc}
y
/rc:axes.titley
标题在图上的百分比距离,float,1.0 为顶部loc
/rc:axes.titlelocation
标题的布局位置
边框(spine
)设置
边框的获取
# 通过形如字典的形式,获取边框并修改
ax.spines['top'].set_visible(False)
# 通过访问类的属性,获取边框并修改
ax.spines.top.set_visible(False)
# 通过传递列表,同时获取多个边框并修改,但只能通过set()或者set_*()修改
ax.spines[['top', 'right']].set_visible(False)
# 通过切片的形式,获取所有边框并修改,但只能通过set()或者set_*()修改
ax.spines[:].set_visible(False)
边框的参数设置
# 设置边框的范围,除了该范围内,范围外不再显示边框。注意区别于 plt.ylim 和 plt.xlim
# x/ylim 设置的是图片x,y的显示范围。但set_bounds设置的边框的长度
spines[:].set_bounds(low:float, high:float)
# 设置相关颜色
spines[:].set_color(color)
# 设置线条风格,
spines[:].set_linestyle('--')
# '-'/'solid' 实线
# '--'/'dashed' 虚线
# '-.'/'dashed' 虚线+点
# ':'/'dotted' 点线
# ''/'none' 不划线
# 设置线条宽度
spines[:].set_linewidth(float)
# 设置绘画优先级,数值越小越先画
spines[:].set_zorder(float)
# 设置是否可见
spines[:].set_visible(bool)
# 将边框设置为其他坐标格式
spines[:].set_patch_arc(center, radius, theta1, theta2) # 圆弧边框
spines[:].set_patch_circle(center, radius) # 圆形边框
spines[:].set_patch_line() # 将边框设置为线性
# 边框的位置
spines[:].set_position(position)
# position 为一个元组(position type, amoumt)
# (outward, 10) 边框向外偏离10个点
# (axes, 0.1) 边框向图中心移动10%
# (data, 2) 边框移动到数据点为2的地方
# 'center' -> ('axes', 0.5)
# 'zero' -> ('data', 0.0)
# 可以通过set()来批量设置部分边框参数
spines[:].set(bounds=(0,1), color='blue')
坐标轴(axis
)
注意区别坐标轴(axis
)和边框(spine
)。图像中,显示坐标轴的线其实是图像的边框(spine
),而坐标轴实际只包含坐标轴名称(x/yaxislabel
)和(x/ytick
)
坐标轴的设置
可以通过Axes.axis.set()
以及Axes.axis.set_*()
两种方式进行设置
# 设置 ticklabel, axislabel的排列方向
# axis_direction : {'left', 'bottom', right', 'top'}
Axes.axis[:].set_axis_direction(axis_direciton)
# 设置坐标轴名称的方向
# label_direction : {'+', '-'}
Axes.axis[:].set_axislabel_direction(label_direction)
# 设置坐标轴的样式,默认为无箭头,'->'为空心尽头,‘-|>’为实心箭头
Axes.axis[:].set_axisline_style(axisline_style=None, **kwargs)
# 设置坐标轴名称
Axes.axis[:].set_label(str)
# 设置刻度标签方向,与坐标轴名称方向相同
Axes.axis[:].set_ticklabel_direction()
# 控制坐标轴的显示
Axes.axis.toggle(all=None, ticks=None, ticklabels=None, label=None)
# 例如:不显示所有对象,除了刻度
axis.toggle(all=False, ticks=True)
# 显示所有对象,但不现实坐标轴名称
axis.toggle(all=True, label=False)
坐标轴显示
Axes.set_xlim(x1, x2)
Axes.set(xlim=(x1, x2))
Axes.set_ybound(x1, x2)
Axes.set(ybound=(x1, x2))
# 注意区别xlim和xbound的区别
# xlim 对于参数x1 和x2 的先后顺序有区别。如果x1 > x2,那么x坐标轴方向将翻转
# xbound 对于参数x1 和x2 的先后顺序没有区别,只会默认的轴方向显示固定的范围。
# 坐标轴显示范围的获取
Axes.get_xbound()
# 让所有坐标轴不显示,与spine类似
Axes.axis[:].set_visible(False)
# 让上面的坐标轴不显示,与spine类似
Axes.axis['top'].set_visible(False)
坐标轴标签设置(x/ylabel
)
Axes.set_ylabel(ylabel:str, fontdict=None, labelpad=None, *, loc=None, **kwargs)
-
ylabel
即标签名 -
labelpad
/rc:axes.labelpad
标签和坐标轴之间的距离,类型为float,默认为0 -
loc
/rc:xaxis.labellocation
标签的位置,可选参数有{‘botton’, ‘center’, ‘top’} -
fontdict
以字典的形式传递参数 -
**kwargs
其他参数,基本上是matplotlib.text.Text 中的参数color
fontfamily
fontproperties
horizontalalignment
align
:{'left', 'center', 'right'}
rotation
:float or {'vertical', 'horizontal'}
rotation_mode
{None, 'default', 'anchor'}
If"default"
, the text will be first rotated, then aligned according to their horizontal and vertical alignments. If"anchor"
, then alignment occurs before rotation. PassingNone
will set the rotation mode to"default"
.
linespacing
- Set the line spacing as a multiple of the font size. The default line spacing is 1.2
multialignment
:{'left', 'right', 'center'}
fontname
:{FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'}
fontsize
fontstretch
fontstyle
fontstyle
:{'normal', 'italic', 'oblique'}
fontvariant
:{'normal', 'small-caps'}
verticalalignment
:{'bottom', 'baseline', 'center', 'center_baseline', 'top'}
fontweight
:{a numeric value in range 0-1000, 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black'}
-
例如:
xlabel_font == {
'fontsize': 30
'fontweight': 'light'
'color': 'blue'
}
Axes.set_xlabel('x', fontdict=xlabel_font, labelpad=20, loc='right')
坐标轴箭头
在坐标轴上加箭头
# 方法一:
# 下面两个函数依次绘制了带箭头的x轴和带箭头的y轴
# 通过transform, 将其转化为坐标轴类型,固定了其在图像中x方向和y方向的位置
# 一坐标轴选取位置(百分比选位)的方式,(1,0),(0,1)绘制了两个三角形的数据点
# clip_on = False,让其能够显示在超越显示范围的空白区域
Axes.plot(1, 0, ">k", transform=ax.get_xaxis_transform(), clip_on = False)
Axes.plot(1, 0, "^k", transform=ax.get_yaxis_transform(), clip_on = False)
# 方法二:
Axes.axis[:].set_axisline_style('-|>')
Axes.axis[:].set_axisline_style('->')
# 以上两个例子分别为实心箭头,和空心箭头
多轴设置
- 通过
Axes.twinx()
创造一个孪生的Axes
对象,两个对象共享x轴的一切设置,但具有独立的y轴设置。
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
fig.subplots_adjust(right=0.75)
twin1 = ax.twinx()
twin2 = ax.twinx()
# Offset the right spine of twin2. The ticks and label have already been
# placed on the right by twinx above.
twin2.spines.right.set_position(("axes", 1.2))
p1, = ax.plot([0, 1, 2], [0, 1, 2], "C0", label="Density")
p2, = twin1.plot([0, 1, 2], [0, 3, 2], "C1", label="Temperature")
p3, = twin2.plot([0, 1, 2], [50, 30, 15], "C2", label="Velocity")
ax.set(xlim=(0, 2), ylim=(0, 2), xlabel="Distance", ylabel="Density")
twin1.set(ylim=(0, 4), ylabel="Temperature")
twin2.set(ylim=(1, 65), ylabel="Velocity")
ax.yaxis.label.set_color(p1.get_color())
twin1.yaxis.label.set_color(p2.get_color())
twin2.yaxis.label.set_color(p3.get_color())
ax.tick_params(axis='y', colors=p1.get_color())
twin1.tick_params(axis='y', colors=p2.get_color())
twin2.tick_params(axis='y', colors=p3.get_color())
ax.legend(handles=[p1, p2, p3])
plt.show()
- 除此之外,可以通过
Axes.secondary_xaxis()
来加入全新的坐标
Axes.secondary_xaxis(location, function, transfrom, **kwargs)
# location 为标尺加入的位置,可以为{'left','right','top','bottom'}或者为一个float。
# 这个float 描述的是标尺的百分比位置
# function 需要传递一个包含两个方程的元组(forward,inverse),原xaxis可以通过forward换算为旧xaxis。旧xaxis可以通过inverse换算为forward。即forward与inverse互为逆函数。
# 例:
import datetime
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from matplotlib.ticker import AutoMinorLocator
fig, ax = plt.subplots(layout='constrained')
x = np.arange(0, 360, 1)
y = np.sin(2 * x * np.pi / 180)
ax.plot(x, y)
ax.set_xlabel('angle [degrees]')
ax.set_ylabel('signal')
ax.set_title('Sine wave')
# 角度制转弧度制
def deg2rad(x):
return x * np.pi / 180
# 弧度制转角度制
def rad2deg(x):
return x * 180 / np.pi
# 创造第二坐标轴
secax = ax.secondary_xaxis('top', functions=(deg2rad, rad2deg))
secax.set_xlabel('angle [rad]')
plt.show()
# transform=ax.transData, 用数据点来确定第二坐标轴的位置
# 在y=0处创建一个新的xaxis
secax = ax.secondary_xaxis(0, transform=ax.transData)
- 但需要注意的是,
secondary_axis()
返回的类型为SecondaryAxis
该类型既不是Axis
也不是spine
,所以关于它的设置可能有所不同
SecondaryAxis.set_xlabel() # 设置第二坐标的颜色
SecondaryAxis.set_color() # 设置第二坐标的所有颜色,包括刻度、文字等
SecondaryAxis.set_ticks()
SecondaryAxis.set_aspect()
SecondaryAxis.set_location()
SecondaryAxis.set_aligment()
SecondaryAxis.set_functions() # 如何将第二坐标从父坐标转化而来
- 同时可以通过
Axes.new_floating_axis()
创造一个新的坐标轴
ax.axis["x"] = ax.new_floating_axis(1, 0.5)
ax.axis["x"].set_axisline_style("->", size=1.5)
# 第一个参数,1代表y轴,0代表x轴
# 第二个参数,代表轴的数据点位置
刻度设置(tick
)
刻度参数设置
大部分刻度的设置都可以通过Axes.tick_params()
进行设置
Axes.tick_params(axis='both', which='major', reset=False**kwaryg)
# axis : {'x', 'y', 'both'}
# which : {'major', 'minor', 'both'}, default:'major'
# reset : bool, 在设置刻度参数前,是否将之前的设置恢复为默认
# 其它参数
direction : {'in', 'out', 'inout'} # 刻度朝向
length : float # 刻度长度
width : float # 刻度宽度
color : color # 刻度颜色
pad : float # 刻度和刻度标签之间的像素距离
labelsize : float or str # Ticklabel 的字体大小 “large”等
labelfontfamily : str
colors : color # 刻度和刻度标签的颜色
zorder : float
bottom, top, left, right: bool # 是否显示对应的刻度
labelbottom, labeltop, labelleft, labelright : bool #是否显示对应的刻度标签
labelrotation : float # 刻度标签的旋转角度
grid_color : color # gridline color
grid_alpha : float # 取值范围0-1,gridline的透明度
grid_linewidth : float # gridline 宽度
grid_linestyle : str # gridline 风格
部分设置,可以通过Axes
,Axes.axis
进行设置
# 切换标签朝向
Axes.Axis[:].invert_ticklabel_direction()
全局参数设置刻度位置
# 将默认的左侧y坐标轴设置到右侧
plt.rcParams['ytick.right'] = plt.rcParams['ytick.labelright'] = True
plt.rcParams['ytick.left'] = plt.rcParams['ytick.labelleft'] = False
刻度标签设置
刻度位置设置
- 让刻度以完整的形式显示
plt.rcParams['axes.autolimit_mode'] = 'round_numbers'
- 通过布局,使得刻度标签可以排列在刻度之间
# 去掉小刻度
ax.tick_params(axis='x', which='minor', tick10n=False, tick20n=False)
# 让标签居中摆放在小刻度正下方
for label in ax.get_xticklabels(minor=True):
label.set_horizontalalignment('center)
- 通过
ax.secondary_xaxis()
可以添加多重刻度标签
sec = ax.secondary_xaxis(location=0)
sec.set_xticks([5, 15, 25], labels = ['\nOughts', '\nTeens', '\nTwenties'])
- 通过
matplotlib.ticker.MultipleLocator()
构建主次刻度
# 设置主刻度为20的倍数,次刻度为5的倍数的坐标。主标尺保留小数点后0位
ax.xaxis.set_major_locator(MultipleLocator(20))
ax.xaxis.set_major_locator(MultipleLocator(5))
ax.xaxis.set_major_formatter('{x:.0f}')
Locator()
合集
# 没有刻度
axs.xaxis.set_major_locator(ticker.NullLocator())
# 倍数刻度, 0.5的整数倍,从0.2出发
axs.xaxis.set_major_locator(tick.MultipleLocator(0.5, offset=0.2))
# 固定刻度,主刻度0,1,5,次刻度0.2,0.4,0.6, 0.8
axs[2].xaxis.set_major_locator(ticker.FixedLocator([0, 1, 5]))
axs[2].xaxis.set_minor_locator(ticker.FixedLocator(np.linspace(0.2, 0.8, 4)))
# 线性刻度,坐标轴上线性分布3个主刻度,31个副刻度。(副刻度会被主刻度挡住)。而且刻度不会随图像移动而移动
axs[3].xaxis.set_major_locator(ticker.LinearLocator(3))
axs[3].xaxis.set_minor_locator(ticker.LinearLocator(31))
# 索引刻度,与倍数刻度相同,但只会在图像开始显示范围内标出刻度,其他部分不标出刻度
axs[4].xaxis.set_major_locator(ticker.IndexLocator(base=0.5, offset=0.25))
# 个数限定刻度,在可见范围内,限定一定的标尺数量
axs[6].xaxis.set_major_locator(ticker.MaxNLocator(4))
axs[6].xaxis.set_minor_locator(ticker.MaxNLocator(40))
# 自动刻度
axs[5].xaxis.set_major_locator(ticker.AutoLocator())
axs[5].xaxis.set_minor_locator(ticker.AutoMinorLocator())
# 对数刻度
axs[7].set_xlim(10**3, 10**10)
axs[7].set_xscale('log')
axs[7].xaxis.set_major_locator(ticker.LogLocator(base=10, numticks=15))
刻度格式设置(Tick Formatters
)
# String Formatting 在标签后加上单位km
ax0.xaxis.set_major_formatter('{x} km')
# Function Formatting, 通过函数进行换算得到新的标签
ax1.xaxis.set_major_formatter(lambda x, pos: str(x-5))
# 刻度上没有标签
ticker.NullFormatter()
+-
# 用str.format格式进行设置
ticker.StrMethodFormatter(str.format)
# 例:StrMethodFormatter('{x:.3f}'),小数点后保留3位数
# FuncStrFormatter,类似str.format()函数其中的'%d'将会被替换
axs2[2].xaxis.set_major_formatter(ticker.FormatStrFormatter("#%d"))
# FuncFormatter, 类似str.format()
def fmt_two_digits(x, pos):
return f'[{x:.2f}]'
axs2[3].xaxis.set_major_formatter(ticker.FuncFormatter(fmt_two_digits))
# FixedFormatter,固定格式
ositions = [0, 1, 2, 3, 4, 5]
labels = ['A', 'B', 'C', 'D', 'E', 'F']
axs2[4].xaxis.set_major_locator(ticker.FixedLocator(positions))
axs2[4].xaxis.set_major_formatter(ticker.FixedFormatter(labels))
# ScalarFormatter, 默认formatter
axs2[5].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
# PercentFormatter,百分比格式,将坐标轴划分为5段百分比刻度
axs2[6].xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))
图例(Legend
)
标注(annotaion
)
线标注
通过vline
/hline
增加垂直/水平线段
# 画一条直线画一条直线垂直坐标轴,axes.hline()类似
Axes.vlines(x, ymin, ymax, colors=None, linestyles='solid', label='', *, data=None, **kwargs)
# ymin和ymax为线段两端对应的数据点坐标
# x,ymin和ymax可以为float或array
# 通过增加参数transform=Axes.get_xaxis_transform(),可让线段变为无限长的直线
# 画一条直线垂直坐标轴,axes.axhline()类似
Axes.axvline(x=0, ymin=0, ymax=1, **kwargs)
# ymin和ymax取值范围为0~1.0
箭头标注
文本标注
Axes.text(x, y, s, fontdict=None, **kwargs)
# x,y 为文本框左下角顶点坐标
# s 为文本内容
其他
边缘留白(x/ymargin
)
# 按照百分比,设置数据到坐标轴之间的留白
# 参数m 为大于-0.5 的浮点数
Axes.set_xmargin(m)
# 例如如果x 的数据范围是[0,2], 若设置Axes.set_xmargin(0.1),则坐标轴显示范围为[-0.2, 2.2]
坐标轴翻转
坐标轴翻转可以通过x/ylim()
或者axis.invert_x/yaxis()
来实现
# 方法一:将范围从大到小设置,就翻转了
ax2.set_ylim(100,0)
ax2.set(ylim=(100,0))
# 方法二:
ax2.invert_yaxis()