Python numpy:具有可变精度的floor和ceil十进制值(用于多批绘图的色条)

Python numpy:具有可变精度的floor和ceil十进制值(用于多批绘图的色条),python,numpy,matplotlib,floor,ceil,Python,Numpy,Matplotlib,Floor,Ceil,要在批处理模式下绘制多个图形,目的是使用np.floor()和np.ceil()定义colorbar的舍入范围。但是,如果最小范围为1.2e-5,则np。地板(1.2e-5)给出0。而不是1.e-5,等等。无法使用Precision函数,因为存在小数值,并且循环中的舍入精度随指数的数量而变化,如本例所示: print('#Each row has the colorbar range to be floored and ceiled for each plot') print('#values

要在批处理模式下绘制多个图形,目的是使用
np.floor()
np.ceil()
定义colorbar的舍入范围。但是,如果最小范围为1.2e-5,则
np。地板(1.2e-5)
给出0。而不是1.e-5,等等。无法使用Precision函数,因为存在小数值,并且循环中的舍入精度随指数的数量而变化,如本例所示:

print('#Each row has the colorbar range to be floored and ceiled for each plot')
print('#values [x]')
x=np.array([[-6.880367e-05, 5.7156103e-03],[-0.18, 101.1]])
print(x)

print('#Get exponent of each decimal value [exp]')
exp=np.floor(np.log10(np.abs(x))).astype(int)
exp[exp>0]=0
print(exp)

print('#Get exponent inverse [expi]')
expi=10**abs(exp).astype(float)
print(expi)

print('#Values to the power of 0 [x0]') 
x0=x*expi
print(x0)

print('#Floor and ceil values to the power of 0 [x0fc]') 
x0fc=np.transpose([np.floor(x0[:,0]),np.ceil(x0[:,1])])
print(x0fc)

print('#Convert back to original exponent [xfc]') 
xfc=x0fc/expi
print(xfc)

print('#Loop [xfc] to get colorbar range for each plot')
for row in xfc:
    print("plt.clim({})".format(str(row)))
此代码将完成此工作,并根据需要提供地板和天花板范围:

#Each row has the colorbar range to be floored and ceiled for each plot
#values [x]
[[-6.8803670e-05  5.7156103e-03]
 [-1.8000000e-01  1.0110000e+02]]
#Get exponent of each decimal value [exp]
[[-5 -3]
 [-1  0]]
#Get exponent inverse [expi]
[[1.e+05 1.e+03]
 [1.e+01 1.e+00]]
#Values to the power of 0 [x0]
[[ -6.880367    5.7156103]
 [ -1.8       101.1      ]]
#Floor and ceil values to the power of 0 [x0fc]
[[ -7.   6.]
 [ -2. 102.]]
#Convert back to original exponent [xfc]
[[-7.00e-05  6.00e-03]
 [-2.00e-01  1.02e+02]]
#Loop [xfc] to get colorbar range for each plot
plt.clim([-7.e-05  6.e-03])
plt.clim([ -0.2 102. ])

然而,对于每个简单的任务来说,这似乎是一个非常冗长的代码。有没有更简单的方法来完成这项任务?

我认为你不能让它更有效率。通过组合一些语句并删减一些不必要的
astype
调用,可以将其缩短一点:

es = 10**np.floor(np.log10(abs(x))) # [1e-5, 1e-3, 1e-1, 1e+2]
es[es > 1] = 1 # [1e-5, 1e-3, 1e-1, 1.0]
for (xlo, xhi), (elo, ehi) in zip(x, es):
    xhi = np.ceil(xhi/ehi) * ehi
    xlo = np.floor(xlo/elo) * elo
    print(f'clim({xlo:.6g}, {xhi:.6g})')
请注意,任何涉及matplotlib的内容都将比您在此处可以矢量化的内容慢很多数量级,因此矢量化此代码没有任何意义

此外,您可以问问自己,像
[-3e-5102]
这样的色条范围是否真的那么有用。如果刻度是1、2或5的倍数,则(在色条或轴上)更容易读取。如果必须显示实际的最小值和最大值,可以将其作为文本注释:

ax.text(0.05, 0.05, f'min={xmin:.3g}, max={xmax:.3g}', 
        transform=ax.transAxes))