此问题在此处已有答案:
Different precision on matplotlib axis(2个答案)
Specify format of floats for tick labels(5个答案)
Is floating point math broken?(34个回答)
10天前关闭。
此帖子已于8天前编辑并提交审核,未能重新打开帖子:
原始关闭原因未解决
举例来说:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0.0,1.2,0.2)
y = np.arange(0.0,1.2,0.2)
labels = np.arange(0.0,1.2,0.2)
plt.plot(x, y)
plt.xticks(x, labels)
plt.show()
字符串
的数据
我不得不使用np.around(np.arange(0.0, 1.2, 0.2),1)
来避免它,但是如果我只运行np.arange(0.0,1.2,0.2)
,它会得到:array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])
,为什么它不同呢?
另外,y轴没有使用0.60...01
作为标签,这也很奇怪。
这个问题是由于IEEE 754浮点精度,我认为它应该有一个很好的解决方案,以四舍五入小数。
2条答案
按热度按时间fcy6dtqo1#
在浮点运算中添加额外的尾随零会导致某些小数不能被精确表示。请阅读this answer沿着其引用。
对于您手头的问题,您可以像这样重新格式化标签
字符串
其中
.1
表示一个有效的十进制数字。3zwjbxry2#
表示0.6的相同浮点数表示匹配整个区间的真实的数。因此,从0.599999999993到0.600000000000003的所有真实的数共享相同的float 64表示。
试试看:
字符串
正如你所看到的,除了第一个和最后一个数字,所有的数字都有相同的表示法。
但这并不是唯一的问题。因为,表示0.59993和0.6003之间的任何真实的的float 64对象,由python表示为该区间的“最圆”数。即,
0.6
。这就是为什么当您在python解释器中键入0.6
时,它不会回复0.599999999999993或0.5999999999999999。(或者,这是测试struct
的最简单方法-但我想介绍struct
-,为什么当你输入0.59999999999994时,python回复0.6,但是当你输入0.5999999999999992时,它会显示0.5999999999999999)问题是0.2都没有精确的表示。
所有从0.1999999999999998到0.20000000000000000002的真实的数都有相同的表示法,而这个表示法只是0.2000000000000001110223024625156540423631668090820的精确表示法.
我知道这是因为:
型
)
现在,我把这个数字乘以3,你得到0.600000000000000003330669073875469621270895004272460.
大于0.6000000000000003
换句话说,0.2*3和0.6并不具有相同的float 64表示。
现在,当打印一个numpy数组时,它有点舍入。
型
⇒
型
这只是numpy的一个显示选项(顺便说一句,可以用
set_printoptions
调整)。__repr__
方法的工作方式。你可以查一下
型
⇒
型
所以你在打印范围时没有看到数值错误。
所有的数字都在那里。只是numpy数组的
__repr__
没有打印出来。0.6也一样
型
至于如何避免:
"0.6"
)xticks
规范。您期望的行为已经是默认行为了xticks
强制使用刻度位置,但不要设置标签,并让默认格式器选择如何打印刻度(因此选择打印哪些刻度,而不是如何打印)plt.xticks(x)
import matplotlib.ticker as tk
plt.gca().xaxis.set_major_formatter(tk.FormatStrFormatter('%.2f'))
我自愿选择使用2位小数来查看与默认值的差异。
xticks
选择在哪里打印标签,用formatter
选择如何打印标签。xticks
来修复tick及其标签,(但我认为应该避免这样做,因为这是重做格式化程序的工作。我只在需要一些特殊标签时才这样做。例如xticks(x, ['zero', '1/5', '40%', '3/5', '80%', 'full'])
),然后传递显式字符串作为标签(如果仍然不能自己选择如何打印传递的非字符串对象,那么重做格式化程序的工作有什么意义呢?)plt.xticks(x, [f'{t:.2f}' for t in x])