如何提高 matplotlib 的精度?

How to increase precision in matplotlib?

我正在尝试绘制一组需要高精度的极端浮点值。在我看来,matplotlib 中存在精度限制。它不能超过 1e28 的比例。

这是我显示图表的代码。

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1737100, 38380894.5188064386003616016502, 378029000.0], dtype=np.longdouble)
y = np.array([-76188946654889063420743355676.5, -76188946654889063419450832178.0, -76188946654889063450098993033.0], dtype=np.longdouble)

plt.scatter(x, y)
#coefficients = np.polyfit(x, y, 2)
#poly = np.poly1d(coefficients)
#new_x = np.linspace(x[0], x[-1])
#new_y = poly(new_x)
#plt.plot(new_x, new_y)
plt.xlim([x[0], x[-1]])
plt.title('U vs. r')
plt.xlabel('Distance r')
plt.ylabel('Total gravitational potential energy U(r)')
plt.show()

我希望中间点的位置高于其他两点。它需要非常高的精度。我该如何配置它?

您当前的问题可能与 matplotlib 无关,而与 np.longdouble 有关。要发现是否是这种情况,运行 np.finfo(np.longdouble)。这将取决于机器,但在我的机器上,这表示我正在使用具有以下描述的 float128

Machine parameters for float128
---------------------------------------------------------------
precision =  18   resolution = 1.0000000000000000715e-18
machep =    -63   eps =        1.084202172485504434e-19
negep =     -64   epsneg =     5.42101086242752217e-20
minexp = -16382   tiny =       3.3621031431120935063e-4932
maxexp =  16384   max =        1.189731495357231765e+4932
nexp =       15   min =        -max
---------------------------------------------------------------

精度只是一个估计值(由于二进制与十进制表示形式),但 18 位是 float128 限制,您的具体数字在那之后才开始变得有趣。

一个简单的测试是打印 y[1]-y[0] 并查看是否得到 0.0 以外的其他内容。

一个简单的解决方案是使用 Python int,因为您会捕获自 [=52= 以来的大部分差异(或 10*yint) ] 具有无限精度 ints。所以像这样:

x = np.array([1737100, 38380894.5188064386003616016502, 378029000.0], dtype=np.longdouble)
y = [-76188946654889063420743355676, -76188946654889063419450832178, -76188946654889063450098993033]

plt.scatter(x, [z-y[0] for z in y]) 

另一种解决方案是从头开始表示数字,以便它们需要更易于访问的精度(即,删除大部分偏移量)。另一种是使用高精度浮点库。这取决于你想走哪条路。

还值得注意的是,至少对于我认为是典型的我的系统,默认的 np.floatfloat64。对于 float64,浮点尾数是 52 位,而对于 float128,它只有 63 位。或者以十进制表示,从大约 15 位数字到 18 位数字。因此,从 np.floatnp.float128 并没有很大的精度提高。 (Here's a discussion 为什么 np.longdouble(或 np.float128)听起来会增加很多精度,但事实并非如此。)

(最后,因为这可能会让一些人感到困惑,如果 np.longdoublenp.float128 对这个问题有用的话,值得注意的是问题中设置的那一行初始数组不会给出 np.longdouble 的预期精度。也就是说,y=np.array( [-76188946654889063420743355676.5], dtype=np.longdouble) 首先创建 Python 浮点数组,然后从中创建 numpy 数组,但精度会丢失在 Python 数组中。因此,如果 longdouble 是解决方案,则需要使用不同的方法来初始化数组。)