Python Matplotlib库 中文手册(自用版)白嫖党专供

新手教程

基本组成&简单的例子

  • 画布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.arraynumpy.ma.masked_array,或者是能够被传递给numpy.asarray()的对象进行输入。Pandas数据和numpy.matrix不能直接作为输入对象。需要转化为numpy.array对象,例如:

b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)

大多数函数需要解析一个“字符串索引”的对象,例如:字典dictstructured 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')

代码风格

两种代码风格:

  • 显式的创建Figureaxes,并通过函数来在上面绘制图形 (the “object-oriented (OO) style”)
  • 通过pyplot隐式的创建和管理Figureaxes,并通过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_xlabelset_ylabelset_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')

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

图例

通常通过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)
刻度

每一个标尺,都有一个刻度定位locator和生成器Formatter。不同的刻度有不同的定位器Tick locator和生成器Tick formatter。可以参看 Tick locatorsTick 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参数而不是vminvmax参数来实现。


颜色条

颜色条colorbar可以通过颜色的指示给予一定的参考,更多可参见Placing colorbars


多图多标尺构建

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

数据点风格
characterdescription
'.'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
线条风格
characterdescription
'-'solid line style
'--'dashed line style
'-.'dash-dot line style
':'dotted line style
颜色
charactercolor
'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. Passing None 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()
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值