6
votes

How can I get from a plot in Python an exact value on y - axis? I have two arrays vertical_data and gradient(temperature_data) and I plotted them as:

plt.plot(gradient(temperature_data),vertical_data)
plt.show()

Plot shown here:

plot

I need the zero value but it is not exactly zero, it's a float.

1
What have you tried? Please create a Minimal, Complete, and Verifiable Example. - DavidG
I guess the problem description is a bit misleading, if present at all. What you want is to find the zero of a numpy array. This has nothing to do with matplotlib. (Also there are more than one zero). This is in general a non-trivial task. But depending on the accuracy needed, can be simplified. - ImportanceOfBeingErnest
Well I should see it in that plotted graph, I think - Arcturus

1 Answers

12
votes

I did not find a good answer to the question of how to find the roots or zeros of a numpy array, so here is a solution, using simple linear interpolation.

import numpy as np
N = 750
x = .4+np.sort(np.random.rand(N))*3.5
y = (x-4)*np.cos(x*9.)*np.cos(x*6+0.05)+0.1


def find_roots(x,y):
    s = np.abs(np.diff(np.sign(y))).astype(bool)
    return x[:-1][s] + np.diff(x)[s]/(np.abs(y[1:][s]/y[:-1][s])+1)

z = find_roots(x,y)

import matplotlib.pyplot as plt

plt.plot(x,y)
plt.plot(z, np.zeros(len(z)), marker="o", ls="", ms=4)

plt.show()

enter image description here

Of course you can invert the roles of x and y to get

plt.plot(y,x)
plt.plot(np.zeros(len(z)),z, marker="o", ls="", ms=4)

enter image description here


y0y-y0
y0 = 1.4
z = find_roots(x,y-y0)
# ...
plt.plot(z, np.zeros(len(z))+y0)

enter image description here


People were also asking how to get the intersection between two curves. In that case it's again about finding the roots of the difference between the two, e.g.

x = .4 + np.sort(np.random.rand(N)) * 3.5
y1 = (x - 4) * np.cos(x * 9.) * np.cos(x * 6 + 0.05) + 0.1
y2 = (x - 2) * np.cos(x * 8.) * np.cos(x * 5 + 0.03) + 0.3

z = find_roots(x,y2-y1)

plt.plot(x,y1)
plt.plot(x,y2, color="C2")
plt.plot(z, np.interp(z, x, y1), marker="o", ls="", ms=4, color="C1")

enter image description here