续前文:
保姆级matplotlib教程:详细目录
保姆级seaborn教程:详细目录
seaborn和matplotlib怎么选,还是两个都要学?
详解Python matplotlib深度美化(第一期)
详解Python matplotlib深度美化(第二期)
详解matplotlib隐式pyplot法和显式axes法
Python matplotlib的上限:可“追星”,可“逐浪”!
Python“万水千山图”—山峦图/嵴线图/峰峦图
6.3.1 坐标轴系统简介
坐标系统主要有以下几种分类:
- 笛卡尔坐标系 (Cartesian Coordinate System):使用直角坐标轴,常见于平面图表。
- 极坐标系 (Polar Coordinate System):基于角度和半径,适用于表示旋转和周期性数据。
- 三维坐标系 (Three-Dimensional Coordinate System):在三维空间中使用三个坐标轴(X、Y、Z),用于展示三维数据。
- 地理坐标系 (Geographic Coordinate System):使用经纬度表示地理位置,常用于地图。
- 对数坐标系 (Logarithmic Coordinate System):Y轴或X轴使用对数尺度,适合表示变化幅度大的数据。
这些系统帮助以不同方式可视化和分析数据,主要通过projection参数设置,各自举个例子,
#6.3.1_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.1 坐标轴系统简介
'''import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as npfig = plt.figure(figsize=(12, 10), dpi=150, frameon=True, edgecolor='grey')
fig.patch.set_linewidth(1)# 笛卡尔坐标系
ax1 = fig.add_subplot(231) #默认使用笛卡尔坐标系,即直角坐标系
x = np.linspace(0, 10, 100)
y = np.sin(x)
ax1.plot(x, y)
ax1.set_title('笛卡尔坐标系')
ax1.set_xlabel('X轴')
ax1.set_ylabel('Y轴')# 极坐标系
ax2 = fig.add_subplot(232,projection='polar' # 设置极坐标系
)
theta = np.linspace(0, 2 * np.pi, 100)
r = 1 + 0.5 * np.sin(5 * theta)
ax2.plot(theta, r)
ax2.set_title('极坐标系')# 三维坐标系
ax3 = fig.add_subplot(233,projection='3d' #设置三维坐标系
)
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)
ax3.scatter(x, y, z)
ax3.set_title('三维坐标系')
ax3.set_xlabel('X轴')
ax3.set_ylabel('Y轴')
ax3.set_zlabel('Z轴')# 地理坐标系:绘制世界地图
ax4 = fig.add_subplot(234)
m = Basemap(projection='ortho', #设置地图坐标系lat_0=0,lon_0=0,ax=ax4)
m.drawcoastlines()
m.drawcountries()
m.drawmapboundary(fill_color='lightblue')
m.fillcontinents(color='lightgreen', lake_color='lightblue')
ax4.set_title('地理坐标系')# 对数坐标系
ax5 = fig.add_subplot(235)
x = np.linspace(1, 10, 100)
y = np.log(x)
ax5.plot(x, y)
ax5.set_title('对数坐标系')
ax5.set_xlabel('X轴')
ax5.set_ylabel('log(Y轴)')
ax5.set_yscale('log') # 设置Y轴为对数尺度ax6 = fig.add_subplot(236)
ax6.axis('off')plt.tight_layout()
plt.show()
当前教程重点关注笛卡尔坐标系 (Cartesian Coordinate System),也就是直角坐标系统。
6.3.2 坐标轴边界(Spines)
在 Matplotlib 中,spines是围绕Axes边界的四条线(上下左右),它们定义了数据绘图区域的边框。Spines 可以用来设置图形的外框线,帮助强调不同的坐标轴。你可以根据需要自定义这些边框,比如隐藏某些边框、调整它们的位置、更改颜色和线宽等,例如,
#6.3.2_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.2 坐标轴边界(Spines)
'''import matplotlib.pyplot as pltfig = plt.figure(figsize=(12, 10), dpi=150, frameon=True, edgecolor='grey')
fig.patch.set_linewidth(1)
axs = fig.subplots(2, 2)# 第一个子图:什么是spines?
axs[0, 0].plot([1, 2, 3, 4], [1, 4, 9, 16])
axs[0, 0].set_title("什么是spines?")axs[0, 0].annotate('左侧spine', xy=(1, 8), xytext=(1.5, 9),arrowprops=dict(facecolor='black', shrink=0.05),fontsize=10, color='black', ha='center', va='center')
axs[0, 0].annotate('右侧spine', xy=(4.1, 8), xytext=(3.5, 9),arrowprops=dict(facecolor='black', shrink=0.05),fontsize=10, color='black', ha='center', va='center')
axs[0, 0].annotate('顶部spine', xy=(2, 16), xytext=(2, 14),arrowprops=dict(facecolor='black', shrink=0.05),fontsize=10, color='black', ha='center', va='center')
axs[0, 0].annotate('底部spine', xy=(2, 0.5), xytext=(2, 2.5),arrowprops=dict(facecolor='black', shrink=0.05),fontsize=10, color='black', ha='center', va='center')# 第二个子图:隐藏顶部和右侧的spines
axs[0, 1].plot([1, 2, 3, 4], [1, 4, 9, 16])
axs[0, 1].spines['top'].set_visible(False) #隐藏顶部的spines
axs[0, 1].spines['right'].set_visible(False) #隐藏右侧的spines
axs[0, 1].set_title("隐藏顶部和右侧的spines")# 第三个子图:移动spines的位置
axs[1, 0].plot([-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2])
axs[1, 0].spines['left'].set_position(('data', 0))
axs[1, 0].spines['bottom'].set_position(('data', 0))
axs[1, 0].set_title("移动spines的位置")# 第四个子图:更改spines的颜色和线宽
axs[1, 1].plot([1, 2, 3, 4], [1, 4, 9, 16])
axs[1, 1].set_title("更改spines的颜色和线宽")# 更改spines的颜色和线宽
axs[1, 1].spines['left'].set_color('red') #更改spines左侧的颜色
axs[1, 1].spines['left'].set_linewidth(2) #更改spines左侧的线宽
axs[1, 1].spines['bottom'].set_color('blue') #更改spines右侧的颜色
axs[1, 1].spines['bottom'].set_linewidth(2) #更改spines右侧的线宽plt.tight_layout()
plt.show()
以上四个子图展示了spines常见的作用。
6.3.3 坐标轴比例(Axis Scales)
坐标轴比例(Axis Scales)的作用是控制数据在坐标轴上的展示方式。通过选择不同的比例,可以改变数据在图中的分布方式,从而更清晰地呈现出数据的特征。比如,使用线性比例会让数据均匀分布,而对数比例则适合处理跨度较大的数据,突出细节变化。不同的比例能帮助更好地分析和解释数据。
matplotlib主要支持以下各类坐标轴比例:
- asinh(双曲正弦反函数比例),类似于对数比例,但能够处理正负数据,且对小数值更敏感。适用于范围较广的数据,尤其是正负值共存的情况。
- function(自定义函数比例),可以让用户自定义数据的缩放方式,通过提供前向和逆向函数来自定义映射。适合需要特殊转换的场景。
- functionlog(自定义对数比例),通过自定义的对数和逆对数函数来缩放数据,适用于需要灵活控制对数变换的情况,比如处理非常小的正数。
- linear(线性比例,默认),数据按照线性方式映射到坐标轴,适合数据值变化平稳、没有极端增长或减少的情况。
- log(对数比例),数据按对数方式缩放,适用于数据跨越多个数量级的场景,特别是指数增长的数据。
- logit(逻辑比例),常用于显示概率或分类数据,在 [0, 1] 区间内以逻辑函数缩放。适合处理百分比或概率数据的场景。
- symlog(对称对数比例),能够同时处理正值和负值的对数缩放,适合跨越正负区间的数据。
一个例子比较各类坐标轴比例的差异,
#6.3.3_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.3 坐标轴比例(Axis Scales)
'''titles = ['asinh: 双曲正弦反函数比例', 'function: 自定义函数比例', 'functionlog: 自定义对数比例','linear: 线性比例', 'log: 对数比例', 'logit: 逻辑比例', 'symlog: 对称对数比例'
]fig = plt.figure(figsize=(12, 10), dpi=150, frameon=True, edgecolor='grey')
fig.patch.set_linewidth(1)axs = fig.subplots(2, 4)
axs = axs.flatten()
x = np.linspace(0, 10, 500)
y = np.arcsinh(x)# Function Mercator transform
def forward(a):a = np.deg2rad(a)return np.rad2deg(np.log(np.abs(np.tan(a) + 1.0 / np.cos(a))))def inverse(a):a = np.deg2rad(a)return np.rad2deg(np.arctan(np.sinh(a)))# 依次应用标题及不同的坐标轴比例
for ax, title in zip(axs, titles):ax.plot(x, y)ax.set_title(title)ax.grid(True)if 'asinh' in title:ax.set_yscale('asinh')elif 'function: 自定义函数比例' in title:ax.set_yscale('function', functions=(forward, inverse))elif 'functionlog' in title:ax.set_yscale('function', functions=(np.log1p, np.expm1))else:scale_type = title.split(':')[0]ax.set_yscale(scale_type)# 删除多余的子图
fig.delaxes(axs[-1])
plt.tight_layout()plt.show()
注意观察以上Y轴的刻度变化,matplotlib主要通过set_yscale设置y轴的坐标轴比例,通过set_xscale设置x轴的坐标轴比例。
6.3.4 坐标轴刻度、刻度标签(Ticks、Tick labels)
每个坐标轴(Axis)上的 x 轴和 y 轴都有默认的刻度(Ticks)和刻度标签(Tick labels),刻度分为主刻度(major ticks)和次刻度(minor ticks),相应地,刻度标签也分为主刻度标签和次刻度标签。刻度用于标示坐标轴上的数据范围和间隔,而刻度标签则为这些刻度提供相应的文字或数值说明。
例如,上文章节“5.2.7 坐标轴刻度间隔、格式、大小、颜色等修改”的下图,以X轴为例子,主刻度、主刻度标签、副刻度、副刻度标签一目了然,
matplotlib可以通过set_xticks和set_yticks来设置刻度和刻度标签,也可以在坐标轴上高度自定义,本节详细介绍。
6.3.4.1 默认主坐标轴刻度、标签
Matplotlib默认的主坐标轴刻度和标签能满足绝大部分需求,一般无需设置,例如,
#6.3.4.1_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.1 默认主坐标轴刻度、标签
'''import matplotlib.pyplot as plt
import numpy as npx1 = np.linspace(0, 10, 100)
y1 = np.sin(x1)fig = plt.figure(figsize=(6, 3), dpi=100, frameon=True, edgecolor='grey')
fig.patch.set_linewidth(1)ax1 = fig.add_subplot(111)
ax1.plot(x1, y1)plt.show()
可以看到,matplotlib默认只显示主刻度,不显示副刻度。
6.3.4.2 自定义主坐标轴刻度、标签
可以使用 set_xticks 来自定义 x 轴的主刻度,使用 set_xticklabels 自定义 x 轴的主刻度标签;同样,使用 set_yticks 来自定义 y 轴的主刻度,而 set_yticklabels 则用于自定义 y 轴的主刻度标签。
例如,y轴刻度和标签只显示1和-1,x轴刻度和标签显示为pi,
#6.3.4.2_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.2 自定义主坐标轴刻度、标签
'''import matplotlib.pyplot as plt
import numpy as npx1 = np.linspace(0, 3 * np.pi, 100)
y1 = np.sin(x1)fig = plt.figure(figsize=(6, 3), dpi=100, frameon=True, edgecolor='grey')
fig.patch.set_linewidth(1)ax1 = fig.add_subplot(111)
ax1.plot(x1, y1)x_ticks = np.arange(np.pi / 2, 3.5 * np.pi, np.pi / 2)
x_labels = [r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$',r'$\frac{5\pi}{2}$', r'$3\pi$'
]
ax1.set_xticks(x_ticks) # 自定义x轴刻度
ax1.set_xticklabels(x_labels) # 自定义x轴刻度标签ax1.set_yticks([-1, 1]) # 自定义y轴刻度
ax1.set_yticklabels(['-1', '1']) # 自定义y轴刻度标签plt.show()
6.3.4.3 自定义副坐标轴刻度、标签
matplotlib默认情况下不显示副坐标轴的刻度和标签,但可以通过使用 set_xticks、set_xticklabels、set_yticks、set_yticklabels和tick_params来启用并自定义这些设置。
#6.3.4.3_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.3 自定义副坐标轴刻度、标签
'''import matplotlib.pyplot as plt
import numpy as npx1 = np.linspace(0, 10, 100)
y1 = np.sin(x1)fig = plt.figure(figsize=(6, 3), dpi=100, frameon=True, edgecolor='grey')
fig.patch.set_linewidth(1)ax1 = fig.add_subplot(111)
ax1.plot(x1, y1)# 设置副刻度
ax1.set_xticks(np.arange(0, 10.5, 0.5), #自定义x轴副刻度minor=True # 开启x轴副刻度
)
ax1.set_yticks(np.arange(-1, 1.5, 0.25), #自定义y轴副刻度minor=True # 开启y轴副刻度
)# 设置副刻度标签
ax1.set_xticklabels([f'{i:.1f}' for i in np.arange(0, 10.5, 0.5)],minor=True) # 自定义x轴副刻度标签格式
ax1.set_yticklabels([f'{i:.2f}' for i in np.arange(-1, 1.5, 0.25)],minor=True) # 自定义y轴副刻度标签格式# 调整副刻度样式
ax1.tick_params(which='minor', length=4, color='blue', labelsize=8)plt.show()
进一步学习👉:
set_xticks
set_yticks
set_xticklabels
set_yticklabels
tick_params
6.3.4.4 自定义刻度、刻度标签外观
matplotlib中的tick_params方法可自定义诸如刻度的方向、长度、宽度、颜色、刻度标签的字体大小、旋转角度等属性。此外,还可以通过该函数控制主刻度和副刻度的显示及样式。
重点参数的含义如下:
- axis:指定要影响的坐标轴,取值为 'x'、'y' 或 'both'。默认值为 'both'。
- which:指定作用的刻度类型,取值为 'major'(主刻度)、'minor'(副刻度)或 'both'。默认值为 'major'。
- direction:设置刻度的方向,取值为 'in'(朝内)、'out'(朝外)或 'inout'(两者)。默认值为 'out'。
- length:指定刻度线的长度,以点为单位。
- width:设置刻度线的宽度。
- color:定义刻度线的颜色。
- pad:设置刻度标签与刻度线之间的距离,以点为单位。
- labelsize:指定刻度标签的字体大小。
- labelcolor:定义刻度标签的颜色。
- grid_color:设置网格线的颜色。
- grid_alpha:控制网格线的透明度。
- grid_linewidth:指定网格线的宽度。
- grid_linestyle:定义网格线的线型,如 '-'(实线)、'--'(虚线)等。
- bottom/top/left/right:布尔值,用于控制是否显示各个边的刻度线。
- labelrotation:用于设置刻度标签的旋转角度。
重点介绍axis、which、direction、labelrotation参数。
重点参数1:axis
axis指定要影响的坐标轴,取值为 'x'、'y' 或 'both',默认值为 'both'。
举个例子介绍各个取值的效果,
#6.3.4.4_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.4 自定义刻度、刻度标签外观
'''import matplotlib.pyplot as plt
import numpy as np# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)fig, axs = plt.subplots(2,2,figsize=(10, 8),dpi=150,constrained_layout=True,frameon=True,edgecolor='grey')
fig.patch.set_linewidth(1)# 第一个子图:默认刻度和标签
axs[0, 0].plot(x, y)
axs[0, 0].set_title('默认刻度和标签')# 第二个子图:仅修改x轴的刻度和标签颜色
axs[0, 1].plot(x, y)
axs[0, 1].tick_params(axis='x', #仅修改x轴的刻度和标签颜色colors='red' #设置x轴的刻度和标签颜色为红色
)
axs[0, 1].set_title("仅修改x轴的刻度和标签颜色")# 第三个子图:仅修改y轴的刻度和标签颜色
axs[1, 0].plot(x, y)
axs[1, 0].tick_params(axis='y', #仅修改y轴的刻度和标签颜色colors='red' #设置y轴的刻度和标签颜色为红色
)
axs[1, 0].set_title("仅修改y轴的刻度和标签颜色")# 第四个子图:同时修改x轴和y轴的刻度和标签颜色
axs[1, 1].plot(x, y)
axs[1, 1].tick_params(axis='both', #同时修改x轴和y轴的刻度和标签颜色colors='red' #同时修改x轴和y轴的刻度和标签颜色为红色
)
axs[1, 1].set_title("同时修改x轴和y轴的刻度和标签颜色")plt.show()
重点参数2:which
which指定作用的刻度类型,取值为 'major'(主刻度)、'minor'(副刻度)或 'both',默认值为 'major'。
举个例子,
#6.3.4.4_02
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.4 自定义刻度、刻度标签外观
'''
import matplotlib.pyplot as plt
import numpy as np# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)# 创建图形和子图
fig, axs = plt.subplots(2, 2, figsize=(10, 8), dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)# 第一个子图,使用默认值(仅主刻度)
axs[0, 0].plot(x, y)
axs[0, 0].set_title("默认 (which='major')")
axs[0, 0].tick_params(which='major', # 主刻度设置length=8, width=2, color='red') # 第二个子图,使用 'major' 作为 which 参数
axs[0, 1].plot(x, y)
axs[0, 1].set_title("which='major'")
axs[0, 1].tick_params(which='major',# 主刻度设置length=8, width=2, color='red') # 第三个子图,使用 'minor' 作为 which 参数
axs[1, 0].plot(x, y)
axs[1, 0].set_title("which='minor'")
axs[1, 0].tick_params(which='minor', # 副刻度设置length=8, width=2, color='red')
#axs[1, 0].tick_params(which='major', length=8, width=2, color='red') # 主刻度设置
axs[1, 0].xaxis.set_minor_locator(plt.MultipleLocator(0.5))
axs[1, 0].yaxis.set_minor_locator(plt.MultipleLocator(0.25)) # 第四个子图,使用 'both' 作为 which 参数
axs[1, 1].plot(x, y)
axs[1, 1].set_title("which='both'")
axs[1, 1].tick_params(which='both',# 主刻度和副刻度设置length=8, width=2, color='red')
axs[1, 1].xaxis.set_minor_locator(plt.MultipleLocator(0.5)) # 添加x轴副刻度
axs[1, 1].yaxis.set_minor_locator(plt.MultipleLocator(0.25)) # 添加y轴副刻度# 调整布局
plt.tight_layout()
plt.show()
注意观察不同子图的变化。
重点参数3:direction
direction设置刻度的方向,取值为 'in'(朝内)、'out'(朝外)或 'inout'(两者),默认值为 'out'。
#6.3.4.4_03
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.4 自定义刻度、刻度标签外观
'''import matplotlib.pyplot as plt
import numpy as np# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)fig, axs = plt.subplots(2, 2, figsize=(10, 8), dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)# 默认设置(direction=default)
axs[0, 0].plot(x, y)
axs[0, 0].set_title("默认 (direction='out')")
axs[0, 0].tick_params(length=8, width=2, color='red')# 设置为 'in'(朝内)
axs[0, 1].plot(x, y)
axs[0, 1].set_title("direction='in'")
axs[0, 1].tick_params(direction='in', #朝内length=8,width=2,color='red')# 设置为 'out'(朝外)
axs[1, 0].plot(x, y)
axs[1, 0].set_title("direction='out'")
axs[1, 0].tick_params(direction='out', #朝外length=8,width=2,color='red')# 设置为 'inout'(两者)
axs[1, 1].plot(x, y)
axs[1, 1].set_title("direction='inout'")
axs[1, 1].tick_params(direction='inout', #朝内外length=8,width=2,color='red')plt.tight_layout()
plt.show()
重点参数4:labelrotation
labelrotation用于设置刻度标签的旋转角度。
#6.3.4.4_04
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.4 自定义刻度、刻度标签外观
'''import matplotlib.pyplot as plt
import numpy as np# 创建数据
x = np.linspace(0, 10, 10)
y = np.sin(x)# 创建图形和子图
fig, axs = plt.subplots(2, 2, figsize=(10, 8), dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)# 默认设置(labelrotation=0)
axs[0, 0].plot(x, y)
axs[0, 0].set_title("默认 (labelrotation=0)")
axs[0, 0].set_xticks(x)
axs[0, 0].set_xticklabels([f'{i:.1f}' for i in x],rotation=0 # 默认设置为0度
)# 设置为 45度
axs[0, 1].plot(x, y)
axs[0, 1].set_title("labelrotation=45°")
axs[0, 1].set_xticks(x)
axs[0, 1].set_xticklabels([f'{i:.1f}' for i in x],rotation=45 # 设置为45度旋转
)# 设置为 90度
axs[1, 0].plot(x, y)
axs[1, 0].set_title("labelrotation=90°")
axs[1, 0].set_xticks(x)
axs[1, 0].set_xticklabels([f'{i:.1f}' for i in x],rotation=90 # 设置为90度旋转
)# 设置为 120度
axs[1, 1].plot(x, y)
axs[1, 1].set_title("labelrotation=120°")
axs[1, 1].set_xticks(x)
axs[1, 1].set_xticklabels([f'{i:.1f}' for i in x],rotation=120 # 设置为120度旋转
)plt.tight_layout()
plt.show()
其它参数
#6.3.4.4_05
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.4 自定义刻度、刻度标签外观
'''import matplotlib.pyplot as plt
import numpy as np# 创建数据
x = np.linspace(0, 10, 100)
y = np.sin(x)fig, axs = plt.subplots(2, 2, figsize=(10, 8), dpi=100, edgecolor='grey')
fig.patch.set_linewidth(1)# 1. 子图1: 设置刻度长度'length'
axs[0, 0].plot(x, y)
axs[0, 0].set_title("length=10")
axs[0, 0].tick_params(length=10 # 刻度线长度为10)# 2. 子图2: 设置刻度宽度'width'
axs[0, 1].plot(x, y)
axs[0, 1].set_title("width=2")
axs[0, 1].tick_params(width=2 # 刻度线宽度为2)# 3. 子图3: 设置刻度颜色'color'
axs[1, 0].plot(x, y)
axs[1, 0].set_title("color='red'")
axs[1, 0].tick_params(color='red' # 刻度线颜色为红色)# 4. 子图4: 设置刻度标签大小'labelsize'
axs[1, 1].plot(x, y)
axs[1, 1].set_title("labelsize=15")
axs[1, 1].tick_params(labelsize=15 # 刻度标签大小为15)plt.tight_layout()
plt.show()
更多参数不一一举例了。
6.3.4.5 自动定义刻度
上文6.3.4.2~6.3.4.4章节介绍了手动设置刻度的方法,能够满足大多数使用场景。然而,在实时数据可视化、交互式图表或数据范围不确定的情况下,自动调整刻度可以根据数据范围和视图动态更新,确保图表始终清晰易读,减少了手动调整的需求。
matplotlib使用坐标轴刻度定位器(locator)自动定义刻度,即自动为刻度安排恰当的位置。这些方法都在ticker中,
#6.3.4.5_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.5 自动定义刻度
'''import matplotlib.ticker as ticker# 获取可用的Tick Locators
tick_locators = [loc for loc in dir(ticker) if 'Locator' in loc and loc != 'Locator'
]# 输出Tick Locators
print("可用的刻度定位器:")
for loc in tick_locators:print(loc, end=',')
可用的刻度定位器: AsinhLocator,AutoLocator,AutoMinorLocator,FixedLocator,IndexLocator,LinearLocator,LogLocator,LogitLocator,MaxNLocator,MultipleLocator,NullLocator,SymmetricalLogLocator, 每种定位器简介
Locator 名称 | 定义和作用 |
---|---|
MaxNLocator | 该定位器根据用户指定的最大刻度数量,智能地选择刻度位置,适合需要简洁展示的图表。 |
AutoLocator | 自动调整刻度位置以适应数据范围,确保主刻度均匀分布,是处理各种数据时的可靠选择。 |
AutoMinorLocator | 这个定位器会自动添加次刻度,为图表提供更多细节,使得数据展示更加清晰。 |
LinearLocator | 按照设定的刻度数量,在特定范围内均匀分布刻度,非常适合需要精确定量分析的数据。 |
LogLocator | 在对数刻度上设置刻度,能够很好地处理指数增长或衰减的数据,确保刻度在对数尺度上合理分布。 |
MultipleLocator | 通过设置固定间隔的刻度,这个定位器适合展示定期数据,如时间序列分析,帮助用户更好地理解趋势。 |
FixedLocator | 允许用户根据特定位置设置刻度,适用于那些需要精准刻度的特殊情况,让图表更加直观。 |
IndexLocator | 根据数据点的索引设置刻度,非常适合展示离散数据,帮助用户快速定位到特定的数值。 |
NullLocator | 隐藏所有刻度,这个定位器在某些情况下尤其有用,比如只需展示图像而非具体数值的场合。 |
SymmetricalLogLocator | 在对称对数刻度上设置刻度,非常适合处理数据分布中正负值对称的情况,增强视觉效果,使数据展示更具美感。 |
AsinhLocator | 用于设置双曲正弦刻度,尤其适合处理范围广泛但对称的数据。 |
LogitLocator | 在 logit 刻度上设置刻度,适合展示比例数据,确保刻度在 [0, 1] 范围内均匀分布。 |
每一种举一个简单的例子,
#6.3.4.5_02
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.5 自动定义刻度
'''import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker# 生成示例数据
x = np.linspace(-10, 10, 100)
y = np.sinh(x)fig, axs = plt.subplots(6, 2, figsize=(14, 30), dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)
axs = axs.flatten()# 子图 1:MaxNLocator
ax1 = axs[0]
ax1.plot(x, y, label="sinh(x)")
ax1.set_title("MaxNLocator (n=2)")
ax1.xaxis.set_major_locator(ticker.MaxNLocator(nbins=2) #限制x轴的刻度数量为2)
ax1.grid(True, linestyle='--', alpha=0.7)
ax1.legend()
for tick in ax1.xaxis.get_major_ticks():tick.label1.set_color("red")# 子图 2:AutoLocator
ax2 = axs[1]
ax2.plot(x, y, label="sinh(x)")
ax2.set_title("AutoLocator")
ax2.yaxis.set_major_locator(ticker.AutoLocator() #自动设置主刻度)
ax2.grid(True, linestyle='--', alpha=0.7)
ax2.legend()
for tick in ax2.yaxis.get_major_ticks():tick.label1.set_color("red")# 子图 3:AutoMinorLocator
ax3 = axs[2]
ax3.plot(x, y, label="sinh(x)")
ax3.set_title("AutoMinorLocator")
ax3.yaxis.set_minor_locator(ticker.AutoMinorLocator() #自动设置次刻度)
ax3.grid(True, which='both', linestyle='--', alpha=0.7)
ax3.legend()ax3.tick_params(axis='y', which='minor', color='red', width=2, size=8)# 子图 4:LinearLocator
ax4 = axs[3]
ax4.plot(x, y, label="sinh(x)")
ax4.set_title("LinearLocator (numticks=6)")
ax4.xaxis.set_major_locator(ticker.LinearLocator(numticks=6) #设置6个均匀分布的刻度)
ax4.grid(True, linestyle='--', alpha=0.7)
ax4.legend()
for tick in ax4.xaxis.get_major_ticks():tick.label1.set_color("red")# 子图 5:LogLocator
ax5 = axs[4]
ax5.plot(x, y, label="sinh(x)")
ax5.set_title("LogLocator")
ax5.set_xscale("log") # 设置x轴为对数刻度
ax5.xaxis.set_major_locator(ticker.LogLocator(base=10.0, #使用10为底的对数刻度
))
ax5.grid(True, which='both', linestyle='--', alpha=0.7)
ax5.legend()
for tick in ax5.xaxis.get_major_ticks():tick.label1.set_color("red")# 子图 6:MultipleLocator
ax6 = axs[5]
ax6.plot(x, y, label="sinh(x)")
ax6.set_title("MultipleLocator (interval=2)")
ax6.xaxis.set_major_locator(ticker.MultipleLocator(2) # 设置固定间隔为2的刻度)
ax6.grid(True, linestyle='--', alpha=0.7)
ax6.legend()
for tick in ax6.xaxis.get_major_ticks():tick.label1.set_color("red")# 子图 7:FixedLocator
ax7 = axs[6]
ax7.plot(x, y, label="sinh(x)")
ax7.set_title("FixedLocator (positions=[-5, 0, 5])")
ax7.xaxis.set_major_locator(ticker.FixedLocator([-5, 0, 5]) #设置具体的刻度位置)
ax7.grid(True, linestyle='--', alpha=0.7)
ax7.legend()
for tick in ax7.xaxis.get_major_ticks():tick.label1.set_color("red")# 子图 8:IndexLocator
ax8 = axs[7]
ax8.plot(x, y, label="sinh(x)")
ax8.set_title("IndexLocator (base=3, offset=-6)")
ax8.xaxis.set_major_locator(ticker.IndexLocator(base=3, #间隔offset=-6 #起始刻度
)) #根据索引位置设置刻度
ax8.grid(True, linestyle='--', alpha=0.7)
ax8.legend()
for tick in ax8.xaxis.get_major_ticks():tick.label1.set_color("red")# 子图 9:NullLocator
ax9 = axs[8]
ax9.plot(x, y, label="sinh(x)")
ax9.set_title("NullLocator (No ticks)")
ax9.xaxis.set_major_locator(ticker.NullLocator() #隐藏所有刻度)
ax9.grid(True, linestyle='--', alpha=0.7)
ax9.legend()# 子图 10:SymmetricalLogLocator
x_sym = np.linspace(-10, 10, 100)
y_sym = np.sinh(x_sym)
ax10 = axs[9]
ax10.plot(x_sym, y_sym, label="sinh(x)")
ax10.set_title("SymmetricalLogLocator (linthresh=1)")
ax10.set_yscale("symlog", linthresh=1) # 设定linthresh=1以对称刻度
ax10.yaxis.set_major_locator(ticker.SymmetricalLogLocator(base=10, #对数基数为10linthresh=1 #在-1到1之间使用线性刻度,而不使用对数刻度。)) #在对称对数坐标轴上设置刻度
ax10.grid(True, which='both', linestyle='--', alpha=0.7)
ax10.legend()
for tick in ax10.yaxis.get_major_ticks():tick.label1.set_color("red")# 子图 11:AsinhLocator
ax11 = axs[10]
x_asinh = np.linspace(0, 10, 100)
y_asinh = np.sinh(x_asinh)
ax11.plot(x_asinh, y_asinh, label="sinh(x)")
ax11.set_title("AsinhLocator (linear_width=1.0)")
ax11.yaxis.set_major_locator(ticker.AsinhLocator(linear_width=1.0)) #自动确定在asinh缩放轴上刻度线的最佳位置
ax11.grid(True, which='both', linestyle='--', alpha=0.7)
ax11.legend()
for tick in ax11.yaxis.get_major_ticks():tick.label1.set_color("red")# 子图 12:LogitLocator
ax12 = axs[11]
x_logit = np.linspace(0.01, 0.99, 100)
y_logit = x_logit
ax12.plot(x_logit, y_logit, label="y=x")
ax12.set_title("LogitLocator")
ax12.set_yscale("logit")
ax12.yaxis.set_major_locator(ticker.LogitLocator()) #在 logit 刻度上设置刻度,适合展示比例数据
ax12.grid(True, which='both', linestyle='--', alpha=0.7)
ax12.legend()
for tick in ax12.yaxis.get_major_ticks():tick.label1.set_color("red")plt.tight_layout()
plt.show()
红色为坐标轴刻度定位器的效果。
6.3.4.6 自动定义刻度标签格式
上文6.3.4.2~6.3.4.4章节介绍了手动设置刻度标签的方法,能够满足大多数使用场景。这里介绍matplotlib内置的另外一些定义刻度标签格式的方法。
matplotlib使用格式生成器(formatter)定义刻度标签格式,定义了与轴上刻度相关联的数值如何格式化为字符串。
#6.3.4.6_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.6 自动定义刻度标签格式
'''import matplotlib.ticker as ticker# 获取可用的Tick Formatters
tick_formatters = [loc for loc in dir(ticker) if 'Formatter' in loc and loc != 'Formatter'
]# 输出Tick Locators
print("可用的刻度标签格式生成器:")
for loc in tick_formatters:print(loc, end=',')
可用的刻度标签格式生成器:
EngFormatter,FixedFormatter,FormatStrFormatter,FuncFormatter,LogFormatter,LogFormatterExponent,LogFormatterMathtext,LogFormatterSciNotation,LogitFormatter,NullFormatter,PercentFormatter,ScalarFormatter,StrMethodFormatter。
刻度标签格式生成器的作用如下表,
Formatter 名称 | 定义和作用 |
---|---|
EngFormatter | 这个格式化器以工程格式显示数值,使得大的数值更易于阅读。它会使用每三位数的前缀,比如 k(千)、M(百万)、G(十亿),非常适合处理大数值的场景。 |
FixedFormatter | 如果你需要在刻度上显示特定的标签而不是默认的数值,FixedFormatter 就是你的理想选择。它允许你手动设置每个刻度的标签,非常适合需要自定义标签的情况。 |
FormatStrFormatter | 这个格式化器让你可以使用格式字符串(类似于 Python 的 % 格式化)来控制刻度标签的输出样式。无论是想显示小数位数还是特定格式,这个工具都能满足你的需求。 |
FuncFormatter | FuncFormatter 的强大之处在于你可以通过自定义函数来格式化刻度标签。这样,无论你的需求多独特,你都可以实现自己想要的输出格式,给予你极大的灵活性。 |
LogFormatter | 当你在使用对数坐标轴时,LogFormatter 可以帮助你更好地格式化刻度标签。它支持自定义对数基数和其他格式设置,让你的数据展示更清晰。 |
LogFormatterExponent | 如果你需要以指数形式显示刻度标签,LogFormatterExponent 就是一个不错的选择。它特别适合处理数值很大的情况,可以让读者迅速理解数据的规模。 |
LogFormatterMathtext | 想在刻度标签中展示数学公式吗?LogFormatterMathtext 就可以帮你实现。它使用 Mathtext 格式,适合那些希望以更专业方式展示数据的用户。 |
LogFormatterSciNotation | 处理非常大的或非常小的数值时,LogFormatterSciNotation 可以将刻度标签格式化为科学记数法,帮助读者更容易理解数值的范围。 |
LogitFormatter | 如果你的数据是概率值(介于 0 和 1 之间),LogitFormatter 会将这些数值转换为 logit 格式进行显示,适合处理概率统计数据。 |
NullFormatter | 当你希望完全隐藏刻度标签时,NullFormatter 是一个很好的选择。它能让图表看起来更加简洁,适合不需要刻度标签的情境。 |
PercentFormatter | PercentFormatter 能将刻度标签格式化为百分比,并且可以设置小数位数,特别适合展示比例数据,让读者一目了然。 |
ScalarFormatter | 这是 Matplotlib 的默认标量格式化器,它会根据数值的大小智能选择显示方式,无论是普通数字还是科学记数法,能够确保你的数据展示清晰。 |
StrMethodFormatter | 使用 StrMethodFormatter 让你可以运用 Python 的字符串格式化方法(如 str.format() )来定义刻度标签的样式。这样可以实现更复杂的格式,提升数据展示的灵活性。 |
每一种formatter使用举例,
#6.3.4.6_02
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author : 公众号:pythonic生物人
@Desc : 6.3.4.6 自动定义刻度标签格式
'''import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker# 生成示例数据
x = np.linspace(0, 1e7, 100)
y = np.sin(x / 1e6)#fig, axs = plt.subplots(6, 2, dpi=150, figsize=(14, 20))fig, axs = plt.subplots(6, 2, figsize=(14, 30), dpi=150, edgecolor='grey')
fig.patch.set_linewidth(1)
axs = axs.flatten()# Formatter 1: EngFormatter
ax1 = axs[0]
ax1.plot(x, y)
ax1.set_title("EngFormatter")
ax1.set_xlabel("Value (engineering prefixes)")
ax1.set_ylabel("Sin value")
ax1.xaxis.set_major_formatter(ticker.EngFormatter(unit='MHz' #指定刻度标签单位。例如,振动次数设置为MHz,替代1e7))
for tick in ax1.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 2: FixedFormatter
ax2 = axs[1]
ax2.plot(x, y)
ax2.set_title("FixedFormatter")
ax2.set_yticks([0, 0.5, 1.0])
ax2.yaxis.set_major_formatter(ticker.FixedFormatter(["0 km", "0.5 km", "1.0 km"] #传入刻度标签列表))
for tick in ax2.yaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 3: FormatStrFormatter
ax3 = axs[2]
ax3.plot(x, y)
ax3.set_title("FormatStrFormatter")
ax3.set_xticks([2000000, 6000000, 10000000])
ax3.xaxis.set_major_formatter(ticker.FormatStrFormatter('Label: %d' #格式化刻度标签,使用常见python字符串格式化输出方法))
for tick in ax3.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 4: FuncFormatter
ax4 = axs[3]
ax4.plot(x, y)
ax4.set_title("FuncFormatter")
ax4.xaxis.set_major_formatter(ticker.FuncFormatter(lambda val, pos: f'{val:.1f} m' #轻松调用任何函数格式化标签,这里使用lambda函数))
for tick in ax4.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 5: LogFormatter
ax5 = axs[4]
x_log = np.linspace(1, 1000, 100)
y_log = np.log10(x_log)
ax5.plot(x_log, y_log)
ax5.set_title("LogFormatter")
ax5.xaxis.set_major_formatter(ticker.LogFormatter() #显示10^3中的10^3)
for tick in ax5.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 6: LogFormatterExponent
ax6 = axs[5]
ax6.plot(x_log, y_log)
ax6.set_title("LogFormatterExponent")
ax6.xaxis.set_major_formatter(ticker.LogFormatterExponent() #显示10^3中的3,对比子图5学习)
for tick in ax6.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 7: LogFormatterMathtext
ax7 = axs[6]
ax7.plot(x_log, y_log)
ax7.set_title("LogFormatterMathtext")
ax7.xaxis.set_major_formatter(ticker.LogFormatterMathtext() #科学计数法)
for tick in ax7.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 8: LogFormatterSciNotation
ax8 = axs[7]
ax8.plot(x_log, y_log)
ax8.set_title("LogFormatterSciNotation")
ax8.xaxis.set_major_formatter(ticker.LogFormatterSciNotation() #与前一种方法类似)
for tick in ax8.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 9: LogitFormatter
ax9 = axs[8]
x_logit = np.linspace(0.01, 0.99, 100)
y_logit = x_logit
ax9.plot(x_logit, y_logit)
ax9.set_title("LogitFormatter")
ax9.set_yscale("logit")
ax9.yaxis.set_major_formatter(ticker.LogitFormatter() #Probability格式)
for tick in ax9.yaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 10: NullFormatter
ax10 = axs[9]
ax10.plot(x, y)
ax10.set_title("NullFormatter")
ax10.xaxis.set_major_formatter(ticker.NullFormatter() #隐藏刻度标签)# Formatter 11: PercentFormatter
ax11 = axs[10]
percent_data = np.linspace(0, 1, 100)
ax11.plot(percent_data, percent_data)
ax11.set_title("PercentFormatter")
ax11.xaxis.set_major_formatter(ticker.PercentFormatter(xmax=1) #刻度标签使用百分数)
for tick in ax11.xaxis.get_major_ticks():tick.label1.set_color("red")# Formatter 12: ScalarFormatter
ax12 = axs[11]
ax12.plot(x, y)
ax12.set_title("ScalarFormatter")
ax12.xaxis.set_major_formatter(ticker.ScalarFormatter() #默认方法)
for tick in ax12.xaxis.get_major_ticks():tick.label1.set_color("red")plt.tight_layout()
plt.show()
红色为坐标轴刻度标签格式生成器的效果。
详解Python matplotlib坐标轴