2

How I can get a point on the curve plotting when I have only one known Y-coordinate equation i.e. P = a * b (where a & b are defined values say 0.8,150) and x-coordinate is totally unknown and there is no equation linking x and y ( ex: y = mx +b; # i don't have this kind of equations). So, now the target is if say I have 'Y-coordinate' value as 120 and need to plot a point on the curve by taking distance or path from the unknown 'x-coordiante' value.

I tried the code as below

One sample figure about how I should plot

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline

# given values
y = np.array([0, 38.39, 71.41, 99.66, 123.67, 143.88, 160.61, 174.03, 184.16, 190.8, 193.52])
x = np.array([0, 0.37, 0.74, 1.11, 1.48, 1.85, 2.22, 2.59, 2.96, 3.33, 3.7])
x_val = np.linspace(0,7) #limts on x-axis
a = 0.8
b = 150
y_val = np.multiply(a, b)
yinterp = np.interp(x_val, x, y)
plt.plot(x, y, '-')
plt.plot(x_val, yinterp, 'o')

#here i need to plot a exact point w.r.t to y_val
#and also need to show the distance with a line from the selected x and y coordinates

plt.plot(x_val,y_val, '--') 
plt.show()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
Santo
  • 41
  • 2
  • 15
  • 1
    I'm not really sure what you are trying to achieve, but you will probably need to use something like `np.interp(y_val, y, x)`. – MB-F Nov 29 '17 at 09:38
  • @kazemakase thanks for the reply, my aim is to plot a point on a curve when i know the y-intercept say (0,120) but i don't know x-intercept values.Now I need to find the x-intercept points by using y-intercept. You can also see the image attached. – Santo Nov 29 '17 at 09:46
  • 1
    I don't know what an intercept is (in this case) but the code in my comment above returns the interpolated x that corresponds to `y_val`, which seems to be what you are after... – MB-F Nov 29 '17 at 09:51
  • Yes the code you written in comment is working but my aim is to get only one point on the curve w.r.t. Y value and in my case the y-intercept value to be taken as(0,y_val). I only need to plot one point on x-axis by using y_value – Santo Nov 29 '17 at 10:17

1 Answers1

4

What you want is to find the root(s) or zero(s) of an array. This question's answer shows how to do that: How to get values from a graph?

Applying the solution to this case here would look as follows:

import matplotlib.pyplot as plt
import numpy as np

# given values
y = np.array([0, 38.39, 71.41, 99.66, 123.67, 143.88, 160.61, 174.03, 184.16, 190.8, 193.52])
x = np.array([0, 0.37, 0.74, 1.11, 1.48, 1.85, 2.22, 2.59, 2.96, 3.33, 3.7])
x_val = np.linspace(0,7) 

plt.plot(x, y, '-')

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)

a = 0.8
b = 150
y_val = np.multiply(a, b)

roots = find_roots(x, y-y_val)
plt.plot(roots[0],y_val, marker="o") 
plt.plot([roots[0],roots[0],0],[0,y_val,y_val], "--")

plt.xlim(0,None)
plt.ylim(0,None)
plt.show()

enter image description here

If the arrays are monotonically increasing, you may of course also simply interpolate:

import matplotlib.pyplot as plt
import numpy as np

# given values
y = np.array([0, 38.39, 71.41, 99.66, 123.67, 143.88, 160.61, 174.03, 184.16, 190.8, 193.52])
x = np.array([0, 0.37, 0.74, 1.11, 1.48, 1.85, 2.22, 2.59, 2.96, 3.33, 3.7])
x_val = np.linspace(0,7) 

plt.plot(x, y, '-')

a = 0.8
b = 150
y_val = np.multiply(a, b)

root = np.interp(y_val,y,x)
plt.plot(root,y_val, marker="o") 
plt.plot([root,root,0],[0,y_val,y_val], "--")

plt.xlim(0,None)
plt.ylim(0,None)
plt.show()
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thanks alot this is what exactly I needed and may I know for this can I take the x,y points as a csv file rather than entering all points. – Santo Nov 29 '17 at 11:30
  • Yes that is sure possible. – ImportanceOfBeingErnest Nov 29 '17 at 11:31
  • for the same question may I know how I can plot if I have a CSV file as attached to the question where there are 3 columns in which x and y columns are used to plot the line and z column is used to group the x and y columns to get multiple lines. – Santo Dec 04 '17 at 07:54
  • I am successful in applying csv files but I need help in finding the roots when x_val is given but y_val is unkown, reverese of above case may I know what factors i need to change in the below equation do i need to inter change x with 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 – Santo Dec 05 '17 at 08:21
  • So, first of all, my solution may have been a bit too complicated for this simple case, so I updated the answer. For doing the inverse, you just change the role of y and x. – ImportanceOfBeingErnest Dec 05 '17 at 10:51
  • Great!! but I am getting an error saying "array of sample points is empty" for the below lines(I coverted it as array to avoid error but still the same error is repeated) : semi_unrein_sig_min is the variable :- y_min = np.asarray(semi_unrein_sig_min,dtype=float) ; x_min = np.interp(y_min,y,x) – Santo Dec 05 '17 at 11:59
  • Most of the times, python errors really directly tell you the problem. In this case, either `x` or `y` or both are empty. I hope you don't expect me to know what you did for that to happen. – ImportanceOfBeingErnest Dec 05 '17 at 12:05
  • my x and y points are also in array:- x=np.asarray(gdf.index.values); y=np.asarray(gdf['y'].values) – Santo Dec 05 '17 at 12:06