为多个子图设置具有固定指数和有效数字的科学计数法 [英] Set scientific notation with fixed exponent and significant digits for multiple subplots
问题描述
我正在尝试将轴固定为两组不同数据的科学计数法,其中一组是[1-9] x1e-3,另一组是[1-9] x1e-4.我想将两个轴都设置为10 ^ -4,并在小数点后添加一位数字(例如%.1e).这是我尝试使用的一个简单版本:我希望轴上的数字至少为1,并且我希望两个幂都相同.
I am trying to fix the axes to scientific notation of two different sets of data where one is [1-9]x1e-3 and the other is [1-9]x1e-4. I would like to set both axes to be 10^-4 and have the one digits after decimal (e.g. %.1e). Here is a simple version that I have tried to play around with: I would like the numbers on the axes to be at least 1 and I want both powers to be the same.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1,9,9)
y1 = x*10**(-4)
y2 = x*10**(-3)
fig, ax = plt.subplots(2,1,sharex=True)
ax[0].plot(x,y1)
ax[0].ticklabel_format(axis='y', style='sci', scilimits=(-4,-4))
ax[0].yaxis.major.formatter._useMathText = True
ax[1].plot(x,y2)
ax[1].ticklabel_format(axis='y', style='sci', scilimits=(-4,-4))
ax[1].yaxis.major.formatter._useMathText = True
plt.show()
推荐答案
您可以将matplotlib.ticker.ScalarFormatter
子类化,并将orderOfMagnitude
属性固定为所需的数字(在本例中为-4
).
以相同的方式,您可以固定要使用的格式.
You can subclass matplotlib.ticker.ScalarFormatter
and fix the orderOfMagnitude
attribute to the number you like (in this case -4
).
In the same way you can fix the format to be used.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
class OOMFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, order=0, fformat="%1.1f", offset=True, mathText=True):
self.oom = order
self.fformat = fformat
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
def _set_order_of_magnitude(self):
self.orderOfMagnitude = self.oom
def _set_format(self, vmin=None, vmax=None):
self.format = self.fformat
if self._useMathText:
self.format = r'$\mathdefault{%s}$' % self.format
x = np.linspace(1,9,9)
y1 = x*10**(-4)
y2 = x*10**(-3)
fig, ax = plt.subplots(2,1,sharex=True)
ax[0].plot(x,y1)
ax[1].plot(x,y2)
for axe in ax:
axe.yaxis.set_major_formatter(OOMFormatter(-4, "%1.1f"))
axe.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4))
plt.show()
虽然乍看之下似乎很复杂,但实际上唯一要做的就是覆盖私有方法_set_orderOfMagnitude
和_set_format
,从而防止它们在我们不希望的后台执行某些复杂的工作.因为最后,我们所需要做的就是,独立于内部发生的事情,self.orderOfMagnitude
始终为-4
,而self.format
始终为"%1.1f"
.
While this may seem complicated at first sight the only thing it really does is overwrite the private methods _set_orderOfMagnitude
and _set_format
and thereby prevent them from doing some sophisticated stuff in the background that we don't want. Because in the end, all we need is that, independent of what happens internally, self.orderOfMagnitude
is always -4
and self.format
is always "%1.1f"
.
注意:在matplotlib中< 3.1所需的类看起来像
Note: In matplotlib < 3.1 the class needed to look like
class OOMFormatter(matplotlib.ticker.ScalarFormatter):
def __init__(self, order=0, fformat="%1.1f", offset=True, mathText=True):
self.oom = order
self.fformat = fformat
matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
def _set_orderOfMagnitude(self, nothing=None):
self.orderOfMagnitude = self.oom
def _set_format(self, vmin=None, vmax=None):
self.format = self.fformat
if self._useMathText:
self.format = '$%s$' % matplotlib.ticker._mathdefault(self.format)
这篇关于为多个子图设置具有固定指数和有效数字的科学计数法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!