用Matplotlib以半对数刻度拟合直线 [英] Fit straight line on semi-log scale with Matplotlib

查看:146
本文介绍了用Matplotlib以半对数刻度拟合直线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力用Matplotlib和Python 3制作的半对数图上拟合直线.我看到了许多对数对数比例图的示例,但是我尝试过的所有解决方案都没有(使用numpy ).该行总是最终在某个地方弯曲.

I have been struggling with fitting a straight line on a semi-log plot made with Matplotlib and Python 3. I have seen many examples of log-log scale figures, but none of the solutions I tried worked (using numpy). The line always ends up being crooked somewhere.

以下是我到目前为止的内容:

The following is what I have thus far:

import os
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

base_path = os.path.dirname(os.path.realpath(__file__))

fig = plt.figure()
ax = fig.add_subplot(111)

# Plot data.
location = os.path.join(base_path, "data.csv")
data = np.genfromtxt(location, delimiter=',', names=['year', 'bw'])
ax.plot(data['year'], data['bw'])

# Fit test.
x = data['year']
y = data['bw']
y_ln = np.log10(y)

n = data.shape[0]
A = np.array(([[x[j], 1] for j in range(n)]))
B = np.array(y_ln[0:n])
B = np.array(y[0:n])

X = np.linalg.lstsq(A, B)[0]
a = X[0]
b = X[1]

fit = a * x + b

p = np.polyfit(x, np.log(y), 1)
ax.semilogy(x, p[0] * x + p[1], 'g--')

ax.set_yscale('log')

关联的data.csv文件如下所示:

2016, 68.41987090116676
2017, 88.9788618486191
2018, 90.94850458504749
2019, 113.20946182004333
2020, 115.71547492850719

我得到的图形如下所示,其中拟合线是弯曲的.

The figure I obtain looks as following, where the fitted line is crooked.

非常感谢您的反馈和建议.

Feedback and suggestions are very much appreciated.

推荐答案

如果将数据的对数拟合到一条线上,则在实际绘制拟合的数据时需要反转此操作. IE.如果您将线插入np.log(y),则需要绘制np.exp(fit_result).

If you fit the logarithm of the data to a line, you need to invert this operation when actually plotting the fitted data. I.e. if you fit a line to np.log(y), you need to plot np.exp(fit_result).

# Fit test.
x = data['year']
y = data['bw']

p = np.polyfit(x, np.log(y), 1)
ax.semilogy(x, np.exp(p[0] * x + p[1]), 'g--')

完整示例:

import io
import matplotlib.pyplot as plt
import numpy as np

u = u"""2016, 68.41987090116676
2017, 88.9788618486191
2018, 90.94850458504749
2019, 113.20946182004333
2020, 115.71547492850719"""

data = np.genfromtxt(io.StringIO(u), delimiter=',', names=['year', 'bw'])

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(data['year'], data['bw'])

# Fit test.
x = data['year']
y = data['bw']

p = np.polyfit(x, np.log(y), 1)
ax.semilogy(x, np.exp(p[0] * x + p[1]), 'g--')

ax.set_yscale('log')

plt.show()

这篇关于用Matplotlib以半对数刻度拟合直线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆