Finding the corresponding X-axis value from graph

27 views Asked by At

Please check my code from the internet. I am trying to find the X-axis values at 10, 50 and 90 Y-axis values from the chart. But np.intercep() is not working.

I have tried the Y-Intercept and other methods. But couldn't find a solution of my problem.

from pandas import DataFrame
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = {'opening': [4.75, 2, 0.850, 0.425, 0.250, 0.150, 0.075],
        'mass_retained': [0, 10.7, 14.3, 20.8, 23.8, 15.7, 9.2]}

df = DataFrame(data)

def calculate_percent_finer(df):
    total_mass = df.mass_retained.sum()
    arr = []
    for count, sieve in enumerate(df.opening.values):
        cumulative_mass = sum([df.mass_retained.values[i] for i in range(count + 1)])
        percent_finer = ((total_mass - cumulative_mass) / total_mass) * 100
        arr.append(percent_finer)
    return df.assign(p_finer=arr)

df2 = calculate_percent_finer(df)

x= df2.opening
y= df2.p_finer
plt.style.use('bmh')
plt.plot(df2.opening, df2.p_finer,'-gD')
plt.gca().invert_xaxis()
plt.xlabel('Grain Size (mm)')
plt.ylabel('Percent Passing')

plt.show()


I have used the following code. but it didnt work

np.interp(10, df2.p_finer,df2.opening)

And is there a way I can draw those lines y=10, 50 and 90 on the graph as well to see the X-axis values.

1

There are 1 answers

0
BitsAreNumbersToo On BEST ANSWER

To have np.interp work correctly, every element must be greater than the previous in the axis, which is not the case in the original data, so we can add df2.sort_values('p_finer', inplace=True) to make it true, in which case that call works as expected.

In order to put some lines on the graph to show where these interpolations are we can loop over the requested values and add some lines using the same plotting call you already used.

Here is an example of those with minimal alterations to your original code:

from pandas import DataFrame
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

requested_values = [10, 50, 90]

data = {'opening': [4.75, 2, 0.850, 0.425, 0.250, 0.150, 0.075],
        'mass_retained': [0, 10.7, 14.3, 20.8, 23.8, 15.7, 9.2]}

df = DataFrame(data)

def calculate_percent_finer(df):
    total_mass = df.mass_retained.sum()
    arr = []
    for count, sieve in enumerate(df.opening.values):
        cumulative_mass = sum([df.mass_retained.values[i] for i in range(count + 1)])
        percent_finer = ((total_mass - cumulative_mass) / total_mass) * 100
        arr.append(percent_finer)
    return df.assign(p_finer=arr)

df2 = calculate_percent_finer(df)
df2.sort_values('p_finer', inplace=True)

x= df2.opening
y= df2.p_finer
plt.style.use('bmh')
plt.plot(df2.opening, df2.p_finer,'-gD')
plt.gca().invert_xaxis()
plt.xlabel('Grain Size (mm)')
plt.ylabel('Percent Passing')

for interp_value in requested_values:
    calced_interp = np.interp(interp_value, df2.p_finer, df2.opening)
    print(interp_value, calced_interp)
    plt.plot([calced_interp, max(df2.opening)], [interp_value] * 2, '-', linewidth=1, color='grey', label=f'{interp_value:3} -> {calced_interp:5.3f}')
    plt.plot([calced_interp] * 2, [interp_value, min(df2.opening)], '-', linewidth=1, color='grey')
plt.legend()
plt.show()

When I run that I get the following console print and plot:

10 0.15159235668789806
50 0.4143382352941176
90 2.321261682242992

demonstration matplotlib plot with grey lines shown at requested interpolation values

Let me know if you have any questions!