Matplotlib:对于浮点值太小的对数标度

时间:2017-05-26 22:44:09

标签: python matplotlib plot floating-point sympy

我想用matplotlib绘制一个图表,其值非常小,以对数刻度显示。这样可以正常工作,直到数字变得太小并且不适合浮动。

我使用SymPy任意精度浮点数表示值,但这些显然在matplotlib内部转换为Python或NumPy机器浮点数。

例如

>>> import sympy
>>> import matplotlib.pyplot as plt
>>> plt.plot([0, 1, 2], [sympy.Float('1e-20'), sympy.Float('1e-100'), sympy.Float('1e-700')])
[<matplotlib.lines.Line2D object at 0x11ac0c208>]
>>> plt.yscale('log')

制作plot

应该显示的是10 ^ -700处的第三个值(不是负无穷大)。

现在我没有希望让matplotlib在内部使用SymPy Floats(如果有可能,请告诉我)。我想要做的是为matplotlib提供值的对数,我可以自己计算得很好,但仍然在y轴上以对数刻度显示该值的指数。

1 个答案:

答案 0 :(得分:3)

您可以进行日志计算,然后绘制数据,如果您想要相同的刻度标签,可以使用FuncFormatter

import sympy
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

x = [0, 1, 2]
y = [sympy.Float('1e-20'), sympy.Float('1e-100'), sympy.Float('1e-700')]

def log_formatter(x, pos):
    return "$10^{{{:d}}}$".format(int(x))

formatter = FuncFormatter(log_formatter)

fig, ax = plt.subplots()

y2 = list(map(lambda x:sympy.log(x, 10), y))
ax.plot(x, y2)
ax.yaxis.set_major_formatter(formatter)
ax.grid();

enter image description here

修改

要添加对数刻度次要刻度,您可以创建Locator

import sympy
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter, Locator

x = [0, 1, 2]
y = [sympy.Float('1e-20'), sympy.Float('1e-100'), sympy.Float('1e-700')]

def log_formatter(x, pos):
    return "$10^{{{:d}}}$".format(int(x))

class LogMinorLocator(Locator):
    def __call__(self):
        majorlocs = self.axis.get_majorticklocs()
        step = majorlocs[1] - majorlocs[0]
        res = majorlocs[:, None] + np.log10(np.linspace(1, 0.1, 10)) * step
        return res.ravel()

formatter = FuncFormatter(log_formatter)

fig, ax = plt.subplots(figsize=(12, 8))
y2 = list(map(lambda x:sympy.log(x, 10), y))
ax.plot(x, y2)
ax.minorticks_on()
ax.yaxis.set_major_formatter(formatter)
ax.yaxis.set_minor_locator(LogMinorLocator())
ax.grid();

这是输出:

enter image description here