如何为matplotlib FuncFormatter()添加额外参数提升使用灵活性
简单示例
如何实现y轴刻度(红圈标注位置)显示$符号,x轴刻度显示£符号?
当前实现代码如下:
import numpy as np import matplotlib from matplotlib import pyplot as plt x = np.arange(0,200, 10) # GBP (0, 10, ... 190, 200) y = x * 1.25 # USD # Make figure fig, ax = plt.subplots(1, 1) ax.scatter(x, y) ax.set_xlabel('GBP') ax.set_ylabel('USD') # How to format tick labels def format_currency(value, pos): currency = '£' # <- hard-coded (for now) - but how to include as argument? return f'{currency}{value:.0f}' # <- e.g., "$100" or "£100" # Format tick labels ax.xaxis.set_major_formatter(plt.FuncFormatter(format_currency)) ax.yaxis.set_major_formatter(plt.FuncFormatter(format_currency)) # <- how to add '$' as an argument?

预期实现目标
理想方案是将currency(货币符号)作为参数传入format_currency()函数,从而灵活为y轴刻度标签添加$符号,目标函数形式如下:
def format_currency(value, pos, currency): return f'{currency}{value:.0f}'
若采用上述函数定义,以下代码行该如何调整以适配传参需求:
ax.yaxis.set_major_formatter(plt.FuncFormatter(format_currency))
已尝试的思路
- 可以为每种货币编写专属格式化函数,例如
format_USD()、format_EUR()等,但货币种类较多时该方案不具备可扩展性。 - 曾尝试使用
*args进行传参,但未找到可行的实现方式。
解决方案
FuncFormatter调用传入的格式化函数时,只会固定传入(刻度值, 刻度位置)两个参数,因此不能直接传入需要第三个参数的format_currency,可以通过以下两种方式实现参数传递,无需为每种货币单独写函数:
方法1:lambda闭包传参
代码改动量最小,直接通过lambda捕获需要传入的货币符号即可,完全适配你写的三参数format_currency函数:
# x轴使用英镑符号£ ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda val, pos: format_currency(val, pos, '£'))) # y轴使用美元符号$ ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda val, pos: format_currency(val, pos, '$')))
方法2:functools.partial 固定参数
使用Python标准库的partial工具提前绑定货币符号参数,逻辑更清晰:
首先在导入模块部分添加导入语句:
from functools import partial
之后设置formatter时直接传入绑定完参数的函数对象即可:
ax.xaxis.set_major_formatter(plt.FuncFormatter(partial(format_currency, currency='£'))) ax.yaxis.set_major_formatter(plt.FuncFormatter(partial(format_currency, currency='$')))
两种方案的扩展性完全一致,后续需要新增其他货币类型的坐标轴时,只需要修改传入的货币符号字符串,不需要重复编写格式化逻辑。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

