我写了一个包含matplotlib图形的UI。它显示图形,我想在轴上使用工程符号(指数是3的倍数)。请注意,我希望写出幂(例如“123×10 ",而不是“123 M”,因此不使用EngFormatter)。
我可以用我多年前写的格式化函数(format_eng
)和matplotlib的set_major_formatter
和fmt_x_data
功能来做到这一点:
def axes_eng_format(ax, x=True, y=True, **kwargs):
if x:
if 'use_si' not in kwargs and 'use_latex' not in kwargs:
ax.xaxis.set_major_formatter(lambda v, pos: format_eng(v, use_latex=True, **kwargs))
else:
ax.xaxis.set_major_formatter(lambda v, pos: format_eng(v, **kwargs))
ax.fmt_xdata = lambda v: format_eng(v, **kwargs)
if y:
if 'use_si' not in kwargs and 'use_latex' not in kwargs:
ax.yaxis.set_major_formatter(lambda v, pos: format_eng(v, use_latex=True, **kwargs))
else:
ax.yaxis.set_major_formatter(lambda v, pos: format_eng(v, **kwargs))
ax.fmt_ydata = lambda v: format_eng(v, **kwargs)
axes_eng_format(ax)
格式化函数本身不应该与这个问题相关(因为它只是一个只接受单个参数的哑格式化程序,因此不能考虑值的范围),但是为了参考,它在这里:https://gist.github.com/abudden/3252252632bd8271c49c886771d8f82d
格式化程序只获取两个参数:的值(v
)和图上的位置(pos
)。只使用值v
是可以的,也可以工作,但是0.5被渲染为500×10立方。如果长轴上的值范围是(比如)0到700×10立方,那么这正是我希望它被渲染的方式,但如果值的范围是(如下面的第二张图)0到3.5,我宁愿它被渲染为0.5,以与轴上的其他值保持一致。
目前我能想到的唯一方法是对所有的tick值进行后处理,但考虑到用户可以放大和缩小等,这似乎不是很健壮。
有没有更好的方法来达到我所追求的效果?我想我可以用pos
做些什么,但我还没有能够得到我的头周围的工作。我应该如何去使用pos
来调整一个数字的格式(或者有没有更好的方法)?
Y轴看起来不错:
Y轴看起来不太好:
1条答案
按热度按时间klr1opcd1#
pos
参数只是当前格式化的tick标签的数字(一个整数值),从0开始计数。因此,使用它来实现上述目的并没有什么用处。相反,您可以使用当前显示的值范围,即使用
xmin, xmax = ax.get_xlim()
和ymin, ymax = ax.get_ylim()
的轴的当前范围。并将其传递给format_eng
函数。当然,format_eng
需要相应地修改。仅考虑正值的简单示例(关于x轴和y轴的最大值,而不是范围):
样地:
放大: