简体   繁体   中英

Python3/Matplotlib: attempt at drawing straight line on log-log scale results in partially curved line

I tried to plot a straight line (linear slope: k = -1.518581016210938 , linear constant (=offset) b = 6.300735205027388 [those numbers were calculated from my data to which I'm trying to plot a best-fit line; I tried a couple of the answers related to plotting logarithmic best-fit lines, but I couldn't get them to work either]) into a log-log scale using matplotlib, but the resulting line looks like it has a curve at the top. Here's my code:

import math

k = -1.518581016210938
b = 6.300735205027388

ext = 1000000

vaakaplot = range(0, 16308+ext)
pystyplot = [10**(k*(math.log(n+1, 10))+b) for n in vaakaplot]

from matplotlib import pyplot as plt

plt.xscale('log')
plt.yscale('log')

plt.plot(vaakaplot, pystyplot, 'b-')

plt.axis([1, 10**6, 1, 10**6])

plt.show()

The output is as follows:

在此处输入图片说明

Can anyone tell me what's wrong and how to fix this?

There's nothing "wrong", per se: a straight line in one frame is not necessarily a straight line in another. This is one of those cases.

A straight line is equivalent to having a constant slope. What you're plotting here, interpreted in a "normal" scale, is the points ( log(x), log(y) ) . As long as the quantities are large, this appears to be a straight line on the log-log scale as well. The slope at any given point past about x=15 is close to k .

However, when x is closer to 0, the tangent involves that +b term in both numerator and denominator. That is what throws off the values you expected. y = kx + b is linear, but your ratio log(y) / log(x) is not.

Try printing the graph in the range 1-10, and you'll see the effect with better magnification.

The relationship you defined is not linear in the log-log domain. For it to be a straight line, we need to be able to substitute x for log(x) and y for log(y) and end up with an equation that looks like y = m*x + b.

In your definition of the y-values, you have added 1 to each value of x. The resulting relationship looks like:

在此处输入图片说明

You cannot substitute log(y) -> y and log(x) -> x without first transforming the x variable. In other words, it is not a linear relationship of log(x) vs log(y), so you should not expect a straight line.

The reason it only looks bent near the left side of the graph is because the effect +1 gets washed out by n as n gets large.

To get a straight line, you can change math.log(n+1, 10) to math.log(n, 10)

vaakaplot = range(1, 16308+ext)
pystyplot = [10**(k*(math.log(n, 10))+b) for n in vaakaplot]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM