在使用matplotlib进行数据可视化时,用户经常需要对绘图进行自定义,以满足特定的视觉要求或突出关键信息。然而,对于某些常见的自定义需求,实现起来可能会有难度。例如,用户可能需要将绘图中的坐标轴居中显示,添加网格线,并在坐标轴末端添加箭头,但同时又希望坐标轴原点只显示一个零值,且不与其他坐标轴重叠。
2、解决方案
- 坐标轴居中
def center_spines(ax=None, centerx=0, centery=0):
# 设置坐标轴 spines 的中心位置
ax.spines['left'].set_position(('data', centerx))
ax.spines['bottom'].set_position(('data', centery))
ax.spines['right'].set_position(('data', centerx - 1))
ax.spines['top'].set_position(('data', centery - 1))
# 在 spines 末端添加箭头
ax.spines['left'].set_path_effects([EndArrow()])
ax.spines['bottom'].set_path_effects([EndArrow()])
# 隐藏多余 spines 的线,保留刻度记号
for side in ['right', 'top']:
ax.spines[side].set_color('none')
# 设置坐标轴的刻度和网格
for axis, center in zip([ax.xaxis, ax.yaxis], [centerx, centery]):
axis.set_ticks_position('both')
axis.grid(True, 'major', ls='solid', lw=0.5, color='gray')
axis.grid(True, 'minor', ls='solid', lw=0.1, color='gray')
axis.set_minor_locator(mpl.ticker.AutoMinorLocator())
formatter = CenteredFormatter()
formatter.center = center
axis.set_major_formatter(formatter)
xlabel, ylabel = map(formatter.format_data, [centerx, centery])
ax.annotate('(%s, %s)' % (xlabel, ylabel), (centerx, centery),
xytext=(-4, -4), textcoords='offset points',
ha='right', va='top')
- 网格线
# 添加网格线
ax.grid(True)
- 隐藏多余的零值
# 隐藏坐标轴原点的零值
ax.xaxis.set_ticks([tick for tick in ax.xaxis.get_ticks() if tick != 0])
ax.yaxis.set_ticks([tick for tick in ax.yaxis.get_ticks() if tick != 0])
- 自定义坐标轴箭头的样式
class EndArrow(mpl.patheffects._Base):
def __init__(self, headwidth=5, headheight=5, facecolor=(0,0,0), **kwargs):
# ... 省略代码 ...
def draw_path(self, renderer, gc, tpath, affine, rgbFace):
# ... 省略代码 ...
- 自定义坐标轴刻度的格式
class CenteredFormatter(mpl.ticker.ScalarFormatter):
def __call__(self, value, pos=None):
if value == self.center:
return ''
else:
return mpl.ticker.ScalarFormatter.__call__(self, value, pos)
代码例子
import matplotlib.pyplot as plt
import numpy as np
# 创建一个matplotlib绘图对象
fig, ax = plt.subplots()
# 设置坐标轴范围
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
# 绘制数据
x = np.arange(-5, 5)
y = x
line, = plt.plot(x, y)
# 调用自定义函数对绘图进行美化
center_spines()
plt.axis('equal')
# 显示绘图
plt.show()
这个代码示例演示了如何将坐标轴居中显示,添加网格线,并在坐标轴末端添加箭头,同时隐藏了坐标轴原点的多余零值。