Ajustar la línea recta en la escala de semi-registro con Matplotlib

He estado luchando para ajustar una línea recta en un gráfico de semi-log hecho con Matplotlib y Python 3. He visto muchos ejemplos de cifras de log-log scale, pero ninguna de las soluciones que probé funcionó (con numpy ). La línea siempre termina siendo torcida en alguna parte.

Lo siguiente es lo que tengo hasta ahora:

 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') 

El archivo data.csv asociado tiene el siguiente aspecto:

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

La figura que obtengo se ve como sigue, donde la línea ajustada está torcida. Parcela semi-log con ajuste que debe ser una línea recta.

Comentarios y sugerencias son muy apreciados.

Si ajusta el logaritmo de los datos a una línea, necesita invertir esta operación cuando realmente grafica los datos ajustados. Es decir, si ajusta una línea a np.log(y) , necesita trazar 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--') 

Ejemplo completo:

 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() 

introduzca la descripción de la imagen aquí