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.
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
Let me know if you have any questions!