【问题标题】:Positioning the exponent of tick labels when using scientific notation in matplotlib在 matplotlib 中使用科学记数法时定位刻度标签的指数
【发布时间】:2019-11-24 21:19:23
【问题描述】:

我正在寻找一种在使用科学记数法时改变指数在轴上的位置的方法。我已经被这个问题困住了好几次了。我已经知道默认格式化程序是ScalarFormatter,但它无法以某种方式访问​​指数。

有一个workaround,但我不喜欢它,因为它还会操纵现有的刻度标签。到目前为止,我发现,如果使用科学记数法,则轴的 get_xmajorticklabels() 方法返回的列表包含一个文本对象。例如:

import matplotlib.pyplot as plt
import numpy as np

fig= plt.figure(figsize = plt.figaspect(0.5))
ax1= fig.add_subplot(121)
ax1.plot(np.arange(146), np.random.rand(146))
print(ax1.get_xmajorticklabels())

ax2= fig.add_subplot(122)
ax2.plot(np.arange(146)*1e-6, np.random.rand(146))
print(ax2.get_xmajorticklabels())

打印结果为:<a list of 9 Text xticklabel objects><a list of 10 Text xticklabel objects> 所以我认为附加的列表项可能是指数的文本对象。但是当我打印文本时它是空的。

有没有办法将这个指数作为文本对象访问?那么它的位置应该是可以设置的吧?

【问题讨论】:

  • 您可以使用ax2.xaxis.get_offset_text() 获取包含指数的Text 对象。虽然这有一个.set_position() 方法,但似乎只要重新绘制画布,它的位置就会重置。如果您能弄清楚发生这种情况的位置,那么您应该能够覆盖文本的位置。

标签: python matplotlib


【解决方案1】:

要访问Text objects 的列表,您可以使用该类的方法,例如get_text():

print([s.get_text() for s in ax2.get_xmajorticklabels()])

但是,结果是

<a list of 9 Text xticklabel objects>
[u'', u'', u'', u'', u'', u'', u'', u'', u'']
<a list of 10 Text xticklabel objects>
[u'', u'', u'', u'', u'', u'', u'', u'', u'', u'']

运行fig.tight_layout()后,现在可以枚举这些Text xticklabel objects的输出:

<a list of 9 Text xticklabel objects>
[(0.0, 0), (20.0, 0), (40.0, 0), (60.0, 0), (80.0, 0), (100.0, 0), (120.0, 0), (140.0, 0), (160.0, 0)]

<a list of 10 Text xticklabel objects>
[(0.0, 0), (2.0000000000000002e-05, 0), (4.0000000000000003e-05, 0), (6.0000000000000008e-05, 0), (8.0000000000000007e-05, 0), (0.0001, 0), (0.00012000000000000002, 0), (0.00014000000000000001, 0), (0.00016000000000000001, 0), (0, 0)]

对于像-7 这样的指数,实际上两个列表中的对象数量相同。

我找到的用于定位标签的最接近的方法是详细的here by Scott。遗憾的是,它只能在 x 轴水平和 y 轴垂直工作,所以你不能在图表上随意放置标签。

ax2.get_xaxis().get_offset_text().set_position((0.5,0))

【讨论】:

  • 非常感谢!我没想到指数会出现在偏移文本中。
  • set_position(x, y),修改y好像没有效果?
【解决方案2】:

我的解决方法产生了这个:

import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np

fig = plt.figure(figsize = plt.figaspect(0.5))
ax1 = fig.add_subplot(121)
ax1.plot(np.arange(146), 1e+5*np.random.rand(146))
yfmt = ticker.ScalarFormatter(useMathText=True)
yfmt.set_powerlimits((3, 4))
ax1.yaxis.set_major_formatter(yfmt)
ax1.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
ax1.get_yaxis().get_offset_text().set_visible(False)
ax_max = max(ax1.get_yticks())
exponent_axis = np.floor(np.log10(ax_max)).astype(int)
ax1.annotate(r'$\times$10$^{%i}$'%(exponent_axis),
             xy=(.01, .96), xycoords='axes fraction')

ax2 = fig.add_subplot(122)
ax2.plot(np.arange(146)*1e-6, np.random.rand(146))
yfmt = ticker.ScalarFormatter(useMathText=True)
yfmt.set_powerlimits((-6, -5))
ax2.xaxis.set_major_formatter(yfmt)
ax2.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
ax2.get_xaxis().get_offset_text().set_visible(False)
ax_max = max(ax2.get_xticks())
exponent_axis = np.floor(np.log10(ax_max)).astype(int)
ax2.annotate(r'$\times$10$^{%i}$'%(exponent_axis),
             xy=(.89, .01), xycoords='axes fraction')

plt.tight_layout()
plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-29
    • 2017-10-07
    • 2012-01-05
    • 2019-06-23
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多