首页 > 解决方案 > 使用 Matplotlib 在半对数尺度上进行线性拟合

问题描述

我一直在玩弄直线拟合(我只是偶然成功)。请帮助我理解为什么此代码绘制一条直线以及更改 plt.xscale 时发生的情况

import matplotlib.pyplot as plt
import numpy as np

# data
x = [0, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100]
y = [0.0, 29.80899, 41.297, 50.22667, 55.605, 60.20733, 65.050, 66.018, 68.4767]

# creates figure
plt.figure()
plt.plot(x, y, marker = 'o', linestyle = '')  # plots data
plt.xlim(-0.01, 150)  # sets the x limits of the current axes

x[0] = 10**(-4)  # replaced zero at index [0] with approximation

# generate linear fit
p = np.polyfit(np.log10(x), y, 1)  # generates m,b values
polynomial = np.poly1d(p)  # creates equation for linear fit of degree 1 with m,b values
log10_y_fit = polynomial(np.log10(x))  # generates values for y axis to be plotted

plt.plot(x, log10_y_fit, 'b-')  # plots linear fit in blue
plt.xscale('symlog', linthresh=1e-3, subs=[1, 2, 3, 4, 5, 6, 7, 8, 9])  # converts x-axis to symmetric log scale

plt.show()

直线图

然而,当我改变

plt.xscale('symlog', linthresh=1e-3, subs=[1, 2, 3, 4, 5, 6, 7, 8, 9])  # converts x-axis to symmetric log scale

别的东西,比如

plt.xscale('symlog', linthresh=1e-1, subs=[2, 3, 4, 5, 6, 7, 8, 9])  # converts x-axis to symmetric log scale

我得到一个像这样的“弯曲”线

“弯曲”图

标签: pythonnumpymatplotlibgraph

解决方案


对称对数标度通常用于对称信号(即在正值和负值之间变化)。在你的情况下,信号是正的,所以我建议使用对数刻度log(见下文)。

信号弯曲的原因: symlog 尺度弯曲效应来自于linethres值,它表示在哪个x值处对数尺度从负值变为正值(有关更多信息,请参见matplotlib 对称对数尺度)。如果该linethres值高于您的最低 x 轴点,则信号“弯曲”以从正对数刻度变为负对数刻度,并显示所有值(在短刻度上挤压)。

  • 这是具有低阈值的代码输出。弯道在这里却看不见

    plt.xscale('symlog', linthresh=1e-4)
    

    具有低阈值的符号日志

  • 现在有了更高的阈值,信号必须比其定义更快地达到 0,以允许对称对数刻度。

    plt.xscale('symlog', linthresh=1e-1)
    

    具有高阈值的符号日志

  • 最后,在您的情况下,您应该更好地使用log比例:

    plt.xscale('log')
    plt.xlim([1e-1, 1e2])  # this if you want to play with axes limits
    

    对数刻度


推荐阅读