BloodSexMagik
BloodSexMagik

Reputation: 398

Plot straight line of best fit on log-log plot

Have some data that I've plotted on a log-log plot and now I want to fit a straight line through these points. I have tried various methods and can't get what I'm after. Example code:

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

x= np.linspace(1,100,10)
y = np.log10(x)+np.log10(np.random.uniform(0,10))
coefficients = np.polyfit(np.log10(x),np.log10(y),1)
polynomial=np.poly1d(coefficients)
y_fit = polynomial(y)
plt.plot(x,y,'o')
plt.plot(x,y_fit,'-')
plt.yscale('log')
plt.xscale('log')

This gives me a ideal 'straight' line in log log offset by a random number to which I then fit a 1d poly. The output is:

enter image description here

So ignoring the offset, which I can deal with, it is not quite what I require as it has basically plotted a straight line between each point and then joined them up whereas I need a 'line of best fit' through the middle of them all so I can measure the gradient of it.

What is the best way to achieve this?

Upvotes: 3

Views: 3428

Answers (1)

Warren Weckesser
Warren Weckesser

Reputation: 114811

One problem is

y_fit = polynomial(y)

You must plug in the x values, not y, to get y_fit.

Also, you fit log10(y) with log10(x), so to evaluate the linear interpolator, you must plug in log10(x), and the result will be the base-10 log of the y values.

Here's a modified version of your script, followed by the plot it generates.

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


x = np.linspace(1,100,10)
y = np.log10(x) + np.log10(np.random.uniform(0,10))

coefficients = np.polyfit(np.log10(x), np.log10(y), 1)
polynomial = np.poly1d(coefficients)
log10_y_fit = polynomial(np.log10(x))  # <-- Changed

plt.plot(x, y, 'o-')
plt.plot(x, 10**log10_y_fit, '*-')     # <-- Changed
plt.yscale('log')
plt.xscale('log')

plot

Upvotes: 1

Related Questions